使用applicationComplete并在flex中一起初始化?

时间:2011-09-26 11:38:08

标签: flex sqlite air

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx" applicationComplete="init();" initialize="initializeHandler(event)">
 <fx:Script>
<![CDATA[

        import mx.collections.ArrayCollection;
        import mx.events.FlexEvent;     
        import sandacreative.sqlite.events.StatementSuccessEvent;
        import sandacreative.sqlite.SQLiteManager;

        private var database:SQLiteManager = SQLiteManager.getInstance();

        protected function initializeHandler(event:FlexEvent):void
        {   trace("inside initializehandler");
            database.start("Users.db", "Users", "CREATE TABLE Users(UserId VARCHAR(150) PRIMARY KEY, UserName VARCHAR(150))");

            database.addEventListener(SQLiteManager.COMMAND_EXEC_SUCCESSFULLY, onSelectResult);
            database.addEventListener(SQLiteManager.COMMAND_EXEC_FAILED, function():void {
                trace("fail!"); 
            });

            readEntries();

        }

        private function insertEntry():void
        {

            var sql:String =  "INSERT INTO Users VALUES('"+nameField.text+"');";
            database.executeCustomCommand(sql);             
        }
// SQLite  Ends Here*/




import flash.media.Camera;
  import sandacreative.WebCam;
  import sandacreative.Base64;
  import mx.core.UIComponent;
  import mx.graphics.codec.JPEGEncoder;

  private var webCam:WebCam;

  private function init():void {
    webCam = new WebCam(160, 120);
    var ref:UIComponent = new UIComponent();
    preview.removeAllChildren();
    preview.addChild(ref);
    ref.addChild(webCam);

  }
</fx:Script>
 <mx:Panel width="180" height="160" id="preview" title="Snapshotr" x="158" y="343"/>
<mx:Button label="Save" id="submit"  x="280" y="521" width="100" enabled="true" click="insertEntry();"/>

init()启动一个凸轮并且正常工作..而initiliseHandler()创建一个sqlite表。但是没有创建表,当我尝试保存它时显示错误

Error: Error #3104: A SQLConnection must be open to perform this operation.
at Error$/throwError()
at flash.data::SQLStatement/checkAllowed()
at flash.data::SQLStatement/checkReady()
at flash.data::SQLStatement/execute()
at sandacreative.sqlite::SQLiteManager/executeCustomCommand()[C:\Documents and Settings\sujith\My Documents\Visitrac1\src\sandacreative\sqlite\SQLiteManager.as:238]
at sandacreative::Main/insertEntry()[C:\Documents and Settings\sujith\My Documents\Visitrac1\src\sandacreative\Main.mxml:34]
at sandacreative::Main/__submit_click()[C:\Documents and Settings\sujith\My Documents\Visitrac1\src\sandacreative\Main.mxml:153]

SQLiteManager.as

    package sandacreative.sqlite
    {
import sandacreative.sqlite.events.StatementSuccessEvent;

import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.errors.SQLError;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;


public class SQLiteManager extends EventDispatcher implements ISQLiteManager
{
    /**
     * Database file name and extension
     */     
    public var dbFullFileName:String;

    /**
     * Database Name
     */     
    public var tableName:String;

    /**
     * SQL command to create the database
     */     
    public var createDbStatement:String;

    // datsbase apis instances
    protected var connection:SQLConnection;
    protected var statement:SQLStatement;
    protected var sqlFile:File;

    // repeated sql command
    protected var repeateFailCallBack:Function;
    protected var repeateCallBack:Function;
    protected var repeateSqlCommand:String = "";

    // events strings
    public static var COMMAND_EXEC_SUCCESSFULLY:String = "commandExecSuccesfully";
    public static var DATABASE_CONNECTED_SUCCESSFULLY:String = "databaseConnectedSuccessfully";
    public static var COMMAND_EXEC_FAILED:String = "commandExecFailed";
    public static var DATABASE_READY:String = "databaseReady";

    // Singleton instance.
    protected static var instance:SQLiteManager;

    /**
     * Enforce singleton design pattern.
     *  
     * @param enforcer
     * 
     */     
    public function SQLiteManager(enforcer:AccessRestriction)
    {
        if (enforcer == null)
            throw new Error("Error enforcer input param is undefined" );
    }

    /**
     * Opens a database connection.
     *  
     * @param dbFullFileName the database file name for instance: Users.sql
     * @param tableName holds the database name, for instance: Users
     * @param createTableStatement holds the create database statment for instance: CREATE TABLE Users(userId VARCHAR(150) PRIMARY KEY, UserName VARCHAR(150))
     * 
     */ 
    public function start(dbFullFileName:String, tableName:String, createTableStatement:String):void
    {    
        this.dbFullFileName = dbFullFileName;
        this.tableName = tableName;
        this.createDbStatement = createTableStatement;

        connection = new SQLConnection();
        sqlFile = File.applicationStorageDirectory.resolvePath(dbFullFileName);

        try
        {
            connection.open(sqlFile);
            this.dispatchEvent(new Event(DATABASE_CONNECTED_SUCCESSFULLY));
        }
        catch (error:SQLError)
        {
            trace("Error message:", error.message);
            trace("Details:", error.details);
            fail();
        }
    }


    /**
     * Close connection 
     * 
     */     
    public function close():void
    {
        connection.close();
    }       

    /**
     * Test the table to ensure it exists. Sends a fail call back function to create the table if 
     * it doesn't exists.
     * 
     */     
    public function testTableExists():void
    {
        var sql:String = "SELECT * FROM "+tableName+" LIMIT 1;";
        executeCustomCommand(sql, this.onDatabaseReady, this.createTable );             
    }

    /**
     * Method to create the database table.
     * 
     */     
    private function createTable():void
    {
        statement = new SQLStatement();
        statement.sqlConnection = connection;
        statement.text = createDbStatement;
        statement.execute();
        statement.addEventListener(SQLEvent.RESULT, onDatabaseReady);           
    }

    /**
     * Common sql command: select all entries in database
     *  
     * @param callback
     * @param failCallback
     * 
     */     
    public function executeSelectAllCommand(callback:Function=null, failCallback:Function=null):void
    {
        var sql:String = "SELECT * FROM "+tableName+";";
        executeCustomCommand(sql, callback, failCallback);
    }

    /**
     * Common sql command: delete all entries in database
     * 
     * @param callback
     * 
     */     
    public function executeDeleteAllCommand(callback:Function=null):void
    {
        var sql:String = "DELETE * FROM "+tableName+";";
        executeCustomCommand(sql, callback);
    }       

    /**
     * Method to execute a SQL command
     * 
     * @param sql SQL command string
     * @param callback success call back function to impliment if necessery
     * @param failCallBack fail call back function to impliment if necessery
     * 
     */ 
    public function executeCustomCommand(sql:String, callBack:Function=null, failCallBack:Function=null):void
    {
        statement = new SQLStatement();
        statement.sqlConnection = connection;

        statement.text = sql;

        if (callBack!=null)
        {
            statement.addEventListener(SQLEvent.RESULT, callBack);
        }
        else
        {
            statement.addEventListener(SQLEvent.RESULT, onStatementSuccess);
        }

        statement.addEventListener(SQLErrorEvent.ERROR, function():void {
                fail();
            });

        try
        {
            statement.execute();
        }
        catch (error:SQLError)
        {
            this.handleErrors(error, sql, callBack, failCallBack);              
        }           
    }

    /**
     * Utility method to clean bad characters that can break SQL commands 
     * 
     * @param str
     * @return 
     * 
     */     
    public static function removeBadCharacters(str:String):String
    {
        var retVal:String = str.split("'").join("&#8217;&rsquo;");
        return retVal;
    }

    // ------------------------------HANDLERS----------------------------       

    /**
     * Method to handle SQL command that create the dataabase.  
     * If the method was created due to a fail SQL command method checks if need to repeate any SQL command.
     *  
     * @param event
     * 
     */     
    private function onDatabaseReady(event:Event=null):void
    {
        var evt:Event = new Event(DATABASE_READY);
        this.dispatchEvent(evt);

        if (repeateSqlCommand != "")
        {
            this.executeCustomCommand(repeateSqlCommand, repeateCallBack, repeateFailCallBack);

            repeateSqlCommand = "";
            repeateFailCallBack = null;
            repeateCallBack = null;
        }
    }

    /**
     * Handle successful calls 
     * @param event
     * 
     */     
    private function onStatementSuccess(event:SQLEvent):void 
    {
        var results:Object = statement.getResult();
        var evt:StatementSuccessEvent = new StatementSuccessEvent(COMMAND_EXEC_SUCCESSFULLY, results);
        this.dispatchEvent(evt);
    }

    /**
     * Error handler
     *  
     * @param error
     * @param sql
     * @param callBack
     * @param failCallBack
     * 
     */     
    private function handleErrors(error:SQLError, sql:String, callBack:Function, failCallBack:Function):void
    {
        trace("Error message:", error.message);
        trace("Details:", error.details);

        if (error.details == "no such table: '"+tableName+"'")
        {
            repeateSqlCommand = sql;
            repeateFailCallBack = failCallBack;
            repeateCallBack = callBack; 
            createTable();
        }
        else
        {
            if (failCallBack != null)
            {
                failCallBack();
            }
            else
            {
                fail();
            }                   
        }           
    }

    /**
     * Handler for fail calls
     *  
     * @param event
     * 
     */     
    private function fail(event:Event=null):void
    {
        var evt:Event = new Event(COMMAND_EXEC_FAILED);
        this.dispatchEvent(evt);

        close();
    }

    /**
     * Method function to retrieve instance of the class
     *  
     * @return The same instance of the class
     * 
     */
    public static function getInstance():SQLiteManager
    {
        if( instance == null )
            instance = new  SQLiteManager(new AccessRestriction());

        return instance;
    }

}
}

class AccessRestriction {} // can this happen ?

ISQLiteManager.as

package sandacreative.sqlite
{
/**
 * Describes the contract for Objects that serve as a central point to access SQLite database.
 *
 * @author Elad Elrom
 *
 */
public interface ISQLiteManager
{
    function start(dbFullFileName:String, tableName:String, createTableStatement:String):void
    function close():void
}

}

StatementSucessEvent.as

package sandacreative.sqlite.events
{
import flash.events.Event;

public class StatementSuccessEvent extends Event 
{
    /**
     *  Holds the event string name
     */     
    public static var COMMAND_EXEC_SUCCESSFULLY:String = "command_exec_succesfully";

    /**
     * Holds results object 
     */         
    public var results:Object;

    /**
     * Default constructor
     *  
     * @param type  event name
     * @param videoList video list collection
     * 
     */         
    public function StatementSuccessEvent(type:String, results:Object)
    {
        super(type);
        this.results = results;
    }
}
}

我从Elad Elrom那里获取了这段代码

是因为我同时使用了applicationComplete和Initilize吗?请帮忙

1 个答案:

答案 0 :(得分:1)

错误很明显。在按下按钮之前,您的数据库尚未创建/连接。此外,永远不会调用createTable函数,因为您永远不会在connection属性上保持状态。

在执行任何语句之前,应始终检查数据库是否已连接。如您所知,连接失败。

第三个(可能是最重要的),您正在执行同步执行,因为您使用了connection.open。为此,您需要在执行任何语句之前执行connection.begin()并使用connection.commit()结束。我认为更好的方法是使用connection.openAsync来创建异步执行,这更容易管理,也可能是您想要做的。如果语句的顺序很重要(例如在事务中或者如果一个语句依赖于另一个语句),则仅使用synchronous。