Everyone knows what Wiki is, however JotSpot invented great concept how to extend wiki to build web based applications. Here is a good start about wiki as an application platform. Short overview of the most exciting features:
- You could send an email and it will appear attached in wiki
- Version control (roll back feature)
- You may create your own forms, dynamic tables and so on. In the other words, you could define custom entities and handle them using different views. For example, you can create Company form, add some companies and view them in a table format. Within 5 minutes.
Such flexibility achieved by using special tags that are similar to ASP.NET tags. It's simple and easy to learn and use. The idea is simple and elegant and I think wiki approach will be used by many small companies to build their own in-hous enterprice systems.
Why developers so often reinventing the wheel? There are so many ready to use solutions, there are so many Persistence Layers, controllers, libraries and components, build tools, templates and so on. Why anybody wants create DAO while there is Hibernate (or other competitors)? Why anybody wants create custom presentation layer while there is Tapestry, Spring and Struts? Well, usual arguments are:
- "This framework is a crap and we should not use it"
- "Did you see source code? It's a hell on the Earth!"
- "Its functionality is incomplete. We have to use tricky-feature-for-transactions, but it is not there"
- "Its too complex to learn and too heavy to work with"
- "We can't integrate all that stuff. It will never work"
While in several cases these arguments are valid, in most cases they hide the following thoughts:
- "Sounds interesting, but I am pretty sure that we will not use it properly and end up with something messy. I don't thing we will be able to apply this technology properly"
- "I don't want to learn new tool. I am pretty comfortable with Java language and new framework don't attract me"
- "This is too complex for me. What if my boss discovers my weakness?"
So most often developers just don't want to try new things, they afraid to expose their weaknesses, or they just do not believe in framework or approach.
I think this is just a lack of courage and trust in the team. Extreme Programming may help to resolve these problems by changing working environment and team's atmosphere. It is really hard to do XP without courage. It is really hard to hide weaknesses while programming in pairs. People change after doing XP several months. They adapt to accept criticism, to express they thoughts with no fear and believe in team. Or they leave.
XP teams has more courage to try new approaches, new frameworks and new methods. However, there is a reverse of the medal. Sometimes XP teams try to bring too many new things into development process. I saw it by myself, and result was very bad. Project was stopped. Well, there was quite good progress in fact, but top management felt that time might be spent more efficiently.
Ok, getting back to the main topic. I think another reason to not try new frameworks is a choice. Really, to decide what O/R mapping framework is great for your, you should spend pretty much time on comparison. You may try dozen tools and still don't decide what to choose. Often time pressure is hard and you should *KNOW* your tools, but not investigate them.
I personally spend some time every week to evaluate new tools and approaches in software development. I learn constantly. And very often I know what to use in particular situation.
It is desirable to know test code coverage sometimes. It indicates quality and amount of tests and helps to ensure that TDD going right. This even could be one of the metrics for release acceptance (code coverage should be no less than 75%, for example).
NCover is a free tool for test code coverage metric generation (for .NET projects). It integrated pretty good with NUnit and within 10 minutes or so you may confugure it and get useful report.
Install NCover and NUnit and add ncover.console.exe and nunit-console.exe into PATH environment variable. Open comand prompt and to to the folder where your DLL with tests located. And just run the following command
> ncover.console /c nunit-console Tests.dll /a Project1;Project2;Project3
By the way, default stylesheet is very bad. You can get more better one here, Replace original Coverage.xslt with new in NCover folder, it will be copied each time when ncover runs.
If you use NAnt, you may add NCover report generation as a task.
Recently I read article Embedded Firebird at Code Project and decided to try FireBird. I like the idea of embedded database. FireBird allows .Net developer to put a dll into bin directory, create database file and use usual database access. It sounds very attractive and simple. In theory. So I decided to migrate from SQL Server to FireBird.
Database Creation and Tools
Embedded version of FireBird is very light, just 1.5 Mb. FireBird Data Provider for .NET is also not so big – 0.7 Mb. I downloaded all these stuffs and put required dlls into bin directory. Then I started database creation. However, FireBird Embedded distributive does not include any tool for database administration. Well, I downloaded standard distributive (4 Mb) and installed full featured SuperServer on my workstation. I dug into Program Files in the hope of find DB administration tool and find one. It was ISQL console tool. “OK, no GUI” – I thought. – “This database is for real geeks”. I opened QuickStart guide, found a section about database creation and tried to create one. But, as you might guess, without success. There was strange behavior, the ISQL refused to believe me that I really creating new database and told that database is unavailable.
Fighting with console for awhile, I decided to find GUI tool. There were several free toll at IBPhoenix web site. First I downloaded IBSQL (1Mb). It ran, but, when I tried to create new database, showed an error “gds32.dll was not found”. I hunted around and find out that original dll could be renamed and putted into the System32 directory. I started IBSQL and it worked! A new database was created!
Do you think the migration is close to completion now? Not at all. Schema importing became a really tough action. At the very beginning I discovered that FireBird does not support IDENTITY keyword. That’s not a problem, I removed it. Then things became weird. IBSQL tool did not execute query popping up the error in the line with second’s table CREATE statement. I tried to correct statements and understood that the tool unable to run several statements! There were about 40 statements to execute, and I was not very enthusiastic about doing that one by one. “Fine, let’s find something more user friendly”. I found FeniSQL - very light (0.5Mb) tool. The same bug! I was slightly tired of that. I found several advices is newsgroups about IBOConsole tool and got them (2Mb). Yes, this tool is really great, has appealing GUI and useful features. And has no silly restrictions on statements execution.
However, SQL was still wrong for FireBird. I used columns named “password”, “value” and “time”. These are reserved keywords. MSSQL Server eats them, but not FireBird. As you understand, renaming several columns is an issue, but I want to set up database at least. So I renamed fields in schema and ran SQL script again. The database schema was created successfully.
Do you think the migration is over? I thought so in that moment, but FireBird converted all tables and columns names in upper case. And the application refused to query database correctly. Ok. Google newsgroups are helpful and I found out that names should be quoted:
CREATE TABLE "releases"
"name" VARCHAR(150) NOT NULL,
"project_plan_id" INTEGER NOT NULL,
"release_id" INTEGER NOT NULL,
CONSTRAINT "pk_releases" PRIMARY KEY ( "release_id" )
I changed SQL and… Yes! I got it! I run the application and all screens seem to be working. Then I tried to add new Project and… Yes, I got an error (I was not surprised in fact). FireBird does not support autoincremental columns. There is a workaround using Triggers and Generators. The main idea is to create generator and invoke it before insertion to increment primary key. Something like that:
CREATE GENERATOR "project_id_gen";
CREATE TRIGGER SET_ID FOR "projects";
"projects"."project_id" = GEN_ID ("project_id_gen", 1);
As I understand, this had to work properly. But it wasn’t.
I spent 4 hours, downloaded 6 distributives, several times queried Google and almost resolve all problems (the keyword is almost). Well, maybe I am not DBA guru, but have a good experience with several major databases and never encountered such difficulties with them. FireBirds behavior is illogical for me in some cases, but I am going to complete migration today. No, I am not a stubborn donkey, just because of the embedding. This way is agile and should be simple, but it is hard. That’s sad.