Skip to main content

Posts

If it can go wrong, it will!

If you've been reading my blog, you know that I am developing an application using Visual Studio 2005 and Castle's ActiveRecord framework. Recently, I bought Visual Studio 2005 Pro so I could use Crystal Reports. Believe it or not, The user was able to install my application without a working version of .Net 2.0 around. As far as I can tell, they did a Windows Update, and somehow it corrupted their video drivers. Then they did a system restore back to before .Net 2.0 was installed. After this, they installed my application, and it crashed (of course!). They tried to repair .Net 2.o Framework, but that didn't quite do it. So now I will probably be connecting via Remote Desktop to survey the damages. I learned something from this, and I will probably have two tiny executables in my bin folder ... a "hello world" application that maybe says "If you can see this, then .Net 2.0 is installed." and maybe does some sniffing around to see if an important...

I won 2 fandango tickets

I know this entry is off-topic, but yesterday was pretty amazing. A co-worker told me about , and I signed up last month. Blingo is a search engine that uses Google's database for results, but as you search, you have a chance to win something. Blingo has "Thousand Dollar Thursdays" and sometimes they even give away an automobile! So yesterday I was trying to figure out why my ABit A8N SLI Fatality motherboard was crashing Windows XP since I added a SATA hard drive and a DVD burner. While I was searching, I won a Fandango movie ticket! That was cool, but I kept searching, and found that I needed to turn off the "[x] Let BIOS decide" option, and then turn off Command Queuing. So 30 minutes later, I did a different search and won again! That is 2 wins in a row! On the side panel, it lists who won what, and it showed me twice. The co-worker who referred me was ecstatic, as he has never won anything on Blingo so far. I use Firefox, and I like a clean...

Defensive Programming with ActiveRecords

[Update 1: finished the entry, and added some compilable code.] [Update 2: Updated the compilable code - improved the Property setter code.] Recently, I have been working on a project with Castle's ActiveRecord support. Since I am changing my database schema as I discover new requirements, and adapt to new data sources, I occasionally run into query / model / table mismatches. Now, gross mismatches cause NHibernate to choke, and refuse to accept my models, but if I have merely added a field, that will be ignored until insert time. Even then, it might not cause an exception if it is a nullable field. Now when I first started on this project, I wrote a simple SQL procedure that selected a list of fields from the database schema, walked through a cursor for each field and PRINTed code, then I would create a class file in Visual Studio 2005 and paste that code in. -- Get a list of tables SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != 'sysdiagrams...

Hibernate Shards for data partitioning across databases

Google has donated Hibernate Shards - a Java 5 add-on to Hibernate that allows application driven data partitioning with your custom or their pre-build configurations. One thing that caught my eye was that when they covered partitioned Native ID generation (aka Identity), they mentioned having Database A use a range 0-200000, Database B use range 200001 - 400000, etc. I know that MySQL cluster suggests using something like this: Database A: Starting ID 1, Increment ID by 3 (number of databases) Database B: Starting ID 2, Increment ID by 3 Database C: Starting ID 3, Increment ID by 3 This allows a hands-off approach, and easily lets you divide ID by 3 and use the remainder to map to a "Shard". Of course, if your data changes significantly, you may have to dump and reload to add another database. One way to avoid a dump and reload is to pick an increment that is larger than your actual database count, and just drop an extra database in an the available Starting ID. This ...

HTML Help on .Net

As I have said before, I am developing with Visual Studio 2005 on .Net 2.0. This summer, I will be creating an application with integrated html help. Of course, my first inclination is to refresh my knowledge of help systems by acquiring Microsoft's HTML Help SDK . The HTML Help Workshop looks like it will do light project management, and it even has an image cropping and screen capture program called "Flash". I did not see any full downloadable examples in the MSDN Help SDK area, but they had a link to the Help Wiki . If you browse through the wiki, you will find some good (but dated) help info about C# . DotNetJunkies has a nice step-by-step c# example for integrating help after you have a compiled help file. I am thankful that my application uses .Net 2.0, as .Net 1.x did not have much support for help systems. The .Net 2.0 HelpProvider seems like it will be very useful (here is a tutorial . HTML Help Tidbit: Your help system can be thought of as a self-cont...

ActiveRecord support for MultiQuery

I have submitted a patch to add MultiQuery support to ActiveRecord. The link is at http://support.castleproject.org/browse/AR-139 . I added ActiveRecordMultiQuery.cs and updated ActiveRecordBaseQuery.cs to allow subclasses to be aggregated (added) to the MultiQuery. I did this to speed up initialization of a form (I know ... premature optimization is the root of all evil). If you like this patch, log in and vote for it! Update: The patch has been applied. In the mean time, let me caution you that ActiveRecordCriteriaQuery from the svn repository (which I also wrote and contributed) and any other "query" that uses criteria will not correctly participate in a multi-query. But if we give the NHibernate team some time, I'm sure this will be resolved. Regarding the implementation, the only thing that I really wondered about was the "root type". This basically selects the session to be created. So all queries in the multi-query need to be registered with the ...

Castle ActiveRecord calling a Stored Procedure

Update: I have contributed patch AR-156 that allows full integration of Insert, Update and Delete to ActiveRecord models . If you've been reading my blog lately, you know that I have been seriously testing the Castle ActiveRecord framework out. I really love it, but I have an existing Microsoft SQL Server database with many stored procedures in it. I have tested the ActiveRecord model out, and I am sure that I will learn enough to be able to use it for standard CRUD (create, read, update, delete aka. insert, select, update, delete) functionality. BUT ... If I really want to integrate with my existing billing procedures, etc, I will have to be able to call stored procedures. I have taken two approaches ... write the ARHelper.ExecuteNonQuery(targetType, dmlString) method that gets a connection for the supplied type, executes dmlString, and closes it. write the ARHelper.RegisterCustomMapping(targetType, xmlString) method that allows me to add mappings that refer to my auto-gener...

Castle ActiveRecord with DetachedCriteria

My current development environment is Visual Studio Express C# Edition (read that as free ), Castle ActiveRecord's latest svn trunk(usually within a few days), and NHibernate svn trunk. As of NHibernate version 1.2.0, there is a very cool new class out there ... DetachedCriteria. This class lets you set all of your Castle relational attributes like BelongsTo, HasMany, etc. as lazy fetch, and over-ride this for searches, reports, or anytime you know ahead of time that you will be touching the related classes by calling detachedCriteria.SetFetchMode(..., FetchEnum.Eager). As a good netizen, I have tried to contribute to NHibernate and Castle ActiveRecord even if only in the smallest of ways . Oh yeah, I tried mapping to a SQL VIEW, and it worked GREAT! I received a comment after my last post, indicating that there is a better way, and I am sure of it, but the view guaranteed that I only have one database request for my dataset. NHibernate was wanting to re-fetch my missing as...

Wading through mud with Castle ActiveRecord

Lately, it feels like I've been wading through mud. As if the ActiveRecord library has been doing nothing but preventing me from getting my work done. In my dreams, I could call MyEntity.Find() with a list of ICriterion objects, and get back what I want. I was having problems with that, because I want to select several object, left joining to a notes table, and return only the most recent note (with max(NoteDate)). While I can think it, and write it in raw SQL, it has been tough doing this in an ActiveRecord query. Just to see if it is possible, I tried HQL, and finally resorted to raw SQL. I learned that "raw SQL" has several requirements imposed on it: * The returned result set must include the complete field list of all entities that you want to return (as far as I can tell). * NHibernate will replace {nt.*} with a complete field list if you include "nt" as an alias for typeof(MyNote). * Do not list an alias unless you are returning that entity in your ...

Castle ActiveRecord with Criteria and Alias

Update May 25, 2007: ActiveRecord now supports DetachedCriteria, which eliminates the need for the SlicedFindAll that I wrote below. It is nice when a library moves to add support for such commonly needed functions. So in summary, use Detached criteria instead of the code below. It is still a nice example of using NHibernate sessions. I have a history log, where each history record "belongs to" a service record. I have to treat this as a child-to-parent join, since some children are orphans. I wanted to use the FindAll(Criteria), but I wanted the option to have optional criteria, orders and aliases. My solution was to create an ARAlias class to represent an Associated Entity and an alias, and then build an ARBusinessBase class with the following method: public static T[] SlicedFindAll(int firstResult, int maxResults, Order[] orders, ARAlias[] aliases, params ICriterion[] criteria) { IList list = null; ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionF...

What is an Active Record anyway?

While looking for Castle ActiveRecord examples, I found a blog by David Hayden - post 1 (design pattern overview) , post 2 (some details on a possible implementation) and post 3 (using the Castle Project). David had a series of articles about Rocky Lhotka's .NET Business Objects (one for each chapter), which I have also read and tried to apply. Don't get me wrong, Rocky's CSLA library works, but as of .Net 1.1 it required a great deal of code on my part. There are reasons why I and many others were investigating code generation tools. I have been studying Castle's ActiveRecord framework for a week and a half, and it is awesome for new development and clean data. During this discussion, remember that ActiveRecord mostly generates the XML mapping files for you and delegates the heavy lifting to NHibernate . If you have a legacy database with "sometimes there" keys, the framework will punish you severely. Below is an example of a legacy scenario that wi...

Finding database model information in Castle and ActiveRecord

Since this is my first post on the subject, let me introduce the Castle project - a .Net framework that I have been exploring recently. It has a project that tries to mimic ActiveRecord in Ruby-On-Rails, although the Castle version of ActiveRecord uses NHibernate. The good news is that an ActiveRecord class doesn't require any XML configuration or mapping files. The somewhat bad news is that you DO have to declare your classes and populate them with properties, private members and AR mapping attributes. Since I will probably use SQLServer 2000, I will just write a few queries to extract the data type and field list for each table that I want to support. More on this later. For today, I wanted to extract the class-to-database mapping information that Castle's ActiveRecords feeds to NHibernate. I finally looked through the source code a bit and after a blind alley (NHibernate.Cfg Configuration is mostly for database connections), I ran across the ActiveRecordModel class...

Table Functions in SQL Server 2000 and up

I recently added a customer tagging feature to our billing system. Users needed to be able to see a list of associated tags in their reports, so I needed to be able to collect all tags for a customer into a single string. Below is a rough approximation of the table schema. I did some research, and ended up creating a user-defined function (UDF) that returns a TABLE variable. Inside the UFD, I used a table variable, a cursor (which I wanted to avoid) and ran a query with the COALESCE() function for each customer. I was able to use my UDF as if it were a temporary table in my reports. Otherwise, I would have had to duplicate this code for each report. Before accepting this solution, I tried various flavors of selecting, updating, etc. but I couldn't find a solution without using a cursor. The code below is an untested generic adaptation of my working solution. TABLE: Customers Customer_ID INTEGER, CustomerName VARCHAR(50) TABLE: Membership Member_ID INTEGER, ...

The Rails Way

There is an excellent article on recommended coding practices "The Rails Way" . The authors are espousing a commonly held coding practice - use base classes or mix-ins (Modules in Ruby) only when code would otherwise be repeated. This reinforces the DRY (Don't Repeat Yourself) philosophy that Ruby encourages and facilitates. A helpful reader offers further explanation for those Rails programmers who have not dug deeply into Ruby yet at Artistic Coding . Ruby is such an amazing and flexible language, but my "Day Job" is .Net, so I can not wait for Ruby.Net , Ruby CLR (or maybe here ), or whatever works. Ruby.Net and Ruby 2.0 (see YARV ). Microsoft is working on IQF (Integrated Query Framework), which will try to offer .Net users the same ease-of-use and elegance that ActiveRecords offers (ActiveRecords is a part of the Rails framework, but can be used separately). If Mono also implements IQF, I will be interested. We shall see.

Online Gaming with Eternal Lands

Note: I wrote this entry while I was still playing Eternal Lands. I have recently stopped playing, but I thought I should share my thoughts anyway. For the past few months, I have been spending time in a free online role playing game - Eternal Lands . The game allows "player kill", but only on certain maps or certain areas, and you receive a warning message before you enter these areas. I haven't joined a guild yet, and the game doesn't force you to do so. All-in-all, I like it, although it could use a lot more quests (I'm working on submitting a few ideas ). I have a few tips for new players. First, concentrate on fighting and building up will at least to 12 first, then start building physique. Do not add to ANY OTHER attributes EVER. Only add pairs of "pick points" to attributes, as odd values are wasted. Don't take any negative perks until you have reached level 25. I would advise against taking any positive perks as well. I took the art...

Installing Ubuntu Dapper Drake

A fellow IT guy walked past my desk and asked about the 400 MHz Celeron box that I had tied to my switch box. I informed him that this was my Linux test box. He said that we have much better boxes than that in our storage room, and invited me to shop. I pulled out a Dell 4100 - with an Intel 815 chipset and ATI Rage 128 Pro graphics. I plan on installing this one as a true server - Apache, Ruby, Rails, MySQL 5.0, and SSH. Here's how I did it: 1. Make an install ISO of Dapper Drake Flight 3 . 2. Select [Install As Server] at the install menu. 3. modify inittab for 3 consoles (put a # in front of other consoles). 4. edit /etc/apt/sources.list to add universe and multiverse 5. apt-get update & apt-get upgrade 6. a. apt-get install openssh-server mysql-client mysql-server ruby apache2 b. apt-get install libapache2-mod-scgi unzip rdoc 7. edit etc/ssh/sshd_config to dis-allow root access, change port number, and AllowLogin for my user id. 8. upgrade linux kernel to latest 686 v...

SQL Quirks - count and sum

I was reminded of a little quirk of SQL recently, and I thought I would share it with my readers. I will be going over the SQL in a manner suitable for beginners, but the quirk that I refer to could catch an intermediate student of SQL. I will use some simple SQL to illustrate my point. -- 1. create temporary table CREATE TABLE #test1 ( id int not null , name varchar(50) not null ) ; -- 2. declare variables DECLARE @cnt int, @sum int ; -- 3. compute statistics SELECT @cnt = count(*) FROM #test1 ; SELECT @sum = sum(id) FROM #test1 ; -- 4. print results to query analyzer PRINT '@cnt = ' + ISNULL( CONVERT(varchar, @cnt), '[NULL]') ; PRINT '@sum = ' + ISNULL( CONVERT(varchar, @sum), '[NULL]') ; -- 5. cleanup DROP TABLE #test1 ; If you will paste this sequence into query analyzer, and run it in a non-production database, you will see that it produces: @cnt = 0 @sum = [NULL] In step 1, we create an empty table. In step 2, we declare two variables, and their...

AppTrain: A Rails Form Generator

If you've been thinking about trying out Ruby On Rails , you just have to check out the AppTrain project on Ruby Forge. There is a step-by-step guide to form generation as well. AppTrain is currently an alpha release, but it still looks quite handy. If you want to install it, use the quick-start . The AppTrain Project seems very committed to making it easy to build rails apps. First, they created a Table Generator , and now they are working on a form generator. That's all some simpler administrative apps need!

SQLServer2000: Capture output of EXEC statements

About 2 years ago, I discovered that I could capture the results of an EXEC (@string_variable) statement. We had a server process that logged in as System Admin (SA), so it could perform a directory scan, bulk insert any files it found, and move those files to a "processed" subdirectory. This process can be used to run any DOS command, and inserts each line of text as a record into a table. We still use this trick to log program responses to a journal table. When reading the sample code, notice that we are using two single-quote characters back-to-back to cause a single quoted argument to be sent to the xp_cmdshell extended command (really a registered DLL accessible only to SA). Here's an example: DECLARE @s varchar(255); CREATE TABLE #cmdOutput(Line varchar(200)) ; SET @s='INSERT INTO #cmdOutput EXEC master.dbo.xp_cmdshell ''dir c:\temp\*.txt /b'''; EXEC (@s) ; SELECT * FROM #cmdOutput WHERE Line IS NOT NULL; DROP TABLE #cmdOutput; A word of c...

Use and Abuse of XML

This may be considered a rant by some, but here goes. XML is a data structure which is easily parsed by 3rd party applications. This does not mean that the data can be easily interpreted as information, that is the responsibility of the XML data designer. Depending on your audience, you may have to spell out units (pounds, kilograms, minutes, seconds, etc.). Also, XML IS NOT FAST. Do not use XML between internal components in your application if at all possible. Thank you for your attention.