2015-03-19 19:36:11 +00:00
|
|
|
/**
|
|
|
|
* Class to handle the Database select results. Also allows
|
|
|
|
* updates, insertions and deletions on tables where the primary key is
|
|
|
|
* selected.
|
|
|
|
*
|
|
|
|
* Note that table names must be unique in the selection query, otherwise
|
|
|
|
* updates are not allowed. If two tables of different schemes
|
|
|
|
* have the same name, an alias should be used to solve this.
|
|
|
|
**/
|
2015-01-23 13:09:30 +00:00
|
|
|
Db.Model = new Class ().extend
|
|
|
|
({
|
|
|
|
Status:
|
|
|
|
{
|
|
|
|
CLEAN : 1
|
|
|
|
,LOADING : 2
|
|
|
|
,READY : 3
|
|
|
|
,ERROR : 4
|
2015-03-19 19:36:11 +00:00
|
|
|
},
|
|
|
|
Mode:
|
|
|
|
{
|
|
|
|
ON_CHANGE: 1
|
|
|
|
,ON_DEMAND: 2
|
|
|
|
},
|
|
|
|
Operation:
|
|
|
|
{
|
|
|
|
INSERT: 1 << 1
|
|
|
|
,UPDATE: 1 << 2
|
|
|
|
,DELETE: 1 << 3
|
|
|
|
}
|
|
|
|
,SortWay:
|
|
|
|
{
|
|
|
|
ASC : 1,
|
|
|
|
DESC : 2
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
Db.Model.implement
|
|
|
|
({
|
|
|
|
Extends: Vn.Object
|
|
|
|
,Tag: 'db-model'
|
|
|
|
,Child: 'query'
|
|
|
|
,Properties:
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The connection used to execute the statement.
|
|
|
|
**/
|
|
|
|
conn:
|
|
|
|
{
|
|
|
|
type: Db.Conn
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._conn = x;
|
|
|
|
this.refresh ();
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._conn;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The result index.
|
|
|
|
**/
|
|
|
|
resultIndex:
|
|
|
|
{
|
|
|
|
type: Number
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._resultIndex = x;
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._resultIndex;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The batch used to execute the statement.
|
|
|
|
**/
|
|
|
|
batch:
|
|
|
|
{
|
|
|
|
type: Sql.Batch
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this.link ({_batch: x}, {'changed': this.refresh});
|
|
|
|
this.refresh ();
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._batch;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The model select statement.
|
|
|
|
**/
|
|
|
|
stmt:
|
|
|
|
{
|
|
|
|
type: Sql.Stmt
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._stmt = x;
|
|
|
|
this.refresh ();
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._stmt;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The model query.
|
|
|
|
**/
|
|
|
|
query:
|
|
|
|
{
|
|
|
|
type: String
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._stmt = new Sql.String ({query: x});
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._stmt.render (null);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The main table.
|
|
|
|
**/
|
|
|
|
mainTable:
|
|
|
|
{
|
|
|
|
type: String
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._mainTable = null;
|
|
|
|
this.requestedMainTable = x;
|
|
|
|
this.refreshMainTable ();
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._mainTable;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Determines if the model is updatable.
|
|
|
|
**/
|
|
|
|
updatable:
|
|
|
|
{
|
|
|
|
type: Boolean
|
|
|
|
,set: function (x)
|
|
|
|
{
|
|
|
|
this._updatable = false;
|
|
|
|
this.requestedUpdatable = x;
|
|
|
|
this.refreshUpdatable ();
|
|
|
|
}
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._updatable;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The number of rows in the model.
|
|
|
|
**/
|
|
|
|
numRows:
|
|
|
|
{
|
|
|
|
type: Number
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
if (this.data)
|
|
|
|
return this.data.length;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* The current status of the model.
|
|
|
|
**/
|
|
|
|
status:
|
|
|
|
{
|
|
|
|
type: Number
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._status;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Checks if the model data is ready.
|
|
|
|
**/
|
|
|
|
ready:
|
|
|
|
{
|
|
|
|
type: Boolean
|
|
|
|
,get: function ()
|
|
|
|
{
|
|
|
|
return this._status == Db.Model.Status.READY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
,_resultIndex: 0
|
|
|
|
,_batch: null
|
|
|
|
,_stmt: null
|
|
|
|
,_status: Db.Model.Status.CLEAN
|
|
|
|
,data: null
|
2015-03-19 19:36:11 +00:00
|
|
|
,tables: null
|
2015-01-23 13:09:30 +00:00
|
|
|
,columns: null
|
|
|
|
,columnMap: null
|
2015-03-19 19:36:11 +00:00
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
,sortColumn: -1
|
2015-03-19 19:36:11 +00:00
|
|
|
,sortWay: null
|
2015-02-08 15:38:38 +00:00
|
|
|
,requestedIndexes: {}
|
|
|
|
,indexes: []
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,mode: Db.Model.Mode.ON_CHANGE
|
|
|
|
,operations: null
|
|
|
|
,operationsMap: null
|
|
|
|
,_insertedRow: -1
|
|
|
|
,defaults: []
|
|
|
|
,columnDefaults: []
|
|
|
|
,requestedMainTable: null
|
|
|
|
,requestedUpdatable: true
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
,initialize: function (props)
|
|
|
|
{
|
|
|
|
this.parent (props);
|
2015-03-19 19:36:11 +00:00
|
|
|
this._cleanData ();
|
|
|
|
this._resetOperations ();
|
|
|
|
this._setStatus (Db.Model.Status.CLEAN);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
,loadXml: function (builder, node)
|
|
|
|
{
|
|
|
|
this.parent (builder, node);
|
|
|
|
|
|
|
|
var query = node.firstChild.nodeValue;
|
|
|
|
|
|
|
|
if (query)
|
|
|
|
this.query = query;
|
|
|
|
}
|
|
|
|
|
|
|
|
,refresh: function ()
|
|
|
|
{
|
|
|
|
if (this._stmt && this._batch)
|
|
|
|
this._stmt.findHolders (this._batch);
|
|
|
|
|
|
|
|
if (this._conn && this._stmt
|
|
|
|
&& (!this._batch || this._batch.isReady ()))
|
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
this._setStatus (Db.Model.Status.LOADING);
|
|
|
|
this._conn.execStmt (this._stmt, this._selectDone.bind (this), this._batch);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
else
|
2015-02-08 15:38:38 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
this._cleanData ();
|
|
|
|
this._setStatus (Db.Model.Status.CLEAN);
|
2015-02-08 15:38:38 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-03-19 19:36:11 +00:00
|
|
|
|
|
|
|
,_selectDone: function (resultSet)
|
|
|
|
{
|
|
|
|
var result;
|
|
|
|
var dataResult;
|
|
|
|
|
|
|
|
this._cleanData ();
|
|
|
|
|
|
|
|
for (var i = 0; result = resultSet.fetchResult (); i++)
|
|
|
|
if (i == this._resultIndex)
|
|
|
|
dataResult = result;
|
|
|
|
|
|
|
|
if (dataResult && typeof dataResult === 'object')
|
|
|
|
{
|
|
|
|
this.sortColumn = -1;
|
|
|
|
this.data = dataResult.data;
|
|
|
|
this.tables = dataResult.tables;
|
|
|
|
this.columns = dataResult.columns;
|
|
|
|
this.columnMap = dataResult.columnMap;
|
|
|
|
this.repairColumns (this.columns);
|
|
|
|
this._refreshRowIndexes ();
|
|
|
|
this.refreshMainTable ();
|
|
|
|
|
|
|
|
for (column in this.requestedIndexes)
|
|
|
|
this._buildIndex (column);
|
|
|
|
|
|
|
|
this._setStatus (Db.Model.Status.READY);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this._setStatus (Db.Model.Status.ERROR);
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_refreshRowIndexes: function ()
|
|
|
|
{
|
|
|
|
for (var i = 0; i < this.data.length; i++)
|
|
|
|
this.data[i].index = i;
|
|
|
|
|
|
|
|
if (this.operationsMap)
|
|
|
|
{
|
|
|
|
this.operationsMap = {};
|
|
|
|
|
|
|
|
for (var i = 0; i < this.operations.length; i++)
|
|
|
|
this.operationsMap[i] = this.operations[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
,_cleanData: function (error)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
this.data = null;
|
|
|
|
this.columns = null;
|
|
|
|
this.columnMap = null;
|
2015-02-08 15:38:38 +00:00
|
|
|
this.indexes = [];
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
,refreshUpdatable: function ()
|
|
|
|
{
|
|
|
|
var oldValue = this._updatable;
|
2015-03-19 19:36:11 +00:00
|
|
|
this._updatable = this._mainTable !== null && this.requestedUpdatable;
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
if (oldValue != this._updatable)
|
|
|
|
this.signalEmit ('updatable-changed');
|
|
|
|
}
|
|
|
|
|
|
|
|
,refreshMainTable: function ()
|
|
|
|
{
|
|
|
|
var newMainTable = null;
|
2015-03-19 19:36:11 +00:00
|
|
|
var tables = this.tables;
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
if (tables)
|
|
|
|
for (var i = 0; i < tables.length; i++)
|
|
|
|
if (tables[i].pks.length > 0)
|
2015-01-23 13:09:30 +00:00
|
|
|
if (!this.requestedMainTable
|
2015-03-19 19:36:11 +00:00
|
|
|
|| tables[i].name === this.requestedMainTable)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
newMainTable = i;
|
2015-01-23 13:09:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._mainTable = newMainTable;
|
|
|
|
this.refreshUpdatable ();
|
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
/**
|
|
|
|
* Sets the default value for inserted fields.
|
|
|
|
*
|
|
|
|
* @param {String} field The destination field name
|
|
|
|
* @param {String} table The destination table name
|
|
|
|
* @param {Sql.Expr} srcColumn The default value expression
|
|
|
|
**/
|
|
|
|
,setDefault: function (field, table, expr)
|
|
|
|
{
|
|
|
|
this.defaults.push
|
|
|
|
({
|
|
|
|
field: field
|
|
|
|
,table: table
|
|
|
|
,expr: expr
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
/**
|
|
|
|
* Sets the default value for inserted fields.
|
|
|
|
*
|
|
|
|
* @param {String} field The destination field name
|
|
|
|
* @param {String} table The destination table name
|
|
|
|
* @param {Object} value The default value
|
|
|
|
**/
|
|
|
|
,setDefaultFromValue: function (field, table, value)
|
|
|
|
{
|
|
|
|
this.defaults.push
|
|
|
|
({
|
|
|
|
field: field
|
|
|
|
,table: table
|
|
|
|
,value: value
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the default value for inserted fields from another column in the
|
|
|
|
* model.
|
|
|
|
*
|
|
|
|
* @param {String} field The destination field name
|
|
|
|
* @param {String} table The destination table name
|
|
|
|
* @param {String} srcColumn The source column
|
|
|
|
**/
|
|
|
|
,setDefaultFromColumn: function (field, table, srcColumn)
|
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
this.defaults.push
|
2015-01-23 13:09:30 +00:00
|
|
|
({
|
|
|
|
field: field
|
|
|
|
,table: table
|
|
|
|
,srcColumn: srcColumn
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the column exists.
|
|
|
|
*
|
|
|
|
* @param {integer} column The column index
|
|
|
|
* @return {Boolean} %true if column exists, %false otherwise
|
|
|
|
**/
|
|
|
|
,checkColExists: function (column)
|
|
|
|
{
|
|
|
|
return this.columns && column >= 0 && column < this.columns.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the row exists.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {integer} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
* @return {Boolean} %true if row exists, %false otherwise
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,checkRowExists: function (rowIndex)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
return this.data && rowIndex >= 0 && rowIndex < this.data.length;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,checkRowUpdatable: function (rowIndex)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
return this.checkRowExists (rowIndex);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the index of the column from its name.
|
|
|
|
*
|
|
|
|
* @param {string} columnName The column name
|
|
|
|
* @return {number} The column index or -1 if column not exists
|
|
|
|
**/
|
|
|
|
,getColumnIndex: function (columnName)
|
|
|
|
{
|
|
|
|
var index;
|
|
|
|
|
|
|
|
if (this.columnMap
|
|
|
|
&& (index = this.columnMap[columnName]) !== undefined)
|
|
|
|
return index;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a value from the model.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {number} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
* @param {string} columnName The column name
|
|
|
|
* @return {mixed} The value
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,get: function (rowIndex, columnName)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
var index = this.getColumnIndex (columnName);
|
|
|
|
|
|
|
|
if (index != -1)
|
2015-03-19 19:36:11 +00:00
|
|
|
return this.getByIndex (rowIndex, index);
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates a value on the model.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {number} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
* @param {string} columnName The column name
|
|
|
|
* @param {mixed} value The new value
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,set: function (rowIndex, columnName, value)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
var index = this.getColumnIndex (columnName);
|
|
|
|
|
|
|
|
if (index != -1)
|
2015-03-19 19:36:11 +00:00
|
|
|
this.setByIndex (rowIndex, index, value);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a value from the model using the column index.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {number} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
* @param {number} column The column index
|
|
|
|
* @return {mixed} The value
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,getByIndex: function (rowIndex, column)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
if (this.checkRowExists (rowIndex) && this.checkColExists (column))
|
|
|
|
return this.data[rowIndex][column];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates a value on the model using the column index.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {number} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
* @param {number} col The column index
|
|
|
|
* @param {mixed} value The new value
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,setByIndex: function (rowIndex, col, value)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
if (!(this.checkRowUpdatable (rowIndex) && this.checkColExists (col)))
|
2015-01-23 13:09:30 +00:00
|
|
|
return;
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
var tableIndex = this.columns[col].table;
|
|
|
|
var pks = this.tables[tableIndex].pks;
|
|
|
|
|
|
|
|
if (pks.length == 0)
|
2015-01-23 13:09:30 +00:00
|
|
|
return;
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
var row = this.data[rowIndex];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
var op = this._createOperation (rowIndex);
|
|
|
|
op.type |= Db.Model.Operation.UPDATE;
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
if (!op.oldValues)
|
|
|
|
op.oldValues = [];
|
|
|
|
if (!op.tables)
|
|
|
|
op.tables = {};
|
|
|
|
|
|
|
|
var tableOp = op.tables[tableIndex];
|
|
|
|
|
|
|
|
if (!tableOp)
|
|
|
|
{
|
|
|
|
tableOp = Db.Model.Operation.UPDATE;
|
|
|
|
|
|
|
|
for (var i = 0; i < pks.length; i++)
|
|
|
|
if (!row[pks[i]] && !op.oldValues[pks[i]])
|
|
|
|
{
|
|
|
|
tableOp = Db.Model.Operation.INSERT;
|
|
|
|
break;
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
op.tables[tableIndex] = tableOp;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-03-19 19:36:11 +00:00
|
|
|
|
|
|
|
if (tableOp & Db.Model.Operation.UPDATE
|
|
|
|
&& op.oldValues[col] === undefined)
|
|
|
|
op.oldValues[col] = row[col];
|
|
|
|
|
|
|
|
this.signalEmit ('row-updated-before', rowIndex);
|
|
|
|
row[col] = value;
|
|
|
|
this.signalEmit ('row-updated', rowIndex, [col]);
|
|
|
|
|
|
|
|
if (this.mode == Db.Model.Mode.ON_CHANGE
|
|
|
|
&& !(op.type & Db.Model.Operation.INSERT))
|
|
|
|
this.performOperations ();
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletes a row from the model.
|
|
|
|
*
|
2015-03-19 19:36:11 +00:00
|
|
|
* @param {number} rowIndex The row index
|
2015-01-23 13:09:30 +00:00
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,deleteRow: function (rowIndex)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
if (!this.checkRowUpdatable (rowIndex))
|
2015-01-23 13:09:30 +00:00
|
|
|
return;
|
2015-03-19 19:36:11 +00:00
|
|
|
|
|
|
|
var op = this._createOperation (rowIndex);
|
|
|
|
op.type |= Db.Model.Operation.DELETE;
|
|
|
|
|
|
|
|
if (this.mode === Db.Model.Mode.ON_CHANGE)
|
|
|
|
this.performOperations ();
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Inserts a new row on the model.
|
|
|
|
*
|
|
|
|
* @return The index of the inserted row
|
|
|
|
**/
|
|
|
|
,insertRow: function ()
|
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
if (!this._updatable || this._insertedRow != -1)
|
2015-01-23 13:09:30 +00:00
|
|
|
return -1;
|
2015-03-19 19:36:11 +00:00
|
|
|
|
|
|
|
var cols = this.columns;
|
|
|
|
var newRow = new Array (cols.length);
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (cols[i].table === this._mainTable)
|
|
|
|
newRow[i] = cols[i].def;
|
2015-01-23 13:09:30 +00:00
|
|
|
else
|
|
|
|
newRow[i] = null;
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
this._insertedRow = this.data.push (newRow) - 1;
|
|
|
|
|
|
|
|
var op = this._createOperation (this._insertedRow);
|
|
|
|
op.type |= Db.Model.Operation.INSERT;
|
|
|
|
|
|
|
|
this.signalEmit ('row-inserted', this._insertedRow);
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
return this._insertedRow;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
/**
|
|
|
|
* Performs all model changes on the database.
|
|
|
|
**/
|
2015-01-23 13:09:30 +00:00
|
|
|
,performOperations: function ()
|
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
if (this.operations.length === 0)
|
2015-01-23 13:09:30 +00:00
|
|
|
return;
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
var stmts = new Sql.MultiStmt ();
|
|
|
|
|
|
|
|
var query = new Sql.String ({query: 'START TRANSACTION'});
|
|
|
|
stmts.addStmt (query);
|
|
|
|
|
|
|
|
for (var i = 0; i < this.operations.length; i++)
|
|
|
|
{
|
|
|
|
query = null;
|
|
|
|
var op = this.operations[i];
|
|
|
|
|
|
|
|
if (op.type & Db.Model.Operation.DELETE)
|
|
|
|
{
|
|
|
|
if (op.type & Db.Model.Operation.INSERT)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
var where = this._createWhere (this._mainTable, op, true);
|
|
|
|
|
|
|
|
if (where)
|
|
|
|
{
|
|
|
|
query = new Sql.Delete ({where: where});
|
|
|
|
query.addTarget (this._createTarget (this._mainTable));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (op.type & (Db.Model.Operation.INSERT | Db.Model.Operation.UPDATE))
|
|
|
|
{
|
|
|
|
query = new Sql.MultiStmt ();
|
|
|
|
|
|
|
|
for (var tableIndex in op.tables)
|
|
|
|
{
|
|
|
|
var stmt = this._createDmlQuery (op, parseInt (tableIndex));
|
|
|
|
query.addStmt (stmt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query)
|
|
|
|
{
|
|
|
|
stmts.addStmt (query);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
console.warn ('Db.Model: %s', _('ErrorSavingChanges'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var query = new Sql.String ({query: 'COMMIT'});
|
|
|
|
stmts.addStmt (query);
|
|
|
|
|
|
|
|
this._conn.execStmt (stmts,
|
|
|
|
this._onOperationsDone.bind (this));
|
|
|
|
}
|
|
|
|
|
|
|
|
,_createDmlQuery: function (op, tableIndex)
|
|
|
|
{
|
|
|
|
var where = this._createWhere (tableIndex, op, false);
|
|
|
|
|
|
|
|
if (!where)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var multiStmt = new Sql.MultiStmt ();
|
|
|
|
var target = this._createTarget (tableIndex);
|
|
|
|
|
|
|
|
var select = new Sql.Select ({where: where});
|
|
|
|
select.addTarget (target);
|
|
|
|
|
|
|
|
var tableOp = op.tables[tableIndex];
|
|
|
|
var table = this.tables[tableIndex];
|
|
|
|
var row = op.row;
|
|
|
|
var cols = this.columns;
|
|
|
|
|
|
|
|
if (tableOp & Db.Model.Operation.INSERT)
|
|
|
|
{
|
|
|
|
var dmlQuery = new Sql.Insert ();
|
|
|
|
|
|
|
|
for (var i = 0; i < this.defaults.length; i++)
|
|
|
|
{
|
|
|
|
var def = this.defaults[i];
|
|
|
|
|
|
|
|
if (def.table === table.name)
|
|
|
|
{
|
|
|
|
if (def.value)
|
|
|
|
dmlQuery.addSet (def.field, def.value);
|
|
|
|
else if (def.expr)
|
|
|
|
dmlQuery.addExpr (def.field, def.expr);
|
|
|
|
else if (def.srcColumn)
|
|
|
|
{
|
|
|
|
var columnIndex = this.getColumnIndex (def.srcColumn);
|
|
|
|
dmlQuery.addSet (def.field, row[columnIndex]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (cols[i].table === tableIndex)
|
|
|
|
{
|
|
|
|
if (row[i] !== null)
|
|
|
|
dmlQuery.addSet (cols[i].orgname, row[i]);
|
|
|
|
|
|
|
|
select.addField (cols[i].orgname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var updateWhere = this._createWhere (tableIndex, op, true);
|
|
|
|
|
|
|
|
if (!updateWhere)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var dmlQuery = new Sql.Update ({where: updateWhere});
|
|
|
|
|
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (cols[i].table === tableIndex && op.oldValues[i] !== undefined)
|
|
|
|
{
|
|
|
|
var fieldName = cols[i].orgname;
|
|
|
|
dmlQuery.addSet (fieldName, row[i]);
|
|
|
|
select.addField (fieldName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dmlQuery.addTarget (target);
|
|
|
|
|
|
|
|
multiStmt.addStmt (dmlQuery);
|
|
|
|
multiStmt.addStmt (select);
|
|
|
|
return multiStmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
,_onOperationsDone: function (resultSet)
|
|
|
|
{
|
|
|
|
if (resultSet.getError ())
|
|
|
|
return;
|
|
|
|
|
|
|
|
resultSet.fetchResult ();
|
|
|
|
|
|
|
|
for (var i = 0; i < this.operations.length; i++)
|
|
|
|
{
|
|
|
|
var isOperation = true;
|
|
|
|
var op = this.operations[i];
|
|
|
|
var row = op.row;
|
|
|
|
|
|
|
|
if (op.type & Db.Model.Operation.DELETE
|
|
|
|
&& op.type & Db.Model.Operation.INSERT)
|
|
|
|
isOperation = false;
|
|
|
|
|
|
|
|
if (op.type & Db.Model.Operation.DELETE)
|
|
|
|
{
|
|
|
|
resultSet.fetchResult ();
|
|
|
|
this._performDelete (row);
|
|
|
|
}
|
|
|
|
else if (op.type & (Db.Model.Operation.INSERT | Db.Model.Operation.UPDATE))
|
|
|
|
{
|
|
|
|
this.signalEmit ('row-updated-before', row.index);
|
|
|
|
|
|
|
|
var updatedCols = [];
|
|
|
|
var cols = this.columns;
|
|
|
|
|
|
|
|
for (var tableIndex in op.tables)
|
|
|
|
{
|
|
|
|
var j = 0;
|
|
|
|
tableIndex = parseInt (tableIndex);
|
|
|
|
var tableOp = op.tables[tableIndex];
|
|
|
|
var table = this.tables[tableIndex];
|
|
|
|
|
|
|
|
resultSet.fetchResult ();
|
|
|
|
var newValues = resultSet.fetchRow ();
|
|
|
|
|
|
|
|
if (tableOp & Db.Model.Operation.INSERT)
|
|
|
|
{
|
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (cols[i].table === tableIndex)
|
|
|
|
{
|
|
|
|
row[i] = newValues[j++];
|
|
|
|
updatedCols.push (i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (cols[i].table === tableIndex
|
|
|
|
&& op.oldValues[i] !== undefined)
|
|
|
|
{
|
|
|
|
row[i] = newValues[j++];
|
|
|
|
updatedCols.push (i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.signalEmit ('row-updated', row.index, updatedCols);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resultSet.fetchResult ();
|
|
|
|
|
|
|
|
if (isOperation)
|
|
|
|
this.signalEmit ('operations-done');
|
|
|
|
|
|
|
|
this._resetOperations ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Undoes all unsaved changes made to the model.
|
|
|
|
**/
|
|
|
|
,reverseOperations: function ()
|
|
|
|
{
|
|
|
|
for (var i = 0; i < this.operations.length; i++)
|
|
|
|
{
|
|
|
|
var op = this.operations[i];
|
|
|
|
var row = op.row;
|
|
|
|
|
|
|
|
if (op.type & Db.Model.Operation.INSERT)
|
|
|
|
{
|
|
|
|
this._performDelete (row);
|
|
|
|
}
|
|
|
|
else if (op.type & Db.Model.Operation.UPDATE)
|
|
|
|
{
|
|
|
|
this.signalEmit ('row-updated-before', row.index);
|
|
|
|
|
|
|
|
var updatedCols = [];
|
|
|
|
var cols = this.columns;
|
|
|
|
|
|
|
|
for (var i = 0; i < cols.length; i++)
|
|
|
|
if (op.oldValues[i] !== undefined)
|
|
|
|
{
|
|
|
|
row[i] = op.oldValues[i];
|
|
|
|
updatedCols.push (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.signalEmit ('row-updated', row.index, updatedCols);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this._resetOperations ();
|
|
|
|
}
|
|
|
|
|
|
|
|
,_resetOperations: function ()
|
|
|
|
{
|
|
|
|
this.operations = [];
|
|
|
|
this.operationsMap = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
,_performDelete: function (row)
|
|
|
|
{
|
|
|
|
if (!this.requestedMainTable)
|
|
|
|
{
|
|
|
|
this.signalEmit ('row-deleted-before', row.index);
|
|
|
|
this.data.splice (row.index, 1);
|
|
|
|
this.signalEmit ('row-deleted', row.index);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.signalEmit ('row-updated-before', row.index);
|
|
|
|
|
|
|
|
var updatedCols = [];
|
|
|
|
|
|
|
|
for (var i = 0; i < this.columns.length; i++)
|
|
|
|
if (this.columns[i].table == this._mainTable)
|
|
|
|
{
|
|
|
|
row[i] = null;
|
|
|
|
updatedCols.push (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.signalEmit ('row-updated', row.index, updatedCols);
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Function used to sort the model.
|
|
|
|
*/
|
|
|
|
,sortFunction: function (column, a, b)
|
|
|
|
{
|
|
|
|
if (a[column] < b[column])
|
|
|
|
return -1;
|
|
|
|
else if (a[column] > b[column])
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Orders the model by the specified column.
|
|
|
|
*
|
|
|
|
* @param {integer} column the column index
|
|
|
|
**/
|
2015-03-19 19:36:11 +00:00
|
|
|
,sort: function (column, way)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
if (!this.checkColExists (column))
|
|
|
|
return;
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
this._setStatus (Db.Model.Status.LOADING);
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
if (column != this.sortColumn)
|
|
|
|
{
|
|
|
|
this.data.sort (this.sortFunction.bind (this, column));
|
|
|
|
this.sortColumn = column;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this.data.reverse ();
|
2015-03-19 19:36:11 +00:00
|
|
|
|
|
|
|
this._refreshRowIndexes ();
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
this._setStatus (Db.Model.Status.READY);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-02-08 15:38:38 +00:00
|
|
|
/**
|
|
|
|
* Builds an internal hash index for the specified column, this speeds
|
|
|
|
* significantly searches on that column.
|
|
|
|
* Not implemented yet.
|
|
|
|
*
|
|
|
|
* @param {String} column The column name
|
|
|
|
**/
|
|
|
|
,indexColumn: function (column)
|
|
|
|
{
|
|
|
|
this.requestedIndexes[column] = true;
|
|
|
|
|
|
|
|
if (this._status == Db.Model.Status.READY)
|
2015-03-19 19:36:11 +00:00
|
|
|
this._buildIndex (column);
|
2015-02-08 15:38:38 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_buildIndex: function (column)
|
2015-02-08 15:38:38 +00:00
|
|
|
{
|
|
|
|
var columnIndex = this.getColumnIndex (column);
|
|
|
|
|
|
|
|
if (columnIndex != -1)
|
|
|
|
{
|
|
|
|
var index = {};
|
|
|
|
var data = this.data;
|
|
|
|
|
|
|
|
switch (this.columns[columnIndex].type)
|
|
|
|
{
|
|
|
|
case Db.Conn.Type.TIMESTAMP:
|
|
|
|
case Db.Conn.Type.DATE_TIME:
|
|
|
|
case Db.Conn.Type.DATE:
|
|
|
|
for (var i = 0; i < data.length; i++)
|
|
|
|
index[data[i][columnIndex].toString ()] = i;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
for (var i = 0; i < data.length; i++)
|
|
|
|
index[data[i][columnIndex]] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.indexes[columnIndex] = index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
/**
|
|
|
|
* Searchs a value on the model and returns the row index of the first
|
|
|
|
* ocurrence.
|
|
|
|
*
|
|
|
|
* @param {String} column The column name
|
|
|
|
* @param {Object} value The value to search
|
|
|
|
* @return {integer} The column index
|
|
|
|
**/
|
|
|
|
,search: function (column, value)
|
|
|
|
{
|
|
|
|
var index = this.getColumnIndex (column);
|
|
|
|
return this.searchByIndex (index, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Searchs a value on the model and returns the row index of the first
|
|
|
|
* ocurrence.
|
|
|
|
*
|
|
|
|
* @param {integer} col The column index
|
|
|
|
* @param {Object} value The value to search
|
|
|
|
* @return {integer} The column index
|
|
|
|
**/
|
|
|
|
,searchByIndex: function (col, value)
|
|
|
|
{
|
|
|
|
if (!this.checkColExists (col))
|
|
|
|
return -1;
|
2015-02-08 15:38:38 +00:00
|
|
|
|
|
|
|
if (value)
|
|
|
|
switch (this.columns[col].type)
|
|
|
|
{
|
|
|
|
case Db.Conn.Type.BOOLEAN:
|
|
|
|
value = !!value;
|
|
|
|
break;
|
|
|
|
case Db.Conn.Type.INTEGER:
|
|
|
|
value = parseInt (value);
|
|
|
|
break;
|
|
|
|
case Db.Conn.Type.DOUBLE:
|
|
|
|
value = parseFloat (value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
value = value.toString ();
|
|
|
|
}
|
|
|
|
|
|
|
|
var index = this.indexes[col];
|
|
|
|
|
|
|
|
if (index)
|
|
|
|
{
|
2015-02-17 11:48:53 +00:00
|
|
|
if (index[value] !== undefined)
|
2015-02-08 15:38:38 +00:00
|
|
|
return index[value];
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
var data = this.data;
|
|
|
|
|
|
|
|
switch (this.columns[col].type)
|
|
|
|
{
|
|
|
|
case Db.Conn.Type.TIMESTAMP:
|
|
|
|
case Db.Conn.Type.DATE_TIME:
|
|
|
|
case Db.Conn.Type.DATE:
|
|
|
|
{
|
|
|
|
for (var i = 0; i < data.length; i++)
|
|
|
|
if (value === data[i][col].toString ());
|
|
|
|
return i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
for (var i = 0; i < data.length; i++)
|
|
|
|
if (value === data[i][col])
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_setStatus: function (status)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
this._status = status;
|
|
|
|
this.signalEmit ('status-changed', status);
|
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_createTarget: function (tableIndex)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
var table = this.tables[tableIndex];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
return new Sql.Table
|
|
|
|
({
|
|
|
|
name: table.orgname
|
|
|
|
,schema: table.schema
|
|
|
|
});
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_createWhere: function (tableIndex, op, useOldValues)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
var where = new Sql.Operation ({type: Sql.Operation.Type.AND});
|
|
|
|
var pks = this.tables[tableIndex].pks;
|
|
|
|
|
|
|
|
if (pks.length === 0)
|
|
|
|
return null;
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
for (var i = 0; i < pks.length; i++)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
var col = pks[i];
|
|
|
|
var column = this.columns[col];
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
var equalOp = new Sql.Operation ({type: Sql.Operation.Type.EQUAL});
|
2015-03-19 19:36:11 +00:00
|
|
|
equalOp.exprs.add (new Sql.Field ({name: column.orgname}));
|
|
|
|
where.exprs.add (equalOp);
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
var pkValue = null;
|
|
|
|
|
|
|
|
if (useOldValues && op.oldValues
|
|
|
|
&& op.oldValues[col] !== undefined)
|
|
|
|
pkValue = op.oldValues[col];
|
2015-01-23 13:09:30 +00:00
|
|
|
else
|
2015-03-19 19:36:11 +00:00
|
|
|
pkValue = op.row[col];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
if (pkValue)
|
|
|
|
equalOp.exprs.add (new Sql.Value ({value: pkValue}));
|
|
|
|
else if (column.flags & Db.Conn.Flag.AI && !useOldValues)
|
|
|
|
equalOp.exprs.add (new Sql.Func ({name: 'LAST_INSERT_ID'}));
|
|
|
|
else
|
|
|
|
return null;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
return where;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
,_createOperation: function (rowIndex)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-03-19 19:36:11 +00:00
|
|
|
var op = this.operationsMap[rowIndex];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
if (!op)
|
|
|
|
{
|
|
|
|
op = {
|
|
|
|
type: 0,
|
|
|
|
row: this.data[rowIndex]
|
|
|
|
};
|
|
|
|
this.operations.push (op);
|
|
|
|
this.operationsMap[rowIndex] = op;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-02-08 15:38:38 +00:00
|
|
|
|
2015-03-19 19:36:11 +00:00
|
|
|
return op;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete when MySQL FLAG and view orgname "bugs" are repaired:
|
|
|
|
|
|
|
|
,tableInfo: {}
|
|
|
|
,fieldFlags: {}
|
|
|
|
|
|
|
|
,setTableInfo: function (table, orgtable, db)
|
|
|
|
{
|
|
|
|
this.tableInfo[table] =
|
|
|
|
({
|
|
|
|
orgtable: orgtable
|
|
|
|
,db: db
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
,setFieldFlags: function (field, flags)
|
|
|
|
{
|
|
|
|
this.fieldFlags[field] = flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
,repairColumns: function (columns)
|
|
|
|
{
|
|
|
|
for (var i = 0; i < columns.length; i++)
|
|
|
|
{
|
|
|
|
var newFlags = this.fieldFlags[columns[i].name];
|
|
|
|
|
|
|
|
if (newFlags)
|
|
|
|
columns[i].flags |= newFlags;
|
|
|
|
|
|
|
|
var tableInfo = this.tableInfo[columns[i].table];
|
|
|
|
|
|
|
|
if (tableInfo)
|
|
|
|
{
|
|
|
|
columns[i].orgtable = tableInfo.orgtable;
|
|
|
|
columns[i].db = tableInfo.db;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|