Flex \ AIR provides a great set of functionality around SQLite. The API is powerful, simple and for my money, I'd say critical to the overall platform. When using SQLite via Flex \ AIR - I've found that the API pretty much just works and we can be up and running in no time. That said, there can be some minor points that are not very obvious up front, one of those is trying to get a list of tables from a SQLite database via the Actionscript based AIR APIs. (Take Me Directly to the solution).
The Oddity: What's So Hard About It?
The basic reason getting a list of tables isn't as simple as the rest of the API is because the solution's implementation doesn't correspond well to general SQLite usage. That's not to say there is anything _wrong_ with AIR API design. There isn't, it's actually rather cool. The problem is, it's just not obvious.
The confusion starts at the SQLite documentation level. The SQLite documentation (which can be found ;mce:script type=">qlite.or<mce:script type=">g/
docs.html">here) actually contains an FAQ entry for getting a list of tables, and the FAQ says:
... get access to table and index names by doing a SELECT on a special table named "SQLITE_MASTER". Every SQLite database has an SQLITE_MASTER table that defines the schema for the database.
In fact, the FAQ even provides a nice query:
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
Now, here's the confusion. This query, and in fact anything about the 'SQLITE_MASTER' table, just doesn't work from the Actionscript API. In this case, the SQLite documentation isn't going to help us. The issue is that the AIR implementation doesn't expose the SQLITE_MASTER table. There's even a bug in the Flex Bug and Issue Management System stemming from this confusion.
Basically, it _feels_ like something is broken, the query (which the SQLite docs say should work) doesn't work. When you use the query, or any query that references the SQLIST_MASTER table, you'll get an error that reports 'sqlite_master' table does not exist.
A Little Help: Using the SQLite Database Browser
When I first ran into this issue, I (like some of the people involved with the bug report) was pretty sure I'd found a bad bug in the AIR API. The SQLite docs said it should work, but it didn't. Was the SQLITE_MASTER table not accessible to me (security issue)? Was the table locked somehow (did I screw something up)? Did the table simply not exist - and thus the database itself wasn't constructed according to the SQLite docs? Hmmmmm.
A while ago, I found a nice tool called the 'SQLite Database Browser' and its awesome. It works on both OS X, Windows and Linux - it's free - and open source. Score! With the browser, I am able to see my store from a SQLite perspective:
Sure, there is no SQLITE_MASTER table listed. However, if we attempt the FAQ's query...
It looks like it's treated special, but the table is there, the database is constructed just as the docs say it should be and the query works. Sooo close!
BTW - SQLite Database Browser
is an essential tool.[
Random Helper: When doing database dev work, I always create and store my databases with a sort of unique extension. This always me to associate the SQLite Database Browser with my unique extension, giving me a great default SQLite database viewer (very very handy)]
How To: The Fix
In the bug I mentioned earlier, Jean-Pascal Hovel mentions using SQLConnection.loadSchema(). Also, poking around livedocs, we can find a very nice write-up on SQL support in local databases. In the write-up, we finally find the core point:
... The following SQL elements and SQLite features are supported in some SQLite implementations, but are not supported in Adobe AIR. Most of this functionality is available through methods of the SQLConnection class ...
so... Some of the normal SQLite goodness, just doesn't work - and...
... System table access is not available: The system tables including sqlite_master and other tables with the "sqlite_" prefix are not available in SQL statements. The runtime includes a schema API that provides an object-oriented way to access schema data. For more information see the SQLConnection.loadSchema() method. ...
Jean-Pascal Hovel was right about SQLConnection.loadSchema(), the bug really isn't a bug - instead - there's a specific mechanism for getting to the SQLITE_MASTER which Adobe intentionally built, good ol' SQLConnection.loadSchema().
The Code
Once we get that using SQLConnection.loadSchema is the right approach, we're golden. The code is fairly trivial, but I'll drop it here just for completeness:
statement.sqlConnection.open(store, SQLMode.READ);
// use SQLTableSchema to get tables only,
// see the loadSchema API Doc
statement.sqlConnection.loadSchema();
var result:SQLSchemaResult = statement.sqlConnection.getSchemaResult();
for each (var table:SQLTableSchema in result.tables)
{
trace(table.name);
}
Do note, that using sqlConnection.loadSchema, you can get fairly specific about what data you want to query for. For example, the above call to loadSchema gets all objects in the database. The sqlConnection.loadSchema documentation provides this reference:
There we are... To get a list of tables for a local data store in AIR, use sqlConnection.loadSchema ... Nice.
Enjoy!