/*
 * Ext JS Library 2.2
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 *
 * function readResults modified by Davide Stefanini
 *
 */
Ext.data.GearsDB = Ext.extend(Ext.data.SqlDB, {
    // abstract methods
    open: function(db, cb, scope){
        this.conn = google.gears.factory.create('beta.database');
        this.conn.open(db);
        this.openState = true;
		this.transactionState = false;
        Ext.callback(cb, scope, [this]);
        this.fireEvent('open', this);
    },
    
    close: function(){
        this.conn.close();
        this.fireEvent('close', this);
    },
	
	remove: function(){
        this.conn.remove();
        this.fireEvent('remove', this);
    },
    
    exec: function(sql, cb, scope){
        log.trace('ext-gears-db - GearsDB.exec SQL -> ' + sql);
        try {
            this.conn.execute(sql).close();
        } 
        catch (e) {
        	log.error('ext-gears-db - GearsDB.exec error! -> ', e);
			Ext.callback(cb, scope, [false]);
        }
        Ext.callback(cb, scope, [true]);
    },
    
    execBy: function(sql, args, cb, scope){
        log.trace('ext-gears-db - GearsDB.execBy SQL -> ' + getQuery(sql, args));
        try {
            this.conn.execute(sql, args).close();
        } 
        catch (e) {
        	log.error('ext-gears-db - GearsDB.execBy error! -> ', e);
			Ext.callback(cb, scope, [false]);
        }
        Ext.callback(cb, scope, [true]);
    },
    
    query: function(sql, cb, scope){
        log.trace('ext-gears-db - GearsDB.query SQL -> ' + sql);
        try {
            var rs = this.conn.execute(sql);
        } 
        catch (e) {
        	log.error('ext-gears-db - GearsDB.query error! -> ', e);
			Ext.callback(cb, scope, [false]);
        }
        var r = this.readResults(rs);
        Ext.callback(cb, scope, [r]);
        return r;
    },
    
    queryBy: function(sql, args, cb, scope){
        log.trace('ext-gears-db - GearsDB.queryBy SQL -> ' + sql);
        try {
            var rs = this.conn.execute(sql, args);
        } 
        catch (e) {
            log.error('ext-gears-db - GearsDB.queryBy error! -> ', e);
            Ext.callback(cb, scope, [false]);
            return false;
        };
        var r = this.readResults(rs);
        Ext.callback(cb, scope, [r]);
        return r;
    },
    
    readResults: function(rs){
        var r = [];
        if (rs) {
            var c = rs.fieldCount();
            // precache field names
            var fs = [];
            for (var i = 0; i < c; i++) {
                fs[i] = rs.fieldName(i);
            }
            // read the data
            while (rs.isValidRow()) {
                var o = {};
                for (var i = 0; i < c; i++) {
                    o[fs[i]] = rs.field(i);
                }
                r[r.length] = o;
                rs.next();
            }
            rs.close();
        }
        /*******/
        r = {
            totalRows: r.length,
            rows: r
        }
        /*******/
        return r;
    },
	
	openTransaction: function(){
		if (!this.transactionState) {
			log.info('ext-gears-db - Inizio transazione');
			this.conn.execute('BEGIN');
			this.transactionState = true;
		} else {
			log.warn('ext-gears-db - Transazione gi'+UNI_A+' aperta');
		}
	},
	
	commitTransaction: function(){
		if (this.transactionState) {
			log.info('ext-gears-db - Commit');
			this.conn.execute('COMMIT');
			this.transactionState = false;
		} else {
			log.warn('ext-gears-db - Commit: transazione non aperta');
		}
	},
	
	rollbackTransaction: function(){
		if (this.transactionState) {
			log.info('ext-gears-db - Rollback');
			this.conn.execute('ROLLBACK');
			this.transactionState = false;
		} else {
			log.warn('ext-gears-db - Rollback: transazione non aperta');
		}
	},
	
	transaction: function(sql, cb, scope){
		if (!Ext.isArray(sql))
			sql = new Array(sql);
		this.openTransaction();
        try {
			for (var i=0, len=sql.length; i<len; i++) {
				log.trace('    ' + sql[i]);
		        this.conn.execute(sql[i]);
			}
			this.commitTransaction();
        } 
        catch (e) {
        	log.error('ext-gears-db - GearsDB.exec error! -> ', e);
			this.rollbackTransaction();
			Ext.callback(cb, scope, [false]);
        }
        Ext.callback(cb, scope, [true]);
	},
    
    // protected/inherited method
    isOpen: function(){
        return this.openState;
    },
    
    getTable: function(name, keyName){
        return new Ext.data.SqlDB.Table(this, name, keyName);
    }
});

