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…
[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;
}
