/**
* Filename: mt-bia.js
*
* @projectDescription MooTools Bia Remoting Library
* @author Matan Lurey
* @version 0.1 Alpha
* @namespace Bia
*
* Bia aids Ajax developers in applications with heavy remoting
* and 'one-load' rich applications; such as editors and games.
*/
/*
* Includes...
* ===========
* Bia.io
* .Cookie
* .create(String id)
* .set(String name, Object value)
* .get(String name)
*
* #remove()
* #update()
* .SQLLiteConnection
* .GoogleGears
* .HTML5
* .FileSystem
* .Remote
* Bia.data
* .SQL
* .Database
* .Table
* #select()
* #update()
* #drop()
* #deleteFrom()
* #expiresIn
* .Row
* #columns
* .create(String name)
*
* #createTable(String name)
* #save(Object connection, Boolean clear)
* #load(Object connection, Boolean clear)
* #drop()
* #autoSave [false]
* #loadOnDemand [true]
* Bia.net
* .WebService
* #establish
* #request
* .CrossDomain
* #close
* .encodeuri
* .decodejson
**/
/**
* Interfaces
*/
var Interface = new Class({
initialize: function()
{
this.required = $A(arguments);
},
test: function(Cls)
{
this.required.each(function (item){
if (!Cls.prototype[x])
throw new Error('Class does not implement Interface.'+item);
});
}
});
/**
* Bia Application Extender Namespace
*/
var Bia = {};
/**
* Data Management Functions for Bia
*/
Bia.data = {sql :{}};
/**
* @constructor 'In-Memory' SQL Database in JavaScript
* Isn't exactly sql, but parallels its features in a sort of huge hash object.
* The cool thing is being able to load and save dynamically...
*
* [Loading]
* ==> fromCookie (cookieName) You can read serialized json data from a cookie.
* Not recommended for more than a handful of rows.
*
* ==> fromFile (fileName) IE with a trusted site can use an ActiveX File System Object
* ==> fromGears (dbName) IE or Firefox users with Google Gears Installed and Allowed can
* read and write directly to a SQLLite Database.
* ==> fromHTML5 (dbName) Nightly builds of browsers with HTML5 SQL can read/write also.
*
* ==> fromRemote (url, dbName) Alternatively, you can read/write data to a PHP Web Service
*
* Rise or Fall uses a Bia SQL Database to cache all important data that will be displayed
* multiple times, such as Players, Nations, Terrain, and Map Locations. Each table is
* assigned an 'expiration' time of X minutes, which means X minutes after a row on the table
* has been established it is requested again from the remote server.
*/
/*
* Examples:
*
* Players stores the players name, nation, and online status. It has an expiration of 15
* minutes, meaning every 15 minutes player information is recalled. This is to make sure
* nation and online status stay up to date.
*
* If a user ever attempts to interact with an offline player, the server will force a
* database update that it is offline, so no worries!
*
* Nation stores the nations name, colour, avatar, capital location, and more. This has
* an expiration of -1, meaning it never expires. Its highly unlikely during one session
* that a nation will change.
*
* Location stores the x, y, terrain and tile. This also has an expiration of -1.
*
* Unit stores information about any sort of unit active on the map. Since units can
* be moved and such, this has an expiration of 5 minutes. However, server-side events
* may override this quicker than this if necessary.
*/
/*
* NOTE:
*
* Using the caching feature of the remote database means that you receive data on demand
* only, and never request data that is unlikely to have changed, so the response is instant!
*
* To use, set the Database#useMemoryCache to true. This should only be used with a remote database,
* local databases don't need this functionality.
*/
Bia.data.sql.Database = new Class({
});
/**
* Input/Output Functions for Bia
*/
Bia.io = {};
/**
* Cookie Object (Extends functionality of MooTools.Cookie)
*/
Bia.io.Cookie = new Class({
initialize: function(name)
{
},
remove: function()
{
// Delete Cookie
},
update: function(newData)
{
// JSON Encode Data and Save
},
getData: function()
{
// JSON Decode Data and Return
}
});
/**
* Creats a Cookie (same as new Cookie())
*/
Bia.io.Cookie.create = function(name)
{
return new Cookie(name);
};
/**
* SQL Lite Interface
*/
Bia.io.SQLLiteConnection = new Interface('get', 'set', 'connect', 'close', 'remove', 'drop');
/**
* SQL Lite Connection for Google Gears
*/
Bia.io.SQLLiteConnection.GoogleGears = new Class({
get: function(table, idOrQuery, cback) {
// [Todo]
},
set: function(cback) {
// [Todo]
},
remove: function(cback) {
// [Todo]
},
connect: function(cback) {
// [Todo]
},
close: function(cback) {
// [Todo]
},
drop: function(cback) {
// [Todo]
}
});
/**
* SQL Lite Connection for HTML5 Proposed Standard
*/
Bia.io.SQLLiteConnection.HTML5 = new Class({
get: function(table, idOrQuery, cback) {
// [Todo]
},
set: function(cback) {
// [Todo]
},
remove: function(cback) {
// [Todo]
},
connect: function(cback) {
// [Todo]
},
close: function(cback) {
// [Todo]
},
drop: function(cback) {
// [Todo]
}
});
/**
* SQL Lite Connection for IE's FileSystem Object
*/
Bia.io.SQLLiteConnection.FileSystem = new Class({
get: function(table, idOrQuery, cback) {
// [Todo]
},
set: function(cback) {
// [Todo]
},
remove: function(cback) {
// [Todo]
},
connect: function(cback) {
// [Todo]
},
close: function(cback) {
// [Todo]
},
drop: function(cback) {
// [Todo]
}
});
/**
* @constructor
* @alias Bia.io.SQLLiteconnection.Remote
* SQL Lite Connection for a remote Web Service using Bia DB API
*/
Bia.io.SQLLiteConnection.Remote = new Class({
/**
* @alias Bia.io.SQLLiteConnection.Remote.prototype.get
* @param {String} table
* @param {Object} idOrQuery
* @param {Function} cback
*
* Runs a 'SELECT FROM' statment on the server. In the case of
* Rise or Fall, we check to make sure the table selected is
* allowed (for example, you cant peak at your opponents gold amount)
* and the columns of the table are filtered --- when selecting a player
* you can see if they are online, but not where on the map they are looking @.
*
* @return {Object/Array[Object]}
*/
get: function(table, idOrQuery, cback) {
this._transport.request({
action: 'get',
table: table,
where: idOrQueryOrNull
}, function(data){
cback(data);
});
},
/**
* @alias Bia.io.SQLLiteConnection.Remote.prototype.set
* @param {String} table
* @param {Object} idOrQueryorNull
* @param {Object} values
* @param {Function} [cback]
*
* Runs either a 'INSERT INTO' or 'UPDATE' statement on the server.
* Again, you must be authenticated server-side to do this.
*
* @return {Integer} Rows Affected
*/
set: function(table, idOrQueryOrNull, values, cback) {
this._transport.request({
action: 'set',
table: table,
where: idOrQueryOrNull,
values: values
}, function(data){
if (cback) cback(data.rowsAffected);
});
},
/**
* @alias Bia.io.SQLLiteConnection.Remote.prototype.remove
* @param {String} table
* @param {Object} idOrQuery
* @param {Function} [cback]
*
* Runs a 'Delete FROM' statement on the server. Your session authenticated user
* must have privelages to do such a request.
*
* @return {Integer} Rows Affected
*/
remove: function(table, idOrQuery, cback) {
this._transport.request({
action: 'remove',
table: table,
where: idOrQuery
}, function(data){
if (cback) cback(data.rowsAffected);
});
},
/**
* @alias Bia.io.SQLLiteConnection.Remote.prototype.connect
* @param {Function} cback Function to call when connection is successful
* @param {CrossDomain} [cd] Optionally specify a cross-domain object to use
*
* Connects to a remote url via a Bia.net.WebService
*/
connect: function(url, cback, cd) {
// Use a different domain object?
var cd = this._window = (cd&&cd.container&&cd.container.contentWindow.Bia) ? cd.container.contentWindow : window;
this._transport = cd.Bia.net.WebService(url);
var handshake = {
'action': 'authenticate'
};
this._transport.request(handshake, function(data){
return cback(data.accepted);
});
},
close: function(cback) {
this._transport.close();
},
/**
* @alias Bia.io.SQLLiteConnection.Remote.prototype.drop
* @param {String} table
* @param {Function} cback
*
* Drop's a table.
*/
drop: function(table, cback) {
this._transport.request({
action: 'drop',
table: table,
where: idOrQuery
}, function(){
if (cback) cback();
});
}
});
/**
* Namespace for Networking Functions for Bia
*/
Bia.net = {
encodeuri: function(data)
{
// [Todo]
},
decodejson: Json.evaluate
};
/**
* @constructor
* @alias Bia.net.WebService
*
* Creates a remote web service url, which is an extended, automatic converting advanced
* JSON Request.
*
* .request({names: ['mati', 'ray', 'alex'], stupid: true, colors: {blue: 0000FF}});
* =>
* &names[]=mati&names[]=ray&names=alex&stupid=1&colors[blue]=0000FF
*
* --- server returns... {data: {accepted: true, names: ['mati', 'ray', 'alex']}}
* <=
* data {Object}
* .accepted {Boolean} = true
* .names {Array}
* [0] 'mati'
* [1] 'ray'
* [2] 'alex'
*/
Bia.net.WebService = new Class({
initialize: function(url)
{
this.establish(url);
},
establish: function(url)
{
this.url = url;
return this;
},
request: function(postData, cBack)
{
var X = new XHR().send(this.url, Bia.net.encodeuri(postData));
X.onSuccess = function()
{
cBack(Bia.net.decodejson(X.response.text));
};
}
});
/**
* @constructor
* @alias Bia.net.CrossDomain
*
* Creates an iFrame Proxy for Cross Domain Ajax. You must create a
* cross-domain.htm that contains links to mootools and mt-bia, i.e.:
*
*
*
*
* [Incompatible] !!!
* Opera does not support accessing elements of another iFrame. It DOES
* support cross-document messaging, but I'm not going to support that just yet -
* to little of the population uses opera for it to be significant... However,
* it WILL be supported in the future!
*/
Bia.net.CrossDomain = new Class({
initialize: function(toCrossDomainDotHTM, rdyCBack)
{
this.container = new Element('iframe', {
src: toCrossDomainDotHTM,
styles: {
width: 0,
height: 0,
position: 'absolute',
left: -500000
}
}).inject(document.body)
// Support for Firefox and Safari
this.container.onload = rdyCBack;
// Support for IE
this.container.onreadystatechange = function()
{
// [todo]
};
}
});