Monday, September 19, 2011

Deploying Buildbot on Windows Server 2003

Recently we started to use Buildbot to improve our development process. Installation didn't take too much time (even on Windows), but then I was a bit confused how to run buidbot master as a Windows service. Buildbot itself contains buildbot_service.py, but I found it much easier to use srvany.exe from Windows Server 2003 Resource Kit Tools.

So, if you don't have Windows Server 2003 Resource Kit Tools installed, download and install them (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17657).

Then I've created start.bat file in the directory where my buildbot project is located and put the following line there:

"c:\Program Files (x86)\Python27\Scripts\buildbot.bat" start master

master here is the name of sub-directory inside buildbot project directory where buildbot master files are.

You could try to run you start.bat to make sure buildbot is working fine.

Then using instsrv.exe from the same Windows Server 2003 Resource Kit Tools package I've created new service:

"c:\Program Files (x86)\Windows Resource Kits\Tools\instsrv.exe" Buildbot "c:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe"

Last thing a had to do was to specify application which srvany.exe has to run. This can be done using regedit:

  1. Open HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Buildbot

  2. Add new key "Parameters"

  3. Inside the "Parameters" add new string value "Application"

  4. Put "c:\path\to\your\buildbot\project\start.bat" as a value

  5. Again inside the "Parameters" add new string value "AppParameters"

  6. Put "/D c:\path\to\your\buildbot\project" as a value. This is important because we have to run start.bat being in the project directory.



Now we can start Buildbot service :)

Friday, August 19, 2011

Command line utility for SQL CE (Microsoft SQL Server Compact)

I'm new to development with Visual Studio, but I was very surprised when I haven't found any command line tool to run SQL queries against Microsoft SQL Server Compact (or simply SQL CE). I wanted to do this in order to get rid of binary .sdf files in my Visual Studio project. These files can be easily edited in Visual Studio, but because they are binary you can't track changes and moreover every time you open it VS modifies something in the file :) So I decided to store SQL code creating database schema and importing initial data under source control and "compile" it into .sdf file every time during the build.

As I wrote above I haven't found any tool allowing you to execute SQL CE code from command line, but luckily it is very easy to create .sdf files and run SQL queries against them on C#. So wrote tiny C# utility creating .sdf file (if it does not exist), reading SQL code from a source file and running it. The only problem I faced was the limitation of SQL Server Compact due to which you can't run more then one query at once (you can't just execute "SELECT * FROM A; SELECT * FROM B", instead you have to split the string into two parts by semicolon and run "SELECT * FROM A" and "SELECT * FROM B" one after another). So I have to split queries from the source file manually and run the one by one. To avoid complicated parsing of SQL code and problems with escaped semicolons and semicolons inside quotes it assume that query separating semicolon is the last non-whitespace character in a line.

Here is the code I made:

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;
using System.IO;

namespace sqlcerun
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("SQL CE code executor");
if (args.Length != 2)
{
Console.WriteLine("2 parameters are required: 1 - database file name, 2 - source code file name.");
return;
}
string fileName = args[0];
string connectionString = "DataSource=\"" + fileName + "\"";

if (!File.Exists(fileName))
{
SqlCeEngine en = new SqlCeEngine(connectionString);
en.CreateDatabase();
en.Dispose();
}

SqlCeConnection conn = null;
try
{
conn = new SqlCeConnection(connectionString);
conn.Open();

StreamReader sr = new StreamReader(args[1]);
string query = "";
string line = sr.ReadLine();
while (line != null)
{
query += line;
if (line.TrimEnd().EndsWith(";"))
{
Console.WriteLine(query);
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteReader();
Console.WriteLine("OK");
query = "";
}
line = sr.ReadLine();
}
sr.Close();
}
catch (Exception e)
{
Console.Error.WriteLine(e.ToString());
Console.WriteLine("Failed!");
return;
}
finally
{
conn.Close();
}
Console.WriteLine("Done!");
}
}
}


The whole Visual Studio project and executable can be found at http://code.google.com/p/sqlceutils/.

To run .sdf generation during the build I've added the following lines into C# project file (.csproj):

 <Target Name="AfterBuild">

    <Delete Files="$(OutDir)\db.sdf" />

    <Exec Command="$(Utils)\sqlcerun.exe $(OutDir)\db.sdf Database\Schema.sql" />

    <Exec Command="$(Utils)\sqlcerun.exe $(OutDir)\db.sdf Database\Data.sql" />

</Target>



If you found any problems with the code please comment.