<?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; AIR</title>
	<atom:link href="http://probertson.com/articles/category/air/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>Mon, 30 Aug 2010 16:38:38 +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>Slides, examples, and links: Developing iPhone apps with the Flash Platform</title>
		<link>http://probertson.com/articles/2010/03/16/slides-and-examples-developing-iphone-apps-flash-platform/</link>
		<comments>http://probertson.com/articles/2010/03/16/slides-and-examples-developing-iphone-apps-flash-platform/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 00:57:00 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=417</guid>
		<description><![CDATA[
Last week I gave a presentation at 360&#124;Flex 2010 (San Jose) on &#8220;Developing iPhone apps with the Flash Platform.&#8221; As always, I wanted to make my slides, notes, reference links, and example code available to those who were there and those who couldn&#8217;t make it:
Download slides, links, and example code (3.1 MB .zip)
I&#8217;ve been traveling [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/resources/2010/03/16/iphone_flash_platform_resources.jpg" alt="Flash logo pointing to iPhone with presentation title" /></p>
<p>Last week I gave a presentation at 360|Flex 2010 (San Jose) on &#8220;Developing iPhone apps with the Flash Platform.&#8221; As always, I wanted to make my slides, notes, reference links, and example code available to those who were there and those who couldn&#8217;t make it:</p>
<p><a href="/resources/2010/03/16/iphone_flash_platform_resources.zip">Download slides, links, and example code</a> (3.1 MB .zip)</p>
<p>I&#8217;ve been traveling since the conference so I didn&#8217;t flesh out my notes as thoroughly as I have for past presentations. If you have a question about a slide, feel free to ask in the comments and I&#8217;ll try to explain it better. The 360|Flex folks recorded video of my presentation as well as a screen capture. I believe the plan is to make those recordings available to attendees as well as people who couldn&#8217;t make it (though they may charge a fee if you didn&#8217;t attend the conference).</p>
<h2>Acknowledgments</h2>
<p>This is in the slides, but I wanted to once again thank all the people who helped me prepare this presentation (some knowingly, others just by virtue of content they&#8217;ve shared):</p>
<ul>
<li><a href="http://flashrealtime.com/">Tom Krcha</a></li>
<li><a href="http://renaun.com/">Renaun Erickson</a></li>
<li><a href="http://www.linkedin.com/pub/jeff-swartz/1/52/b84">Jeff Swartz</a></li>
<li><a href="http://adityabansod.net/">Aditya Bansod</a></li>
<li><a href="http://www.onflash.org/">Ted Patrick</a></li>
<li><a href="http://www.mikechambers.com/">Mike Chambers</a></li>
<li><a href="http://theflashblog.com/">Lee Brimelow</a></li>
<li><a href="http://www.linkedin.com/in/chiedozi">Chiedo Acholonu</a></li>
<li><a href="http://twitter.com/gburch">Greg Burch</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2010/03/16/slides-and-examples-developing-iphone-apps-flash-platform/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thoughts on multi-screen, multi-context app development</title>
		<link>http://probertson.com/articles/2010/02/09/thoughts-on-multi-screen-context-app-development/</link>
		<comments>http://probertson.com/articles/2010/02/09/thoughts-on-multi-screen-context-app-development/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 01:00:58 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Contextual design]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Multi-screen]]></category>
		<category><![CDATA[Opinions]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[User-centered design]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=372</guid>
		<description><![CDATA[Around 8 months ago I was asked to start thinking about the now emerging (particularly from a Flash Platform perspective) world of multi-screen application development. What are issues to consider? What guidance should we offer?
It turns out that my thinking on that topic isn&#8217;t going to become anything in the Adobe documentation. So I&#8217;ve sort [...]]]></description>
			<content:encoded><![CDATA[<p>Around 8 months ago I was asked to start thinking about the now emerging (particularly from a Flash Platform perspective) world of multi-screen application development. What are issues to consider? What guidance should we offer?</p>
<p>It turns out that my thinking on that topic isn&#8217;t going to become anything in the Adobe documentation. So I&#8217;ve sort of just been sitting on my ideas with the idea that someday I&#8217;ll probably share them.</p>
<p>Which brings me to this post.</p>
<h2>Aside: upcoming presentations on multi-screen development</h2>
<p>This is really a side note to the main ideas here, but I thought I&#8217;d mention it since it&#8217;s the reason I actually stopped to write this. In one of my mind-wandering moments this morning, I realized that at the upcoming <a href="http://360flex.com/">360|Flex conference (San Jose, March 7-10)</a> I&#8217;ll be involved in two presentations that are directly related to practical aspects of building multi-screen apps:</p>
<ul>
<li>
<p>As part of the pre-conference free training, <a href="http://joelhooks.com/">Joel Hooks</a> and I are doing a four-hour training on using the <a href="http://robotlegs.org/">Robotlegs micro-architecture</a>. (Joel is the main speaker, fortunately, because he&#8217;s one of the core Robotlegs developers and the main &#8220;evangelist.&#8221; I&#8217;ll be helping out, to try and help save his voice and maybe to help find typos. =)</p>
<p>If you&#8217;re wondering what a Robotlegs session has to do with multi-screen apps&#8230;keep reading, it&#8217;s explained below.</p>
</li>
<li>On Tuesday and Wednesday, <a href="http://renaun.com/">Renaun Erickson</a> and I are giving (two separate) presentations about building iPhone apps using Flash Platform tools. My session is more of an intro into the workflow, how it&#8217;s similar to other app building, and how it&#8217;s different. (Plenty of code to look at &#8212; don&#8217;t worry!) Renaun is going to get more into specifics of building a game, as well as some more intermediate/advanced topics like performance.</li>
</ul>
<p>Funny that I never really made that connection until this morning. I guess subconsciously I knew this is a direction I want to move in, and that&#8217;s why I&#8217;ve been focusing my learning (and hence my presenting) on these topics =)</p>
<h2>Background</h2>
<p>While I was partially trying to keep my thinking abstract, from a practical perspective I centered my thoughts around developing using the Flash Platform. So conceptually, what I was thinking about was the idea of making a single &#8220;app&#8221; for multiple screens, which would mean that (in the technology of the next year or so) it could be potentially take several forms:</p>
<ul>
<li>a browser/computer app (Flash Player)</li>
<li>a browser/mobile app (Flash Player)</li>
<li>a desktop app (AIR)</li>
<li>a mobile (iPhone) app (Publisher for iPhone, similar to AIR)</li>
<li>a mobile app for other devices (AIR)</li>
<li>a TV app or widget (<a href="http://tv.adobe.com/watch/max-2009-design/flash-for-the-digital-home-flash-on-tv/">Flash for the digital home</a>)
</ul>
<p>(Obviously many of these are only out in public beta, some have only been vaguely publicly acknowledged, and others may or may not ever exist as actual Adobe products =)</p>
<h2>One app, or many?</h2>
<p>Back when I started thinking about this, there seemed to be two main camps. One group was a strong advocate for the &#8220;single source&#8221; idea: you would build one SWF or one AIR app and distribute that same app on any platforms (desktop/mobile/TV). Obviously a key element to that, especially for desktop/mobile apps rather than browser apps, would be having code that detects screen size and device capabilities and adapts the UI to the device.</p>
<p>The second group felt that it was more likely that developers who are creating an app for multiple screens would actually create multiple apps (from the perspective of the IDE). The apps would obviously share some code, visual assets, etc., but would be different enough that they&#8217;d be created separately and distributed as separate file types. (In the case of apps created for the iPhone, of necessity this has to be true, at least in terms of the publishing part.)</p>
<p>Since I try to be pragmatic about things unless I have a <em>really</em> good reason, I favored the second viewpoint. However, I acknowledge that in some circumstances the first approach might be used. As always, I think that developers are going to use a mix of approaches.</p>
<p>For example, suppose I&#8217;m building an app and I want to create a version for desktop computers, a version for the iPhone, and a version for other mobile devices. Personally I see this not just as an issue of &#8220;porting&#8221; the app from one platform to another. I think that each device has its strengths, and more importantly, each device is used for different purposes and in different contexts. If I&#8217;m building an app for a device, I should definitely be <a href="http://blog.digitalbackcountry.com/2009/10/introducing-contextual-applications/">taking that notion of context into account</a> as I&#8217;m designing the app. That pretty much rules out the possibility of using the exact same app (UI and everything) for both computers and mobile devices, unless I want it to run as a widget-type app on the desktop.</p>
<p class="editornote">Also see: <a href="http://www.adobe.com/devnet/flashplatform/context_apps/">Adobe Flash Platform contextual applications developer center</a></p>
<h2>Adaptable code to the rescue</h2>
<p>On the other hand, that doesn&#8217;t mean that developers will always create completely separate projects. For example, suppose I&#8217;m creating an app for iPhone, and another for another mobile device. Or perhaps I&#8217;m using the Publisher for iPhone to create an iPhone version of my app and an iPad version. If my app is a game where I can more freely discard the conventions of the platforms, perhaps the only platform difference I need to consider is the difference in screen dimensions and pixel density. In that case, it&#8217;s quite possible that I can <a href="http://www.adobe.com/devnet/flash/articles/authoring_for_multiple_screen_sizes.html"use the same source code and have it adapt to the different screen sizes</a>.</p>
<h2>Frameworks to the rescue</h2>
<p>Even for a more line-of-business or productivity app, one of the key ideas in <a href="http://tv.adobe.com/watch/max-2009-develop/preview-flex-for-mobile-devices/">Slider</a>, the future <a href="http://flashmobile.scottjanousek.com/2010/02/12/adobe-flex-for-mobile-whitepaper/">Flex mobile framework</a>, is to (as much as possible) abstract away platform convention differences. For example, if iPhone usually puts the back button on the top, and another platform puts it on the bottom, and another platform puts it in a menu, and another platform has it assigned to a physical button on the device, then Slider might have a &#8220;back&#8221; event that you can hook into, and you can make your app perform the necessary &#8220;back&#8221; tasks regardless of platform.</p>
<h2>Design patterns to the rescue</h2>
<p>And, of course, in some situations you&#8217;ll almost surely need to create different versions of apps for different screens. For example, suppose you&#8217;re building a desktop Twitter client and a mobile Twitter client. Chances are good you&#8217;ll put some functionality into the desktop version that doesn&#8217;t go into the mobile one &#8212; such as previewing images, or maybe Facebook integration. On the other hand, adding a feature like automatic location tagging would make lots of sense in the mobile version, but not so much in the desktop one.</p>
<p>As I was thinking, many months ago, about the idea of efficiently creating different versions of the same app for different devices, a thought hit me like a ton of bricks. This is exactly the use case that the oft-mentioned &#8220;separation of concerns&#8221; is designed for:</p>
<p>Over several years, various &#8220;micro architectures&#8221; and &#8220;application frameworks&#8221; have emerged and waxed and waned in popularity. Many of these architectures are modeled around the &#8220;<a href="http://en.wikipedia.org/wiki/Model-view-controller">Model-View-Controller</a>&#8221; design pattern (or its many variations).</p>
<p>One of the key benefits that these architectures claim is that it helps you keep the pieces of your application separate, without explicit links and dependencies between them. I&#8217;ve looked into and even tried out several of these over the years. One example that is frequently used to describe the notion of separation of concerns, which I always struggled with, goes something like this:</p>
<blockquote><p>
Suppose you&#8217;re creating an app, and you build the user interface and the other logic like server communication and data processing. If you use MVC/separation of concerns, then it&#8217;s really easy to just rip out your whole user interface layer and replace it with a new one.
</p></blockquote>
<p>They usually lost me with that one. As much as I tried, I couldn&#8217;t imagine a situation in which I&#8217;d want to build my app and then just rip out the UI and replace it with a different one <a id="note1src" class="footnote" href="#note1">note 1</a>.</p>
<p>Until now.</p>
<p>Suddenly I had discovered, for myself at least, a real-world use case for the separation-of-concerns-so-you-can-swap-out-the-UI argument. If I&#8217;m building an app for the desktop and mobile, I&#8217;d like to be able to reuse my code where I can. At the same time, some functionality is only going to apply to one app or the other, so it&#8217;d be nice to be able to plug it in cleanly. Oh and by the way, the user interfaces are going to be different, so being able to swap those out is an absolute must.</p>
<p>I&#8217;d always liked micro-architectures in general, if only because I like knowing that I&#8217;m building my app using some pattern or structure that is based on developers&#8217; real-world experience. It&#8217;s much nicer than trying to invent it myself and having to deal with all the pain points they&#8217;ve already gotten over. Now that I am imagining a world where I create multiple versions of the same app, with similar functionality but different user interfaces, suddenly micro-architecture patterns have become indispensable in my mind.</p>
<h2>Conclusion</h2>
<p>These are only just a few of my thoughts about the future world of multi-screen, contextual applications. Like Lee Brimelow, I believe that going forward <a href="http://theflashblog.com/?p=1743">building multi-screen, multi-context apps is going to be a much more common scenario</a>. From my perspective as someone who thinks a lot about user experience design, and trying to optimize tools for the task and context, I think this is one of the most exciting aspects of the current technology revolution. I&#8217;ll definitely continue to share my thoughts and ideas in the future (hopefully more practical ones, too, not just abstract ones like this =)</p>
<h2>Notes</h2>
<p class="footnote" id="note1">Note 1: Just to be clear, I&#8217;m not trying to sound negative about MVC or micro-architectures/frameworks. Most of them provide many benefits, many of which are also related to the idea of separation of concerns, such as making code easier to test, making code cleaner, reducing boilerplate code, providing structure so that teams or developers who inherit a project can get going more quickly, etc. Swapping out the view layer is just one little benefit they mention. (<a href="#note1src">back</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2010/02/09/thoughts-on-multi-screen-context-app-development/feed/</wfw:commentRss>
		<slash:comments>2</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>Flex and AIR usability studies</title>
		<link>http://probertson.com/articles/2009/07/14/flex-and-air-usability-studies/</link>
		<comments>http://probertson.com/articles/2009/07/14/flex-and-air-usability-studies/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 17:46:28 +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[Life at Adobe]]></category>
		<category><![CDATA[User-centered design]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=312</guid>
		<description><![CDATA[My team at Adobe is conducting a few usability-type studies to learn more about how our customers actually work (and hopefully improve our products as a result =). To sweeten the deal, we&#8217;re offering Amazon gift cards for participants. (There are a limited number of participant slots available.)
We&#8217;re mainly looking for developers who have Flex [...]]]></description>
			<content:encoded><![CDATA[<p>My team at Adobe is conducting a few usability-type studies to learn more about how our customers actually work (and hopefully improve our products as a result =). To sweeten the deal, we&#8217;re offering Amazon gift cards for participants. (There are a limited number of participant slots available.)</p>
<p>We&#8217;re mainly looking for developers who have Flex experience but little or no experience developing for Adobe AIR. There aren&#8217;t many other restrictions &#8212; We&#8217;ll conduct the study on the phone and online using Adobe Connect.</p>
<p>Admittedly, I realize that if you read what I write here then there&#8217;s a good chance that you&#8217;ve already got too much AIR development experience. Even so, we&#8217;d appreciate it if you can spread the word to other developers you know who might be qualified.</p>
<p>If you&#8217;re interested or want to get more details, check out the official post on my team&#8217;s blog:</p>
<p><a href="http://blogs.adobe.com/actionscriptdocs/2009/07/need_participants_for_studies.html">Need participants for studies about AIR and Flex</a></p>
<p>On a related note, we&#8217;re also conducting some (very brief) surveys about your experience developing AIR applications (Flex or HTML/JS). I can&#8217;t remember all the places where you might encounter them, but if you browse around the documentation or the developer center for a while there&#8217;s a chance you&#8217;ll be offered the survey. If you&#8217;ve done some AIR development and get a chance to take the survey, we&#8217;d like to hear about your experiences.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/07/14/flex-and-air-usability-studies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Survey: Is a ChosenSecurity certificate trusted on your machine?</title>
		<link>http://probertson.com/articles/2009/06/24/survey-chosensecurity-certificate-trusted/</link>
		<comments>http://probertson.com/articles/2009/06/24/survey-chosensecurity-certificate-trusted/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 18:32:34 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Privacy/security]]></category>
		<category><![CDATA[Surveys]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=296</guid>
		<description><![CDATA[Please take the following &#8220;survey&#8221; to see if a ChosenSecurity code-signing certificate is trusted on your machine.
(If you&#8217;re curious, you can read the background details below.)
Here&#8217;s how you can help:

Download the .air file for the test application (339 KB)
Double-click the .air file to install it (you&#8217;ll need to have Adobe AIR installed already, of course).

When [...]]]></description>
			<content:encoded><![CDATA[<p>Please take the following &#8220;survey&#8221; to see if a ChosenSecurity code-signing certificate is trusted on your machine.</p>
<p>(If you&#8217;re curious, you can read the <a href="#background">background details</a> below.)</p>
<p>Here&#8217;s how you can help:</p>
<ol>
<li>Download <a href="/resources/2009/06/24/CertTest.air">the .air file for the test application</a> (339 KB)</li>
<li>Double-click the .air file to install it (you&#8217;ll need to have <a href="http://get.adobe.com/air/">Adobe AIR</a> installed already, of course).</li>
<li>
<p>When the installer gets to the warning dialog, check to see if the certificate is trusted or not. If the certificate is trusted, the dialog will look like this (the circled areas are the specific things to check for):
<div><img src="/resources/2009/06/24/cert-test-install-dialog-callouts.png" width="480" height="364" /></div>
<p>You can cancel the installation once you&#8217;ve seen the dialog &#8212; it&#8217;s just a super-plain &#8220;hello world&#8221; application anyway.</p>
</li>
<li><a href="#respond">Leave a comment</a> with your results! If the certificate is trusted (if it looks like the image) leave a &#8220;Yes&#8221; comment. If the certificate isn&#8217;t trusted, say &#8220;No&#8221; in your comment. In either case, you get bonus points if you add what kind of computer (manufacturer and model name) you tested, what operating system (including version number and language) you&#8217;re running, and where (country/city) you live.</li>
<li>Repeat the test on other computers you may have access to (parents, friends, roommates, etc.). Spread the word and ask your developer friends to test it out also! I&#8217;d like to get a good cross-section of machines, not just developer machines in the United States running the latest OS X or Windows.</li>
</ol>
<p>Once again, here&#8217;s the link to <a href="#respond">leave a comment</a> with your results.</p>
<h2 id="background">Background</h2>
<p>I got a code-signing certificate from <a href="http://www.chosensecurity.com/products/tc_publisher_id_adobe_air.htm">ChosenSecurity</a>. Since they&#8217;re not a &#8220;big name&#8221; Certificate Authority like Verisign, I was worried that the certificate might not be trusted on as many machines. (If on a given machine a chain of trust can&#8217;t be established for a certificate you get the &#8220;unknown publisher&#8221; dialog when you&#8217;re installing AIR apps signed with that cert, regardless of whether the certificate is self-signed or not.)</p>
<p>However, since I was <a href="http://www.adobe.com/go/airmarketplace">getting my code-signing certificate for free</a>, I decided to give it a try and be the &#8220;guinea pig&#8221; for other developers who might be considering a ChosenSecurity certificate. (The advantages of the ChosenSecurity cert are that it costs less and you don&#8217;t have to have a backing company &#8212; you can get the certificate as an individual.)</p>
<p>Thanks very much for participating. Remember, this isn&#8217;t just for me &#8212; this is for all AIR developers who are wanting to get a code-signing certificate for less, but are concerned that the certificate might not be trusted on every machine where they&#8217;d like their apps to run.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/06/24/survey-chosensecurity-certificate-trusted/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>New features in the next Adobe AIR &#8220;Athena&#8221;</title>
		<link>http://probertson.com/articles/2009/06/24/new-features-adobe-air-athena/</link>
		<comments>http://probertson.com/articles/2009/06/24/new-features-adobe-air-athena/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 17:51:03 +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[Privacy/security]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=282</guid>
		<description><![CDATA[Note: article updated Sept. 18, 2009 with additional features that have been made public since the original post.
&#8230;and another update Sept. 22, 2009
&#8230;and still another update Sept. 25, 2009
If you were following Twitter during the San Francisco Flash Camp on May 29, you might have seen that Arno Gourdol, Engineering manager for AIR, announced/showed a [...]]]></description>
			<content:encoded><![CDATA[<p class="editornote">Note: article updated Sept. 18, 2009 with <a href="#update1">additional features</a> that have been made public since the original post.</p>
<p class="editornote">&#8230;and another update <a href="#update2">Sept. 22, 2009</a></p>
<p class="editornote">&#8230;and still another update <a href="#update3">Sept. 25, 2009</a></p>
<p>If you were following Twitter during the San Francisco Flash Camp on May 29, you might have seen that <a href="http://arno.org/">Arno Gourdol</a>, Engineering manager for AIR, announced/showed a few features that are going to be in the next major version of AIR code name &#8220;Athena&#8221;.</p>
<div><img src="/resources/2009/06/24/arno-flash-camp-athena-slide.jpg" width="378" height="270" /></div>
<p>Today I found the link to the video of Arno&#8217;s presentation &#8220;<a href="http://labs.adobe.com/technologies/flash/videos/flashcamp/gourdol/">Flash Camp Update on Adobe AIR</a>,&#8221; so even if you couldn&#8217;t attend you can learn about those features yourself. The video&#8217;s fairly long and the new stuff is near the middle/end, so here are the highlights for you to watch for (sadly the video doesn&#8217;t have time markers so I can&#8217;t give exact times):</p>
<ul>
<li>
<p>He starts the demo a little past the half-way point of the presentation.</p>
</li>
<li>
<p>He shows an app that detects when a drive is mounted/unmounted by listening for the new <code>StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT</code> and <code>STORAGE_VOLUME_UNMOUNT</code> events. He plugs a USB thumb drive into his computer and, sure enough, the new drive appears in the FileSystemDataGrid in his app.</p>
<div><img src="/resources/2009/06/24/arno-flash-camp-code-sneak-1.jpg" width="427" height="248" /></div>
</li>
<li>
<p>Next he shows a change to the AIR installation process that&#8217;s coming in the &#8220;Squirter&#8221; release, which is a dot release coming out &#8220;probably late this summer&#8221; according to the video. The change is specifically to the warning dialog that&#8217;s displayed when a user installs an AIR app that&#8217;s signed by a trusted security certificate.</p>
<p>Here&#8217;s the new version that he showed:</p>
<div><img src="/resources/2009/06/24/arno-flash-camp-air-install-dialog.jpg" width="280" height="202" alt="Arno Gourdol shows the new AIR installation dialog." /></div>
<p>For reference, here&#8217;s an example of the current warning dialog. The highlighted items are the parts that are removed in the new dialog. It also looks like the &#8220;Install&#8221; and &#8220;Cancel&#8221; buttons have switched places for some reason, and some white space has been tightened up. Other than that the new dialog is the same (as far as I can tell):</p>
<div><img src="/resources/2009/06/24/cert-test-install-dialog-new-version-highlights.png" width="480" height="364" /></div>
</li>
</ul>
<h2 id="update1">Update Sept. 18, 2009</h2>
<p>A couple of other new features have been mentioned publicly since I posted this:</p>
<ul>
<li>
<p>In an <a href="http://forums.adobe.com/message/2243429#2243429">AIR forum post</a>, product manager Rob Christensen mentioned that the next major version of AIR will &#8220;provide an API to allow you to open documents&#8221; in their default applications. (The examples discussed in the post are opening Word or Excel files in their respective applications.) The code for this feature actually appears in the sample Arno showed at Flash Camp &#8212; he just didn&#8217;t point it out (look right above his head):</p>
<p><img src="/resources/2009/06/24/arno-flash-camp-code-sneak-2.jpg" width="426" height="261" /></li>
<li>AIR principal scientist Oliver Goldman <a href="http://blogs.adobe.com/simplicity/2009/07/max_2009_air_deployment_and_di.html">mentioned in a blog post</a> that in his MAX 2009 talk he will be talking about &#8220;the new deployment options that will be available in Adobe AIR 2, including the native installer support required to use some of the advanced new AIR 2 APIs.&#8221;</li>
<li>And of course, Oliver&#8217;s quote also makes it explicit that the next major release of AIR is called &#8220;AIR 2.&#8221; In case that wasn&#8217;t so likely as to be obvious.</li>
</ul>
<h2 id="update2">Update Sept. 22, 2009</h2>
<p>Another update: In his Flash on the Beach 2009 presentation &#8220;<a href="http://www.mikechambers.com/blog/2009/09/22/fotb-slides-advanced-desktop-development-with-adobe-air/">Advanced Desktop Development with Adobe AIR</a>&#8221; Mike Chambers described the following feature (on page 20 of his slides):</p>
<blockquote><p>NativeProcess API</p>
<ul>
<li>New API in AIR 2.0</li>
<li>Can call and communicate with external applications</li>
<li>Requires application be distributed as native installer (no AIR files)</li>
<li>Cannot execute applications within application directory</li>
<li>Must add &#8220;extendedDesktop&#8221; to support profiles</li>
</ul>
</blockquote>
<h2 id="update3">Update Sept. 25, 2009</h2>
<p>At a Flash users&#8217; group meeting in Paris, Mike Chambers announced and demoed &#8220;the new raw microphone access feature coming in AIR 2.0.&#8221; <a href="http://theflashblog.com/?p=1426">Source and video: Lee Brimelow</a></p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/06/24/new-features-adobe-air-athena/feed/</wfw:commentRss>
		<slash:comments>3</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>7</slash:comments>
		</item>
	</channel>
</rss>
