Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Asynchronous Data Access Layer  (Read 11248 times)
dkarten
Newbie
*
Posts: 2


View Profile Email
« on: February 26, 2015, 07:53:15 »

I'm trying to refactor an existing project into PureMVC. This is an Adobe AIR desktop app taking advantage of the SQLite library included with AIR and building upon it with a few other libraries:


I made my current implementation of the database similar to the websql-js (http://websql-js.googlecode.com/hg/docs/websql.html) promise based SQL access layer and it works pretty well, however I am struggling to see how it can work in PureMVC. The async SQLite library linked above uses a "SQLRunner" which maintains a pool of connections which it opens and closes as necessary.

Currently, I have my VOs that will be paired with DAOs (data access objects) for database access. Where I'm stuck is how to track the dbFile and sqlRunner instances across the entire program. The DAOs will need to know about the sqlRunner, or at the very least, the dbFile. Should the sqlRunner be treated as singleton-esque? Or created for every database query?

Finally, how do I expose the dbFile or sqlRunner to the DAOs? In my head right now I see keeping these in a DatabaseProxy that would be exposed to other proxies, and instantiate DAOs when needed. What about a DAO factory pattern?

I know from some reading and research that Cliff/PureMVC is geared to an XML database and there area already existing utilities for that, but it is too much of a refactor to move from the existing SQLite to XML.

I'm very new to PureMVC but I really like the structure and separation of roles. Please don't hesitate to tell me if this implementation simply will not work.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: March 03, 2015, 10:11:52 »

Hi there,

The XMLDatabase is just one utility, it doesn't mean PureMVC is necessarily geared more toward that than SQL. It just means there isn't a utility as of yet. Your idea of a DatabaseProxy is right. DAOs typically don't store data, so I'm not sure about the need for a factory. The data ends up in a VO. A DAO is equivalent to a Delegate on the client side. The DatabaseProxy would be the business object in the pattern: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html

The SQLRunner instance as well as the VOs (or TOs - Transfer Objects if you like) would be maintained as well by the DatabaseProxy. No other actor should be fiddling with it, and should go through the DatabaseProxy for operations. The Proxy should hide ALL of the DB stuff from the app and provide methods for accessing VOs and updating them. Internally it would use the DAOs to reflect those operations on the database.

Logged
dkarten
Newbie
*
Posts: 2


View Profile Email
« Reply #2 on: March 04, 2015, 02:38:44 »

Hi, thanks for your reply. I understand that PureMVC is hugely flexible, I guess I just see more examples with XML databases, that's all.

For the design problem, I've reached two diverging paths. In one path, we use data access objects. There is a top level data access object which implements database read and write functions, (so select, insert, update, and delete). Then specific DAOs would extend this abstract DAO and override the r/w call with reference to the specific table. Ex: DataAccessObject has an update method, which takes table name, update parameters, and a where query to match the update with. Then CustomerDAO extends DataAccessObject and it's update function returns the super's update function with proper parameters filled in
:
public function update(params:Object):Promise {
    return super.update("customer", params, "customer_id=:id", {id:uid});
}
This assumes every DAO has a uid property which references its SQL primary key. If we keep all database operations in the DatabaseProxy, then we have to write cases for every VO/DAO pair we will be working with. Finally the DatabaseProxy would be tasked with responding to the promises and updating the corresponding vo in memory.

The second path, which I am leaning more towards, is not to implement a DAO pattern, but rather have the DatabaseProxy act as the top level DAO with abstract read/write functions. Then specific proxies would extend the DatabaseProxy with specific behavior. Does this violate the idea of isolating all DB interaction to the DatabaseProxy? This design seems better to me, because it still isolates the database dependency to the DatabaseProxy. Changing to a different style of database would require only rewriting the r/w functions in the DatabaseProxy. It also allows me to take advantage of a Proxy's data property. As an example if we had a database of books and publishers, these would likely be two different SQL tables. There would be a BooksProxy and a PublishersProxy. When the BooksProxy is instantiated, it would retrieve all books in the table and store them as an Array or ArrayCollection in the data property. Similarly for the PublishersProxy. Then adds, updates, and deletes would be saved to the DB and tracked in memory. This makes passing data to the view with a mediator much easier.

There's probably no right or wrong way to do this, but I appreciate all the input!

Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: March 06, 2015, 09:54:13 »

Essentially your system of Proxies do the same thing as the DAOs. The DatabaseProxy would have the reference to the DB and the CRUD logic. The BooksProxy, et al, would manage a set of BookVOs and expose methods for getting them or setting them so the rest of the app interacts with them and not the DatabaseProxy. Those classes wouldn't extend the DatabaseProxy (which has as its data object the database itself), but would interact with it via composition. During startup of the app, while preparing the model, you would create the DatabaseProxy first, and then create all the other proxies like BookProxy and give them references to the DatabaseProxy. They'd hang onto that proxy and make calls on it.

If you wanted to support multiple databases, then make an IDatabaseProxy interface, and have all the proxies like BookProxy interact with DatabaseProxy using the interface. So instead of DatabaseProxy, maybe its SqlLightDatabaseProxy. Then if another DB comes along, you build another proxy that implements IDatabaseProxy and provide that to your per-table proxies.
Logged
Pages: [1]
Print