<?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("’’");
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吗?请帮忙
答案 0 :(得分:1)
错误很明显。在按下按钮之前,您的数据库尚未创建/连接。此外,永远不会调用createTable
函数,因为您永远不会在connection
属性上保持状态。
在执行任何语句之前,应始终检查数据库是否已连接。如您所知,连接失败。
第三个(可能是最重要的),您正在执行同步执行,因为您使用了connection.open
。为此,您需要在执行任何语句之前执行connection.begin()
并使用connection.commit()
结束。我认为更好的方法是使用connection.openAsync
来创建异步执行,这更容易管理,也可能是您想要做的。如果语句的顺序很重要(例如在事务中或者如果一个语句依赖于另一个语句),则仅使用synchronous。