Monday, September 7, 2015

Disable ctrl + p keys to prevent

Disable ctrl + p keys to prevent

Reference: http://forums.asp.net/post/4012820.aspx

function disableCtrlKeyCombination(e)
{
        //list all CTRL + key combinations you want to disable
    var forbiddenkeys = new Array('a', 'n', 'c', 'x', 'v', 'j', 'p');
        var key;
        var isCtrl;
        if(window.event)
        {
                key = window.event.keyCode;     //IE
                if(window.event.ctrlKey)
                        isCtrl = true;
                else
                        isCtrl = false;
        }
        else
        {
                key = e.which;     //firefox
                if(e.ctrlKey)
                        isCtrl = true;
                else
                        isCtrl = false;
        }


        //if ctrl is pressed check if other key is in forbidenKeys array
        if(isCtrl)
        {
                for(i=0; i<forbiddenkeys.length; i++)
                {
                        //case-insensitive comparation
                    if (forbiddenkeys[i].toLowerCase() == String.fromCharCode(key).toLowerCase())
                        {
                                alert("Key combination CTRL + "
                                        +String.fromCharCode(key)
                                        +" has been disabled.");
                                return false;
                        }
                }
        }
        return true;
    }
    var oEventUtil = new Object();
    oEventUtil.AddEventHandler = function (oTarget, sEventType, fnHandler) {
        if (oTarget.addEventListener) {
            oTarget.addEventListener(sEventType, fnHandler, false);
        } else if (oTarget.attachEvent) {
            oTarget.attachEvent('on' + sEventType, fnHandler);
        } else {
            oTarget['on' + sEventType] = fnHandler;
        }
    }
    var oTB = function () {
        document.getElementById("TextBox1").focus();
    }
onkeypress="return disableCtrlKeyCombination(event);" onkeydown="return disableCtrlKeyCombination(event);" >

Sunday, September 6, 2015

Finding Missing Table Index - analysis

The below query identifies the missing index on table:

After the post production -  one can run below query to analyze what are the index can be built in order to improve application performance.



SELECT 
       [Impact] = (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans), 
       [Table] = [statement],
       [CreateIndexStatement] = 'CREATE NONCLUSTERED INDEX ix_'
              + sys.objects.name COLLATE DATABASE_DEFAULT
              + '_'
              + REPLACE(REPLACE(REPLACE(ISNULL(mid.equality_columns,'')+ISNULL(mid.inequality_columns,''), '[', ''), ']',''), ', ','_')
              + ' ON '
              + [statement]
              + ' ( ' + IsNull(mid.equality_columns, '')
              + CASE WHEN mid.inequality_columns IS NULL THEN '' ELSE
                     CASE WHEN mid.equality_columns IS NULL THEN '' ELSE ',' END
              + mid.inequality_columns END + ' ) '
              + CASE WHEN mid.included_columns IS NULL THEN '' ELSE 'INCLUDE (' + mid.included_columns + ')' END
              + ';',
       mid.equality_columns,
       mid.inequality_columns,
       mid.included_columns
FROM sys.dm_db_missing_index_group_stats AS migs
       INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
       INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
       INNER JOIN sys.objects WITH (nolock) ON mid.OBJECT_ID = sys.objects.OBJECT_ID
WHERE (migs.group_handle IN
              (SELECT TOP (500) group_handle
              FROM sys.dm_db_missing_index_group_stats WITH (nolock)
              ORDER BY (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) DESC)) 
       AND OBJECTPROPERTY(sys.objects.OBJECT_ID, 'isusertable') = 1
       AND mid.database_id = DB_ID()

ORDER BY [Impact] DESC , [CreateIndexStatement] DESC

Saturday, September 5, 2015

Splitting a Generic List into Multiple Chunks

Refer: http://www.chinhdo.com/20080515/chunking/

Splitting a Generic List into Multiple Chunks


public static List> BreakIntoChunks(List list, int chunkSize)
{
    if (chunkSize <= 0)
    {
        throw new ArgumentException("chunkSize must be greater than 0.");
    }

    List> retVal = new List>();

    while (list.Count > 0)
    {
        int count = list.Count > chunkSize ? chunkSize : list.Count;
        retVal.Add(list.GetRange(0, count));
        list.RemoveRange(0, count);
    }

    return retVal;
}

Thursday, January 15, 2015

All About TransactionScope

What a fantastic blog,

You can refer the complete blog, I have copied just for my information.

http://www.codeproject.com/Articles/690136/All-About-TransactionScope



I want to create a file/folder dynamically inside a transaction scope. If my transaction is rolled back then I want that created file/folder to be removed automatically, like a database row.
Implementation:
string newDirectory = @"D:\TestDirectory";
string connectionString = ConfigurationManager.ConnectionStrings["db"].ConnectionString;
using (var scope = new TransactionScope())
{
    using (var conn = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = "Insert into data(Code) values ('A001');";
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
        }
    }
    Directory.CreateDirectory(newDirectory);
    File.Create(@"D:\NewFile.txt").Dispose();
    scope.Dispose();
} 
TranactionScope is not limited for only databases. It will support other data sources like FileSystem, MSMQ, etc. But you need more work to support TranactionScope. First of all what I show in the above code block will not work. Why? Because that directory creation and file creation will not be marked for transaction by default. Then what do we need to do?
public interface IEnlistmentNotification
{       
    void Commit(Enlistment enlistment);       
    void InDoubt(Enlistment enlistment);      
    void Prepare(PreparingEnlistment preparingEnlistment);        
    void Rollback(Enlistment enlistment);
} 
The System.Transactions namespace has an interface named IEnlistmentNotification. If I want my component/service to be transaction aware then I need to implement that interface. The following code will show a very simple and straightforward way to implement this:
public class DirectoryCreator : IEnlistmentNotification
{
    public string _directoryName; 
    private bool _isCommitSucceed = false;
    public DirectoryCreator(string directoryName)
    {
        _directoryName = directoryName;
        Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None);
    }
    public void Commit(Enlistment enlistment)
    {
        Directory.CreateDirectory(_directoryName);
        _isCommitSucceed = true;
        enlistment.Done();
    }
    public void InDoubt(Enlistment enlistment)
    {
        enlistment.Done();
    }
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        preparingEnlistment.Prepared();
    }
    public void Rollback(Enlistment enlistment)
    {
        if (_isCommitSucceed))
            Directory.Delete(_directoryName);
        enlistment.Done();
    }
} 
The above class will create a directory (folder) and this component is transaction aware. We can use this class with any TranactionScope and if TranactionScope is committed the directory will be created, otherwise it will be deleted (if already created). I show here just the diretory creation, if you want you can create a class/component for file creation. Now, how to use this class in the transactions scope?
string newDirectory = @"D:\TestDirectory";
string connectionString = ConfigurationManager.ConnectionStrings["db"].ConnectionString;
using (var scope = new TransactionScope())
{
    using (var conn = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = "Insert into data(Code) values ('A001');";
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
        }
    }
    var creator = new DirectoryCreator(newDirectory);
    Transaction.Current.Rollback();
    //scope.Complete();
}
Now, it will work!
Transactional NTFS(TxF) .NET is a open source project. You can use this library for creating/writing/coping file/directory inside transactionscope and it will support transaction automatically.
  • You first need to download component from http://txfnet.codeplex.com
  • Add that component as reference to your project.
  • Use component api to your transactional block.
Txf API usage code sample:
using (var ts = new System.Transactions.TransactionScope())
{
    using (var conn = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = "Insert into data(Code) values ('A001');";
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
        }
    }
    TxF.Directory.CreateDirectory("d:\\xyz", true);
    TxF.File.CreateFile("D:\\abc.txt", File.CreationDisposition.OpensFileOrCreate);
    ts.Complete();
}
TxF component supports:
  • Create/Delete Directory
  • Create/Delete File
  • Read/Write File
  • Copy File