Thursday, April 16, 2009

Chinook: Cross-Database (SQL Server, Oracle, MySQL) Sample

The Chinook database is a sample database that is an alternative to the Northwind sample. One of the advantages it has over Northwind is that it can be installed on SQL Server (including the Compact Edition), Oracle and MySQL. Therefore it can be used to test Object-relational mapping (ORM) frameworks (e.g. NHibernate, SubSonic etc).

Wednesday, April 15, 2009

Code Generation with MyGeneration

Rather than type repetitive code, a code generator could be used to do it for you. MyGeneration is one such piece of software that will help. As the output is just text, you can output code in any language (ASP.NET, C#, VB.NET, PHP, JavaScript etc) - although with a bit of extra work, PDF's can be generated (using iTextSharp - which would need to be downloaded and the dll saved in the MyGeneration install folder). It can query many database types (SQL Server, Oracle, SQLite, MySQL, PostgreSQL and more), but a database isn't required for it to be of use. You can set up an interface (to select columns in a table for example), but it is optional.

For example, to loop through columns in a database table:

Template Code

<%
public class GeneratedTemplate : DotNetScriptTemplate
{
 public GeneratedTemplate(ZeusContext context) : base(context) {}
 
 private string DatabaseName;
 private string TableName;
 private ITable table;
 private ArrayList columns;
 private string PrimaryKey = string.Empty;

 //---------------------------------------------------
 // Render() is where you want to write your logic    
 //---------------------------------------------------
 public override void Render()
 {
  DatabaseName = input["databaseName"].ToString();
  TableName = input["tableName"].ToString();
  table = MyMeta.Databases[DatabaseName].Tables[TableName];
  columns = input["lstColumns"] as ArrayList;
  try
  {
   PrimaryKey = table.PrimaryKeys[0].Name; 
  }
  catch (System.Exception ex)
  {
   // no primary key
  }
  foreach (string columnName in columns)
  {
  %>
  <li><%= columnName %></li><%
  }
 }
 
 // check if column has been selected via UI
 private bool IsInColumns(Column c)
 {
  foreach (string columnName in columns)
  {
   if (columnName == c.Name) return true;
  }
  return false;
 }
}
%>

Interface Code

public class GeneratedGui : DotNetScriptGui
{
 public GeneratedGui(ZeusContext context) : base(context) {}
 
 private string DatabaseName;
 private string TableName;
 private string PrimaryKey = string.Empty;
 private ArrayList columns;
 private ITable table;

 //-----------------------------------------
 // The User Interface Entry Point
 //-----------------------------------------
 public override void Setup()
 {

  ui.Width  = 500;
  ui.Height = 350;
  
  // Setup Database selection combobox.
  GuiLabel lblDatabases = ui.AddLabel("lblDatabases", "Select a database:", "Select a database in the dropdown below.");
  GuiComboBox cmbDatabases = ui.AddComboBox("databaseName", "Select a database.");
  
  // Setup Tables selection multi-select listbox.
  GuiLabel lblTables = ui.AddLabel("lblTables", "Select table:", "Select table from the combobox below.");
  GuiComboBox cmbTables = ui.AddComboBox("tableName", "Select a table.");
  
  // setup columns list box
  GuiLabel lblColumns = ui.AddLabel("lblColumns", "Select columns:", "Select columns from the listbox below.");
  GuiListBox lstColumns = ui.AddListBox("lstColumns", "Select columns.");
  
  lstColumns.Height = 130;
  
  // bind data to the controls
  cmbDatabases.BindData(MyMeta.Databases);
  cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Name;
  cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables );
  
  // Attach the onchange event to the cmbDatabases control.
  cmbDatabases.AttachEvent("onchange", "cmbDatabases_onchange");
  cmbTables.AttachEvent("onchange", "cmbTables_onchange");
  
  ui.ShowGui = true;
 }
 
 public void cmbDatabases_onchange(GuiComboBox control)
 {
  GuiComboBox cmbDatabases = ui["databaseName"] as GuiComboBox;
  GuiComboBox cmbTables = ui["tableName"] as GuiComboBox;
  cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables );
  GuiListBox lstColumns = ui["lstColumns"] as GuiListBox;
  lstColumns.Clear();
 }
 
 public void cmbTables_onchange(GuiComboBox control)
 {
  try 
  {
   GuiComboBox cmbDatabases = ui["databaseName"] as GuiComboBox;
   GuiComboBox cmbTables = ui["tableName"] as GuiComboBox;
   GuiListBox lstColumns = ui["lstColumns"] as GuiListBox;
   lstColumns.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables[cmbTables.SelectedValue].Columns );
  }
  catch (Exception ex)
  {
  }
 }
}

To loop through a collection (e.g. ArrayList).

Template Code

<%
public class GeneratedTemplate : DotNetScriptTemplate
{
 public GeneratedTemplate(ZeusContext context) : base(context) {}

 //---------------------------------------------------
 // Render() is where you want to write your logic    
 //---------------------------------------------------
 public override void Render()
 {
  int i;
  ArrayList items = new ArrayList();
  items.Add("Array Item 1");
  items.Add("Array Item 2");
  items.Add("Array Item 3");
  items.Add("Array Item 4");
  items.Add("Array Item 5");
  
  for(i = 0; i < items.Count; i++)
  {
  %>
    <p><%= items[i].ToString() %></p>
  <%
  }
 }

}
%>

Interface Code

public class GeneratedGui : DotNetScriptGui
{
 public GeneratedGui(ZeusContext context) : base(context) {}

 //-----------------------------------------
 // The User Interface Entry Point
 //-----------------------------------------
 public override void Setup()
 {
  // ** UNCOMMENT CODE BELOW TO SEE UI **

  //ui.Width  = 100;
  //ui.Height = 100;
  //GuiLabel lblDemo = ui.AddLabel("lblDemo", "Demo", "Demo Tooltip");
  //ui.ShowGui = true;
 }

}

MyGeneration comes with a template library built in, so chances are, someone may have already done a template that does what you want. You can post your own templates online as well (MyGeneration can download templates from this site, so you don't need to actually go to the site to get them).

It is also on SourceForge: http://sourceforge.net/projects/mygeneration/, so you can download the source code for it and make changes or add features.

Friday, April 10, 2009

GIMP Button Templates - Web 2.0 Style

Created some GIMP images that can be used as templates for creating buttons. Available in 64x64 and 256x64 sizes. Text can be altered and the background style changed (by altering visibility).

Sunday, April 05, 2009

Raphaël - a JavaScript library for creating vector images

Raphaël enables you to create geometric shapes / vector images in your web page without needing to know the syntax of Vector Markup Language (VML) or Scalable Vector Graphics (SVG). You can follow Raphaël on Twitter.

Sample code (example from website) shows how easy it is to work with.

// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(10, 50, 320, 200);
// Creates circle at x = 50, y = 40, with radius 10
var circle = paper.circle(50, 40, 10);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f00");
// Sets the stroke attribute of the circle to white (#fff)
circle.attr("stroke", "#fff");

Animation of the shapes created can also be done with it (e.g. circles into squares).