I spent most of the week prototyping
some things in Silverlight. I figured during the holiday week most
people out there goofed off on their jobs a lot this week, so rather
than work on my roadmap priorities, I decided to have some fun and play with Silverlight.
Some of you who have followed my blog for a while may remember some
posts I made in the past about my plans for Site Office as a second
plug in model for mojoPortal
more geared to line of business apps that need a consistent look and
feel rather than the web site kind of look, they need to look like
applications. I originally protyped the UI using Dojo and then later
re-did it with ExtJs. You can see the ExtJs version if you login to this site (or http://demo.mojoportal.com
using admin@admin.com and password admin), then click the Site Office
link at the top. You'll see the drag resizable panes that give the idea
of where I wanted to go with Site Office as a UI for LOB applications.
This prototype has just been sitting there without much attention
because of other priorities and also partly because my enthusiasm for
ExtJs disappeared when they changed the license from LGPL to GPL.
Anyway, even back then I implemented a google gears query tool. Its
really the only functioning app in the old Site Office prototype, you
can find it by clicking the My Stuff in the left accordian menu in Site
Office and then click SQL. For those who don't know, google gears is a
client side SQL database built on SQLite and having this database
available opens a lot of possibilities in web development for very rich
and responsive applications.
Well, now my plan is to scrap the old ExtJs based Site Office
prototype and build a better one with Silverlight. I've already got the
Google Gears Query Tool re-implemented in Silverlight as shown below:

I wrote a nice managed code wrapper around the javscript calls for
gears. The only problem is, it doesn't work well in IE 7 for some
reason, it works great in Firefox. I've sent an email off to Scott
Guthrie at Microsoft in hopes of some help looking into the problem,
but for now you can try it out online at http://demo.mojoportal.com/Index.aspx,
you can see that I've got the basic layout of Site Office again
implemented in Silverlight with the drag re-sizable panes. I plan to
build a plug in model that allows you to plugin your own Silverlight
applets and let the framework provide stuff thats common across
applications. If I can get google gears working well across browsers
with Silverlight its really going to be sweet. The code for this is in
my svn sandbox and will probably land in trunk sometime next week.
Now using the managed gears wrapper can be seen in this client side business/data class, it looks very much like a server side class but its a client side object populated from a client side database in a very similar fashion to what it would look like in server side code. Notice the parametrized queries to prevent sql injection attacks. This class represents a saved query but it could represent anything.
using System;
namespace mojoPortal.Silverlight.Helpers.Gears
{
public class SavedQuery
{
public SavedQuery()
{}
private int id = -1;
private string name = string.Empty;
private string query = string.Empty;
public int Id
{
get { return id; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Query
{
get { return query; }
set { query = value; }
}
public void Save(GearsDb gearsDb)
{
if (id == -1) { Create(gearsDb); return; }
Update(gearsDb);
}
private void Create(GearsDb gearsDb)
{
if (gearsDb == null) { return; }
string sqlCommand = "insert into savedqueries (name, query) values (?, ?)";
object[] parameters = new object[2];
parameters.SetValue(name, 0);
parameters.SetValue(query, 1);
gearsDb.Execute(sqlCommand, parameters);
id = gearsDb.LastInsertRowId();
}
private bool Update(GearsDb gearsDb)
{
if (gearsDb == null) { return false; }
string sqlCommand = "update savedqueries set name = ?, query = ? where id = ?";
object[] parameters = new object[3];
parameters.SetValue(name, 0);
parameters.SetValue(query, 1);
parameters.SetValue(id, 2);
gearsDb.Execute(sqlCommand, parameters);
int rowsAffected = gearsDb.RowsAffected();
return (rowsAffected > 0);
}
public static SavedQuery GetQuery(GearsDb gearsDb, int id)
{
if (gearsDb == null) { return null; }
string sqlCommand = "select * from savedqueries where id = ?";
object[] parameters = new object[1];
parameters.SetValue(id, 0);
GearsResultSet rs = new GearsResultSet(gearsDb.Execute(sqlCommand, parameters));
SavedQuery query = null;
if (rs.IsValidRow())
{
query = new SavedQuery();
query.id = Convert.ToInt32(rs.GetFieldValue("id"));
query.name = rs.GetFieldValue("name").ToString();
query.query = rs.GetFieldValue("query").ToString();
}
rs.Close();
return query;
}
public static SavedQuery GetQuery(GearsDb gearsDb, string name)
{
if (gearsDb == null) { return null; }
string sqlCommand = "select * from savedqueries where name = ?";
object[] parameters = new object[1];
parameters.SetValue(name, 0);
GearsResultSet rs = new GearsResultSet(gearsDb.Execute(sqlCommand, parameters));
SavedQuery query = null;
if (rs.IsValidRow())
{
query = new SavedQuery();
query.id = Convert.ToInt32(rs.GetFieldValue("id"));
query.name = rs.GetFieldValue("name").ToString();
query.query = rs.GetFieldValue("query").ToString();
}
rs.Close();
return query;
}
public static bool Delete(GearsDb gearsDb, int id)
{
if (gearsDb == null) { return false; }
string sqlCommand = "delete from savedqueries where id = ?";
object[] parameters = new object[1];
parameters.SetValue(id, 0);
gearsDb.Execute(sqlCommand, parameters);
int rowsAffected = gearsDb.RowsAffected();
return (rowsAffected > 0);
}
}
}