PDA

View Full Version : Problem accessing property of Singleton Class


DrGoomba
07-04-2007, 03:27 AM
First off, i am really confused on how to make properties global in a flex app and this is probably why i can't grasp this concept. But i have created a singleton class to instantiate a database connection. When i try to access the connection through another view AIR throws me an error saying "database must be open to perform this operation". But i did open it at the begining of the app, and in my singleton, if it hasn't been already initialized, then it will initialize it. But this tells me the class knows its already open otherwise i wouldn't get that error. So i am obviously not accessing it properly. What am i missing? How do i access my static property in other components after it has been inistantiated?

Here is my singleton class
package com.smallfry.connections.db {

import flash.data.SQLConnection;
import flash.filesystem.File;
import flash.events.SQLEvent;
import flash.events.SQLErrorEvent;

public class DatabaseConnector extends SQLConnection {

private static var _instance:DatabaseConnector;

public function DatabaseConnector(enforcer:SingletonEnforcer) {
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolve("mydatabase.sqlite");

conn.open(dbFile, false);
}

public static function getInstance():DatabaseConnector {
if (DatabaseConnector._instance == null) {
DatabaseConnector._instance = new DatabaseConnector(new SingletonEnforcer());
}
return DatabaseConnector._instance;
}

private function openHandler(event:SQLEvent):void {
trace("the database initialized successfully");
}

private function errorHandler(event:SQLErrorEvent):void {
trace("Error code:", event.error.code);
trace("Details:", event.error.message);
}

}
}

class SingletonEnforcer {}


My main application:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:views="views.*">


<mx:Script>
<![CDATA[
import com.smallfry.connections.db.DatabaseConnector;

private var conn:DatabaseConnector = DatabaseConnector.getInstance();

]]>
</mx:Script>

<mx:TabNavigator y="10" width="818" height="700" x="10">
<views:Inventory/>
<views:InventoryRec verticalScrollPolicy="off" horizontalScrollPolicy="off" width="100%" height="100%"/>
</mx:TabNavigator>

</mx:WindowedApplication>



Then the InventoryReceiving.mxml:

private var selectStmt:SQLStatement = new SQLStatement();
private var conn:DatabaseConnector = DatabaseConnector.getInstance();

private function genLocatorCode(spaceRequired:Number):void {
// create the SQL statement
selectStmt.sqlConnection = conn;

// define the sql text
var sql:String =
"SELECT min(locCode) " +
"FROM Location ";

selectStmt.text = sql;

// register listeners for the result and error events
selectStmt.addEventListener(SQLEvent.RESULT, selectResult);
selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError);

// execute the statement
selectStmt.execute();

}

hangalot
07-04-2007, 11:46 AM
what version of AIR?

DrGoomba
07-04-2007, 09:22 PM
Good question. I dont even know how to find that out. But i did download it less than a week ago, so it should be the current version. I did get it to work correctly though by adding a getter which i could reference.

The modified part of the class looks like this:

private static var _instance:DatabaseConnector;
private var _conn:SQLConnection;

public function get database():SQLConnection {
return _conn;
}

public function DatabaseConnector(enforcer:SingletonEnforcer) {
trace("i have initialized");
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolve("mydatabase.sqlite");

conn.open(dbFile, false);
_conn = conn;
}



And now i reference by calling the database property DatabaseConnector.getInstance().database

If there is a more efficient way of doing this, please don't hold back.

Another thing. The database i am accessing i created using SQLiteManager but AIR doesn't seem to like it. I don't get any errors connecting to it, but i presume this is because my code creates a new database if one doesn't already exist. So this would explain when i try to access a table in the generated db that i receive an error saying the table cannot be found.

I would like to be able to include a separate database with my app, just so its easier to for people to make backups or be able to access it through other applications. Any ideas on why i am unable to use a pre-defined database?

Thanks!!!

hangalot
07-06-2007, 11:15 AM
i have not used the sqlite yet, i asked some people i work with about their experience with it but they could not say for certain.
i think a singleton is a very valid way of doing this

DrGoomba
07-06-2007, 03:46 PM
I've figured it out. It didnt like my pre built database because i was trying to access it via the applicationStorageDirectory rather than a user file directory such as desktopDirectory. now it works.