Caveman's Blog

My commitment to learning.

Archive for the ‘General Programming’ Category

Sql Merge/Consolidator

Posted by cavemansblog on March 11, 2009

In this article I will showcase a cool application that would merge/consolidate all the sql files in a folder into a single SQL file that is executable. This tool has been very useful to me to roll out releases into stage and production environments.

This makes life simpler in the sense that you have to run only one sql file as opposed to running multiple SQL script files for every database release.

The two main steps to merge the SQL files are as follows:

1. Use the GetFiles method of the DirectoryInfo class to fetch all the names of SQL files of the folder in where this application executed.

string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] sqlfiles = dir.GetFiles("*.sql");

2. Loop through the file list, read the content of each file and write it into the consolidation file.

foreach (FileInfo f in sqlfiles)
{
  fileContent = ReadFromFile(f.Name);
  temp_arraylist.Add(fileContent);
}

WriteToFile(temp_arraylist, "AllInOne.sql");

Tips for a successful database release:

1. Make sure that the SQL scripts always successfully pass through the development, QA and stage environments before reaching the production/live environment.

2. Always take a backup of the database before executing a SQL script in production/Stage environment. This might add some overhead, but trust me this habit will help you in the long run. A rollback on an serious error while script execution can be handled efficiently with a backup copy.

3. Make sure that every Sql file has a “GO” at the end, so that the variables in one scripts do not get messed up.

4. Prefix the file names with numbers to define the order of execution. I usually name my files as follows:

  • Script_001_firstFile.sql
  • Script_002_secondFile.sql
  • Script_003_anotherfile.sql …

5. It is good practice to sandwich your code in between a Transaction and Rollback/Commit block. Caution has to be exercised while working with huge amounts of data; you don’t want to follow this practice because, the transaction log could grow and runs out of space causing a crashing of your SQL Server.

Following is the C# code for the Merge tool:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Collections;

namespace SQLMerge
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList al = new ArrayList();

            FileInfo[] sqlfiles = null;
            sqlfiles = GetFileNames();
            string fileContent = string.Empty;
            foreach (FileInfo f in sqlfiles)
            {
                Console.WriteLine(f.Name);
                fileContent = ReadFromFile(f.Name);
                al.Add(fileContent);
            }

            WriteToFile(al, "AllInOne.sql");

            Console.Read();
        }

        static string ReadFromFile(string filename)
        {
            string s = String.Empty;

            try
            {
                // Specify file, instructions, and privelegdes
                FileStream file = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read);

                // Create a new stream to read from a file
                StreamReader sr = new StreamReader(file);

                // Read contents of file into a string
                s = "  print 'Begin Executing: " + filename + "' ";
                s = s + sr.ReadToEnd();
                s = s + "  print 'Done Executing: " + filename + "' ";

                // Close StreamReader
                sr.Close();

                // Close file
                file.Close();
            }
            catch (Exception ex)
            {
                Console.Write("Reading of file: " + filename + " has failed because: " + ex.ToString());
                MessageBox.Show("Reading of file: " + filename + " has failed because: " + ex.ToString());
            }

            return s;
        }

        static void WriteToFile(ArrayList al, string filename)
        {
            try
            {
                // *** Write to file ***

                // Specify file, instructions, and privelegdes
                FileStream file = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write);

                // Create a new stream to write to the file
                StreamWriter sw = new StreamWriter(file);

                foreach (string s in al)
                {
                    // Write a string to the file
                    sw.WriteLine(s);
                    sw.WriteLine("\n GO \n\n");
                }

                // Close StreamWriter
                sw.Close();

                // Close file
                file.Close();
            }
            catch (Exception ex)
            {
                Console.Write("Writing to file: " + filename + " has failed because: " + ex.ToString());
                MessageBox.Show("Writing to file: " + filename + " has failed because: " + ex.ToString());
            }
        }

        static FileInfo[] GetFileNames()
        {
            string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            DirectoryInfo dir = new DirectoryInfo(path);
            FileInfo[] sqlfiles = dir.GetFiles("*.sql");
            Console.WriteLine("Total number of sql files to be merged: {0}", sqlfiles.Length);

            return sqlfiles;
        }
    }
}

PS: Dare to Dream and Strive to Achieve

Posted in General Programming, Sql Server, Sudheer Reddy Battula | Tagged: , , | Leave a Comment »

Installing Dotnet Windows Services (the easiest way).

Posted by cavemansblog on June 19, 2008

Introduction
I will demonstrate the easiest way of installing a windows service. Using the InstallUtil.exe has been my primary mechanism of installing a windows service until I came across Windows Services Can Install Themselves by W. Kevin Hazzard. That article has demonstrated a service can be installed/uninstalled/launched from the command line alone. I on the other hand have come up with a way to install/uninstall the windows service by double clicking the service executable.

Traditional command line approach: C:\> InstallUtil MyWinService.exe
Kevin Hazzard’s command line approach: C:\> MyWinSvcHost.exe -install
My approach: Just double click on the Service exe.

How the code works

The first double click on the service executable will install the service and the second double click on the service executable will uninstall the service.

When ever we run a windows service, the main method gets executed as this serves as the entrypoint for the service. The list of of existing windows services can be fetched using the GetServices method of the Service controller class. Loop through the array of services to determine if our service is already installed.

ServiceController[] services = ServiceController.GetServices();

foreach (ServiceController service in services)
{
if (service.ServiceName.Equals(SERVICE_NAME))
{
_IsInstalled = true;
}
}

If the service does not exist on the machine we will install it by executing the InstallMe method of the SelfInstaller class, followed by a messagebox notification of the same.

SelfInstaller.InstallMe();
MessageBox.Show("Successfully installed the " + SERVICE_NAME, "Status", MessageBoxButtons.OK, MessageBoxIcon.Information);

If the service does not exist on the machine we will uninstall it by executing the UninstallMe method of the SelfInstaller class, followed by a messagebox notification of the same.

SelfInstaller.UninstallMe();
MessageBox.Show("Successfully uninstalled the " + SERVICE_NAME, "Status", MessageBoxButtons.OK ,MessageBoxIcon.Information);

As Kevin said in his article this style of installing the service without using the InstallUtil.exe provides us with many options of installing and invoking the service. Happy coding my dear fellow s/w brothers. There might be a downside to this approach; what is someone double clicks on the exe in mission-critical environment [3] ? Situations like that can be prevented by prompting the user if he/she would really likes to Install/Uninstall the service. Another cool suggestion from PIEBALDconsult is to develop a windows form inside the service that would actually allow the user to install/uninstall and control the state of the windows service.

Update

Version 2.0: Code is located in CoolService_V2.zip

a) Added SMESSER’s [4] code to get rid the annoying alert box (Cannot start service from the command line or a debugger.) that appears after the service has been installated/uninstalled.

b) Added code to make this approch more secure (Thanks to PIEBALDconsult’s concern) by prompting the user, is he/she REALLY likes to install/uninstall the service.

c) Moved the WSInstaller class to a WSInstaller.cs for a cleaner code.

References:
1. MSDN
2. Windows Services Can Install Themselves by W. Kevin Hazzard
3. PIEBALDconsult (A fellow member at Code Project)
4. SMESSER (A fellow member at Code Project)

kick it on DotNetKicks.com

Posted in General Programming, IIS, Sudheer Reddy Battula | Tagged: , , , | 2 Comments »

Version Tolerant Serialization

Posted by cavemansblog on April 1, 2008

Recently we had a situation where the datatypes of a few properties in a extended commerce server 2007 class had to be changed. This class is serializable and a change to the datatypes would break compatibility with the data from the past. The data from the past has to be supported by the application for a period of about 3 months.

The challenge on hand is to make the changes to the class in such a way that changes would not make the application to break compatibility with the data form the past.

One solution that we have implemented was to change the type Property, add a new version of the private data member and retain the older data member. This gives us the flexibility of casting the old data into the new type and returning it via the property.

VTS

Version Tolerant Serialization (VTS) is a set of features introduced in .NET Framework 2.0 that makes it easier, over time, to modify serializable types. Specifically, the VTS features are enabled for classes to which the SerializableAttribute attribute has been applied. VTS makes it possible to add new fields to those classes without breaking compatibility with other versions of the type. [1]

The VTS features are enabled when using the BinaryFormatter. Additionally, all features except extraneous data tolerance are also enabled when using the SoapFormatter. For more information about using these classes for serialization, see Binary Serialization. [1]

The set of features includes the following [1]:

Tolerance of Extraneous or Unexpected Data

In the past, during deserialization, any extraneous or unexpected data caused exceptions to be thrown. With VTS, in the same situation, any extraneous or unexpected data is ignored instead of causing exceptions to be thrown. This enables applications that use newer versions of a type (that is, a version that includes more fields) to send information to applications that expect older versions of the same type.

Tolerance of Missing Data

Fields can be marked as optional by applying the OptionalFieldAttribute attribute to them. During deserialization, if the optional data is missing, the serialization engine ignores the absence and does not throw an exception. Thus, applications that expect older versions of a type can send data to applications that expect newer versions of the same type.

Serialization Callbacks

Serialization callbacks are a mechanism that provides hooks into the serialization/deserialization process at four points.

Using Callbacks

To use callbacks, apply the appropriate attribute to a method that accepts a StreamingContext parameter. Only one method per class can be marked with each of these attributes.

The VersionAdded Property

The OptionalFieldAttribute has the VersionAdded property. In version 2.0 of the .NET Framework, this is not used. However, it is important to set this property correctly to ensure that the type will be compatible with future serialization engines.

The property indicates which version of a type a given field has been added. It should be incremented by exactly one (starting at 2) every time the type is modified.


Best Practices
[1]

1. To ensure proper versioning behavior, follow these rules when modifying a type from version to version:

2. Never remove a serialized field.

3. Never apply the NonSerializedAttribute attribute to a field if the attribute was not applied to the field in the previous version.

4. Never change the name or the type of a serialized field.

5. When adding a new serialized field, apply the OptionalFieldAttribute attribute.

6. When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.

7. For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.

To ensure that a type will be compatible with future serialization engines, follow these guidelines:

1. Always set the VersionAdded property on the OptionalFieldAttribute attribute correctly.

2. Avoid branched versioning.

References:
1. MSDN Online

kick it on DotNetKicks.com

Posted in General Programming, Sudheer Reddy Battula | Tagged: | Leave a Comment »

Replace special characters in XML, using C#

Posted by cavemansblog on March 25, 2008

We can use the SecurityElement.Escape method to replace the invalid XML characters in a string with their valid XML equivalent [1]. The following table shows the invalid XML characters and their respective replacements.

invalid XML Character

Replaced With

“<”

“&lt;”

“>”

“&gt;”

“\”"

“&quot;”

“\’”

“&apos;”

“&”

“&amp;”


//Usage
srtXML = SecurityElement.Escape(strXML);

Namespace: System.Security
Assembly: mscorlib (in mscorlib.dll)

I have used the HttpUtility classes UrlEncode and UrlDecode methods to handle cross-site scripting attacks and this also helped me to get rid of the XmlException – “Data at the root level is invalid”.

Reference:
1. MSDN

Posted in General Programming, Sudheer Reddy Battula | Tagged: , | Leave a Comment »

C# Copy Constructor

Posted by cavemansblog on January 28, 2008

C# does not provide a copy constructor by default. We have to write an appropriate constructor method that will create a new object and to copy the values from an existing object. This implementation is nothing like the C++ copy constructor.

If we need a copy of an object we can use cloning techniques.

Observation:
This method has to be called explicitly.

Note: “A shallow copy creates a new instance of the same type as the originalobject, and then copies the non-static fields of the original object. If thefield is a value type, a bit-by-bit copy of the field is performed. If thefield is a reference type, the reference is copied but the referred objectis not; therefore, the reference in the original object and the reference inthe clone point to the same object. In contrast, a deep copy of an objectduplicates everything directly or indirectly referenced by the fields in theobject.”

References:
1. MSDN Online

Posted in General Programming, Sudheer Reddy Battula | Tagged: , , | Leave a Comment »