package com.ericfeminella.air.cairngorm.business
{
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;
import flash.net.Responder;
import flash.data.SQLResult;
/**
*
* Provides an API from which Adobe AIR SQL specific classes can be
* managed uniformly as a Service when building an application on
* Adobe Cairngorm
*
* <p>
* <code>SQLService</code> wraps both the <code>SQLStatement</code>
* and <code>SQLConnection</code> in order to provide a Service
* from which CRUD operations can be performed on a SQLite database
* in the same manner as one would access typical RPC Services.
* </p>
*
* <p>
* <code>SQLService</code> supports both synchronous and asyncronous
* transactions. A set of convenience methods have also been provided
* to interface with the underlying <code>SQLConnection</code> object
* in order to perform transactions.
* </p>
*
* @example The following example demonstrates a typical implementation of
* <code>SQLService</code> defined by <code>AIRServiceLocator</code>
*
* <listing version="3.0">
*
* <?xml version="1.0" encoding="utf-8"?>
* <services:AIRServiceLocator xmlns:mx = "http://www.adobe.com/2006/mxml"
* xmlns:services = "com.ericfeminella.air.cairngorm.business.*\" >
*
* <services:SQLService id = "service"
* localDatabaseFilePath = "{ File.desktopDirectory.nativePath.toString() }"
* localDatabaseFileName = "air.cairngorm.example.db"
* />
*
* </listing>
*
* @see com.adobe.cairngorm.business.ServiceLocator
*
* @see flash.filesystem.File
* @see flash.data.SQLConnection
* @see com.ericfeminella.sql.ISQLResponder
*
*/
public class SQLService
{
/**
*
* Defines the qualified name of a local SQLite database
*
*/
protected var databaseFileName:String;
/**
*
* Defines the absolute path to a local SQLite database
*
*/
protected var databaseFilePath:String;
/**
*
* Defines a reference to the physical file which contains
* a local SQLite database
*
* @see flash.filesystem.File
*
*/
protected var _databaseFile:File;
/**
*
* Defines the <code>SQLConnection</code> from which the
* Service is connected
*
*/
protected var _connection:SQLConnection;
/**
*
* Defines the <code>SQLStatement</code> from which queries
* are executed
*
*/
protected var _statement:SQLStatement;
/**
*
* Creates a new instance of <code>SQLService</code> and
* initiates members
*
*/
public function SQLService()
{
_connection = new SQLConnection();
_statement = new SQLStatement();
}
/**
*
* Retrieves the path to the local SQLite database
*
* @return the qualified path of the SQLite database
*
*/
public function get localDatabaseFilePath() : String
{
return databaseFilePath;
}
/**
*
* Sets the path to the local SQLite database
*
* @param the path to the database file
*
*/
public function set localDatabaseFilePath(value:String) : void
{
databaseFilePath = value;
}
/**
*
* Retrieves the name of the local SQLite database
*
* @return the name of the local SQLite database
*
*/
public function get localDatabaseFileName() : String
{
return databaseFileName;
}
/**
*
* Sets the name of the local SQLite database
*
* @param the name in which the database is to be named
*
*/
public function set localDatabaseFileName(value:String) : void
{
databaseFileName = value;
}
/**
*
* Retrieves the local SQLite database file object
*
* @return the local SQLite database file object
*
*/
public function databaseFile() : File
{
return _databaseFile;
}
/**
*
* Retrieves the SQLService SQLStatement instance
*
* @return SQLService SQLStatement instance
*
*/
public function get statement() : SQLStatement
{
return _statement;
}
/**
*
* Retrieves the SQLService SQLConnection instance
*
* @return SQLService SQLConnection instance
*
*/
public function get connection() : SQLConnection
{
return _connection;
}
/**
*
* Provides a mechanism for opening the underlying SQLite database connection
* in synchronous mode
*
* @return reference to the <code>SQLConnection</code> which has been opened
*
*/
public function open() : SQLConnection
{
_databaseFile = new File( databaseFilePath + File.separator + databaseFileName );
_connection = new SQLConnection();
_connection.open( _databaseFile );
_statement = new SQLStatement();
_statement.sqlConnection = _connection;
return _connection;
}
/**
*
* Provides a mechanism for opening the underlying SQLite database connection
* in asynchronous mode
*
* @param optional handler for an <code>SQLEvent.OPEN</code> event
* @param optional handler for an <code>SQLErrorEvent.ERROR</code> event
*
*/
public function openAsync(openHandler:Function = null, errorHandler:Function = null) : void
{
_databaseFile = new File( databaseFilePath + File.separator + databaseFileName );
_connection = new SQLConnection();
_statement = new SQLStatement();
_statement.sqlConnection = _connection;
if ( openHandler != null )
{
_connection.addEventListener( SQLEvent.OPEN, openHandler );
}
if ( openHandler != null )
{
_connection.addEventListener( SQLErrorEvent.ERROR, errorHandler );
}
_connection.openAsync( _databaseFile );
}
/**
*
* Executes a specific SQL operation against the <code>SQLService</code>
* in asynchronous mode
*
* @param the SQL statement which to execute
* @param responder which handles the operation result / fault
* @param specifies the type in which a result is to be deserialized
* @param optional prefetch
*
*/
public function executeAsync(statement:String, responder:ISQLResponder, dataType:Class = null, prefetch:int = -1.0) : void
{
_statement = new SQLStatement();
_statement.sqlConnection = _connection;
_statement.text = statement;
if ( dataType != null )
{
_statement.itemClass = dataType;
}
_statement.execute( prefetch, new Responder( responder.result, responder.fault) );
}
/**
*
* Executes a specific SQL operation against the <code>SQLService</code>
* synchronous mode
*
* @param the SQL statement which to execute
* @param responder which handles the operation result / fault
* @param specifies the type in which a result is to be deserialized
* @param optional prefetch
*
*/
public function execute(statement:String, dataType:Class = null, prefetch:int = -1.0) : SQLResult
{
_statement.text = statement;
if ( dataType != null )
{
_statement.itemClass = dataType;
}
_statement.execute( prefetch );
return _statement.getResult();
}
/**
*
* Begins a transaction, within which all SQL statements executed
* against the connection's database(s) are grouped.
*
*/
public function beginTransaction(lockType:String = null) : void
{
_connection.begin( lockType );
}
/**
*
* Commits an existing transaction, causing any actions performed by
* the transaction's statements to be permanently applied to the
* database.
*
*/
public function commitTransaction() : void
{
_connection.commit();
}
/**
*
* Rolls back an existing transaction created using the begin() method,
* meaning all changes made by any SQL statements in the transaction
* are discarded.
*
*/
public function rollbackTransaction() : void
{
_connection.rollback();
}
/**
*
* Retrieves the <code>SQLResult</code> object instance from the last
* statement execution. For synchronous mode only.
*
* <p>
* Typically one uses a <code>SQLResult.data</code> object to access the
* rows of data returned by a SELECT statement.
* </p>
*
* @return
*
*/
public function get result() : SQLResult
{
return statement.getResult();
}
}
}