///////////////////////////////////////////////////////////////////////////
//
// XBSDB - Cross-Browser JavaScript Database library
// Copyright (C) 2010 Alexey A.Znayev
//
// This file is part of XBSDB.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Alexey A.Znayev, znaeff@mail.ru
//
///////////////////////////////////////////////////////////////////////////
// This file contains public class XBSDB
///////////////////////////////////////////////////////////////////////////
// database
///////////////////////////////////////////////////////////////////////////
// constructor
// parameters:
// [sLocale] - string of current locale or null (means 'en')
// returns:
// object of XBSDB
function XBSDB(sLocale){
// public fields
this.sResultCode = 'OK';
// private fields
if(sLocale && typeof sLocale == 'string'){
if(XBSDB.prototype.Text && typeof XBSDB.prototype.Text == 'object' && typeof XBSDB.prototype.Text[sLocale] == 'object'){
this._sLocale = sLocale;
}else{
this.sResultCode = 'DB_LOCALE_NOT_DEFINED';
this._sLocale = 'en';
}
}else{
this.sResultCode = 'DB_LOCALE_NOT_STRING';
this._sLocale = 'en';
}
this._oTables = {}; // hash for tables
}
///////////////////////////////////////////////////////////////////////////
// class fields
///////////////////////////////////////////////////////////////////////////
// Text - hash of locale-based texts used
// ex: Text['en']['OK'] = 'No errors';
// locale-based texts must be in separate files
if(!XBSDB.prototype.Text || typeof XBSDB.prototype.Text != 'object'){ XBSDB.prototype.Text = {}; }
///////////////////////////////////////////////////////////////////////////
// public methods
///////////////////////////////////////////////////////////////////////////
// database related
///////////////////////////////////////////////////////////////////////////
// LoadDB - loads entire database from database import dump
// parameters:
// object or string vDatabase - database import dump object or its JSON-string
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.LoadDB = function(vDatabase){
this.sResultCode = 'OK';
var oDatabase;
if(typeof vDatabase == 'string'){
try{
eval('oDatabase = ' + vDatabase);
}catch(e){
this.sResultCode = 'DB_LOADDB_BAD_STRING';
return false;
}
if(typeof oDatabase != 'object'){
this.sResultCode = 'DB_LOADDB_EVAL_NOT_OBJECT';
return false;
}
}else if(typeof vDatabase == 'object'){
oDatabase = vDatabase;
}else{
this.sResultCode = 'DB_LOADDB_NOT_STRING_NOT_OBJECT';
return false;
}
if(!oDatabase){
this.sResultCode = 'DB_LOADDB_OBJECT_NULL';
return false;
}
this._oTables = {};
for(var sTableName in oDatabase){
if(!this.LoadTable(sTableName, oDatabase[sTableName])){
return false;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////
// DumpDB - dumps entire database (all tables) to database export dump
// parameters:
// [string sType] - type of dump, 'object' or 'string' or null (means 'object')
// returns:
// database export dump when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.DumpDB = function(sType){
this.sResultCode = 'OK';
var oDump = {}, vTableDump;
for(var sTableName in this._oTables){
vTableDump = this._oTables[sTableName].Dump();
if(typeof vTableDump == 'boolean'){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
oDump[sTableName] = vTableDump;
}
if(sType && sType == 'string'){
var vJSON = this._JSONize(oDump);
if(typeof vJSON == 'string'){
return vJSON;
}else{
this.sResultCode = 'DB_CANNOT_JSONIZE_DB';
return false;
}
}else{
return oDump;
}
}
///////////////////////////////////////////////////////////////////////////
// table related
///////////////////////////////////////////////////////////////////////////
// LoadTable - loads table structure, data and maybe indexes from table import dump
// parameters:
// string sTableName - table name to load structure and data
// object or string vTable - table import dump object or its JSON-string
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.LoadTable = function(sTableName, vTable){
this.sResultCode = 'OK';
var oTable;
if(typeof vTable == 'string'){
try{
eval('oTable = ' + vTable);
}catch(e){
this.sResultCode = 'DB_LOADTABLE_BAD_STRING';
return false;
}
if(typeof oTable != 'object'){
this.sResultCode = 'DB_LOADTABLE_EVAL_NOT_OBJECT';
return false;
}
}else if(typeof vTable == 'object'){
oTable = vTable;
}else{
this.sResultCode = 'DB_LOADTABLE_NOT_STRING_NOT_OBJECT';
return false;
}
if(!oTable){
this.sResultCode = 'DB_LOADTABLE_OBJECT_NULL';
return false;
}
if(typeof sTableName != 'string'){
this.sResultCode = 'DB_TABLE_NAME_NOT_STRING';
return false;
}
if(Object.prototype.toString.call(oTable.aStructure) !== '[object Array]'){
this.sResultCode = 'DB_STRUCTURE_NOT_ARRAY';
return false;
}
if(this.IsTable(sTableName)){
if(!this.DropTable(sTableName)){
return false;
}
}
if(!this.CreateTable(sTableName,oTable.aStructure)){
return false;
}
if(!this.LoadTableData(sTableName,oTable)){
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
// LoadTableData - loads table data and maybe indexes from table data import dump
// parameters:
// string sTableName - table name to load data
// object or string vTable - table import dump object or its JSON-string
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.LoadTableData = function(sTableName, vTable){
this.sResultCode = 'OK';
var oTable;
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(typeof vTable == 'string'){
try{
eval('oTable = ' + vTable);
}catch(e){
this.sResultCode = 'DB_LOADTABLEDATA_BAD_STRING';
return false;
}
if(typeof oTable != 'object'){
this.sResultCode = 'DB_LOADTABLEDATA_EVAL_NOT_OBJECT';
return false;
}
}else if(typeof vTable == 'object'){
oTable = vTable;
}else{
this.sResultCode = 'DB_LOADTABLEDATA_NOT_STRING_OBJECT';
return false;
}
if(!oTable){
this.sResultCode = 'DB_LOADTABLEDATA_OBJECT_NULL';
return false;
}
if(oTable.aData){
if(Object.prototype.toString.call(oTable.aData) === '[object Array]'){
if(!this._oTables[sTableName].Load(oTable.aData)){
return false;
}
if(oTable.aKeys){
if(Object.prototype.toString.call(oTable.aKeys) === '[object Array]'){
for(var i=0; i<oTable.aKeys.length; i++){
if(typeof oTable.aKeys[i] != 'object'){
this.sResultCode = 'DB_LOADTABLEDATA_KEY_NOT_OBJECT';
return false;
}
if(typeof oTable.aKeys[i].sExpression != 'string'){
this.sResultCode = 'DB_LOADTABLEDATA_KEY_EXPR_NOT_STRING';
return false;
}
if(oTable.aKeys[i].aData && Object.prototype.toString.call(oTable.aKeys[i].aData) !== '[object Array]'){
this.sResultCode = 'DB_LOADTABLEDATA_KEY_DATA_NOT_ARRAY';
return false;
}
if(!this._oTables[sTableName].AddKey(oTable.aKeys[i].sExpression,oTable.aKeys[i].aData)){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
}else{
this.sResultCode = 'DB_LOADTABLEDATA_KEYS_NOT_ARRAY';
return false;
}
}
}else{
this.sResultCode = 'DB_LOADTABLEDATA_DATA_NOT_ARRAY';
return false;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////
// DumpTable - dumps table without indexes to table export dump
// parameters:
// string sTableName - table name to create
// [string sType] - type of dump, 'object' or 'string' or null (means 'object')
// returns:
// table export dump when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.DumpTable = function(sTableName, sType){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
var vTableDump = this._oTables[sTableName].Dump();
if(typeof vTableDump == 'boolean'){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
if(sType && sType == 'string'){
var vJSON = this._JSONize(vTableDump);
if(typeof vJSON == 'string'){
return vJSON;
}else{
this.sResultCode = 'DB_CANNOT_JSONIZE_TABLE';
return false;
}
}else{
return vTableDump;
}
}
///////////////////////////////////////////////////////////////////////////
// CreateTable - creates a new table in database
// parameters:
// string sTableName - table name to create
// array aTableStructure - table structure
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.CreateTable = function(sTableName, aTableStructure){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKNotExist(sTableName)){
return false;
}
if(Object.prototype.toString.call(aTableStructure) !== '[object Array]'){
this.sResultCode = 'DB_STRUCTURE_NOT_ARRAY';
return false;
}
if(aTableStructure.length > 0){
var oFieldNames = {}, i;
for(i = 0; i < aTableStructure.length; i++){
if(Object.prototype.toString.call(aTableStructure[i]) === '[object Array]'){
if(aTableStructure[i].length < 2){
this.sResultCode = 'DB_STRUCTURE_BAD';
return false;
}
if(typeof aTableStructure[i][0] != 'string'){
this.sResultCode = 'DB_FIELD_NAME_NOT_STRING';
return false;
}
if(aTableStructure[i][0].length == 0){
this.sResultCode = 'DB_FIELD_NAME_EMPTY';
return false;
}
if(oFieldNames[aTableStructure[i][0]]){
this.sResultCode = 'DB_STRUCTURE_FIELD_DUPLICATE';
return false;
}else{
oFieldNames[aTableStructure[i][0]] = true;
}
}else{
this.sResultCode = 'DB_STRUCTURE_BAD';
return false;
}
}
}else{
this.sResultCode = 'DB_STRUCTURE_EMPTY';
return false;
}
var oTable = new XBSTable(aTableStructure);
if(oTable.sResultCode == 'OK'){
this._oTables[sTableName] = oTable;
return true;
}else{
this.sResultCode = oTable.sResultCode;
delete oTable;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// IsTable - checks is table exists or not
// parameters:
// string sTableName - table name to check
// returns:
// true when table exists
// false when table doesn't exist
// false when failed (sResultCode != 'OK')
XBSDB.prototype.IsTable = function(sTableName){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOK(sTableName)){
return false;
}
if(this._oTables[sTableName]){
return true;
}else{
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// ShowTables - lists all tables in database
// parameters:
// none
// returns:
// array with table names when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.ShowTables = function(){
this.sResultCode = 'OK';
var aResult = [];
for(var s in this._oTables){
aResult.push(s);
}
return aResult;
}
///////////////////////////////////////////////////////////////////////////
// DropTable - removes table from a database
// parameters:
// string sTableName - table name to remove
// returns:
// true when table removed
// false when failed (sResultCode != 'OK')
XBSDB.prototype.DropTable = function(sTableName){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
delete this._oTables[sTableName];
return true;
}
///////////////////////////////////////////////////////////////////////////
// field related
///////////////////////////////////////////////////////////////////////////
// ShowFields - lists fields names & types in table
// parameters:
// string sTableName - table name
// returns:
// array of 2-element arrays [name, type]
// false when failed (sResultCode != 'OK')
XBSDB.prototype.ShowFields = function(sTableName){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
var vResult = this._oTables[sTableName].GetStructure();
if(vResult){
return vResult;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// key related
///////////////////////////////////////////////////////////////////////////
// CreateIndex - creates a new key in table
// parameters:
// string sTableName - table name
// string sKeyExpr - key expression
// returns:
// key id (normalized key expression) when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.CreateIndex = function(sTableName, sKeyExpr){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(typeof sKeyExpr != 'string'){
this.sResultCode = 'DB_KEY_EXPR_NOT_STRING';
return false;
}
if(sKeyExpr.length == 0){
this.sResultCode = 'DB_KEY_EXPR_EMPTY';
return false;
}
var vResult = this._oTables[sTableName].AddKey(sKeyExpr);
if(vResult){
return vResult;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// IsIndex - checks is key exists or not
// parameters:
// string sTableName - table name
// string sKeyID - key id
// returns:
// true when key exists
// false when key doesn't exist
// false when failed (sResultCode != 'OK')
XBSDB.prototype.IsIndex = function(sTableName, sKeyID){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(!this._IsParamKeyIDOK(sKeyID)){
return false;
}
var vResult = this._oTables[sTableName].IsKey(sKeyID);
if(vResult){
return vResult;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// ShowIndexes - lists all keys of one type in table
// parameters:
// string sTableName - table name
// returns:
// array with key names when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.ShowIndexes = function(sTableName){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
var vResult = this._oTables[sTableName].GetKeyIDs();
if(vResult){
return vResult;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// DropIndex - removes key from table
// parameters:
// string sTableName - table name
// string sKeyID - key id
// returns:
// true when key removed
// false when failed (sResultCode != 'OK')
XBSDB.prototype.DropIndex = function(sTableName, sKeyID){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(!this._IsParamKeyIDOK(sKeyID)){
return false;
}
if(this._oTables[sTableName].DropKey(sKeyID)){
return true;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// data related
///////////////////////////////////////////////////////////////////////////
// InsertOne - inserts one record into table
// parameters:
// string sTableName - table name
// array aFieldValues - array of fields values
// [array aFieldNames] - array of fields names or null
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.InsertOne = function(sTableName, aFieldValues, aFieldNames){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(Object.prototype.toString.call(aFieldNames) === '[object Array]'){
if(aFieldNames.length == 0){
aFieldNames = null;
}
}
if(aFieldNames){
if(!this._IsParamFieldNamesOK(sTableName,aFieldNames)){
return false;
}
if(!this._IsParamFieldValuesOKByNames(sTableName,aFieldNames,aFieldValues)){
return false;
}
if(this._oTables[sTableName].InsertOneByFields(aFieldNames,aFieldValues)){
return true;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}else{
if(!this._IsParamFieldValuesOKByNumbers(sTableName,aFieldValues)){
return false;
}
if(this._oTables[sTableName].InsertOneByOrder(aFieldValues)){
return true;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
}
///////////////////////////////////////////////////////////////////////////
// InsertMany - inserts many records into table at once
// parameters:
// string sTableName - table name
// array aRows - array of arrays of fields values
// [array aFieldNames] - array of fields names or null
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.InsertMany = function(sTableName, aRows, aFieldNames){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(Object.prototype.toString.call(aFieldNames) === '[object Array]'){
if(aFieldNames.length == 0){
aFieldNames = null;
}
}
if(Object.prototype.toString.call(aRows) !== '[object Array]'){
this.sResultCode = 'DB_AROWS_NOT_ARRAY';
return false;
}
var vInserted, i;
if(aFieldNames){
if(!this._IsParamFieldNamesOK(sTableName,aFieldNames)){
return false;
}
for(i = 0; i < aRows.length; i++){
if(!this._IsParamFieldValuesOKByNames(sTableName,aFieldNames,aRows[i])){
return false;
}
}
vInserted = this._oTables[sTableName].InsertManyByFields(aFieldNames,aRows);
if(typeof vInserted == 'number'){
return vInserted;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}else{
for(i= 0; i < aRows.length; i++){
if(!this._IsParamFieldValuesOKByNumbers(sTableName,aRows[i])){
return false;
}
}
vInserted = this._oTables[sTableName].InsertManyByOrder(aRows);
if(typeof vInserted == 'number'){
return vInserted;
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
}
///////////////////////////////////////////////////////////////////////////
// Update - updates data in table
// parameters:
// string sTableName - table name
// array aFieldValues - array of fields values
// [array aFieldNames] - array of fields names or null
// [string sWhereExpr] - WHERE-expression or null
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.Update = function(sTableName, aFieldValues, aFieldNames, sWhereExpr){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(Object.prototype.toString.call(aFieldNames) === '[object Array]'){
if(aFieldNames.length == 0){
aFieldNames = null;
}
}
if(sWhereExpr){
sWhereExpr = sWhereExpr.replace(/^\s+/,'').replace(/\s+$/,'');
if(sWhereExpr != ''){
if(!this._IsParamWhereExprOK(sWhereExpr)){
return false;
}
}
}else{
sWhereExpr = '';
}
var vUpdated, vWhereResult;
if(aFieldNames){
if(!this._IsParamFieldNamesOK(sTableName,aFieldNames)){
return false;
}
if(!this._IsParamFieldValuesOKByNames(sTableName,aFieldNames,aFieldValues)){
return false;
}
if(sWhereExpr.length > 0){
vWhereResult = this._GetRecordsWhere(sTableName,sWhereExpr);
}else{
vWhereResult = this._GetRecordsAll(sTableName);
}
if(Object.prototype.toString.call(vWhereResult) !== '[object Array]'){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
vUpdated = this._oTables[sTableName].UpdateByFields(aFieldNames,aFieldValues,vWhereResult);
if(typeof vUpdated == 'number'){
if(vUpdated == vWhereResult.length){
return vUpdated;
}else{
this.sResultCode = 'DB_RECORDS_2UPD_NE_UPDATED : updated ' + vUpdated + ' instead of ' + vWhereResult.length;
return false;
}
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}else{
if(!this._IsParamFieldValuesOKByNumbers(sTableName,aFieldValues)){
return false;
}
if(sWhereExpr.length > 0){
vWhereResult = this._GetRecordsWhere(sTableName,sWhereExpr);
}else{
vWhereResult = this._GetRecordsAll(sTableName);
}
if(Object.prototype.toString.call(vWhereResult) !== '[object Array]'){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
vUpdated = this._oTables[sTableName].UpdateByOrder(aFieldValues,vWhereResult);
if(typeof vUpdated == 'number'){
if(vUpdated == vWhereResult.length){
return vUpdated;
}else{
this.sResultCode = 'DB_RECORDS_2UPD_NE_UPDATED : updated ' + vUpdated + ' instead of ' + vWhereResult.length;
return false;
}
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
}
///////////////////////////////////////////////////////////////////////////
// Delete - removes data from table
// parameters:
// string sTableName - table name
// [string sWhereExpr] - WHERE-expression or null
// returns:
// number of deleted records when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.Delete = function(sTableName, sWhereExpr){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(sWhereExpr){
sWhereExpr = sWhereExpr.replace(/^\s+/,'').replace(/\s+$/,'');
if(sWhereExpr != ''){
if(!this._IsParamWhereExprOK(sWhereExpr)){
return false;
}
}
}else{
sWhereExpr = '';
}
var vWhereResult, nRecDel;
if(sWhereExpr.length > 0){
vWhereResult = this._GetRecordsWhere(sTableName,sWhereExpr);
}else{
vWhereResult = this._GetRecordsAll(sTableName);
}
if(Object.prototype.toString.call(vWhereResult) !== '[object Array]'){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
if(vWhereResult.length > 0){
nRecDel = this._oTables[sTableName].Delete(vWhereResult);
if(nRecDel == vWhereResult.length){
return nRecDel;
}else{
this.sResultCode = 'DB_RECORDS_2DEL_NE_DELETED' + ' : ' + this._oTables[sTableName].sResultCode;
return false;
}
}else{
return 0;
}
}
///////////////////////////////////////////////////////////////////////////
// Select - selects data from table
// parameters:
// string sTableName - table name
// [array aFieldNames] - array of result fields names or null
// [string sWhereExpr] - WHERE expression or null
// [string sOrderByExpr] - ORDER BY expression to sort output or null
// [boolean bDescFlag] - DESC flag of reverse sorting or null, valid when sOrderByExpr not null only
// [string sGroupByExpr] - GROUP BY expression to group output or null
// returns:
// array of record values arrays when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.Select = function(sTableName, aFieldNames, sWhereExpr, sOrderByExpr, bDescFlag, sGroupByExpr){
var vResult = this.SelectToRecordSet(sTableName,sWhereExpr,sOrderByExpr,bDescFlag,sGroupByExpr);
if(vResult){
return this.SelectFromRecordSet(sTableName,vResult,aFieldNames);
}
return false;
}
///////////////////////////////////////////////////////////////////////////
// SelectToRecordSet - gets array of record identifiers from table
// parameters:
// string sTableName - table name
// [string sWhereExpr] - WHERE-expression or null
// [string sOrderByExpr] - ORDER BY expression to sort output or null
// [boolean bDescFlag] - DESC flag of reverse sorting or null, valid when sOrderByExpr not null only
// [string sGroupByExpr] - GROUP BY expression to group output or null
// returns:
// array of record identifiers when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.SelectToRecordSet = function(sTableName, sWhereExpr, sOrderByExpr, bDescFlag, sGroupByExpr){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(sWhereExpr){
sWhereExpr = sWhereExpr.replace(/^\s+/,'').replace(/\s+$/,'');
if(sWhereExpr != ''){
if(!this._IsParamWhereExprOK(sWhereExpr)){
return false;
}
}
}else{
sWhereExpr = '';
}
if(sOrderByExpr){
if(!this._IsParamOrderByExprOK(sOrderByExpr)){
return false;
}
}else{
sOrderByExpr = '';
}
if(bDescFlag){
if(!this._IsParamDescFlagOK(bDescFlag)){
return false;
}
}else{
bDescFlag = false;
}
if(sGroupByExpr){
if(!this._IsParamGroupByExprOK(sGroupByExpr)){
return false;
}
}else{
sGroupByExpr = '';
}
var vResult;
if(sWhereExpr.length > 0){
vResult = this._GetRecordsWhere(sTableName,sWhereExpr);
}else{
vResult = this._GetRecordsAll(sTableName);
}
if(!vResult){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
if(sOrderByExpr.length > 0){
var bResult = this._oTables[sTableName].SortRecordsOrderBy(vResult,sOrderByExpr,bDescFlag);
if(!bResult){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
if(sGroupByExpr.length > 0){
var vResult = this._oTables[sTableName].GetRecordsGroupBy(vResult,sGroupByExpr);
if(!vResult){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
return vResult;
}
///////////////////////////////////////////////////////////////////////////
// SelectFromRecordSet - selects data from array of record identifiers
// parameters:
// string sTableName - table name
// array aRecords - array of record identifiers
// [array aFieldNames] - array of result fields names or null
// [number nOffset] - offset of result records or null
// [number nLimit] - number of result records or null
// returns:
// array of record values arrays when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.SelectFromRecordSet = function(sTableName, aRecords, aFieldNames, nOffset, nLimit){
this.sResultCode = 'OK';
if(!this._IsParamTableNameOKExist(sTableName)){
return false;
}
if(Object.prototype.toString.call(aRecords) === '[object Array]'){
if(aRecords.length == 0){
return [];
}
}else{
this.sResultCode = 'DB_RECORDS_NOT_ARRAY';
return false;
}
if(Object.prototype.toString.call(aFieldNames) === '[object Array]'){
if(aFieldNames.length == 0){
aFieldNames = null;
}
}
if(aFieldNames){
if(!this._IsParamFieldNamesOK(sTableName,aFieldNames)){
return false;
}
}
if(nOffset){
if(typeof nOffset == 'number'){
if(nOffset < 0){
this.sResultCode = 'DB_OFFSET_NEGATIVE';
return false;
}
}else{
this.sResultCode = 'DB_OFFSET_NOT_NUMBER';
return false;
}
}else{
nOffset = 0;
}
if(nLimit){
if(typeof nLimit == 'number'){
if(nLimit < 0){
this.sResultCode = 'DB_LIMIT_NEGATIVE';
return false;
}
}else{
this.sResultCode = 'DB_LIMIT_NOT_NUMBER';
return false;
}
}else{
nLimit = aRecords.length;
}
if(aFieldNames){
vResult = this._oTables[sTableName].GetRows(aFieldNames,aRecords,nOffset,nLimit);
}else{
vResult = this._oTables[sTableName].GetRowsAll(aRecords,nOffset,nLimit);
}
if(!vResult){
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
return vResult;
}
///////////////////////////////////////////////////////////////////////////
// Rows2String - gets string from array of record value arrays, uses toString
// parameters:
// array aRows - array of record values arrays
// string sRowBefore - string to put before each row
// string sRowAfter - string to put after each row
// string sValueBefore - string to put before each value
// string sValueAfter - string to put after each value
// string sEmptyString - string to replace empty string values
// returns:
// string
// false when failed (sResultCode != 'OK')
XBSDB.prototype.Rows2String = function(aRows, sRowBefore, sRowAfter, sValueBefore, sValueAfter, sValueEmpty){
this.sResultCode = 'OK';
if(Object.prototype.toString.call(aRows) !== '[object Array]'){
this.sResultCode = 'DB_AROWS_NOT_ARRAY';
return false;
}
if(sRowBefore){
if(typeof sRowBefore != 'string'){
this.sResultCode = 'DB_ROW_BEFORE_NOT_STRING';
return false;
}
}else{
sRowBefore = '';
}
if(sRowAfter){
if(typeof sRowAfter != 'string'){
this.sResultCode = 'DB_ROW_AFTER_NOT_STRING';
return false;
}
}else{
sRowAfter = '';
}
if(sValueBefore){
if(typeof sValueBefore != 'string'){
this.sResultCode = 'DB_VALUE_BEFORE_NOT_STRING';
return false;
}
}else{
sValueBefore = '';
}
if(sValueAfter){
if(typeof sValueAfter != 'string'){
this.sResultCode = 'DB_VALUE_AFTER_NOT_STRING';
return false;
}
}else{
sValueAfter = '';
}
if(sValueEmpty){
if(typeof sValueEmpty != 'string'){
this.sResultCode = 'DB_VALUE_EMPTY_NOT_STRING';
return false;
}
}else{
sValueEmpty = '';
}
var sResult = '', i, j, sOut;
for(i = 0; i < aRows.length; i++){
if(Object.prototype.toString.call(aRows[i]) === '[object Array]'){
sResult += sRowBefore;
for(j = 0; j < aRows[i].length; j++){
if(aRows[i][j] != null){
sOut = aRows[i][j].toString();
}else{
sOut = sValueEmpty;
}
sResult += sValueBefore + sOut + sValueAfter;
}
sResult += sRowAfter;
}
}
return sResult;
}
///////////////////////////////////////////////////////////////////////////
// Rows2LocaleString - gets string from array of record value arrays, uses toLocaleString
// parameters:
// array aRows - array of record values arrays
// string sRowBefore - string to put before each row
// string sRowAfter - string to put after each row
// string sValueBefore - string to put before each value
// string sValueAfter - string to put after each value
// string sEmptyString - string to replace empty string values
// returns:
// string
// false when failed (sResultCode != 'OK')
XBSDB.prototype.Rows2LocaleString = function(aRows, sRowBefore, sRowAfter, sValueBefore, sValueAfter, sValueEmpty){
this.sResultCode = 'OK';
if(Object.prototype.toString.call(aRows) !== '[object Array]'){
this.sResultCode = 'DB_AROWS_NOT_ARRAY';
return false;
}
if(sRowBefore){
if(typeof sRowBefore != 'string'){
this.sResultCode = 'DB_ROW_BEFORE_NOT_STRING';
return false;
}
}else{
sRowBefore = '';
}
if(sRowAfter){
if(typeof sRowAfter != 'string'){
this.sResultCode = 'DB_ROW_AFTER_NOT_STRING';
return false;
}
}else{
sRowAfter = '';
}
if(sValueBefore){
if(typeof sValueBefore != 'string'){
this.sResultCode = 'DB_VALUE_BEFORE_NOT_STRING';
return false;
}
}else{
sValueBefore = '';
}
if(sValueAfter){
if(typeof sValueAfter != 'string'){
this.sResultCode = 'DB_VALUE_AFTER_NOT_STRING';
return false;
}
}else{
sValueAfter = '';
}
if(sValueEmpty){
if(typeof sValueEmpty != 'string'){
this.sResultCode = 'DB_VALUE_EMPTY_NOT_STRING';
return false;
}
}else{
sValueEmpty = '';
}
var sResult = '', i, j, sOut;
for(i = 0; i < aRows.length; i++){
if(Object.prototype.toString.call(aRows[i]) === '[object Array]'){
sResult += sRowBefore;
for(j = 0; j < aRows[i].length; j++){
if(aRows[i][j] != null){
sOut = aRows[i][j].toLocaleString();
}else{
sOut = sValueEmpty;
}
sResult += sValueBefore + sOut + sValueAfter;
}
sResult += sRowAfter;
}
}
return sResult;
}
///////////////////////////////////////////////////////////////////////////
// locale related
///////////////////////////////////////////////////////////////////////////
// ResultText - returns last result status explaination in current locale
// returns:
// string
XBSDB.prototype.ResultText = function(){
var sResultText = this.sResultCode;
if(sResultText != 'OK'){
sResultText = 'ERROR: ' + sResultText;
}
if(this.Text[this._sLocale] && typeof this.Text[this._sLocale] == 'object'){
for(var s in this.Text[this._sLocale]){
sResultText = sResultText.replace(s,this.Text[this._sLocale][s]);
}
}
return sResultText;
}
///////////////////////////////////////////////////////////////////////////
// SetLocale - sets database locale
// parameters:
// string sLocale - string of locale
// returns:
// true when success
// false when failed (sResultCode != 'OK')
XBSDB.prototype.SetLocale = function(sLocale){
this.sResultCode = 'OK';
if(sLocale && typeof sLocale == 'string'){
if(XBSDB.prototype.Text && typeof XBSDB.prototype.Text == 'object' && typeof XBSDB.prototype.Text[sLocale] == 'object'){
this._sLocale = sLocale;
return true;
}else{
this.sResultCode = 'DB_LOCALE_NOT_DEFINED';
return false;
}
}else{
this.sResultCode = 'DB_LOCALE_NOT_STRING';
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// GetLocale - gets database locale
// parameters:
// none
// returns:
// string - current locale
XBSDB.prototype.GetLocale = function(){
this.sResultCode = 'OK';
return this._sLocale;
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// private methods
///////////////////////////////////////////////////////////////////////////
// parameter checking methods
XBSDB.prototype._IsParamTableNameOK = function(sTableName){
if(typeof sTableName != 'string'){
this.sResultCode = 'DB_TABLE_NAME_NOT_STRING';
return false;
}
if(sTableName.length == 0){
this.sResultCode = 'DB_TABLE_NAME_EMPTY';
return false;
}
return true;
}
XBSDB.prototype._IsParamTableNameOKExist = function(sTableName){
if(!this._IsParamTableNameOK(sTableName)){
return false;
}
if(!this._oTables[sTableName]){
this.sResultCode = 'DB_TABLE_NOT_EXIST';
return false;
}
return true;
}
XBSDB.prototype._IsParamTableNameOKNotExist = function(sTableName){
if(!this._IsParamTableNameOK(sTableName)){
return false;
}
if(this._oTables[sTableName]){
this.sResultCode = 'DB_TABLE_EXIST';
return false;
}
return true;
}
XBSDB.prototype._IsParamFieldNamesOK = function(sTableName,aFieldNames){
if(Object.prototype.toString.call(aFieldNames) !== '[object Array]'){
this.sResultCode = 'DB_FIELD_NAMES_NOT_ARRAY';
return false;
}
if(aFieldNames.length > 0){
var oFieldNames = {}, i;
for(i = 0; i < aFieldNames.length; i++){
if(typeof aFieldNames[i] != 'string'){
this.sResultCode = 'DB_FIELD_NAME_TYPE_NOT_STRING';
return false;
}
if(!this._oTables[sTableName].IsCol(aFieldNames[i])){
this.sResultCode = 'DB_FIELD_NAME_NOT_EXIST';
return false;
}
if(oFieldNames[aFieldNames[i]]){
this.sResultCode = 'DB_FIELD_DUPLICATE';
return false;
}else{
oFieldNames[aFieldNames[i]] = true;
}
}
}else{
this.sResultCode = 'DB_FIELD_NAMES_EMPTY';
return false;
}
return true;
}
XBSDB.prototype._IsParamFieldValuesOKByNames = function(sTableName,aFieldNames,aFieldValues){
if(Object.prototype.toString.call(aFieldValues) !== '[object Array]'){
this.sResultCode = 'DB_FIELD_VALUES_NOT_ARRAY';
return false;
}
if(aFieldValues.length > 0){
for(var i = 0; i < aFieldValues.length; i++){
if(typeof aFieldValues[i] != this._oTables[sTableName].GetColTypeByName(aFieldNames[i])){
this.sResultCode = 'DB_FIELD_VALUE_TYPE_MISMATCH';
return false;
}
}
}else{
this.sResultCode = 'DB_FIELD_VALUES_EMPTY';
return false;
}
return true;
}
XBSDB.prototype._IsParamFieldValuesOKByNumbers = function(sTableName,aFieldValues){
if(Object.prototype.toString.call(aFieldValues) !== '[object Array]'){
this.sResultCode = 'DB_FIELD_VALUES_NOT_ARRAY';
return false;
}
if(aFieldValues.length > 0){
for(var i = 0; i < aFieldValues.length; i++){
if(typeof aFieldValues[i] != this._oTables[sTableName].GetColTypeByNumber(i)){
this.sResultCode = 'DB_FIELD_VALUE_TYPE_MISMATCH';
return false;
}
}
}else{
this.sResultCode = 'DB_FIELD_VALUES_EMPTY';
return false;
}
return true;
}
XBSDB.prototype._IsParamKeyIDOK = function(sKeyID){
if(typeof sKeyID != 'string'){
this.sResultCode = 'DB_KEY_ID_NOT_STRING';
return false;
}
if(sKeyID.length == 0){
this.sResultCode = 'DB_KEY_ID_EMPTY';
return false;
}
return true;
}
XBSDB.prototype._IsParamWhereExprOK = function(sWhereExpr){
if(typeof sWhereExpr != 'string'){
this.sResultCode = 'DB_WHERE_EXPR_NOT_STRING';
return false;
}
return true;
}
XBSDB.prototype._IsParamOrderByExprOK = function(sOrderByExpr){
if(typeof sOrderByExpr != 'string'){
this.sResultCode = 'DB_ORDER_BY_EXPR_NOT_STRING';
return false;
}
return true;
}
XBSDB.prototype._IsParamDescFlagOK = function(bDescFlag){
if(typeof bDescFlag != 'boolean'){
this.sResultCode = 'DB_DESC_FLAG_NOT_BOOL';
return false;
}
return true;
}
XBSDB.prototype._IsParamGroupByExprOK = function(sGroupByExpr){
if(typeof sGroupByExpr != 'string'){
this.sResultCode = 'DB_GROUP_BY_EXPR_NOT_STRING';
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
// data operation methods
XBSDB.prototype._GetRecordsWhere = function(sTableName, sWhereExpr){
var vResult = this._oTables[sTableName].GetRecordsWhere(sWhereExpr);
if(vResult){
if(Object.prototype.toString.call(vResult) === '[object Array]'){
return vResult;
}else{
this.sResultCode = 'DB_RECORDS_NOT_ARRAY';
return false;
}
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
XBSDB.prototype._GetRecordsAll = function(sTableName){
var vResult = this._oTables[sTableName].GetRecordsAllPacked();
if(vResult){
if(Object.prototype.toString.call(vResult) === '[object Array]'){
return vResult;
}else{
this.sResultCode = 'DB_RECORDS_NOT_ARRAY';
return false;
}
}else{
this.sResultCode = this._oTables[sTableName].sResultCode;
return false;
}
}
///////////////////////////////////////////////////////////////////////////
// JSON operation methods
XBSDB.prototype._JSONize = function(vValue){
switch(typeof vValue){
case 'boolean' :
case 'number' :
return('' + vValue);
case 'string' :
return('"' + vValue.replace(/\\/g,'\\').replace(/"/g,'\"').replace(/\//g,'\/').replace(/[\b]/g,'\b').replace(/\f/g,'\f').replace(/\n/g,'\n').replace(/\r/g,'\r').replace(/\t/g,'\t') + '"');
case 'object' :
var sResult = '', vJSON, i
if(Object.prototype.toString.call(vValue) === '[object Array]'){
sResult = '';
for(i=0; i<vValue.length; i++){
vJSON = this._JSONize(vValue[i]);
if(typeof vJSON == 'string'){
sResult += (sResult.length == 0 ? '' : ',') + vJSON;
}else{
return false;
}
}
sResult = '[' + sResult + ']';
}else{
sResult = '';
for(i in vValue){
vJSON = this._JSONize(vValue[i]);
if(typeof vJSON == 'string'){
sResult += (sResult.length == 0 ? '' : ',') + '"' + i + '":' + vJSON + '';
}else{
return false;
}
}
sResult = '{' + sResult + '}';
}
return sResult;
}
return false;
}
|