Archive for April, 2009

SQLStatementExecutionException:SQLStatement could not be executed due to an invalid state

Monday, April 20th, 2009

I am using the AIR SQL framework developed by  Eric J. Feminella. I create my “UserSQLDAO” derived from “AbstractAsynchronousSQLDAO” and start an asynchronous “select” query like “SELECT * FROM users” by executing a defined SQLStatement. However, I can not get the result one time and the SQLStatement is always executing. So if I execute this SQLStatement again, I will receive the exception showed as the title.

After a great searching work, I find nothing helpful. At last, I notice these words below mentioned here.

When the statement’s text property is a SELECT statement, this value indicates how many rows are returned at one time by the statement. The default value is -1, indicating that all the result rows are returned at one time.

I open the source file of class “AbstractAsynchronousSQLDAO”, find “statement.execute( 1, responder );” in the definition of method “execute”. After I set “1″ to “-1″, all bugs are cleared. I feel the sunshine on the next morning.

Below is the class definition I modified from the original file “AbstractAsynchronousSQLDAO.as”. The mokey patch trick is used to hack the air.sql.swc.

/*
Copyright (c) 2006 - 2008 Eric J. Feminella <eric@ericfeminella.com>
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@internal
*/

package com.ericfeminella.sql.dao
{
import flash.data.SQLMode;
import flash.data.SQLStatement;
import flash.filesystem.File;
import flash.net.Responder;
import flash.data.SQLConnection;

/**
*
* <code>AbstractAsynchronousSQLDAO</code> provides an abstraction of
* an asynchronous SQL DAO implementation.
*
*/
public class AbstractAsynchronousSQLDAO extends AbstractSQLDAO
{
/**
*
* Defines the <code>Responder</code> instance which handles
* <code>AbstractAsynchronousSQLDAO</code> SQL operation responses.
*
* @see flash.net.Responder
*
*/
protected var _responder:Responder;

/**
*
* <code>AbstractAsynchronousSQLDAO</code> constructor requires the
* databasePath from which the database connection is made as well as
* an optional <code>ISQLConnectionResponder</code> for handling the
* connection response.
*
* @param the path from which the database connection is made
*
*/
public function AbstractAsynchronousSQLDAO(connection:SQLConnection, databaseFile:File = null)
{
super( connection );

if ( !connection.connected )
{
connection.openAsync( databaseFile, SQLMode.CREATE, new Responder( openResult, openFault ) );
}
}

/**
*
* Assigns a reference to the <code>Responder</code> instance which
* handles SQL operation responses.
*
* @see flash.net.Responder
*
*/
public function set responder(responder:Responder) : void
{
_responder = responder;
}

/**
*
* Retrieves a reference to the <code>Responder</code> instance which
* handles SQL operation responses.
*
* @return flash.net.Responder
*
*/
public function get responder() : Responder
{
return _responder;
}

/**
*
* Convenience method which executes a prepared SQL statement against a local
* SQL Lite database
*
* @param SQL
* @param args
*
*/
public function execute(statement:SQLStatement, …parameters) : void
{
applyStatementParameters.apply( null, [ statement ].concat( parameters ) );

////////////////////////////////////////
// ORIGINAL:
// statement.execute( 1, responder );
// MODIFIED:
statement.execute( -1, responder );
//
// Because I want the “select” sql
// statement returns all the rows I
// requested.
//
////////////////////////////////////////
}
}
}

将Object类的实例转换为特定类的实例

Monday, April 20th, 2009

DECLARATION : This is a re-paste of Convert Generic Objects into Class Instances from darron schall


This questionhas comeupa lotonAIRIArecently, so I wanted to offer to the community a generic solution to convert plain old vanilla objects into full-fledged class instances.

I had originally developed this solution to be used with theJSON library that I made for the Adobe Labs Corelib project, but it’s really an all-purpose solution. Essentially, my utility method allows you to turn any remote service that returns plain old ActionScript objects (like JSON, WebServices, etc) into a service that returns typed class instances, much like RemoteObject.

This makes it easier to employ the ValueObject pattern… instead of getting back an object with some properties attached, I can convert that object into, say, a Book ValueObject. The Book then is easier to work with because I get IDE and compiler support from strong typing, and it also speeds up the code execution since accessing values in typed objects executes faster than in non-typed objects.

You can download my ObjectTranslator, and its test cases, here.  (MIT License)

Usage is as follows:

import com.darronschall.examples.vo.Book;
import com.darronschall.serialization.ObjectTranslator;
// Define an object with properties that mimic the variable names
// inside of the Book class
var bookObj:Object = { title: “My Book title”, pageCount: 10, inLibrary: true };
// Convert the generic object into an instance of the Book class
var book:Book = ObjectTranslator.objectToInstance( bookObj, Book ) as Book;

Yup, it’s really that simple.

Unfortunately, things get a little more complicated when you have nested ValueObjects. I didn’t take the time to make my method recursive, so it’s up to you to first convert the nested objects into instances, and then convert the top level object into an instance. It’s a little more work that can avoided by some recursion. I’ve outlined what the algorithm would look like inside of the code, I just haven’t had the time to write it yet.

import com.darronschall.examples.vo.Book;
import com.darronschall.examples.vo.Student;
import com.darronschall.serialization.ObjectTranslator;
var studentObj:Object = { firstName: “test first”, lastName: “test last”, favoriteBook: { title: “Favorite Book!” } };
// First we need to convert the nested objects to classes studentObj.
favoriteBook = ObjectTranslator.objectToInstance( studentObj.favoriteBook, Book );
// Convert the student object to a Student class
var student:Student = ObjectTranslator.objectToInstance( studentObj, Student ) as Student;

So, to summarize, the objectToInstance method allows JSON and WebService services to return true class instances from the server, making them behave like RemoteObject and allowing developers to more easily employ the ValueObject pattern. Use the objectToInstance method on the object that the service returns, and then use the converted instance elsewhere in your code.

Those who are curious about the implementation will get a kick out of the simplicity of my algorithm. Essentially, all I’m doing is constructing an AMF packet with the class name and the object property values, then doing a byteArray.readObject() to convert the AMF packet into a class instance. The code is fairly well commented so you can follow along easily. I’d like to think this is one of those “so simple it’s brilliant” type of moments…

Have fun, and let me know if you run into any issues!

大意是有一个Object对象的实例myBook,它有两个属性,name,price
我们有一个类Book,如何将myBook转换为Book呢?
注意myBook是Object类型的,无法Book(myBook)这样进行强制转换
伟大的作者在看到无数条类似问题后,给出了他的解决方案
var book:Book = ObjectTranslator.objectToInstance( myBook, Book ) as Book;
多么简洁,多么强大!!

如果鸟语生疏的话,直接看代码吧
You can download my ObjectTranslator, and its test cases, here.  (MIT License)

那么这个有什么用呢?
比如,我现在在开发一个基于AIR+sqlite的东东,从sqlite返回的每行数据被封装在一个Object类型的实例中,但是针对每张表我都建立了相关的VO,将这个Object转换为VO就是比较有意思的事情了,幸好有作者的无私奉献,终于能少死一些脑细胞了。
同样的,在做Flex+WebService的时候,返回的数据可能是Object或者ObjectProxy,那么用这个方法可以很轻松的将其转换为我们所需要的类型。
Enjoy!!

不装饰你的梦

Saturday, April 18th, 2009

不装饰你的梦 蔡国权

愿意心痛苦 不装饰你的梦
别再将我心 反复的戏弄
宁愿我携着忧郁归去
像刚消失那阵风

别再伤我心 它伤得那么重
像块冰碎开 它显得太空洞
狂热与天真早消失了
在郁郁的岁月中

谁愿意一颗心永落空
谁愿意只装饰你的梦
宁任我的心在长期地痛
亦不想给你抚弄

让每声叹息 消失于你的梦
让每点笑声 响于你的梦
曾为你献出的点点真爱 在空气内流动

谁愿意一颗心永落空
谁愿意只装饰你的梦
宁任我的心在长期地痛
亦不想给你抚弄

让每声叹息 消失于你的梦
让每点笑声 响于你的梦
曾为你献出的点点真爱 在空气内流动
曾为你献出的点点真爱 在空气内流动

429c572b029f89275243c1d5

Life?

Wednesday, April 1st, 2009

虽然阅读了无数激情澎湃的励志故事,倾听了无数振聋发聩的至理名言,但是不知为何,静下来的时候,总觉得心中空荡荡的。

TODO写了一遍又一遍,压栈,压栈,还是压栈。总提不起精神来完成那么多看起来很有趣的事情。

在两种情况下能让人忘记平淡中的压抑,DOTA的时候,沉入到工作的时候。

Google Reader里未阅读的日志总数早已上千,每每打开密密麻麻的列表,往日里新技术新知识带来的乐趣被深深的厌恶所替代。脑袋里不由自主的生出无数反感。

计算机的世界是如此庞大博杂,无数问题接踵而至,Bug,Bug,还是Bug。成功的一霎那,没有欢呼,只有解脱的后的深深疲倦。

我要吃饭,我想有个家——大多数人都在为自己的生计而奔波。

当欲望从心底升起的时候,实现目标所需的条件中,排在第一位的始终是MONEY。

自由——遥不可及!

为了生存?为了欲望?竞争如此残酷,学习,提升,杀脑细胞……

头痛,很痛,休息,沉睡——往往被心中挂念的事所惊起。

如此疲倦……

I'm in the shadow

寻找温柔的光明?

你,在哪里?