Paul Robertson's words, punctuated

Thoughts on development, user-centered design, code, etc. by Paul Robertson

Learn ActionScript from Colin Moock for free!

Tours are starting to be all the rage with Adobe (and others). With the launch of CS3 Adobe did a conference tour, and of course there’s the onAIR bus tour that’s making it’s way around the country promoting AIR.

Now, if you or someone you know is a Flash designer with almost-none-to-basic ActionScript experience, and you want to learn ActionScript from the established master, you can do it for free. Adobe is sponsoring a free, one-day ActionScript training course given by Colin Moock that’s traveling around the U.S. (and eventually the world) starting in October 2007.

They’re calling it ”Colin Moock’s ActionScript 3.0: From the Ground Up Tour.” And you shouldn’t feel intimidated if you are just getting started with ActionScript – the site explicitly says it’s not for advanced developers, so if you’re just getting going (i.e. you’ve done some frame scripts but not anything with classes) you should be in your element.

Currently it looks like there are stops scheduled in San Francisco, Los Angeles, and New York City. Even if you don’t live in one of those areas, think of it this way – for only the price of travel you’re getting an awesome training experience.

(via Stefan Gruenwedel)

Asynchronous database operations with AIR, SQL, and JavaScript

Justin (“AlternateIdea”) has a nice, fairly technical write up of dealing with asynchronous operations when you’re using the AIR SQL database with JavaScript.

I admit, my JavaScript is much rustier than my ActionScript/Flex, so I’m glad to see these sorts of things – it helps me to see what patterns and approaches work for the larger-than-you-might-imagine JavaScript AIR developer audience.

Update: added links, so that you can actually find the article (Doh!)

Problem (and solution): Any AIR app can read any other app’s databases

In a side note on a recent post about the AIR functionality for working with local SQL databases, Tim Anderson raised some concerns about the security model for AIR local SQL databases, that I thought would be valuable to discuss more.

Tim also raises other concerns which aren’t so much issues to keep in mind when developing AIR apps as they are issues surrounding the documentation. I’ve attempted to respond to those concerns in a separate post.

Tim says:

unlike [Google] Gears, AIR makes no attempt to isolate databases based on the origin of the application. In AIR, a SQLite database may be anywhere in the file system, and it’s equally available to any AIR application - a big hole in the AIR sandbox.

I think Tim raises an important point (although I disagree a bit with his conclusion). Very soon after I started working with the local SQL database functionality in AIR I realized the same thing – since any AIR database can be read by any AIR application, it means that I can write a database application in AIR, and you can write an application that finds the file I create with my app, and reads its data.

But let’s take a moment to get a little perspective, after which we’ll consider what we can do about it.

It’s true that in AIR, a SQLite database may be anywhere in the file system, and in general it’s equally available to any AIR application. However, while this differs from Google Gears’ approach, there are some key reasons why this difference is allowed, and why it’s not considered a “big hole” security-wise.

First of all, there’s a significant difference between Google Gears and Adobe AIR. Google Gears is an extension to the standard capabilities of web browsers, but ultimately an application that uses Google Gears runs in a web browser and is therefore subject to all the security constraints of a browser-based application. This is similar to content that runs in the Flash Player browser plugin, or in a non-Gears-enabled HTML/JavaScript application – neither of which can freely access a user’s hard drive. Why is that? Well, it’s because all it takes for a user to access a Google Gears application is for the user to visit the url of that application in his or her web browser. That could be by clicking a link, or even by an automatic redirect that the user has limited control over.

On the other hand, an AIR application doesn’t require or use a browser. In order for a user to access an AIR application, he or she must first choose to install the application, including going through a security dialog that will describe whether the application was signed with a security certificate. In this way, an AIR application is comparable to any other desktop application, such as one written in C++. Since any C++ application could theoretically include the SQLite library, installing an AIR application is no different from installing any C++ application in the sense that, by doing so, a user opens himself up to possible abuses and security risks.

Likewise, any application that can read files from the file system (AIR or not) has the same potential for “stealing” sensitive information. If someone has written down his passwords in a Microsoft Word file, an installed application could search the hard drive for all Word files and read them all and send their contents to a malicious author. Even if your application uses a custom binary file format, there’s nothing that can be done to prevent someone else from reverse-engineering your file format and then writing an app that reads your files and extracts the data. Of course, it’s true that by using a SQLite-format database file, in return for the convenience and benefits it gives you, you’re saving Joe Evil the trouble of needing to reverse engineer your file format, and instead you’re handing your data over quite handily in a wonderful structured way.

On the other hand, all this openness actually has benefits. Since my app can read files written by another app, I can write two different apps that can understand each others’ data. If I make a certain kind of app, and later you make another app that does the same thing but does it better, you can read my file format and import my data into your app – meaning you can help users migrate from my crummy app to your awesome one.

Having said all that, I don’t want you to think that I’m simply washing my hands of the issue. I think it’s an extremely important one, and I’m very glad it came up.

Tell me how to fix it, already

All openness aside, if you’re storing sensitive data in your application, data that you don’t think other applications ought to be able to read, there are some things you can do to try to minimize the potential for damage. Note that since the problem isn’t exclusive to apps that use a local SQL database (although it is perhaps more apparent for those apps), the possible solutions aren’t exclusive to local SQL databases either.

Use user-specific directories

Every AIR application has a special folder in the operating system that can be used to store files related to the app. The folder, known as the “application storage directory,” is actually different for different logged-in users of the same application. In that way it’s a convenient way to separate files for different users of your application. It’s location is always available using the File.applicationStorageDirectory property. Similarly, you can access the directories representing the user’s desktop and his/her documents directory; again, these are folders that will be different per-user, but your app can use the same code to access them regardless of who is using the app.

Note that this only provides limited protection. Any AIR app or any other app can traverse the file system (assuming the logged-in user has permission to do so) and discover and read files in the application storage directory or other user-specific directories. So while this might protect files belonging to other user accounts (if the user running the malicious app isn’t an administrator), it won’t protect files belonging to the logged-in user.

Encrypt your data

The most reliable way to protect sensitive data from other applications is to encrypt it. This can be done in a couple of ways:

  • Encrypt the database file itself. This approach could be somewhat involved. When a user opens the app you’d decrypt the database file and store the decrypted copy in a temporary location from which the app would actually access the db. Then, when your app shuts down (or at some other time) you’d encrypt the temporary file and save the encrypted version wherever you store that master version, and delete the temporary file. As a simpler but less secure variation, you could use a simpler form of encryption. For example, you could append some bytes (either random or meaningful) to the beginning of the database file (or end, or middle or any combination of the three). Before using the database file, you’d need to remove the extra bytes, of course, and actually access the unencrypted version of the file with your application.
  • Encrypt sensitive data within the database. Rather than encrypting the entire database file, if your application stores some data that would be considered sensitive, you could simply encrypt the raw data before writing it to the database in your INSERT/UPDATE statement, then decrypt it after reading it with a SELECT statement.

Note that in both of these cases I’m talking about using a two-way encryption algorithm. Typically such algorithms require you to have some sort of secret – the encryption key – that is used by the application to encrypt and decrypt the data. Since an AIR app consists of HTML and JavaScript files (plain text) and/or SWF files (binary, but known to be de-compileable), you won’t want to store the encryption key for your application within the source code of your application. Rather, you’ll want to generate the key for each user, and store it separately from the application data. Christian Cantrell’s “Salsa” application demonstrates how to do this (it actually uses a user-selected passphrase as the encryption key, although the release notes say that future versions won’t require that) so that’s an example app to look at for an example of two-way encryption.

Not just reading

On a somewhat related note, another concern with other applications being able to access your app’s data has to do with the integrity of the data. Not only could another app read your application’s data, but it could just as easily change the data as well. Apart from two-way encrypting the entire database file, there isn’t really any way to protect against this. If you don’t want to encrypt the entire database file, one way you can at least verify the integrity of your data is by using a one-way encryption algorithm (also know as a hash). It works like this:

  1. After closing your database, your app encrypts all or some of your database (either the bytes of the db file, or the db data) using a one-way encryption algorithm.
  2. The next time your app opens your database (or before opening the db if you hashed the file itself) you run the same file (or portion of the file or data) through the encryption algorithm again.
  3. If the source data (your db’s contents) hasn’t changed, the resulting hash value should be identical. If the contents of the database have changed, the resulting hash value will have changed – meaning the data has been tampered with by something other than your application.

You could even combine an integrity check with two-way encrypting the file. For example, you could create a hash of all or part of the database file, then append the result to the file. When you reopen the file, you would need to extract the hash, then you could compare it to the rest of the database as well as using the database file (minus the hash) for your application.

Finally, I should acknowledge that, while I’ve done some study of encryption and securing applications, by no means do I consider myself an expert on the topic. If anyone has other ideas, suggestions, and especially if you see some issues with the techniques I’ve recommended here, please share your experience!

Brandon Ellis’s DataAccess Utility class

If you’re looking to simplify the local database access part of your AIR app, this might be the ticket. Brandon Ellis has written a no-frills wrapper class for AIR local database operations. The biggest benefit it provides is that if you add, delete, or update data in a table, it automatically updates whatever component is displaying the data from the related SELECT statement.

The part that caught my eye the most was that the wrapper class doesn’t dispatch any events to notify the view when the operations have completed. How, I asked myself, does it notify the view when the updated data loads? After a few seconds I realized the answer – it’s the magic of Flex data binding. The DataAccess class exposes the SELECT results as a property (dbResult) that’s a Flex ArrayCollection, and it’s marked [Bindable]. A Flex control can bind to that property as a data provider, and whenever the DataAccess instance reloads its data and updates the ArrayCollection. Then the Flex framework takes over, and the view gets updated automatically. Pretty slick; and it definitely saves a lot of event-handling code. So I guess seeing this in action gave me further appreciation for the power of data binding.

It has a couple of minor issues that I’ve noted in the comments on that page (but mostly they should be fairly easy to fix, if Brandon or someone else decides to do so).

(via: Greg Hamer)

Why doesn’t Adobe’s AIR dev guide mention SQLite? A response to Tim Anderson

Yesterday Tim Anderson asked a question: ”Why doesn’t Adobe’s AIR dev guide mention SQLite?” As the author of the ”Working with local SQL databases” chapter in the AIR Developers Guide that Tim refers to, as well as the related sections of the AIR language reference, I guess I know better than most people the answer to that question. Unfortunately, although it was a consciously considered decision that underwent a reasonable amount of discussion, I can’t promise that the reasoning is absolutely irrefutable logic that will stand the test of time. But then, if it was, Tim probably wouldn’t have asked the question =)

Note: This post won’t make as much sense unless you read Tim’s post first. So I’ll pause for a moment while you go read it – don’t worry, it’s not nearly as long as this one =)

As suggested by John Dowdell in the comments on Tim’s post, the biggest reason why SQLite isn’t mentioned by name in the documentation is a somewhat complex matter involving the timing of when the feature was developed, deadlines for when the documentation had to be done in order to include it in the beta release, and the timing of when Google Gears was announced.

Background: Development schedules, marketing announcements, and the realities of human limits

If you don’t mind, I’ll start off with a bit of background/context on the timing of the local SQL database feature being developed and the agreement with Google.

Note: Admittedly I’m making educated guesses on the timing described here, based on things I observed but without actually being involved in the conversations between Adobe and Google.

Before any sort of agreement about synchronized APIs and common code had been reached, perhaps before it had even started, Adobe, and presumably Google, had both separately developed most of their respective implementations of database functionality based on SQLite. Naturally, at the point that they agreed to make their APIs agree with each other, both companies could have chosen to postpone releasing their implementations until the final, synchronized API was finished. Not surprisingly, both companies felt it was more important to get something out to developers sooner (even if it wasn’t the “synchronized API”) rather than later when things were final. From a public visibility perspective, Google made their announcement first, so they have the benefit of being perceived as the “original” and I expect many developers expected the AIR API to be identical when it was released (about a week and a half later, it’s important to note).

I wasn’t involved in any of the planning or discussion surrounding the AIR-Google Gears “synchronized API” decision, and in fact I didn’t know anything about it until I read the public announcements. (If you can, imagine my reaction when I read that the APIs were going to be aligned – since I had just finished the API reference documentation the previous week! =) The fact that I wasn’t involved in the conversations doesn’t bother me and makes sense to me – there wasn’t really any compelling reason why I should have been involved in those conversations – but obviously that had a direct impact on my ability to anticipate the consequences of that announcement while I was writing the documentation. By the time the announcement was made, it was too late to go back and change the documentation, and definitely too late for us to actually change the API.

With that background, let me address some of the specific points that Tim raises. He asks the question, “why doesn’t Adobe’s AIR dev guide mention SQLite?”, and gives three points about why he isn’t pleased that SQLite isn’t mentioned:

1. “It stinks”

Of course, what I’ve said up to this point suggests that, were it not for the Google Gears announcements, Adobe might not have ever announced that we are using SQLite. I can’t speak for alternative futures, of course, but I think it’s possible that Adobe would never have mentioned SQLite in the documentation. Does that “stink” as Tim suggests? Is it discourteous? I can definitely understand the sentiment behind those expressions. I’m a firm believer in “credit where it’s due.” When I wrote the documentation, I certainly didn’t mean it as a discourtesy or to minimize my opinion of the value of SQLite that SQLite was not mentioned. I think SQLite is a great tool, and I’m very glad it exists, and that the authors have been so generous with the license.

On the other had, as Tim notes, Adobe has no legal obligation to acknowledge that they included source code from SQLite. Nor does Adobe have any obligation to acknowledge that a significant part of the documentation on the SQL dialect was adapted from the SQLite documentation, because the authors were even kind enough to secure public domain releases for the documentation – although I will readily admit that I did in fact adapt portions of the SQLite documentation – which was very helpful because it saved me a lot of duplicate effort!

So, were we intentionally trying to hide the fact that it was SQLite? No, although we chose not to advertise the fact either, for a few reasons:

  • Our intention was to provide sufficient documentation so that a developer wouldn’t have any need to look at the SQLite documentation. (In fact, due to the short time frame for getting things done, one idea that was considered and rejected was just to point developers to the SQLite documentation for the first beta release.) With that decision made, we realized that there wasn’t any absolute need to make reference to SQLite.
  • In many respects, the choice of SQLite was originally considered to be an “implementation detail” – something that developers didn’t really need to know or care about. Obviously in the wake of the Google Gears announcements, there is now more reason why it does matter (to some developers) that Adobe chose to use SQLite.
  • In fact, when you get down to it, the choice of SQLite could still be considered an “implementation detail.” After all, consider what happens in the future when AIR version 5 or 10 is released. What if SQLite is no longer the best choice for an embedded database? Should AIR developers be limited by the fact that AIR is absolutely tied to SQLite? As long as the API continues to work, and the older file-format databases are supported, and older applications continue to run, how much does it matter whether the embedded database is SQLite or something else?

    Obviously that’s not a highly likely scenario. From a practical standpoint, even if another database engine were used, it would be pretty involved to ensure backwards compatibility, both with the API and especially with the supported SQL dialect.

In summary, when the time came to decide whether to explicitly mention SQLite in the documentation, it came down to this. As we all know, it’s common practice in the software industry, including at Adobe, that when a certain aspect of a feature is considered an “implementation detail” and “not important to developers,” that aspect of the feature isn’t described in the documentation. Sometimes developers find out anyway, either through their own experimentation, or through experience, or whatever. Even if Adobe didn’t announce that the AIR local database engine was based on SQLite, it’s highly likely that it would have come out sooner rather than later. That’s fine – developers can choose to use the knowledge they acquire, and Adobe can choose to change things that aren’t documented.

As I’ve said, at the time the documentation was being written and finalized, the word I was going on was that the fact that the engine uses SQLite is an implementation detail. I gave some thought to whether we should explicitly mention that the database uses SQLite – certainly there were advantages and disadvantages either way. The issue was discussed by me, members of management, and the lead engineer for the feature. In the end, however, for the reasons listed above, and without any knowledge (at least on my part) of the very-soon-to-be-forthcoming Google Gears alignment announcement, we decided that the priorities fell on the side of not stating that the database uses SQLite.

Having said all that, as a result of the announcements relating to Adobe AIR and Google Gears, it is public knowledge that Adobe is using SQLite. Although it may not make sense to anyone but me, that announcement “changes the balance” of priorities in my mind, so in fact at this point I agree with Tim that the benefits of mentioning in the documentation that the database uses SQLite (giving credit where it’s due, and guiding developers to other SQLite tools that might help them) outweigh the potential downsides of stating it in the documentation (the unlikely but can’t-rule-it-out-completely possible future case in which we no longer use SQLite for the underlying database engine, and the possibility of distracting/confusing developers who read the SQLite documentation and find something that’s not supported in AIR and wonder why).

Even as I write this, I acknowledge that my stated set of reasons, and this description of trying to find the best balance between the tradeoffs of “officially” disclosing information versus “officially” keeping information “undocumented” sounds very fuzzy. And I agree that the value of giving credit to the authors of SQLite is a compelling reason for stating in the documentation that AIR uses SQLite. I’m afraid I can’t completely communicate how fast and furiously we were working to get this feature (and the associated documentation) done for the beta, and consequently how we tried to make the best choices we could in a limited time frame. And again, without the smallest clue of the then-forthcoming Google Gears announcement.

Fortunately, as Tim points out, “this is all beta, of course, so it can change.” So, Tim, allow me to tell you that your feedback has helped us to realize that the value of giving credit to the authors of SQLite outweighs any potential drawbacks, and I will shortly be adding explicit mention of the fact that the runtime uses SQLite for its local SQL database functionality. A week ago I asked for feedback on the SQL documentation, and while this wasn’t exactly what I had in mind, it is nonetheless appreciated and hopefully it’s clear that it has been taken into consideration.

2. “It’s unhelpful”

Tim makes the suggestion that it would be helpful to “set out exactly how AIR’s SQLite differs from the standard build.” I think that sounds like a useful suggestion; I’ve made a note to research the topic and see how difficult it would be to compile that information, and how we could usefully incorporate it into the documentation. I admit that the thought didn’t even occur to me (which doesn’t surprise me – I have some good ideas sometimes, but I certainly don’t ever have all the good ideas =).

Although I acknowledge that it sounds like an idea with merit, the devil’s advocate in me impels me to admit that specifying how AIR’s SQLite implementation is different from other SQLite implementations isn’t as much of a priority as some of the other tasks that I’ve got in the lineup. It turns out that there were several things that I wanted to write, and we just didn’t have time to get them all in for the beta release. Since the SQLite library is designed for use as an embedded database, and the target audience (developer-wise) for AIR is developers with web development experience, chances are the majority of the target audience for AIR hasn’t ever programmed for SQLite. That means that documentation comparing AIR’s implementation to other implementations will probably only be useful for a minority of AIR developers – which unfortunately is something that we have to take into account when we’re scheduling the “features” that are chosen to be included in the documentation.

Nevertheless, I do think that it’s a good suggestion, and in some ways I think that it will be useful to more advanced developers whether they’ve used SQLite or not, so I’ll see what I can do.

3. Skepticism that the AIR and Google Gears APIs will align

Hopefully my earlier background information has made it clear that the reason the APIs don’t align right now is really a matter of scheduling, engineering effort, design effort, and a desire on the part of both companies to get their technologies into the hands of developers, and not any sort of conspiracy. I will say that I know for certain that the effort to align the APIs is still going on.

“A big hole in the AIR sandbox”

Tim makes a side note at this point, that the difference between the AIR approach to SQLite and the Google Gears approach has some security implications. This is an important point, so I’ve written a separate post in which I’ve discussed why the two systems use different models, and how to address some of the potential security issues.

Summary: Tim’s wish list

Going back to Tim, he concludes with a “wish list” of three things he’d like to see happen in the AIR documentation and implementation:

  • Proper credit for SQLite in the docs.
  • Use the Gears code - full text search could be very useful - and deliver on the promise of aligning the API.
  • Failing that, set out exactly how AIR’s SQLite differs from the standard build.

I’ll consider these one at a time:

Proper credit for SQLite in the docs

As Tim and I have both mentioned, SQLite is in the public domain, so in fact from a legal definition Adobe is already giving “proper credit” (that is, no credit required) for SQLite. I’m certain that’s not what Tim had in mind, and I’ve also mentioned that I believe it’s worthwhile to give credit to the authors of SQLite. As I’ve also said, I’m planning to add in at least a couple of prominent places a statement that AIR uses SQLite for its database functionality. If that’s not what you had in mind, Tim, please let me know.

Use the Gears code - full text search could be very useful - and deliver on the promise of aligning the API.

I’m 100% certain Adobe is not going to “use the [Google] Gears code,” at least not wholesale – the two products have already been developed in isolation much too much for that to work (in my opinion – but of course I’m not the engineer). Nevertheless, I agree that full text search could be very useful – I would love to see it make it in to AIR as well – and as I’ve said here and also last week, Adobe and Google are continuing to work on aligning their database APIs.

Failing that, set out exactly how AIR’s SQLite differs from the standard build.

This statement is actually a bit misleading, I think, since I’m certain Google Gears doesn’t use a 100% “standard”, out of the box SQLite build. (For that matter, I’m not sure what a “standard” SQLite build would be, since the whole point of SQLite is to be an embedded database, built into another product, and not to stand on its own.)

All that notwithstanding, as I’ve mentioned I have now assigned myself the task of researching the changes that we’ve made from what someone who’s used SQLite in another product might expect, and (time permitting) to add a section to the documentation describing those differences.

Conclusion

I realize this whole post is long, and meanders quite a bit, and probably doesn’t show the degree of concrete explanation (or completely serious consideration) that might be desirable. I believe that we made the decisions we made for good reasons, using the information we had available at the time. I’m also glad that we’ve only released a beta and not the final version yet, and I’m glad that Tim’s post caused me and others in Adobe to sit up and take notice, and reconsider some of our decisions in light of the new information that’s become available since the time when we previously made them.

And once again, if anyone has thoughts or suggestions about the AIR local SQL database documentation, please don’t hesitate to share them. I’ll try not to post an essay in response to each one =)

AIR, local SQL databases, and my role

As everyone knows, today Adobe released a public beta of AIR (formerly “Apollo”). As you likely know, since it was announced last week, one of the big new features in this release is an integrated database engine that allows AIR applications to create and use local SQL databases.

Okay, that sounds really boring. But I don’t mean it to. I’m actually incredibly excited by this, because it makes it a lot easier for people like me, with web app experience but not desktop app experience, to create data-driven apps and store persistent data using techniques that I’m familiar with.

And, on a personal note, it means that I finally get to talk about what I’ve been working on for the last couple of months. If you actually follow my web site, you’ve probably picked up on the fact that I was heavily involved in the ActionScript-related documentation for the Flash CS3 release. Well, naturally, now that Flash CS3 is out the door, I’ve been moved onto another project – onto Apollo/AIR, specifically.

More specifically, since I’ve been programming SQL databases for many years, as part of my web app development work, I got pegged (well, I actually volunteered) to do the documentation and samples for the local SQL databases feature.

When I first read the spec for the feature, I was completely floored. I was expecting some minimal support for a few things, but what we’ve got is much more than I could come up with use cases for. Want a good idea of the breadth of the functionality that’s available? Spend some time reading ”SQL support in local databases” (it’s an appendix of the AIR language reference). Views? Indexes? Triggers? They’re in there.

In case you don’t have a free few hours, I’ll just point out my favorite parts of the feature. These will probably be most meaningful if you’ve already faced the joy and pain of working with web-database apps, especially with an OOP language:

  • SQLStatement.itemClass: This was my immediate favorite. You specify a class, and SELECT statement result rows are automatically converted into instances of that class (saving lots of boilerplate code to loop through results and turn rows into instances of some other class). If I could have done this in ASP.NET, I’d probably have saved about 25% of the total code I wrote.
  • SQLStatement.prepare() and SQLStatement.parameters: Now that I’ve spent some time building apps and working with the code, I’ve gotten a lot of respect for this method. Basically, this is the way to create the equivalent of pre-compiled stored procedures for your AIR app.
  • SQLResult.lastInsertRowID: I had to lobby long and hard for this one, which, since I’m a remote employee, meant lots of email exchanges. Finally I managed to clearly articulate my reason, and sure enough, persistence paid off. If you’ve created a database app, chances are you’ve run into the case where you INSERT a row, and you need to get back the auto-generated primary key so that you can insert a related row. The wrong way to do it is SELECT MAX(id_column) FROM table. The right way, in AIR, is to use lastInsertRowID.

I’m excited that I can talk about this now. I’ve got some samples, practices, and information that I’m looking forward to sharing. I’ll start with an answer to a question that I’ve seen asked around (well, mostly I’ve just seen misinformation, not people asking whether it’s right) about the relationship between the AIR local SQL database API and the Google Gears SQL database API:

  • Does Apollo “include” part of Google Gears? - No. There is no shared code between AIR and Google Gears (with the possible exception noted in the next answer).
  • What do AIR and Google Gears have in common, then? - Both AIR and Google Gears let you create applications that access databases located on a users local machine. Both AIR and Google Gears chose to use SQLite, a free, public domain embedded SQL database engine, to provide that functionality. So whatever code AIR uses that hasn’t been modified from SQLite, is the same as the code that Google Gears uses that hasn’t been modified in its implementation of SQLite.
  • What’s this about AIR including the same database API as Google Gears? - To be honest, although I’ve been involved in the AIR database API for a while, the first I heard of Google Gears’ database API was when the public announcements were made. Thinking back, I see now that discussions were going on for a while, and I even unknowingly provided some support to the management team and others who were involved in that discussion. Right now, although the underlying database engines are based on the same engine, since SQLite is written in C, any implementation that doesn’t use C/C++ needs to write its own API. The two implementations (Adobe’s and Google’s) weren’t developed together, and at this point (from what I’ve seen) the two APIs are pretty different. Case in point: synchronous versus asynchronous database operations. In Google Gears, data access operations are synchronous – calls to the database are blocking, meaning the runtime freezes at the line of code that called the database until the result is returned. In AIR, on the other hand, all data operations are asynchronous – you call SQLStatement.execute() to run a query, and when the result comes back an event listener function is called (at which point the result data can be accessed). That alone means a big difference in how you write code to work with the two systems.
  • So wait a minute, what about the whole “Adobe and Google are working together on the database API” thing? - Adobe and Google are having “discussions,” and (from what I’ve heard) the plan is to hopefully make the APIs the same or similar enough that a developer who writes data access code for Google Gears will have an easy time writing data access code for AIR (and vice versa). In addition, since the SQL part of both runtimes really is dependent on SQLite much more than the particular runtime implementation, and SQL code probably is interchangeable between the two runtimes, assuming the same database schema etc.

So from me, and the other engineers and stakeholders inside Adobe, please try out the local SQL database functionality of Apollo, and please let us know what we can do to make it better. In particular, let me know what is missing or what you’d like to see in terms of documentation and samples – but don’t limit yourself to that. Please share your comments/suggestions!

On a more personal note…

I’m really excited about this. I really just can’t say in words how excited I am. When I decided to accept an offer to work full-time for Adobe, one of the first “regrets” that crossed my mind was when I considered that it was highly likely that I wouldn’t be doing any more database programming (since my work involves dealing with ActionScript, and up to now there hasn’t really been any direct database access from ActionScript). So I was excited to say the least when I heard about this feature and it was decided that I’d get to work on it.

Suffice it to say, this has been a pretty busy time. This feature was actually slated to appear in a later release, but at the near-last minute the decision was made to get it done in time for the public beta. That meant a lot of writing and application-building in a hurry! Then two weeks and a private beta release later, a group of people including me, engineers and QEs, and other interested folks, went through a few rounds of discussions on what was missing and what we could do to make the API better. The result, which of course still isn’t finished, is what you can download today.

And, although she isn’t a developer and doesn’t use Apollo/AIR at all, it’s an understatement to say that my wife is glad to see this beta out the door, if only because it means I don’t have to work evenings any more (it’s been a very busy month+ =).

New project: ActionScript Regular Expressions Testing Tool

Over the last couple of weeks I’ve been working on a Flex project where I’ve had to make heavy use of regular expressions. As always seems to happen when I work with regular expressions in any language, I found that one of the more complex parts of the process was just figuring out the exact regular expression pattern to use.

Having been down this road before with other languages, I decided to put together a simple tool for testing out regular expressions. I wanted to be able to enter a pattern and a test string, and have it check to see if it was a match. That way, I could test out various possible good matches (and non-matches) to see if they give the right result. I was using named capturing groups quite a bit on this project, so I added an extra feature where it shows all the groups that are captured as well.

Anyway, I realized this might be useful for anyone who’s trying to use regular expressions in an ActionScript 3.0 project, so I thought I’d make it available.

Want to test it out? Visit the project page to see the tool and download the source code.

If you have comments or improvements for the project, feel free to add a note in the comments on the project page.

How to: determining when data is edited using the Flash CS3 DataGrid component

Note: a version of this article was posted on the Adobe Developer Center in November 2007. That article is based heavily on this one – essentially I took the text here, and revised a few sentences and word choices for clarity. However, if you’re interested in the “latest” version, you can find it here: ”Detecting when data is edited in the DataGrid component.”

Suppose you’re creating a user interface with Flash CS3, using the new lightweight ActionScript 3.0 components. You’re using the DataGrid component to display – what else – a table of data. You want users to be able to edit the data, and you want to know when the user changes the data so that you can update the application.

For example, suppose you’re building something like this simple spreadsheet application:

Latest Tweets

  • Status updating…

Google+