JavaScript LINQ

•November 2, 2009 • Leave a Comment

Since I’ve been using a lot of JavaScript recently and doing database queries, I thought it would be nice to be able to use LINQ.  So instead of attempting to try to bring in actual .NET CLR stuff into JavaScript for my tests, I thought I would write my own version.  So here it is…

- Example Usage
[jScript]
var q = new Query("SERVER\\INSTANCE", "Database");
var lowerCaseMethod = q.select("*").from("MyTable").execute();
var upperCaseMethod = q.SELECT("*").FROM("MyTable").EXECUTE();
var camelCaseMethod = q.Select("*").From("MyTable").Execute();
var shortHandMethod = q.s("*").f("MyTable").x();
// Each of these will return the same results

 

- Query Class
//////////////////////////////////////////////////
// JavaScript LINQ
//////////////////////////////////////////////////

function Query(server, database, provider)
{
	if(server == null) { Log.Error("Query Error: Server not provided."); return null; }
	if(database == null) { Log.Error("Query Error: Database not provided."); return null; }

	// Properties
	this.Connection		= null;
	this.ConnectionString   = null;
	this.Provider		= (provider == null ? "SQLNCLI10" : provider);
	this.Server			= server;
	this.Database		= database;
	this.RecordSet		= null;
	this.Command		= null;
	this.query 			= "";	

	// Database Connection Commands
	this.Connect		= Query_Connect;
	this.Open			= Query_Open;
	this.Close			= Query_Close;
	this.RecordSetToList	= Query_RecordSetToList;

	this.Execute		= Query_Execute;
	this.ex			= Query_Execute;
	this.EX			= Query_Execute;
	this.run			= Query_Execute;
	this.RUN			= Query_Execute;
	this.X			= Query_Execute;
	this.x			= Query_Execute;

	// ---------------------------------------------------------------------------------------------------
	// SQL Commands - LowerCase
	// ---------------------------------------------------------------------------------------------------
	//									// Syntax				=> Results
	// ---------------------------------------------------------------------------------------------------
	this.and			= Query_And;			// obj.and(condition)		=> AND condition
	this.or			= Query_Or;				// obj.or(condition)		=> OR condition
	this.altertable		= Query_AlterTable;		// obj.altertable(table)	=> ALTER TABLE table
	this.as			= Query_As;				// obj.as(alias)			=> AS alias
	this.between		= Query_Between;			// obj.between(val1, val2)	=> BETWEEN val1 AND val2
	this.createdatabase	= Query_CreateDatabase;		// obj.createdatabase(db)	=> CREATE DATABASE db
	this.createtable		= Query_CreateTable; 		// obj.createtable(table, col, dataType, col2, dataType2, ...) => CREATE TABLE table(col1 dataType, col2, dataType2, ...)
	this.createindex		= Query_CreateIndex;		// obj.createindex(index)	=> CREATE INDEX index
	this.createuniqueindex	= Query_CreateUniqueIndex;	// obj.createuniqueindex(index)=>CREATE UNIQUE INDEX index
	this.createview		= Query_CreateView;		// obj.createview(view)		=> CREATE VIEW view AS
	this.deletefrom		= Query_DeleteFrom;		// obj.deletefrom(table)	=> DELETE FROM table
	this.del			= Query_Delete;			// obj.delete(select,table)	=> DELETE select FROM table
	this.drop			= Query_Drop;			// obj.drop(db)			=> DROP DATABASE db
	this.dropcolumn		= Query_DropColumn;		// obj.dropcolumn(col)		=> DROP COLUMN col
	this.dropindex		= Query_DropIndex;		// obj.dropindex(table,index)	=> DROP INDEX table.index
	this.droptable		= Query_DropTable;		// obj.droptable(table)		=> DROP TABLE table
	this.from			= Query_From;			// obj.from(value)		=> FROM value
	this.groupby		= Query_GroupBy;			// obj.groupby(col)		=> GROUP BY col
	this.having			= Query_Having;			// obj.having(func,col,op,val)=> HAVING func(col) op val
	this._in			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.iin			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.in_			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.inn			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.insertinto		= Query_InsertInto;		// obj.insertinto(table,c,v,.)=> INSERT INTO table (col1, col2, ...) VALUSE (val1, val2, ...)
	this.innerjoin		= Query_InnerJoin;		// obj.innerjoin(table)		=> INNER JOIN table
	this.leftjoin		= Query_LeftJoin;			// obj.leftjoin(table)		=> LEFT JOIN table
	this.rightjoin		= Query_RightJoin;		// obj.rightjoin(table)		=> RIGHT JOIN table
	this.fulljoin		= Query_FullJoin;			// obj.fulljoin(table)		=> FULL JOIN table
	this.like			= Query_Like;			// obj.like(pattern)		=> LIKE pattern
	this.on			= Query_On;				// obj.on(table, col)		=> ON table(col)
	this.orderby		= Query_OrderBy;			// obj.orderby(col, dir)	=> ORDER BY col [ASC|DESC]
	this.select			= Query_Select;			// obj.select(value)		=> SELECT value
	this.selectdistinct	= Query_SelectDistinct;		// obj.selectdistinct(col,tab)=> SELECT DISTINCT col FROM table
	this.selectinto		= Query_SelectInto;		// obj.selectinto(col,table)	=> SELECT col INTO table
	this.selecttop		= Query_SelectTop;		// obj.selecttop(value)		=> SELECT TOP value
	this.truncatetable	= Query_TruncateTable;		// obj.truncatetable(table)	=> TRUNCATE TABLE table
	this.union			= Query_Union;			// obj.union(col, table)	=> UNION SELECT col FROM table
	this.unionall		= Query_UnionAll;			// obj.unionall(col,table)	=> UNION ALL SELECT col FROM table
	this.update			= Query_Update;			// obj.update(table)		=> UPDATE table
	this.where			= Query_Where;			// obj.where(value)		=> WHERE value
	this.y			= Query_Y;				// obj.y(value)			=> value

	// ---------------------------------------------------------------------------------------------------
	// SQL Commands - UpperCase
	// ---------------------------------------------------------------------------------------------------
	//									// Syntax				=> Results
	// ---------------------------------------------------------------------------------------------------
	this.AND			= Query_And;			// obj.and(condition)		=> AND condition
	this.OR			= Query_Or;				// obj.or(condition)		=> OR condition
	this.ALTERTABLE		= Query_AlterTable;		// obj.altertable(table)	=> ALTER TABLE table
	this.AS			= Query_As;				// obj.as(alias)			=> AS alias
	this.BETWEEN		= Query_Between;			// obj.between(val1, val2)	=> BETWEEN val1 AND val2
	this.CREATEDATABASE	= Query_CreateDatabase;		// obj.createdatabase(db)	=> CREATE DATABASE db
	this.CREATETABLE		= Query_CreateTable; 		// obj.createtable(table, col, dataType, col2, dataType2, ...) => CREATE TABLE table(col1 dataType, col2, dataType2, ...)
	this.CREATEINDEX		= Query_CreateIndex;		// obj.createindex(index)	=> CREATE INDEX index
	this.CREATEUNIQUEINDEX	= Query_CreateUniqueIndex;	// obj.createuniqueindex(index)=>CREATE UNIQUE INDEX index
	this.CREATEVIEW		= Query_CreateView;		// obj.createview(view)		=> CREATE VIEW view AS
	this.DELETEFROM		= Query_DeleteFrom;		// obj.deletefrom(table)	=> DELETE FROM table
	this.DEL			= Query_Delete;			// obj.delete(select,table)	=> DELETE select FROM table
	this.DELETE			= Query_Delete;			// obj.delete(select,table)	=> DELETE select FROM table
	this.DROP			= Query_Drop;			// obj.drop(db)			=> DROP DATABASE db
	this.DROPCOLUMN		= Query_DropColumn;		// obj.dropcolumn(col)		=> DROP COLUMN col
	this.DROPINDEX		= Query_DropIndex;		// obj.dropindex(table,index)	=> DROP INDEX table.index
	this.DROPTABLE		= Query_DropTable;		// obj.droptable(table)		=> DROP TABLE table
	this.FROM			= Query_From;			// obj.from(value)		=> FROM value
	this.GROUPBY		= Query_GroupBy;			// obj.groupby(col)		=> GROUP BY col
	this.HAVING			= Query_Having;			// obj.having(func,col,op,val)=> HAVING func(col) op val
	this.IN			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.INSERTINTO		= Query_InsertInto;		// obj.insertinto(table,c,v,.)=> INSERT INTO table (col1, col2, ...) VALUSE (val1, val2, ...)
	this.INNERJOIN		= Query_InnerJoin;		// obj.innerjoin(table)		=> INNER JOIN table
	this.LEFTJOIN		= Query_LeftJoin;			// obj.leftjoin(table)		=> LEFT JOIN table
	this.RIGHTJOIN		= Query_RightJoin;		// obj.rightjoin(table)		=> RIGHT JOIN table
	this.FULLJOIN		= Query_FullJoin;			// obj.fulljoin(table)		=> FULL JOIN table
	this.LIKE			= Query_Like;			// obj.like(pattern)		=> LIKE pattern
	this.ON			= Query_On;				// obj.on(table, col)		=> ON table(col)
	this.ORDERBY		= Query_OrderBy;			// obj.orderby(col, dir)	=> ORDER BY col [ASC|DESC]
	this.SELECT			= Query_Select;			// obj.select(value)		=> SELECT value
	this.SELECTDISTINCT	= Query_SelectDistinct;		// obj.selectdistinct(col,tab)=> SELECT DISTINCT col FROM table
	this.SELECTINTO		= Query_SelectInto;		// obj.selectinto(col,table)	=> SELECT col INTO table
	this.SELECTTOP		= Query_SelectTop;		// obj.selecttop(value)		=> SELECT TOP value
	this.TRUNCATETABLE	= Query_TruncateTable;		// obj.truncatetable(table)	=> TRUNCATE TABLE table
	this.UNION			= Query_Union;			// obj.union(col, table)	=> UNION SELECT col FROM table
	this.UNIONALL		= Query_UnionAll;			// obj.unionall(col,table)	=> UNION ALL SELECT col FROM table
	this.UPDATE			= Query_Update;			// obj.update(table)		=> UPDATE table
	this.WHERE			= Query_Where;			// obj.where(value)		=> WHERE value
	this.Y			= Query_Y;				// obj.y(value)			=> value

	// ---------------------------------------------------------------------------------------------------
	// SQL Commands - CamelCase
	// ---------------------------------------------------------------------------------------------------
	//									// Syntax				=> Results
	// ---------------------------------------------------------------------------------------------------
	this.And			= Query_And;			// obj.and(condition)		=> AND condition
	this.Or			= Query_Or;				// obj.or(condition)		=> OR condition
	this.AlterTable		= Query_AlterTable;		// obj.altertable(table)	=> ALTER TABLE table
	this.As			= Query_As;				// obj.as(alias)			=> AS alias
	this.Between		= Query_Between;			// obj.between(val1, val2)	=> BETWEEN val1 AND val2
	this.CreateDatabase	= Query_CreateDatabase;		// obj.createdatabase(db)	=> CREATE DATABASE db
	this.CreateTable		= Query_CreateTable; 		// obj.createtable(table, col, dataType, col2, dataType2, ...) => CREATE TABLE table(col1 dataType, col2, dataType2, ...)
	this.CreateIndex		= Query_CreateIndex;		// obj.createindex(index)	=> CREATE INDEX index
	this.CreateUniqueIndex	= Query_CreateUniqueIndex;	// obj.createuniqueindex(index)=>CREATE UNIQUE INDEX index
	this.CreateView		= Query_CreateView;		// obj.createview(view)		=> CREATE VIEW view AS
	this.DeleteFrom		= Query_DeleteFrom;		// obj.deletefrom(table)	=> DELETE FROM table
	this.Del			= Query_Delete;			// obj.delete(select,table)	=> DELETE select FROM table
	this.Delete			= Query_Delete;			// obj.delete(select,table)	=> DELETE select FROM table
	this.Drop			= Query_Drop;			// obj.drop(db)			=> DROP DATABASE db
	this.DropColumn		= Query_DropColumn;		// obj.dropcolumn(col)		=> DROP COLUMN col
	this.DropIndex		= Query_DropIndex;		// obj.dropindex(table,index)	=> DROP INDEX table.index
	this.DropTable		= Query_DropTable;		// obj.droptable(table)		=> DROP TABLE table
	this.From			= Query_From;			// obj.from(value)		=> FROM value
	this.GroupBy		= Query_GroupBy;			// obj.groupby(col)		=> GROUP BY col
	this.Having			= Query_Having;			// obj.having(func,col,op,val)=> HAVING func(col) op val
	this.In			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.InsertInto		= Query_InsertInto;		// obj.insertinto(table,c,v,.)=> INSERT INTO table (col1, col2, ...) VALUSE (val1, val2, ...)
	this.InnerJoin		= Query_InnerJoin;		// obj.innerjoin(table)		=> INNER JOIN table
	this.LeftJoin		= Query_LeftJoin;			// obj.leftjoin(table)		=> LEFT JOIN table
	this.RightJoin		= Query_RightJoin;		// obj.rightjoin(table)		=> RIGHT JOIN table
	this.FullJoin		= Query_FullJoin;			// obj.fulljoin(table)		=> FULL JOIN table
	this.Like			= Query_Like;			// obj.like(pattern)		=> LIKE pattern
	this.On			= Query_On;				// obj.on(table, col)		=> ON table(col)
	this.OrderBy		= Query_OrderBy;			// obj.orderby(col, dir)	=> ORDER BY col [ASC|DESC]
	this.Select			= Query_Select;			// obj.select(value)		=> SELECT value
	this.SelectDistinct	= Query_SelectDistinct;		// obj.selectdistinct(col,tab)=> SELECT DISTINCT col FROM table
	this.SelectInto		= Query_SelectInto;		// obj.selectinto(col,table)	=> SELECT col INTO table
	this.SelectTop		= Query_SelectTop;		// obj.selecttop(value)		=> SELECT TOP value
	this.TruncateTable	= Query_TruncateTable;		// obj.truncatetable(table)	=> TRUNCATE TABLE table
	this.Union			= Query_Union;			// obj.union(col, table)	=> UNION SELECT col FROM table
	this.UnionAll		= Query_UnionAll;			// obj.unionall(col,table)	=> UNION ALL SELECT col FROM table
	this.Update			= Query_Update;			// obj.update(table)		=> UPDATE table
	this.Where			= Query_Where;			// obj.where(value)		=> WHERE value	

	// ---------------------------------------------------------------------------------------------------
	// SQL Commands - ShortHand
	// ---------------------------------------------------------------------------------------------------
	//									// Syntax				=> Results
	// ---------------------------------------------------------------------------------------------------
	this.a			= Query_And;			// obj.and(condition)		=> AND condition
	this.at			= Query_AlterTable;		// obj.altertable(table)	=> ALTER TABLE table
	this.b			= Query_Between;			// obj.between(val1, val2)	=> BETWEEN val1 AND val2
	this.cd			= Query_CreateDatabase;		// obj.createdatabase(db)	=> CREATE DATABASE db
	this.ct			= Query_CreateTable; 		// obj.createtable(table, col, dataType, col2, dataType2, ...) => CREATE TABLE table(col1 dataType, col2, dataType2, ...)
	this.ci			= Query_CreateIndex;		// obj.createindex(index)	=> CREATE INDEX index
	this.cui			= Query_CreateUniqueIndex;	// obj.createuniqueindex(index)=>CREATE UNIQUE INDEX index
	this.cv			= Query_CreateView;		// obj.createview(view)		=> CREATE VIEW view AS
	this.df			= Query_DeleteFrom;		// obj.deletefrom(table)	=> DELETE FROM table
	this.d			= Query_Drop;			// obj.drop(db)			=> DROP DATABASE db
	this.dc			= Query_DropColumn;		// obj.dropcolumn(col)		=> DROP COLUMN col
	this.di			= Query_DropIndex;		// obj.dropindex(table,index)	=> DROP INDEX table.index
	this.dt			= Query_DropTable;		// obj.droptable(table)		=> DROP TABLE table
	this.f			= Query_From;			// obj.from(value)		=> FROM value
	this.gb			= Query_GroupBy;			// obj.groupby(col)		=> GROUP BY col
	this.h			= Query_Having;			// obj.having(func,col,op,val)=> HAVING func(col) op val
	this.i			= Query_In;				// obj.in(val1, val2, ...)	=> IN (val1, val2, ...)
	this.ii			= Query_InsertInto;		// obj.insertinto(table,c,v,.)=> INSERT INTO table (col1, col2, ...) VALUSE (val1, val2, ...)
	this.ij			= Query_InnerJoin;		// obj.innerjoin(table)		=> INNER JOIN table
	this.lj			= Query_LeftJoin;			// obj.leftjoin(table)		=> LEFT JOIN table
	this.rj			= Query_RightJoin;		// obj.rightjoin(table)		=> RIGHT JOIN table
	this.fj			= Query_FullJoin;			// obj.fulljoin(table)		=> FULL JOIN table
	this.l			= Query_Like;			// obj.like(pattern)		=> LIKE pattern
	this.ob			= Query_OrderBy;			// obj.orderby(col, dir)	=> ORDER BY col [ASC|DESC]
	this.s			= Query_Select;			// obj.select(value)		=> SELECT value
	this.sd			= Query_SelectDistinct;		// obj.selectdistinct(col,tab)=> SELECT DISTINCT col FROM table
	this.si			= Query_SelectInto;		// obj.selectinto(col,table)	=> SELECT col INTO table
	this.st			= Query_SelectTop;		// obj.selecttop(value)		=> SELECT TOP value
	this.tt			= Query_TruncateTable;		// obj.truncatetable(table)	=> TRUNCATE TABLE table
	this.u			= Query_Union;			// obj.union(col, table)	=> UNION SELECT col FROM table
	this.ua			= Query_UnionAll;			// obj.unionall(col,table)	=> UNION ALL SELECT col FROM table
	this.up			= Query_Update;			// obj.update(table)		=> UPDATE table
	this.w			= Query_Where;			// obj.where(value)		=> WHERE value
}

//////////////////////////////////////////////////
// Connection Methods
//////////////////////////////////////////////////

function Query_Connect()
{
	if(this.Server == null || this.Server == "") { Log.Error("Cannot connect to database. No server provided."); return; }

	this.Connection = ADO.CreateConnection();
	this.ConnectionString = "Provider=" + this.Provider + "; Server=" + this.Server + "; " + (this.Database == null || this.Database == "" ? "" : "Database=" + this.Database + "; ") + " Integrated Security=SSPI;";
	this.Connection.ConnectionString = this.ConnectionString;
}

function Query_Open()
{
	this.Connection.Open();
}

function Query_Close()
{
	this.Connection.Close();
}

function Query_Execute()
{
	try
	{
		this.Connect();
		this.Open();
		this.RecordSet 			= null;
	      this.Command 			= ADO.CreateCommand();
	      this.Command.ActiveConnection = this.Connection;
	      this.Command.CommandType 	= 1;
	      this.Command.CommandText 	= this.query;
	      this.Command.CommandTimeout 	= 5000;
	      this.RecordSet 			= this.Command.Execute();
		var out = this.RecordSet.GetString(2, this.RecordSet.RecordCount, ",", "|");
		var ret = this.RecordSetToList(out);
		this.Close();
		return ret;
	}
	catch(ex)
	{
		Log.Error("Failed to execute SQL query [" + this.query + "]", ex.description);
		return ex.description;
	}
}

function Query_RecordSetToList(RecordSet)
{
	var ret = new Array();
	var index = 0;
	var rows = RecordSet.split("|");

	for(var i = 0; i < rows.length; i++)
	{
		var rowList = new Array();
		var index2 = 0;
		var row = rows[i];
		var cells = row.split(",");
		for(var j = 0; j < cells.length; j++)
		{
			var cell = cells[j];
			rowList[index2++] = cell;
		}
		ret[index++] = rowList;
	}

	return ret;
}

//////////////////////////////////////////////////
// SQL Methods
//////////////////////////////////////////////////

function Query_Select(value)
{
	this.query += "SELECT " + value + " ";
	return this;
}

function Query_From(value)
{
	this.query += "FROM " + value + " ";
	return this;
}

function Query_Where(value)
{
	this.query += "WHERE " + value + " ";
	return this;
}

function Query_And(value)
{
	this.query += "AND " + value + " ";
	return this;
}

function Query_Or(value)
{
	this.query += "OR " + value + " ";
	return this;
}

function Query_AlterTable(value)
{
	this.query += "ALTER TABLE " + value + " ";
	return this;
}

function Query_As(value)
{
	this.query += "AS " + value + " ";
	return this;
}

function Query_Between(value1, value2)
{
	this.query += "BETWEEN " + value1 + " AND " + value2 + " ";
	return this;
}

function Query_CreateDatabase(value)
{
	this.query += "CREATE DATABASE " + value + " ";
	return this;
}

// CREATE TABLE table_name( col_name1 data_type, col_name2 data_type, ...)
function Query_CreateTable()
{
	var q = arguments[0] + "(";
	for(var i = 1; i < arguments.length; i += 2)
	{
		q += arguments[i] + " " + arguments[i + 1] + ",";
	}
	q += ")";
	this.query += "CREATE TABLE " + q + " ";
	return this;
}

function Query_CreateIndex(index_name)
{
	this.query += "CREATE INDEX " + index_name + " ";
	return this;
}

function Query_On(table, col)
{
	this.query += "ON " + table + "(" + col + ") ";
	return this;
}

function Query_CreateUniqueIndex(index_name)
{
	this.query += "CREATE UNIQUE INDEX " + index_name + " ";
	return this;
}

function Query_CreateView(view_name)
{
	this.query += "CREATE VIEW " + view_name + " AS ";
	return this;
}

function Query_DeleteFrom(table_name)
{
	this.query += "DELETE FROM " + table_name + " ";
	return this;
}

function Query_Delete(select, table_name)
{
	this.query += "DELETE " + select + " FROM " + table_name + " ";
	return this;
}

function Query_Drop(database_name)
{
	this.query += "DROP DATABASE " + database_name + " ";
	return this;
}

function Query_DropColumn(col)
{
	this.query += "DROP COLUMN " + col + " ";
	return this;
}

function Query_DropIndex(table_name, index_name)
{
	this.query += "DROP INDEX " + table_name + "." + index_name + " ";
	return this;
}

function Query_DropTable(table_name)
{
	this.query += "DROP TABLE " + table_name + " ";
	return this;
}

function Query_GroupBy(col_name)
{
	this.query += "GROUP BY " + col_name + " ";
	return this;
}

function Query_Having(func, col_name, op, value)
{
	this.query += "HAVING " + func + "(" + col_name + ") " + op + " " + value;
	return this;
}

// value1, value2, value3, ...
function Query_In()
{
	var value = "";
	for(var i = 0; i < arguments.length; i++)
	{
		value += arguments[i] + (i != arguments.length - 1 ? "," : "");
	}
	this.query += "IN (" + value + ") ";
	return this;
}

// arguments = table_name, col1, val1, col2, val2, ...
function Query_InsertInto()
{
	var col = "";
	var val = "";
	for(var i = 1; i < arguments.length; i++)
	{
		col += arguments[i] + (i != arguments.length - 2 ? "," : "");
		val += arguments[i + 1] + (i != arguments.length - 1 ? "," : "");
	}
	this.query += "INSERT INTO " + arguments[0] + " (" + col + ") VALUES(" + val + ") ";
	return this;
}

function Query_InnerJoin(table1, table2, col1, col2)
{
	this.select(col1).from(table1);
	this.query += "INNER JOIN " + table2 + " ON " + table1 + "." + col1 + "=" + table2 + "." + col2 + " ";
	return this;
}

function Query_LeftJoin(table1, table2, col1, col2)
{
	this.select(col1).from(table1);
	this.query += "LEFT JOIN " + table2 + " ON " + table1 + "." + col1 + "=" + table2 + "." + col2 + " ";
	return this;
}

function Query_RightJoin(table1, table2, col1, col2)
{
	this.select(col1).from(table1);
	this.query += "RIGHT JOIN " + table2 + " ON " + table1 + "." + col1 + "=" + table2 + "." + col2 + " ";
	return this;
}

function Query_FullJoin(table1, table2, col1, col2)
{
	this.select(col1).from(table1);
	this.query += "FULL JOIN " + table2 + " ON " + table1 + "." + col1 + "=" + table2 + "." + col2 + " ";
	return this;
}

function Query_Like(pattern)
{
	this.query += "LIKE " + pattern + " ";
	return this;
}

// dir = ASC || DESC
function Query_OrderBy(col, dir)
{
	this.query += "ORDER BY " + col + " " + dir + " ";
	return this;
}

function Query_SelectDistinct(col, table)
{
	this.query += "SELECT DISTINCT " + col + " FROM " + table;
	return this;
}

function Query_SelectInto(col, newTable)
{
	this.select(col);
	this.query += "INTO " + newTable + " ";
	return this;
}

function Query_SelectTop(value)
{
	this.query += "SELECT TOP " + value + " ";
	return this;
}

function Query_TruncateTable(table)
{
	this.query += "TRUNCATE TABLE " + table + " ";
	return this;
}

function Query_Union(col, table)
{
	this.query += "UNION ";
	this.select(col).from(table);
	return this;
}

function Query_UnionAll(col, table)
{
	this.query += "UNION ALL ";
	this.select(col).from(table);
	return this;
}

function Query_Update(table)
{
	this.query += "UPDATE " + table + " ";
	return this;
}

// arguments = col=val, col2=val2, ...
function Query_Set()
{
	var value = "";
	for(var i = 0; i < arguments.length; i += 2)
	{
		value += arguments[i] + "=" + arguments[i + 1] + (i != arguments.length - 2 ? "," : "");
	}
	this.query += "SET " + value + " ";
	return this;
}

// enables insertion of anything extra
function Query_Y(value)
{
	this.query += value + " ";
	return this;
}

TestComplete Reference Sheet

•October 20, 2009 • Leave a Comment

Working on a reference sheet for various commands in TestComplete.

It can be downloaded from my SkyDrive at

TestComplete 7 Reference.xlsx

Programming eBooks

•October 19, 2009 • Leave a Comment

JSON in TestComplete

•October 19, 2009 • 1 Comment

I’ve figured out how to implement JSON into TestComplete.  Most of it is already there if you use JScript / C#Script / C++Script in TestComplete.  The only manipulating needed is when you read the JSON in from a file, but it can be easily wrapped up into a function.

Lets see how some code turns out on here.

function Main()
{
     var objJSON = { "FirstName" : "John", "LastName" : "Doe", "Age" : 24 };

     Log.Message(objJSON.FirstName); // Logs "John"
     Log.Message(objJSON.LastName); // Logs "Doe"
     Log.Message(objJSON.Age); // Logs "24"

     var data = aqFile.ReadWholeTextFile("c:\\test.json", aqFile.ctANSI);
     var objJSON2;
     eval("objJSON2 = {" + data + "};");

     Log.Message(objJSON2.Animal.Dog); // Logs "Friendly"

     var objJSON3 = GetJsonFromFile("c:\\test.json");
     Log.Message(objJSON3.Color); // Logs "Blue"
}

function GetJsonFromFile(strFilename)
{
	var data = aqFile.ReadWholeTextFile(strFilename, aqFile.ctANSI);
	var ret;
	eval("ret = {" + data + "};");
	return ret;
}

[test.json]
‘Color’ : ‘Blue’,
‘Animal’ : {‘Dog’ : ‘Friendly’ }
[/test.json]

First Thoughts

•October 16, 2009 • Leave a Comment

Working on some new projects to hopefully get out to everyone.  Finally figured out how to dock a window to the desktop in WPF now and I am wrapping that up into a library.

Current Projects

  • hacker (Hacking RPG/Puzzle game)
  • Elysium (Engine / Library)
  • Elysium Evolve (Episodic RPG for Windows/Xbox)
  • Aether (Performance monitoring system)
  • DesktopDockLib
  • Transmute (Full featured editor / debugger for Elysium)
  • DatabaseManager (Program for work)
  • JSON importing in XNA