Pete and RePete a place for my stuff

23Mar/10Off

Castle Project ActiveRecord for ASP.Net Tutorial: Part 1 Introduction and a Single Table

I recently began working with Castle ActiveRecord. It is an Object Relational Mapping (ORM) tool for .Net applications. If you're reading this I probably don't have to explain what an ORM is, but essentially, instead of using ADO.Net/SQL to interact with your data, you get to manipulate each database record as if it were a .Net object, with CRUD operations available directly as object methods. While the getting started guide on the Castle Project website is generally adequate, it's for WinForms instead of ASP.Net, there's a few typos/inconsistencies in code examples, and it's getting a little dated. I wanted to document my experience here so that others don't run into the same problems I did while learning. I'll be making a very simple blog application that generally follows the getting started guide on the ActiveRecord website, but I'm going to break up my tutorial slightly differently. In part one we'll setup the environment and write the code for a very simple, single table object. In part two we'll introduce relationships into the application and pretty up the interface a bit. I assume some level of competency in C#, ASP.Net and Visual Studio, but you can be completely new to ActiveRecord, NHibernate, and ORMs in general. To begin, you'll need:

  • Visual Studio or the free Visual Web Developer Express Edition (I'll be using Visual Web Developer 2008)
  • SQL Express, likely installed with your Visual Studio
  • The Castle Project AcriveRecord Binaries. This tutorial is based on ActiveRecord 2.0

Adding References Begin by creating a new website and calling it ActiveRecordTutorial. Right click on the web site in the solution explorer and click "Add References..." Browse to the place you extracted the ActiveRecord DLLs and add Castle.ActiveRecord.dll. This should automatically add a number of other references including, Castle.Components.Validator.dll, Castle.Core.dll, Iesi.Collections.dll, Lucene.Net.dll, NHibernate.dll, and NHibernate.Search.dll. Not included is NHibernate.ByteCode.Castle.dll, add this as well. The official getting started guide actually misses this resource. Creating The First Database Table Right click on the App_Data folder and select "Add New Item..." Select SQL Server, and name it ActiveRecordDB.mdf. Note that this is a SQL Server Express database. You may want to use the full version of SQL Server, or even PostgreSQL or MySQL, but I'll be using Express as it's the easiest to integrate with an ASP.Net web site. Then view the database in the Database Explorer, right click on the Tables folder and select "Add New Table", this will be your Person table. The getting started guide used "User" but I found there was some conflict with the existing .Net User class, which made debugging slightly challenging. Create columns for Id (int), UserName (nvarchar(25)), and Password (nvarchar(25)). Id will be the primary key, and should also be an Identity column.  After saving this table as Person, it should look like the following: User Table Structure Adding the Person Class For each table that you want to use in your application with ActiveRecord, you will create a corresponding class. Add a new class to your application called User.cs. You will get an alert prompting you to put this code file in the App_Code folder. Accept this option. You should then put the following code into this class.

 namespace ActiveRecordTutorial { using System; using Castle.ActiveRecord; [ActiveRecord] public class Person:ActiveRecordBase<person> { private int id; private string username; private string password; public Person() { } public Person(string username, string password) { this.username = username; this.password=password; } [PrimaryKey] public int Id { get { return this.id; } set { this.id = value; } } [Property] public string Username { get { return this.username; } set { this.username = value; } } [Property] public string Password { get { return this.password; } set { this.password = value; } } } } 

There are at 4 things that separate this from a normal class. 1. The ActiveRecord attribute on the class name. 2. Inheritance from ActiveRecordBase<Person>. 3. The PrimaryKey attribute on the Id property. 4. Property attributes on all remaining properties. All of these attributes are used by ActiveRecord define the relation between the table and the class. Initializing The Framework Easily the most frustrating part of trying to adapt the official getting started guide to an ASP.Net application was configuring and initializing the framework. The guide creates an XML file to store settings, but ASP.Net already has an XML file handy, the web.config file. To begin, add the following just inside the configSections element, just before the sectionGroup for system.web.extensions

 </person></p>
<p><section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord"> <section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord"> 

Next, immediately following the empty connectionStrings element, add the following

 <activerecord isweb="true"> <config> <add key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"> <add key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"> <add key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider"> <add key="connection.connection_string" value="Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\ActiveRecordDB.mdf; Integrated Security=True;User Instance=True"> <add key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"> </add></add></add></add></add></config> </activerecord> 

Notice that I am using the MsSql2008Dialect. There is no dialect specific to SQL Expres. MsSql2005Dialect also works against SQL Server 2008, but does not take advantage of some of the new Date data types in SQL Server 2008. See the NHibernate blog post NHibernate and Ms Sql Server 2008 for more details. Finally you will need to add the following inside the httpModules element.

 <add name="ar.sessionscope" type="Castle.ActiveRecord.Framework.SessionScopeWebModule, Castle.ActiveRecord"> 

This module provides default behaviour for SessionScope. You could replace this with custom code in the Global.asax file, but the module will do for now. Next, we need to run some code to initialize the application the first time it's run. Create a Global.asax file and change it's Inherits property to ActiveRecordTutorial.MyHttpApplication. We do this so that we can place code in a separate class called MyHttpApplication. It is also possible to write your code directly in the Global.asax file, but this was the approach taken by the getting started guide, so it's what I follow here. Then create a new class called MyHttpApplication and place the following code in it.

 namespace ActiveRecordTutorial { using System; using System.Web; using Castle.ActiveRecord; using Castle.ActiveRecord.Framework; using Castle.ActiveRecord.Framework.Config; public class MyHttpApplication : HttpApplication { protected void Application_Start(Object sender, EventArgs e) { //get the settings from web.config IConfigurationSource source = ActiveRecordSectionHandler.Instance; //register your objects with ActiveRecord ActiveRecordStarter.Initialize(source, new Type[] { typeof(Person) }); } } } 

I have only skimmed the surface of configuration and initialization. For more information see the initialization step of the getting started guide, and the Web Applications guide in the official documentation. Using the Person Class Finally, to test the Person class put the following in Default.aspx.cs

 using System; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using ActiveRecordTutorial; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //create your new user and set properties Person myPerson = new Person(); myPerson.Username = &quot;name&quot;; myPerson.Password = &quot;secret&quot;; try { //try to save myPerson to database myPerson.Create(); } catch (Exception err) { string errReport = &quot;Failed trying to save user \n&quot;; errReport += err.Message; System.Diagnostics.Debug.Write(errReport); } } } 

Run the page with F5 and if you're page successfully loads, you should have a user in the database. User In Database Conclusion You have now created your first web site using Castle Project ActiveRecord. This framework not only greatly simplifies data access by abstracting SQL calls to objects, but also encourages OOP patterns, leading to more maintainable code. In part two I will be creating Blog and Post objects to illustrate relationships. Until then.

3Jul/091

JavaScript and SQL using Rhino and SQLite

My previous posts have revolved around running JavaScript in environments outside of the browser. After the disappointment of Microsoft dropping plans for Managed JScript, I’ve taken some time to work with Mozilla Rhino.

As an aside, it’s been quite nice to work with a strictly open source product. My company is a heavy user of Microsoft products so I’m very much exposed to the .Net ecosystem. I think it’s very strong, but I do yearn for a little more open community.

Recently, I’ve become interested with SQLite, and I thought it would be a great exercise to use SQLite from Rhino. I could find all kinds of articles that cover similar topics, but none that covered exactly this, so I get to feel like I’m getting first tracks, even if down a smaller slope.

SQLite is kept small and nimble by only providing an API to C/C++ and Tcl. So you’ll need a way to bind Java to SQLite. I used SQLite JDBC That project appears to be under relatively active development, works on all platforms, and is available as a compiled jar. The jar contains all the code you need so you don’t even have to install SQLite separately.

Next start the Rhino shell including the SQLite jar on your classpath. I’m running Windows and use a batch file to do this, do my batch file looks like this:


@echo off

echo Starting Rhino

cd c:\Rhino1_7r2

java -cp ".;C:\rhino1_7r2\jar\sqlitejdbc-v056.jar;;C:\rhino1_7r2\js.jar" org.mozilla.javascript.tools.shell.Main

If you’re typing this in the interactive shell, I’ve added come some of the return statements in comments.


//import the Java SQL package

importPackage(java.sql);

//load the SQLite driver

//importPackage does not work here

java.lang.Class.forName("org.sqlite.JDBC");

// returns:class org.sqlite.JDBC

//Create connection to test.db

//That database is created if it doesn’t exist.

//Normally, you could supply two more arguments here with

//username and password, but SQLite doesn’t support this

var conn = DriverManager.getConnection("jdbc:sqlite:test.db");

//Use the connection to create a Statement object

var stat = conn.createStatement();

stat.executeUpdate("drop table if exists people ;");

//returns: 0

stat.executeUpdate("create table people (name, occupation);");

//returns: 0

//Create a prepared statement object

var prep = conn.prepareStatement("insert into people values (?, ?);");

prep.setString(1, "Gandhi");

prep.setString(2, "politics");

prep.addBatch();

prep.setString(1, "Turing");

prep.setString(2, "Computers");

prep.addBatch();

conn.setAutoCommit(false);

//Execute the prepared statements

prep.executeBatch();

//returns: [I@6e1408

conn.setAutoCommit(true);

var resultSet = stat.executeQuery("select * from people;");

while (resultSet.next()){

print(resultSet.getString("name") + “ – “ + resultSet.getString("occupation"));

}

//returns

// Gandhi - politics

// Turing – Computers

//cleanup

//While SQLite really isn’t the tool to use if

//data needs to be shared across multiple applications

// or users, be sure to close resultSet otherwise the

//db will stay locked

resultSet.close();

stat.close();

conn.close();

You can then launch your SQLite inspector of choice, I use the fantastic SQLiteman. Select * from people and you will see what you’ve just added. Satisfying isn’t it?

Notice that I had to specify java.lang.Class.forName whereas most examples you see connecting to a SQL database will simply call Class.forName. This is because the lang package isn’t imported by default into Rhino, where is normally is in Java.

Tagged as: , 1 Comment
13Jun/092

Still Waiting: The Story of Two Anticipated But Absent JavaScript Projects Pt 2

In my previous post I bemoaned the languishing existence of Managed Jscript. Since then I’ve come across this thread on the DLR Codeplex project.  So essentially, Jscript on the DLR is pretty much dead in the water, which is a shame. I really do like the .Net platform and I want to write code in ECMAScript for platforms other than the browser.

However, Managed Jscript was far from the only option to get into non-browser JavaScript. Once again, the good people of the Mozilla Foundation have come to the rescue of JavaScript by giving us Rhino. For those of you that don’t know, Rhino is a JavaScript engine compliant to ECMAScript X.X. But the key is the whole thing is written in Java. That means that you can import Java packages, just as easily as you could use other JavaScript libraries. With the wealth of Java libraries out there, it’s quickly obvious this is a good thing.

My primary interest in Managed JScriptis in using JavaScript on the server side. I don’t want to use more than one language if I don’t have to between the browser and server, but up until this point JavaScript has not had a strong enough standard library because of the security sandbox. But with Rhino, all of a sudden Java’s full ecosystem became available. Now the only thing holding me back was a robust web-framework.

‘But why not just build your own?’ you ask. Because, primarily, I’m not that good. I have a degree in business, not computer science. I enjoy the technical parts of my job, but at my core I’m far more strategy minded than technology. I want as easy an entry as possible. I know a bit of JavaScript, I want to play with JavaScript, not PHP/Python/Ruby (see above comment about using one language).

In my search for a server side JavaScript (SSJS) framework I came across a post by Steve Yegge  and a follow up interview with him about his experimental port of Ruby on Rails to JavaScript, using Rhino as the JS engine. To be clear, I’ve never touched Ruby, but when every developer and their dog is jumping on the Rails bandwagon, you know it’s got something special.

So I waited with bated breath. When would Google give this lowly engineer the right to open source his code and release it to the world. There seemed to be considerable buzz about it so it must be happening soon.

But it did not happen soon. But surely something this clever and innovative will be released eventually. It must, right?

Well maybe not, we’re now two years since that original announcement and nothing has happened. Google didn’t announce a brand new framework to accompany it’s Java App Engine. Steve hasn’t made much direct mention about this since last year at Google I/O.

Sadly, we may be experiencing Duke Nukem Forever syndrome. This is when a project is supposed to be released, but for one reason or another never is. Perhaps it is time to move on. I’ve started looking at Helma (NG), a very cool framework that brings Rhino to the server for the same purpose.

Now this is a very different situation than Microsoft announcing Managed JScript only to decide against it a year later. This is one very bright engineer making a point on how flexible a language is then suggesting a possibility of releasing it open sourced

However, there is the commonality of two very large corporations that have cool JavaScript projects that may never come to completion because there aren’t the resources to finish it. And open souring doesn’t appear to be an option because both projects utilize proprietary systems.

Why am I writing this? Partly out of frustration/disappointment that these projects have not (yet) seen the light of day. Partly because I want to make sure that anyone with a Google Alert for Managed JScript or Rhino Not/On Rails knows they’re not alone.

5Jun/090

Still Waiting: The Story of Two Anticipated But Absent JavaScript Projects Pt 1

This is the story of two very exciting JavaScript projects that were announced to a minor flurry of activity, and then promptly forgotten about by the people that introcuded them to the world. What makes this interesting is the two, very different sources that these products came from. I am talking about Managed JScript and Rhino on Rails. This post will focus on Managed JScript

Managed JScript is Microsoft's implementation of JScript (JavaScript/ECMAScript) for the .Net platform. Specifically, Managed JScript will run on the Dynamic Language Runtime (DLR) which has risen to a certain amount of acclaim since IronPython and IronRuby began strutting their stuff. When the DLR was announced, it was bundled with demos of IronPython, IronRuby, and Managed JScript, all for SilverLight. This was an impressive step for Ruby and Python, as these are two languages that hadn't been able to easily run in the browser. However, JavaScript was born in the browser so this was a smaller step.  What I, and I'm sure many other JavaScript users, wanted to see was a way to run desktop and server side applications in JavaScript, using the .Net framework's tools. It looked like Microsoft may be ready to deliver on this with their inclusion of Managed JScript in a .Net futures release, but that was only a technology preview and not ready for prime time.

So now IronPython is released and making geek blog headlines for being faster than CPython and IronRuby just released 0.5 which can now pretty much run Rails, which is quite the feat. And Managed JScript? Nowhere to be seen, not even a status update.

Now, is it right to blame Microsoft for this? They've fully supported the development of the DLR, going as far as to open source the code. There's even a project on Codeplex, MyJscript, that is intented to be a teaching language to learn how to create a DLR language by implementing JScript. It's also possible that Microsoft is waiting until ECMAScript5 has been standardized so they won't have to tack a major update onto the language only months after it has been released. However, because Microsoft has announced plans to eventually release Mnaged JScript, it would be foolish for any programmer to sink time into creating an open source DLR JavaScript. If Microsoft did ever release this fabled language, all that time invested would be wiped out buy what would (hopefully) be a well polished and supported language.

So if you're interested in JavaScript for .Net there are two options the way I see it:

  • Wait until Microsoft releases Managed JScript, which may be never, and will possibly be closed source (notice that Managed was used and not the Iron convention of the other open source languages)
  • Create your own implementation called "Managed IronJscript.Net # (Sharp)," that may get trounced by an official release.

JScript.Net is not an options, it's dead.

Links:

JScript Team Blog Announcing Managed JScript

MyJScript

   

Search engine optimization by SEO Design Solutions