(function(){var param_re=/{{{([""'']?\w+)}}}/g;var divid_re=/({{{[\'\"]?)|(}}})/g;DbRelay={adapters:{},DBRELAY_HOST:null,query:function(connection,sql,callback,error,scope,query_tag){var params={};for(var k in connection){if(k!=='dbrelay_host'){params[k]=connection[k];}}
params.sql=sql;params.query_tag=query_tag||null;if(!params.connection_name){params.connection_name='dbrquery_'+new Date().getTime();}
var dbrHost=connection.dbrelay_host||DbRelay.DBRELAY_HOST;if(dbrHost){jQuery.getJSON(dbrHost+'/sql?js_callback=?',params,function(response){if(response&&response.data){callback.call(scope||window,response);}
else{if(error){error.call(scope||window,response);}}});}
else{$.post('/sql',params,function(response){if(response&&response.data){callback.call(scope||window,response);}
else{if(error){error.call(scope||window,response);}}},"json");}},queryStatus:function(callback,scope,dbrhost){var params={status:1};dbrhost=dbrhost||DbRelay.DBRELAY_HOST;if(dbrhost){jQuery.getJSON(dbrhost+'/sql?js_callback=?',params,function(response){callback.call(scope||window,response);});}
else{$.post('/sql',params,function(response){callback.call(scope||window,response);},"json");}},kill:function(sockpath,callback,scope,dbrhost){var params={cmd:'kill',param1:sockpath};var dbrhost=dbrhost||DbRelay.DBRELAY_HOST;if(dbrhost){jQuery.getJSON(dbrhost+'/sql?js_callback=?',params,function(response){callback.call(scope||window,response);});}
else{$.post('/sql',params,function(response){callback.call(scope||window,response);},"json");}},quoteSingles:function(text){text+='';return text.replace(/'/g,"''");},quoteDoubles:function(text){text+='';return text.replace(/"/g,'""');},cook:function(string,params){return string.replace(param_re,function(match,word){var quoteFunc=undefined;if(word.charAt(0)=="'"){word=word.slice(1);quoteFunc=Dbrelay.Util.quoteSingles;};if(word.charAt(0)=='"'){word=word.slice(1);quoteFunc=Dbrelay.Util.quoteDoubles;};if(params[word]){return(quoteFunc?quoteFunc(params[word]):params[word]);}else{return'';};});},get_params:function(query){var matches=query.match(param_re);for(var m in matches){if(typeof(matches[m])!=='string'){continue};matches[m]=matches[m].replace(divid_re,'');};return matches;}};DbRelay.adapters.BaseAdapter=function(name,queries){this.name=name;this.queries=queries;return this;};DbRelay.adapters.BaseAdapter.prototype={get:function(name,params){if(!this.queries[name]){return null;}
return DbRelay.cook(this.queries[name],params||{});}};DbRelay.adapters.SqlServer=new DbRelay.adapters.BaseAdapter('SqlServer',{list_databases:"USE MASTER;SELECT NAME FROM sys.sysdatabases ORDER BY NAME ASC",create_table:"create table {{{table}}} {{{columns}}}",drop_table:"drop table {{{table}}}",commit_transaction:"BEGIN TRANSACTION "
+"BEGIN TRY "
+" {{{statements}}} "
+"    COMMIT TRANSACTION "
+"END TRY "
+"BEGIN CATCH "
+"   ROLLBACK TRANSACTION "
+"END CATCH",get_rowcounts:"SELECT t.name, sum(p.rows) as [rows] "
+"FROM   sys.tables t "
+"JOIN   sys.indexes i "
+"ON     t.object_id = i.object_id "
+"JOIN   sys.partitions p "
+"ON     i.object_id = p.object_id "
+"AND    i.index_id = p.index_id "
+"WHERE  i.index_id in (0,1) "
+"group by t.name "
+"ORDER BY SUM(P.ROWS) DESC",get_columncounts:"SELECT TABLE_NAME,TABLE_SCHEMA, COUNT(COLUMN_NAME) as 'columns' FROM INFORMATION_SCHEMA.COLUMNS GROUP BY TABLE_NAME,TABLE_SCHEMA ",fetch_all_rows:"select * from {{{table}}}",fetch_rows:"select {{{columns}}} from {{{table}}}\n {{{where}}} \n{{{orderBy}}}",get_count:"SELECT COUNT({{{columns}}}) FROM {{{table}}} \n{{{where}}}",row_add:"INSERT INTO {{{table}}} {{{columns}}} VALUES {{{values}}}",delete_row:"DELETE FROM {{{table}}} WHERE \n{{{where}}}",fetch_paged_rows:"select * from ("
+" Select ROW_NUMBER () OVER(Order By \n{{{orderBy}}}) \nas dbrelayRowNum, *"
+"  From (SELECT * FROM {{{table}}} \n{{{where}}}) \ndbrelayInnerp1"
+" ) dbrelayInnerp2"
+" WHERE dbrelayRowNum BETWEEN {{{minRow}}} and {{{maxRow}}}",update_row:"UPDATE {{{table}}} SET {{{setvalues}}} WHERE \n{{{where}}}"});DbRelay.BatchManager=function(){this.queries={};};DbRelay.BatchManager.prototype={push:function(name,query){if(this.queries[name]){this.queries[name]+=";\n"+query;}else{this.queries[name]=query;};},empty:function(name){try{delete(this.queries[name]);}
catch(e){}},get:function(name){return this.queries[name]||null;}};})();dbrelayQuery=function(connection,sql,callback,query_tag){DbRelay.query(connection,sql,callback,null,window,query_tag);};dbrelayStatus=function(callback,dbrhost){DbRelay.queryStatus(callback,window,dbrhost);};dbrelayKillConnection=function(sockpath,callback,dbrhost){DbRelay.kill(sockpath,callback,window,dbrhost);};sqlObject=function(connection,sql_queries){connection.sql_type=connection.sql_type||'sqlserver';return new DbRelay.QueryHelper(connection);};DbRelay.QueryHelper=function(connection){this.log=[];var cn=connection.connection_name;connection.connection_name=(cn&&cn!=='')?cn:'';connection.flags=connection.flags||'';var adapterName=connection.sql_type||"SqlServer";this.adapter=DbRelay.adapters[adapterName];this.batches=new DbRelay.BatchManager();delete connection.sql_type;this.connection=connection;return this;};DbRelay.QueryHelper.prototype={run:function(verb,cfg,success,error,scope){var cookedQuery=this.adapter.get(verb,cfg||{});if(!cookedQuery){alert('"'+verb+'" is not supported for '+this.adapter);return;}
this.executeSql(cookedQuery,[],success,error,this);},getLog:function(){return this.log;},clearLog:function(){this.log=[];},throwError:function(name,message,body,hard){if(console&&console.dir){console.dir({"name":name,"message":message,"body":body});};if(hard){throw{"name":name,"message":message,"body":body};};},run_batch:function(batch_name,success,error,scope){this.executeSql(this.batches.get(batch_name),[],success,error,this);this.batches.empty(batch_name);},getBatch:function(batch){return this.batches.get(batch);},emptyBatch:function(batch){this.batches.empty(batch);},addToBatch:function(verb,params,batch){this.batches.push(batch,this.adapter.get(verb,params||{}));},testConnection:function(callback,scope){this.executeSql('select 1 as one',[],function(){if(callback){callback.call(scope||window,this,true);}},function(dba,resp){if(callback){callback.call(scope||window,this,false);}},this);},setFlag:function(flag,on){var flags=this.connection.flags+',',isInFlags=flags.indexOf(flag+',')!==-1;if(on){if(!isInFlags){this.connection.flags+=','+flag;}}
else{if(isInFlags){this.connection.flags=flags.replace(flag+',','');}}},setDbrelayHost:function(dbrhost){this.connection.dbrelay_host=dbrhost;},commitBatchTransaction:function(batch,callback,scope){this.commitTransaction(this.getBatch(batch),callback,scope);},getDatabases:function(success,error,scope){this.run('list_databases',{},function(qh,resp){if(resp.data.length===2){var dbs=[],rows=resp.data[1].rows;for(var i=0,len=rows.length;i<len;i++){dbs.push(rows[i].NAME);}
if(success){success.call(scope||window,this,dbs);}}
else{if(error){error.call(scope||window,this,resp,"sqlDbAccess.getDatabases > Data was missing");}}},function(qh,resp,err){if(error){error.call(scope||window,this,resp,err);}},scope);},commitTransaction:function(statements,callback,scope){this.run('commit_transaction',{statements:statements},function(qh,resp){if(callback){callback.call(scope||window,this,resp);}},null,this);},getAllRowCounts:function(callback,errorfn,scope){this.run('get_rowcounts',{},function(qh,resp){var rows=resp.data[0].rows,countObj={};for(var i=0;i<rows.length;i++){var row=rows[i];countObj[row.name]=row.rows;}
if(callback){callback.call(scope||window,this,resp,countObj);}},errorfn,this);},getAllCellCounts:function(callback,errorfn,scope){this.getAllRowCounts(function(sqld,resp,rowcounts){this.run('get_columncounts',{},function(qh,colresp){var rows=colresp.data[0].rows,cellCounts={};for(var i=0;i<rows.length;i++){var row=rows[i];cellCounts[row.TABLE_SCHEMA+'.'+row.TABLE_NAME]=rowcounts[row.TABLE_NAME]*row.columns;}
if(callback){callback.call(scope||window,this,resp,cellCounts);}},errorfn,this);},function(sqld,resp){if(errorfn){errorfn.call(scope||window,this,resp);}},this);},adminQuery:function(params,success,error,scope){for(var k in this.connection){if(k!=='dbrelay_host'&&k!=='sql'){params[k]=this.connection[k];}}
var dbrhost=this.connection.dbrelay_host;if(dbrhost){jQuery.getJSON(dbrhost+'/sql?js_callback=?',params,function(data){if(success){success.call(scope||window,data);}});}
else{$.post('/sql',params,function(data){if(success){success.call(scope||window,data);}},"json");}},getTables:function(callback,scope){this.adminQuery({cmd:'tables'},function(resp){var rows=resp.data[0].rows,tableNames=[];for(var i=0;i<rows.length;i++){tableNames[i]=rows[i].TABLE_NAME;}
if(callback){callback.call(scope||window,this,resp,tableNames);}},this);},createTable:function(table,columns,callback,scope){this.run('create_table',{table:table,columns:'('+columns+')'},function(qh,resp){if(callback){callback.call(scope||window,resp);}},null,this);},dropTable:function(table,callback,scope){this.run('drop_table',{table:table},callback,null,scope);},executeSql:function(sql,flags,success,error,scope,queryTag){var params={};for(var x in this.connection){params[x]=this.connection[x];}
if(flags){params.flags=params.flags||'';for(var i=0;i<flags.length;i++){params.flags+=','+flags[i];}}
DbRelay.query(params,sql,function(resp){this.log.push('<p style="color:blue">'+resp.log.sql+'</p>');if(success){success.call(scope||window,this,resp);}},function(resp){this.log.push('<p style="color:red">FAIL: ('+(resp.log.error||'Unknown Reason')+')'+resp.log.sql+'</p>');if(error){error.call(scope||window,this,resp,resp.log.error);}},this,queryTag);}};sqlDbAccess=function(connection){return new DbRelay.QueryHelper(connection);};DbRelay.TableHelper=function(table,queryHelper){this.queryHelper=queryHelper.connection?queryHelper:new DbRelay.QueryHelper(queryHelper);var t=table.split('.');this.table=(t.length===2?t[1]:table);this.tableSchema=(t.length===2?t[0]:null);return this;}
DbRelay.TableHelper.prototype={queryColumns:function(callback,error,scope){this.queryHelper.adminQuery({cmd:'columns',param1:this.table},function(resp){if(!resp||!resp.data){return;}
var data=resp.data[0],count=data.count,rows=data.rows,columns=[],columnsByName={};for(var i=0,len=rows.length;i<len;i++){var col=rows[i];columns[i]={name:col.COLUMN_NAME,required:col.IS_NULLABLE==='NO',dataType:col.DATA_TYPE,valueQuote:col.NUMERIC_SCALE===null?"'":"",isIdentity:col.IS_IDENTITY===1,noDefault:col.HAS_DEFAULT===0};columnsByName[col.COLUMN_NAME]=columns[i];}
this.tableColumns=columns;this.tableColumnsByName=columnsByName;if(callback){callback.call(scope||window,this,resp,columns);}},function(resp){if(error){error.call(scope||window,this,resp);}},this);},fetchAll:function(callback,scope){this.fetchRows(null,callback,scope);},getFullTableName:function(){return(this.tableSchema?this.tableSchema+'.':'')+this.table;},fetchRows:function(cfg,callback,scope){cfg=cfg||{};this.queryHelper.run('fetch_rows',{table:this.getFullTableName(),columns:cfg.columns||'*',where:cfg.where?('WHERE '+cfg.where):'',orderBy:cfg.orderBy?'ORDER BY '+cfg.orderBy:''},function(qh,results){if(callback){callback.call(scope||window,this,results);}},null,this);},fetchPagingRows:function(cfg,callback,error,scope){cfg=this.applyProperties(cfg||{},{columns:'*',recordStart:0,pagingSize:20,where:''});if(!cfg.orderBy){if(!this.tableColumns){this.queryColumns(function(sqlt,resp,columns){if(resp&&resp.data){cfg.orderBy=columns[0].name+' asc';this.fetchPagingRows(cfg,callback,error,scope);}},function(sqlt,err){if(error){error.call(scope||window,this,err);}},this);return;}
else{cfg.orderBy=this.tableColumns[0].name+' asc';}}
if(typeof(cfg.recordStart)!=='number'||typeof(cfg.pagingSize)!=='number'){alert('recordStart and pagingSize should be numeric');return{};}
this.queryHelper.run('fetch_paged_rows',{columns:cfg.columns,where:cfg.where?'WHERE '+cfg.where:'',orderBy:cfg.orderBy,table:this.getFullTableName(),minRow:cfg.recordStart+'',maxRow:cfg.recordStart+cfg.pagingSize},function(qh,results){if(callback){callback.call(scope||window,this,results,cfg);}},function(qh,results){if(error){error.call(scope||window,this,results,cfg);}},this);},addRows:function(rows,callback,scope){var batch=this.setAddRowsBatch(rows);if(!batch){return;}
this.queryHelper.commitBatchTransaction(batch,function(qh,resp){qh.emptyBatch(batch);if(callback){callback.call(scope||window,this,resp);}},this);},setAddRowsBatch:function(rows){if(rows.length===0){return false;}
var batch='add'+new Date().getTime();for(var i=0,len=rows.length;i<len;i++){var row=rows[i],values=[],columns=[];for(var k in row){if(row.hasOwnProperty(k)){if(!this.tableColumnsByName[k].isIdentity){if(row[k]||this.tableColumnsByName[k].noDefault){var quote=this.tableColumnsByName[k].valueQuote;if(quote||row[k]){values.push(quote+(row[k]+'').replace(/'/g,"''")+quote);}else{values.push("NULL");};columns.push(k);};};};}
this.queryHelper.addToBatch('row_add',{table:this.getFullTableName(),columns:'('+columns.join(',')+')',values:'('+values.join(',')+')'},batch);}
return batch;},safeSqlString:function(s,f){var col=this.tableColumnsByName[f];var quote=col?"'":col.valueQuote;return quote+(s+'').replace(/'/g,"''")+quote;},deleteRows:function(rows,callback,scope){var batch=this.setDeleteRowsBatch(rows);if(!batch){return;}
this.queryHelper.commitBatchTransaction(batch,function(qh,resp){qh.emptyBatch(batch);if(callback){callback.call(scope||window,this,resp);}},this);},setDeleteRowsBatch:function(rows){if(rows.length===0){return false;}
var batch='delete'+new Date().getTime();for(var i=0,len=rows.length;i<len;i++){var row=rows[i],wheres=[];for(var k in row){wheres.push(k+"="+this.safeSqlString(row[k],k))}
this.queryHelper.addToBatch('delete_row',{table:this.getFullTableName(),where:'('+wheres.join(' AND ')+')'},batch);}
return batch;},updateRows:function(set,wheres,callback,scope){var batch=this.setUpdateRowsBatch(set,wheres);if(!batch){return;}
this.queryHelper.commitBatchTransaction(batch,function(qh,resp){qh.emptyBatch(batch);if(callback){callback.call(scope||window,this,resp);}},this);},setUpdateRowsBatch:function(set,wheres){if(set.length===0){return false;}
var batch='update'+new Date().getTime();for(var i=0,len=set.length;i<len;i++){var values=set[i],valueparam=[],where='';for(var col in values){if(!this.tableColumnsByName[col].isIdentity){if(this.tableColumnsByName[col].valueQuote==="'"||values[col]){valueparam.push(col+"="+this.safeSqlString(values[col],col));}else{valueparam.push(col+"=NULL");};};}
var wherecols=wheres[i];if(typeof(wherecols)==='string'){where=wherecols;}
else{var whereparam=[];for(var k in wherecols){whereparam.push(k+"="+this.safeSqlString(wherecols[k],k));}
where=whereparam.join(' AND ');}
this.queryHelper.addToBatch('update_row',{table:this.getFullTableName(),setvalues:valueparam.join(','),where:where},batch);}
return batch;},queryPrimaryKeys:function(callback,error,scope){this.queryHelper.adminQuery({cmd:'pkey',param1:this.table},function(resp){var rows=resp.data[0].rows,keys=[];for(var i=0;i<rows.length;i++){keys[i]=rows[i].COLUMN_NAME;}
this.pkeyColumns=keys;if(callback){callback.call(scope||window,this,resp,keys);}},function(resp){if(error){error.call(scope||window,this,resp);}},this);},queryTotalRows:function(cfg,callback,error,scope){cfg=cfg||{};var where=cfg.where||{},whereparam=[];if(typeof(where)==='string'){whereparam='WHERE '+where;}
else{for(var w in where){whereparam.push(k+"="+this.safeSqlString(where[w],w));}
whereparam=whereparam.length===0?'':'WHERE '+whereparam.join('AND')}
this.queryHelper.run('get_count',{table:this.getFullTableName(),columns:cfg.pkeys||'*',where:whereparam},function(qh,resp){var total=resp.data[0].rows[0][1];if(callback){callback.call(scope||window,this,resp,total);}},function(qh,resp){if(error){error.call(scope||window,this,resp);}},this);},getQueryHelper:function(){return this.queryHelper;},applyProperties:function(dest,src,overwrite){dest=dest||{};for(var p in src){if(overwrite||!dest[p]){dest[p]=src[p];}}
return dest;}};sqlTable=function(table,queryHelper){return new DbRelay.TableHelper(table,queryHelper);}
