About Me

Tuesday, November 29, 2011

Batch file to delete files older than N days

Most of us remember times when we used MS-DOS commands, Norton Commander and staff like that.
Experience from that period of time is still usefull. From time to time i have to create bat files that does some boring things for me.
Its great to find something new in that area.
Today, thankfully to  guys from the stackoverflow, I found really easy way how to delete files older then N days.
I never know about forfiles command, its really awesome :

forfiles /P c:\DBbackup\CT\LogShipping\ /S /M *.* /D -1 /C "cmd /c del @path"

That simple command deletes (cmd /c del @path) all files (*.*) from a path (c:\DBbackup\CT\LogShipping\) that older than one day (/D -1)

In case if you want to remind a list of available DOS commands and find ones you never know, read a list of  "An A-Z Index of the Windows CMD command line"

P.S. In case if you get errors like "Invalid argument/option - '@path'" try to remove double quotes around a path if you have any.


Monday, November 28, 2011

How to use LINQ with DataTable

LINQ came into .NET developers life and at present moment I can't imagine my life without it. Actually, I can imagine, but it will be horrible.

Few days ago I had to modify some old project that has ADO.NET code in it.
Unfortunately we still have to work with all that datasets and datatables from time to time.
However, we can make life easier if start to use LINQ for operating with that. Its really easy.

First of all you need to add a reference to System.Data.DatasetExtensions library from a project where you going to use LINQ.
That library, as you may see from the name, contains some extension methods that allows to write LINQ queries directly on DataTables.

public DeviceFamilyInfo Get(int deviceFamilyId)
{
 DataSet rawFamilyInfo = DBMethods.GetDeviceFamily(deviceFamilyId);
 EnumerableRowCollection tblDevices = rawFamilyInfo.Tables[1].AsEnumerable();

 List>DeviceInfo> devices = GetDevicesList(tblDevices);

 return rawFamilyInfo.Tables[0].AsEnumerable()
  .Select(f =< 
   new DeviceFamilyInfo(devices)
    {
     Id = (int) f["Id"], 
     FamilyName = (string) f["Name"]
    }).First();
}

As you may see, the secret in converting datatable into IEnumerable by calling of AsEnumerable() method from the referenced library.
After that conversion, you can do with your data whatever you want. In my case, i just wrote a simple mapper that converts a DataTable into  instance of DeviceFamilyInfo class

Convert datatable into entity with BLToolkit

BLToolkit is a very good library that can make life easier when working with ADO.NET.
I used it for one project as a mapper that converts a data from a database into objects.

Normally, you have to pass a procedure name to the method of the BLToolkit library with params, specify what type you need to return and that's all.
However, few days ago, i needed more complicated thing.
Instead of making BLToolkit to do an SQL request, i did it by myself and get the DataTable.
It was needed to get some specific data from a DataTable that can't be converted into the existing type.
After that I expected that I can convert the result DataTable into list of Entities

Fortunately BLTollkit is able not only to make a conversion of  SQL requests on the fly, but has methods that allows to pass a DataTable into it, specify a desired type and get a result collection.

public IList<IScoutProfileInfo> SearchScouts(string toSearch, out int totalItems)
{
 totalItems = 0;
 using (DbManager db = new DbManager())
 {
  DataTable dataTable = db.SetSpCommand("usp_ScoutProfile_Search", toSearch).ExecuteDataTable();
  var enumerableRowCollection = dataTable.AsEnumerable();

  if (enumerableRowCollection.Any())
  {
   totalItems = (int) enumerableRowCollection.First()["TotalItems"];
  }

  MappingSchema schema = new MappingSchema();
  return schema.MapDataTableToList<ScoutProfileInfo>(dataTable).OfType<IScoutProfileInfo<().ToList();
 }
}

As you may see, the MappingSchema.MapDataTableToList does the trick.

Wednesday, October 12, 2011

How to read a content of the text file in C#

While reading the book of Andrew Troelsen "C# 2010" I was very surprised when found really easy way how to read the content of the file.
What I always used to do when facing with the issue to read the content of the file is to use a filestream, read data to the bytes array and then convert it into text:
                
private static string ReadFile()
{
    FileInfo fileToRead = new FileInfo("SomeTextFile.txt");

    using (FileStream stream = fileToRead.OpenRead())
    {
        byte[] content = new byte[stream.Length];
        stream.Read(content, 0, content.Length);
        return Encoding.ASCII.GetString(content);
    }
}

private static string ReadFile2()
{
    FileInfo fileToRead = new FileInfo("SomeTextFile.txt");

    using (StreamReader stream = fileToRead.OpenText())
    {
        return stream.ReadToEnd();
    }
}
As you may see, the second method is much shorter then the first one. However, the code may be even more short:
                
private static string ReadFile3()
{
    return System.IO.File.ReadAllText("SomeTextFile.txt");
}
Look at the System.IO.File class! How many wonderful things it has inside that can make your code shorter and life easier!
 Below is few methods that will be very useful:

  • File.ReadAllLines("SomeTextFile.txt") - Opens the file read all lines and return you an array of lines instead of just a string
  • File.WriteAllLines("SomeTextFile.txt", new [] {"Line1", "Line2"}) - Opens a file and saves array of lines into it
  • File.WriteAllText("SomeTextFile.txt", "Line1\r\nLine2") - Opens a file and  writes a string into it.
There are much more.

The main benefit i see is that you should not care any more about closing the file after reading, handle streams and so on. Really, methods for lazy people! 
However, I still think its useful because can save your time for more important and interesting things!

Friday, September 23, 2011

Could not load file or assembly 'Skybound.Gecko, Version=1.9.1.0, Culture=neutral...

Today I was faced with the trouble how to make the Geckofx component.
They asked me to launch the project and see if its working on my side.
After i launched the code on my computer, I got following exception:


System.BadImageFormatException: Could not load file or assembly 'Skybound.Gecko, Version=1.9.1.0, Culture=neutral, PublicKeyToken=3209ac31600d1857' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'Skybound.Gecko, Version=1.9.1.0, Culture=neutral, PublicKeyToken=3209ac31600d1857'
   at Zniper.Form1..ctor(ArrayList& arrayListImgHref, String xml, String webSiteURL, Dictionary`2 dic, String passedPath, ArrayList arrayOfWebSites, String browserPath, String outputPath)
   at Zniper.Code.MADCrawler.Crawl(ArrayList& arrayListImgHref, String xml, String webSiteURL, Dictionary`2 dic, String pathBaseLocation, ArrayList arrayOfWebSites, String browserPath, String outputPath) in C:\Work\Comscore\Src\Accurev\AMXM_INT\AdMetrix\src\Zniper\Code\MADCrawler.cs:line 44


=== Pre-bind state information ===
LOG: User = ....
LOG: DisplayName = Skybound.Gecko, Version=1.9.1.0, Culture=neutral, PublicKeyToken=3209ac31600d1857
 (Fully-specified)
LOG: Appbase = file:///C:/Work/Comscore/Src/Accurev/AMXM_INT/AdMetrix/src/Zniper/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : Zniper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Work\Comscore\Src\Accurev\AMXM_INT\AdMetrix\src\Zniper\bin\Debug\Zniper.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Skybound.Gecko, Version=1.9.1.0, Culture=neutral, PublicKeyToken=3209ac31600d1857
LOG: Attempting download of new URL file:///C:/Work/Comscore/Src/Accurev/AMXM_INT/AdMetrix/src/Zniper/bin/Debug/Skybound.Gecko.DLL.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.


My configuration is Windows Vista 64bit and that's was the reason why it was not working.
The project was compiled with "Any CPU" value selected under "Platform target" property:


The solution was to change the Platform target to "x86".
After that the component started working as it should.

I hate such kind of troubles when you hitting the wall without no result. So, I hope that this post will help.

Monday, September 19, 2011

Good unit tests

This article is a short description of the way how to create good unit tests.
I want to recomend the book "The Art Of Unit Testing" to every one who is facing with requirements to cover its code with unit tests. Its really great book that contains enough descriptions and examples (in C#) to write the correct tests.
What's the "correct" tests are? Related to the book, "correct" tests should follow the following requirements:
  • It’s an automated piece of code that invokes a different method and
    then checks some assumptions on the logical behavior of that
    method or class.

    Correct unit test should contain 3 small piece of code - Arrange-Action-Assert (AAA):
    [Test]
    public void SetCurrentSpeed_NewSpeedOfThePlaneIsBiggerThenMinimumTakeOffSpeed_PlaneCanTakeOff()
      {
       ///Arrange - prepare object that is going to be tested
       Plane plane = PlanesFactory.CreatePlane(Planes.Boeing747_400);
       int takeOffSpeed = 160;
    
       ///Action - execute method that's going to be tested
       plane.SetCurrentSpeed(takeOffSpeed);
    
       ///Assert - test the state of the object
       Assert.IsTrue(plane.CanTakeOff);
    
      }
  • It’s written using a unit-testing framework.
    Normally you can use NUnit framework for it. Most of companies I worked for used NUnit. But, there are other you can also use. The principles are the same everywhere.
  • It can be written easily.
    As you may see in example above, its not need to create big amount of lines of code. The code should contain minimum lines of code. In my experience, most of unit test code is taking Arrange part. Its taking a lot of lines to initialize all objects and prepare them for the execution.
    Using Moq library can significant reduce the number of lines you have to type to create stubs of the components you are going to use in the test.
    For instance, in the example below we are going to test, is factory creates correct plane:
    [Test]
      public void SetCurrentSpeed_NewSpeedOfThePlaneIsBiggerThenMinimumTakeOffSpeed_PlaneCanTakeOff()
      {
       ///Arrange - prepare object that is going to be tested
       Mock<iwings> moqWings = new Mock<iwings>();
       moqWings.Setup(f => f.WingSize).Returns(100);
    
       ///Our factory will create plane according to the size of its wings.
       /// The take off speed depends of the size of the wing
       Plane plane = PlanesFactory.CreatePlane(moqWings.Object);
       int takeOffSpeed = 160;
    
       ///Action - execute method that's going to be tested
       plane.SetCurrentSpeed(takeOffSpeed);
    
       ///Assert - test the state of the object
       Assert.IsTrue(plane.CanTakeOff);
    
      }
    
    As you may see from the example, the PlanesFactory takes an object that describes wings of the plane. Without using Moq, you would need to create test class that implements IWing interface, create instance, set the size of the wing to 100 and only after that pass it to the the PlanesFactory. Moq is making your life easier, the code less and much more easier to understand - it creates the instance of IFly interface on the fly for you.
  • It runs quickly.
    This is obvious, as more simple your test code, as more fast it working
  • It can be executed repeatedly by anyone on the development team.
    One of the purpose of writing unit tests is to make the life of your coworkers easier. When the guy from your team want to change your code or a code in a functionality that relates to the one you created, he need to be sure, that he did not break something.
    The guy is changing the code, then running all existing unit tests and saying "Woohoo! I did not break anything!". As more the code of your applicaiton is covered with the unit tests, as more free can feel the developer while adding a modifications to the code.
Things above are principles of writing unit tests.
Below, I going to specify few  important recommendations about the structure of the unit test.
They were also taken from the book with my short explanation.


  • It’s common practice to have one test class per tested class, one test
    project per tested project, and at least one test method per tested method.
    This advice related to the structure of your code. Everything is obvious here. To make the code clear and easy to read and modify, create a separate file for each testing class.
    In my opinion, sometimes, when you are writing a test to some manager class that contains a lot of methods independent from each other, its better to have one class for each testing method. In this case, its better to create a folder with the name of the manager class and put there all methods testing classes:
  • Name your tests clearly using the following model: [MethodUnderTest]_[Scenario]_[ExpectedBehavior].
    As you may see in example above, my test class is following to the requirement and has name "SetCurrentSpeed_NewSpeedOfThePlaneIsBiggerThenMinimumTakeOffSpeed_PlaneCanTakeOff".
    The reason of naming the method in this way is that its much easier to understand which tests did not pass, what functionality they do and where are they are locating.
    You may also be less strict in using the rule. The main idea of naming the test method is that  its name should follow if/then manner : "If_I_Put_New_Speed_Of_Plane_To_The_Value_That_Is_Bigger_Then_A_TakeOff_Speed_Then_CanTakeOff_property_should_be_set". This name can be also quite informative.
  • Use the [SetUp] and [TearDown] attributes to reuse code in your tests, such as code for creating and initializing objects all your tests use.
    If your test requires initialization of the DB or some complex object like COM, this staff should be placed to the [SetUp] method. The reason is simple - to keep the testing code as much simpler as possible.
    If you have few classes that doing the same in [SetUp] and [TearDown], create an abstract test class and move all logic in there. Then create your tests as inheritors of that base class.
    Don't confuse two attributes [SetUp] and [SetUpFixture]. [SetUp] is calling before EACH TEST in a test class and [SetUpFixture] is calling before FIRST TEST in a class will be called.
  • Don’t use [SetUp] and [TearDown] to initialize or destroy objects that
    aren’t shared throughout the test class in all the tests, because it makes
    the tests less understandable. Someone reading your code won’t
    know which tests use the logic inside the setup method and which
    don’t.

    Let's take a look on the example below:
    [TestFixture]
     public class PlaneTests
     {
      private iengine[] _enginesForTestCollection;
    
      [SetUp]
      public void SetUp()
      {
       Mock<iengine>() engine1 = new Mock<iengine>();
       engine1.Setup(f => f.Power).Returns(50);
    
       Mock<iengine>() engine2 = new Mock<iengine>();
       engine2.Setup(f => f.Power).Returns(99);
       
       _enginesForTestCollection = new IEngine[] {engine1.Object, engine2.Object};
      }
    
      [Test]
      public void SetCurrentSpeed_NewSpeedOfThePlaneIsBiggerThenMinimumTakeOffSpeed_PlaneCanTakeOff()
      {
       ///Arrange - prepare object that is going to be tested
       ...
       
       Plane plane = PlanesFactory.CreatePlane(moqWings.Object, _enginesForTestCollection[0]);
       int takeOffSpeed = 160;
    
       ///Action - execute method that's going to be tested
       plane.SetCurrentSpeed(takeOffSpeed);
    
       ///Assert - test the state of the object
       Assert.IsTrue(plane.CanTakeOff);
    
      }
    
      [Test]
      public void SetCurrentSpeed_NewSpeedOfThePlaneIsLessThenMinimumTakeOffSpeed_PlaneCanNotTakeOff()
      {
       ///Arrange - prepare object that is going to be tested
       ...
       Plane plane = PlanesFactory.CreatePlane(moqWings.Object, _enginesForTestCollection[1]);
       int takeOffSpeed = 120;
    
       ///Action - execute method that's going to be tested
       plane.SetCurrentSpeed(takeOffSpeed);
    
       ///Assert - test the state of the object
       Assert.IsFalse(plane.CanTakeOff);
    
      }
    
     }
    
    As you may see, I doing the thing that should not - initializing engines in the setup variable.
    I'm expecting, that my _enginesForTestCollection will have an engine for each test.
    Then, when I'm writing test, I'll use an appropriate engine.
    First problem with this approach is that when new guy, or even you, will read this code in the future, he will have to find, where is _enginesForTestCollection[1] is initializing and check the initial values of it. When your test class contains dozen of tests, it may be difficult.
    The second problem may come when you will want to write new test. In this case you will have a temptation to use one of existing engines. Then, if requirements will change and you will need to change the parameters of the engine, this change will affect two or more tests, depends of how many times you used the same engine. As result, some tests may not working or, what's more dangerous, some tests will remain success but they will not test things that were expected at the beginning.
    That's why its better to create each engine in its own test method and don't create unique moq for all tests.

Thursday, September 8, 2011

Converting comma separated string into table

From time to time I'm facing with trouble in SQL how to convert  comma separated string into table.
For instance, you may have set of comma delimited parameters that you want to use in select:
"'US','UA','RU','DE'"
You want to use this set of country codes to select clients.
Without converting the comma separated string into table you will have to use dynamic SQL:
  exec 'Select * from clients where Country in (' + @countryList + ')'
This solution is not very good because if you have request bigger then one line, its will be difficult to trace it in case of errors.

There is a small function that converts comma separated string into table:
CREATE FUNCTION [dbo].[fn_CommaSeparatedStringToTable] 
( 
    @CommaSeparatedValues     VARCHAR(MAX),
      @IncludeEmptyStrings    CHAR(1)
) 
RETURNS @Item TABLE  
( 
      RowId int IDENTITY(1, 1) NOT NULL,  
    Value VARCHAR(200) 
)
AS
BEGIN
      DECLARE @IndefOfComma int,@Value VARCHAR(200),@StartPos bigint,@EndPos bigint,@LengthOfString int, @ReachedEnd Char(1)
 

      SET @StartPos=1
      SET @EndPos=0
      SET @LengthOfString=LEN(@CommaSeparatedValues)
      SET @ReachedEnd='N'
 

      WHILE @ReachedEnd<>'Y'
            BEGIN
                  SET @EndPos=CHARINDEX(',',@CommaSeparatedValues,@StartPos) 
                  IF @EndPos>0
                  BEGIN
                      SET @Value = SUBSTRING(@CommaSeparatedValues, @StartPos,@EndPos-@StartPos)  
                      SET @StartPos=@EndPos+1       
                  END
                  ELSE
                  BEGIN
                     SEt @ReachedEnd='Y'
                     SET @Value = SUBSTRING(@CommaSeparatedValues, @StartPos,@LengthOfString-(@StartPos-1))
                  END
                  IF(@Value<>'' OR @IncludeEmptyStrings='Y')
                  INSERT INTO @Item(Value) VALUES(@Value)
      END
      RETURN
END

After using this function, you can use reqular sql queries:
    Select 
        * 
    from 
        clients c
        inner join dbo.fn_CommaSeparatedStringToTable(@countryList, 'N') t on t.Value = c.Country 

As you may see, this way is much more useful.