If you’re a windows dev and use github for source control, you should set the autocrlf setting in git like described in this github article. I’m also setting the safecrlf setting, and hopefully those funky end of line characters I got going on will wiggle there way out. I wasn’t aware of this but probably should have thought of it, but git will add unix end of line characters to your files when you check them into a git repository. Just make sure everyone on the project has the autcrlf set to true, and everything will be fine. Use git bash and run these commands:
git config --global core.autocrlf false
git config --global core.safecrlf false
It’s easy to miss. I ended up adding those unix eof’s into the solution file and others for FluentMigrator. Justin Etheredge pointed out the problem and the fix. Hopefully it will all be cleared up soon. It doesn’t seem to prevent VS from opening and compiling, and even the build server continues to run.
UPDATE: I realized I was giving bad advice. You should set autocrlf to false not true.
-j
blog comments powered by
Here’s a little secret. Slow tests really annoy me. You know, when you run a single test that takes 10+ seconds or a small set of tests takes 3 minutes. One of the many reasons I really like unit testing is getting a measure on my progress quickly. That enables continuing to make quick progress or quickly fixing the problem. That falls apart when tests run slow. For example, my tests on one particular project where one test takes 10 seconds. Granted its an integration test and all subsequent tests run much faster. Still I would like to improve that.
I know exactly what the problem is; I created the problem. On purpose. It’s resetting my database schema back to the version I want using FluentMigrator by stepping down to version zero and then migrating back up. I want a clean database when I run integration tests. The thing is there is almost a solution for the problem: FluentMigrator.
My database is sql server; but if I was running sqlite in memory, the tests should be really fast. This leads to the debate inside my head. You see, sqlite doesn’t support foreign keys which my sql schema uses. On top of that, It’s throwing an error in the sqlite generator when you try to create a foreign key. But should it? On one hand, it’s not supported in sqlite so it kind of makes sense. It would be nice to gracefully handle it though for situations where you might want some flexibility with your back end. Like my integration testing scenario. Before I ask, I know it’s thin ice to perform integration testing against a different db than your target product db. Now, what do you think? I’m thinking towards allowing both but defaulting to throwing an error with FK’s in sqlite.
Maybe something like this to avoid the FK error with sqlite?
1: Create.ForeignKey("FK_Approvals_UserId").FromTable("Approvals").ForeignColumn("UserId").ToTable("Users").PrimaryColumn("Id").SoftFail();
-j
blog comments powered by
Well alright, I’m finding more ways in which SQL Server schema differs from SQLite. I’m not really surprised; just learning how much. For instance, SQLite doesn’t support Foreign Keys, which is why the SQliteGenerator in FM throws a NotImplementedException when it tries to generate sql for Foreign Keys. Also, you can’t do a simple rename of a column in SQLite. You have to rename the table, create a new table with the new column name, copy the data from the old into the new, and then drop the old table.
So a quick web search found a couple articles on differences between sql server and sqlite: uno, dos. Chances are there will be more issues to address.
I’m not going to worry about it to much right now since I don’t need it. I just need to change the sample migration so the tests pass withthe SQLite generator. If we ever work on supporting mysql, there will be similar problems. Ultimately, you have to know at least a little about the database you are creating schema for.
-j
blog comments powered by
As I previously mentioned, I’m starting to work on FluentMigrator which is a database schema generator and versioning library. I’m doing this for my own need, but am trying to continue to respect the potential for others. I’ve found some syntax errors in generated sql statements, and one in particular causing a test to fail. It’s a t-sql versus SqLite problem. Ideally, one could define a migration that would be valid for both SqlServer and SqLite as long as the generator builds the proper sql statements. It’s not as easy as you (or at least me) would think at first. Consider this migration code:
1: public override void Up()
2: {
3: Create.Table("Users")
4: .WithColumn("UserId").AsInt32().Identity().PrimaryKey()
5: .WithColumn("UserName").AsString(32).NotNullable()
6: .WithColumn("Password").AsString(32).NotNullable();
7: }
8:
9: public override void Down()
10: {
11: Delete.Table("Users");
12: }
It’s a really simple example to be sure, but look at the difference in the ideal sql statements:
[SQL Server]
1: CREATE TABLE Users
2: (
3: UserId int IDENTITY(1,1) PRIMARY KEY,
4: UserName nvarchar(32) NOT NULL,
5: Password nvarchar(32) NOT NULL
6: )
[SQLite]
1: CREATE TABLE Users
2: (
3: UserId integer PRIMARY KEY AUTOINCREMENT,
4: UserName varchar(32) NOT NULL,
5: Password varchar(32) NOT NULL
6: )
But those aren’t the sql statements it currently generates.
Problem:
For SQLite to have the same behavior as SQL Server, you need to define the column as “PRIMARY KEY AUTOINCREMENT” instead of “IDENTITY(1,1) PRIMARY KEY”. But the migration generator is just trying to translate the syntax .Identity() into the database specific keyword(s). Both SQLite and SQL Server have an IDENTITY keyword but it means something different in SQLite. It only means that the column is the identity for the row but doesn’t auto-populate it as it would in SQL Server.
Solution:
I’m working on it. Obviously, we want this to be handled. I just don’t want to spend a lot of time making the SQLite generator too smart. Especially since it’s not something I need. I’m sure the answer is out there. If you happen to know, please contact me.
-j
blog comments powered by
Well more like it was peacefully sleeping until I came along and started pounding it on the chest. Now it’s hunched over and coughing while muttering something about me under it’s breath. But anyway..
I wanted to build schema management into one of the projects I’m working on, and found FluentMigrator partly by reference and partly by accident. The point is to build up and change database schema in code with a fluent syntax. Perfect, only I wanted my app to automatically update if it has a newer version than the database. So I went about adding that to the code, and all of a sudden this fork appeared for me in github while angelic voices sung magically in the background. Right before I pulled the sword from the stone! Seriously though, I’m working on adding functionality to an excellent project started by Justin Etheredge and Nate Kohari. You can find my github fork here.
My focus will be on my own needs, but feel free to make requests along the way. Even better, feel free to help! Hopefully, Justin will accept my changes into the master tree and maybe we can put together a release.
To give you a bit of a preview, here is a sample migration to create a couple tables and foreign keys:
1: [Migration(1)]
2: public class TestMigration : Migration
3: {
4: public override void Up()
5: {
6: Create.Table("Users")
7: .WithColumn("UserId").AsInt32().Identity().PrimaryKey()
8: .WithColumn("GroupId").AsInt32().NotNullable()
9: .WithColumn("UserName").AsString(32).NotNullable()
10: .WithColumn("Password").AsString(32).NotNullable();
11:
12: Create.Table("Groups")
13: .WithColumn("GroupId").AsInt32().Identity().PrimaryKey()
14: .WithColumn("Name").AsString(32).NotNullable();
15:
16: Create.Column("Foo").OnTable("Users").AsInt16().Indexed();
17:
18: Create.ForeignKey("FK_Foo").FromTable("Users").ForeignColumn("GroupId").ToTable("Groups").PrimaryColumn("GroupId");
19:
20: Create.Table("Foo")
21: .WithColumn("Fizz").AsString(32);
22:
23: Rename.Table("Foo").To("Bar");
24: Rename.Column("Fizz").OnTable("Bar").To("Buzz");
25:
26: Insert.IntoTable("Users").Row(new { UserName = "Data1", Password = "Data2" });
27: }
28:
29: public override void Down()
30: {
31: Delete.ForeignKey("FK_Foo").OnTable("Users");
32:
33: Delete.Table("Bar");
34: Delete.Column("Foo").FromTable("Users");
35: Delete.Table("Users");
36: Delete.Table("Groups");
37: }
38: }
I’m actually not so much of a fan of the class attribute to specify the version. I’d prefer to have a convention using the class name, and a convention to specify where the migration classes live within an assembly. We’ll work with this for now and see what can be done later. So go check it out.
-j
blog comments powered by
Well I blame Antonio Cangiano for this.. last thing I needed is another distraction, but he just hit my Achilles and gave me a new feed for my RSS reader. I like Math but haven’t done that much since college. I also like what I do which is largely write code. This uses both and is a tempting distraction. Drats!
Euler (pronounced Oy-ler) was an 18th century mathematician and physicist famous for his work with calculus and graph theory. His work was the basis of my first college calculus class. We studied his work on decision making and routes (graph theory) and led into Riemann sums then integral calculus. Euler did a lot with applied math, which ended up being my focus in earning a Bachelor of Science in Mathematics.
Project Euler is a web site with math and programming challenges. If you like either, you’ll probably like the site. I may have to intentionally avoid it due to my obsessive drive to solve problems. (I’m sure I’ll do at least a few of them at some point)
blog comments powered by
I’m posting this mostly for my own reference, but also to promote good work by smart people.
blog comments powered by
James Gregory and friends have brought FluentNHibernate up to 1.0 RC with RTM expected soon. If you haven’t heard about FluentNH or NHibernate, please go learn about it. I wouldn’t hesitate to use it now, and started playing with it from source a few weeks ago. I’m using it on one particular project along with FluentMigrator (more on that coming soon).
blog comments powered by
For all that I do to push for better software design and testing, my job is to build the software my client wants in the environment they choose. I’m pretty fortunate and have had good clients, but everything isn’t always done according to me. That’s life. So I’ve never built an NHibernate based app. Not truly anyway. I have built stuff on Castle ActiveRecord (built on nhib), which was great! Now I’ve got a project I work at once in a while which I have complete control over. I’ve rewritten it a few times, and this last time chose to use ASP.Net MVC, NHibernate, FluentNhibernate, and FluentMigrator. I’ll be using either nUnit or xUnit for testing, and probably RhinoMocks for mocking. Oh yeah, any IoC will use Castle Windsor.
This is a little bit of new ground for me so I’m treading slowly. It’s easy to forget to separate integration tests from unit tests especially since my current client project doesn’t. I find myself struggling to choose how to do certain things like initializing the database schema which is done with FluentMigrator. I want a nice migration experience, but I’m not sure if I want it to automatically update schema without any user action. You can get into trouble with that if there is a problem with the migration; it can cause an infinite loop of attempting to update the schema.
Also, I nearly fell into the trap of requiring updated schema for the unit test. Unit tests shouldn’t need schema because they should not be testing database integration. Integration tests will need that, and will test that the data model behave properly when using the database.
What is great about this is that it forces me to improve, which is a big part of the reason why I’ve rewritten this a few times. This is also my first time working with ASP.Net MVC (have used and love Castle Monorail) but it’s just MVC again with whatever dialect MS put on it. The team behind it are excellent so I’m expecting good stuff. I’m open to input, especially with testing UI. I haven’t done much of that and plan to with this project. Let me know any recommendations.
I’m not sure what will happen with this little stealth project and don’t want to tip my hand yet. ..but here is a little, carefully redacted teaser:
1: Delete.ForeignKey("FK_TimeEntries_UserId");
2: Delete.ForeignKey("FK_Companies_UserId");
3: Delete.ForeignKey("FK_Approvals_UserId");
4:
5: Delete.Table("Companies");
6: Delete.Table("TimeEntries");
7: Delete.Table("Users");
-j
blog comments powered by
Having recently been through another, I thought it might be helpful to post a few tips on surviving a death march on a software project. If you haven’t heard the term before, it’s basically an insane working pace trying to make impossible deadlines. There are often various humorous aspects as well like changing requirements.
It’s best to avoid the Death March. Good project planning and processes will normally help you prevent that, but maybe not always. Here’s some ideas on dealing with it when you have to.
Tip 1: Whistle while you work
I don’t mean literally, but something to take the edge off during the day. Joke around with co-workers, listen to music, take a 5-15 minute break every 90 minutes. Continually stressing yourself out will drain your moral and productivity.
Tip 2: Check your identity
Do you identify yourself by your job? That’s a problem both in a death march and even when your not. I can be a bit of a workaholic by some standards, but I know it’s not all I am. If you feel like that’s basically who you are and the project/job isn’t going well, you could be beating yourself up emotionally.
Tip 3: Easy wins
I find it helpful to complete some easy wins from time to time during each week. Stuff like short, simple features or bug fixes. When things are going poorly, it helps to have some feeling of progress or the situation may feel worse than it really is.
Tip 4: Now for something completely different
If you are driven to do something, like me, then do something different. Don’t get burned out; write some code for a personal idea or utility or an open source project. Read. I like reading so this is an easy call for me although I don’t read as much as I would like. Don’t read work related stuff though as that uses the brain in the same way as your work.
Tip 5: Exercise
Exercise is a great way to release stress and revive yourself mentally and emotionally. It has to be something strenuous though. If you’re not trying, it’s not helping. I’d also recommend not over doing it though. Since you are already in a stressed condition, you are likely to be more prone to injury. Limiting the time is my favorite way to prevent over-exercising.
Tip 5: Looking forward
Plan something for after the project is over. This forces you to think of something different for a while and something to look forward to. Hope is a powerful thing and lack of it just makes any current stress seem much worse.
Tip 6: It’s all over but the crying
Knowing when it’s just not going to work can be a little hard, and then even harder when you know but management doesn’t think so. Express your thoughts to the right people but don’t whine. Then put in an healthy effort even if your warning isn’t heeded. At the end of it, you will know you made your case and gave it your best.
Wrap Up
Feel free to add your own tips in the comments. Everyone has their own experience, and will find some things work better for them than others.
-j
blog comments powered by