I am going to start doing a couple of Adobe AIR projects that will be using SQLite
feature provided by AIR
. Since this is the first time I am attem
The first and by far most important decision you have to make, is whether you're going to access that database synchronously or asynchronously. They both have their pros and cons, so it will depend on your situation.
Synchronous
Good for small scale app
Asynchronous
LocalUserService
and RemoteUserService
both implement an interface that forces them to have a method saveUser()
)Good for larger scale app and synchronizing local and remote data.
I tend to almost always opt for the asynchronous approach - since it's more flexible - and abstract the complexity away in ... a wrapper class. So that answers that part of your question.
Architecture
I don't like frameworks, so I can't answer your question about Mate
or -shudder- Cairngorm
. But here's what I consider a fairly good approach:
UserDAO
for quering Users). That class should contain only queries.As for keeping the connection open. I've always done so and never had any issues with it. I don't exactly know what happens when an application crashes and the connection wasn't properly closed, but this is not Oracle or SQL Server we're talking about. I don't think SQLite will keep open pointers or something since it's just a simple file, but I might be wrong.
Edit: some more details on the DAO / Factory pattern (as requested by OP).
An example of a UserDAO with one function:
public class PupilDAO extends AsynchronousDAO {
public function getUserById(id:int, handleResult:Function):Responder {
return getResults(
"SELECT * FROM user WHERE user_id = ?",
handleResult, [id]
);
}
}
As you can see, I've abstracted out the complexity into the AsynchronousDAO
base class, so we can see only the necessary information in UserDAO. The handleResult
function is a callback that will be called whenever the query is ready, passing in the resultset as an argument. We'll usually pass that resultset into the factory/builder class.
An example of a UserBuilder:
public class UserBuilder {
public function buildUser(record:*):User {
var user:User = new User();
user.id = record.user_id;
user.firstname = record.firstname;
user.lastname = record.lastname;
return user;
}
}
This is obviously a simple example, but you can create more complex data structures in the builder. For some info on the difference between the Factory and Builder patterns I recommend Google.
Now let's tie it together in the service class:
public class UserService {
private var dao:UsetDAO;
private var builder:UserBuilder;
public UserService(dao:UserDAO, builder:UserBuilder) {
this.dao = dao;
this.builder = builder;
}
public function getUserById(id:int, handleResult):void {
var handleResultSet:Function = function(resultSet:SQLResult):void {
var user:User = builder.buildUser(resultSet.data[0]);
if (handleResult!= null) handleResult(user);
}
dao.getUserById(id, handleResultSet);
}
}
Finally, let's put the trio to use:
var userService = new UserService(new UserDAO(), new UserBuilder());
userService.getUserById(1, handleUser);
function handleUser(user:User):void {
trace(user);
}
For the example I constructed the classes with new
and passed the dao and the builder as constructor arguments, but you could use injection or singletons or whatever framework you like to do the construction for you.