Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, 1 September 2016

The decoration of objects

This is an image of tree rings. As you know the rings indicate the age of the tree. 

Now coming to our example of Decorator pattern, the "first year of growth is our original object and the rest of the rings are the decorators"


Decorator pattern is used as an alternative for subclassing when we need the functionality to be extended. It is also an example of the Open- Closed Principle where we are allowed only to extend instead of modify.

When do we used decorator pattern?
When we have a set of large combination of two or more different sets of logic to be performed, instead of having a nightmare of derived classes we would rather bind the required logic dynamically.

Consider a web cam device that rotates and takes a photo everytime it senses motion of object in front of it.

Pseudo Code

InstructionCode  ActionPerformed
CC                         Check if device is awake/Powered on

SS                          Check if sensor is functional

TT                          Take a snapshot

RR                          Rotate towards object of movement

DD                          Detect motion

MM                        TimerControl

Scenario 1:
The workflow will be such as

CC- Check if device is awake  >>  SS- Check if sensor is functional  >> DD- Detect Motion  >> RR- Rotate towards motion >> TT - Take Snapshot.


So the code you would need to write would be
CC SS DD RR TT

Scenario 2:
Now if the functionality of the device is changed to take pictures at every interval of time.

The workflow will be

CC- Check if device is awake >> MM- Timer Control >> TT- Take Snapshot.

So the code you would need to write would be
CC MM TT

If you considered the above scenario writing without a decorator pattern and having derived classes etc, it would have taken a lot of time modifying the codebase to fit in scenario 2 and violating the open closed principle of SOLID. Instead on using decorator we leave the scenrario 1  code untouched while we implement the scenario 2 logic.

In the above example we have limited number of instructions, consider writing a code for a IOT device which has numerous instruction sets all that need to be constructed to interact with a device. In such a scenario you would definitely prefer writing less code and opt for decorator pattern.

Below is a basic code example of an Ice Cream Preparation using decorator pattern.

Image result for ice cream toppings display

The Ice Cream comes with a base Cone and with one scoop of ice cream.
It can be topped with chocolate sauce, sprinkles, gummy bears or all the above.

using System;

namespace IceCreamDecoration
{
    public abstract class BaseCone
    {
        protected double myPrice;

        public virtual double GetPrice()
        {
            return this.myPrice;
        }
    }

    public abstract class IceCreamToppingsDecorator : BaseCone
    {
        protected BaseCone basecone;
        public IceCreamToppingsDecorator(BaseCone baseconeToDecorate)
        {
            this.basecone = baseconeToDecorate;
        }

        public override double GetPrice()
        {
            return (this.basecone.GetPrice() + this.myPrice);
        }
    }

    class Program
    {
        
        static void Main()
        {
          
            OneScoop basecone = new OneScoop();
            Console.WriteLine("Just one scoop : " + basecone.GetPrice().ToString());

            SprinklesTopping sprinkles = new SprinklesTopping(basecone);
            SprinklesTopping moresprinkles = new SprinklesTopping(sprinkles);
            Console.WriteLine("single scoup with sprinkles: " + moresprinkles.GetPrice().ToString());

            GummyBearsTopping gummyBears = new GummyBearsTopping(moresprinkles);
            Console.WriteLine("single scoup with more sprinkles and gummy bears: " + gummyBears.GetPrice().ToString());

            ChocolateSauceTopping chocolateSauce = new ChocolateSauceTopping(gummyBears);
            Console.WriteLine("single scoup with more sprinkles and gummy bears and chocolate sauce: " + chocolateSauce.GetPrice().ToString());

            Console.ReadLine();
        }
    }

    public class OneScoop : BaseCone
    {
        public OneScoop()
        {
            this.myPrice = 6.99;
        }
    }

    public class Dessert : BaseCone
    {
        public Dessert()
        {
            this.myPrice = 7.49;
        }
    }

    public class SprinklesTopping : IceCreamToppingsDecorator
    {
        public SprinklesTopping(BaseCone baseconeToDecorate)
            : base(baseconeToDecorate)
        {
            this.myPrice = 0.99;
        }
    }

    public class GummyBearsTopping : IceCreamToppingsDecorator
    {
        public GummyBearsTopping(BaseCone baseconeToDecorate)
            : base(baseconeToDecorate)
        {
            this.myPrice = 1.49;
        }
    }

    public class ChocolateSauceTopping : IceCreamToppingsDecorator
    {
        public ChocolateSauceTopping(BaseCone baseconeToDecorate)
            : base(baseconeToDecorate)
        {
            this.myPrice = 2.49;
        }
    }
}

Tuesday, 16 August 2016

Setting up OTP Auth for your application with Google Auth

Cover art
Two factor authentication has become a necessary evil these days. Unlike the olden days where people carried a RSA token generator with them, these days we use apps such as Google Authenticator.

Below are the steps for helping you get started with it.

1. Get nugget package GoogleAuthenticator

2. Add the following code

     TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
     var setupCode = tfa.GenerateSetupCode("issuer", "accountTitle", "poiuytrewq123456", 300, 300);

            string qrCodeImageUrl = setupCode.QrCodeSetupImageUrl;
            string manualEntrySetupCode = setupCode.ManualEntryKey;
            Console.WriteLine(manualEntrySetupCode);

Use any key in place of "poiuytrewq123456"
On execution of this code you will get a Manual Entry Setup Code.

3. Install GoogleAuthenticator on your phone from Google Play.
Open App Goto
Options >> Setup Account >> Enter Provided Key >>  Enter the alphanumeric displayed by the above program and enter the same "accountTitle" given in the code above in the "Account Name" field.
Now your account is setup.

4. Add the following code to validate the OTP in your mobile.

            Console.WriteLine("Enter OTP ");
            string enteredOTP=Console.ReadLine();
          
            bool isCorrectPIN = tfa.ValidateTwoFactorPIN("poiuytrewq123456", enteredOTP);
            if (isCorrectPIN)
            {
                return true;
            }
            else
                return false;

That's it you are done.

Run the Program
Enter the OTP in the console as shown in your mobile.
If the OTP matches you will get authenticated.

Will share the Github repo link.


Sunday, 27 September 2015

SQL Timeout Exception Prevention and Tuning Stored Procedures


Prevent Stored Procedure Timeout

Write efficient Stored Procedures

Prevent More Disk Reads

Prevent Dead Locks


System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.


The following are the collection of my learning as a SQL developer.

Because of large data on the tables, the join operations and other operations will take up lot of time hence causing the application to time out, also reducing the performance.


Parameter Sniffing
In short, parameter sniffing is one exec plan for all parameter combinations. 

- This option causes the compilation process to ignore the value for the specified variable and use the specified value instead.
- Unlike the other workaround (Option(Recompile)), this option avoid the overhead of recompiling the query every time.


This is the most common problem, The workaround is to declare the input params  again with different variable name and use the
 new variable through out the SP.

In the Example @local_SetupId

CREATE PROCEDURE [dbo].[pr_get_user_ids]
(
@in_SetupId  int
)
As
begin
Declare @local_SetupId int =@in_SetupId
Select UserId from UserDetail where SetupId=@local_SetupId

end




Use Local Temp Tables




Store the data from large tables such as Product / Orders/ Hierarchy into Local temp Tables and Use them when joining – This is will Prevent the joining of heavy tables.

This is Subject to temp Db Size. Consider the temp Db size.

Select only the needed columns for your Transaction operation and put it into a local temp  table. Hence on performing joins the tables will be lighter  and preventing the use of excess Resource.

In the Example We have filtered out few columns  from productHierarchy table using setupid in Where  clause and used it to join with Product table.

SELECT * into #TempProductHierarchy FROM
(SELECT ProductHierarchy,ProductHierarchyId,ProductId from ProductHierarchyDetails where SetupId=@local_SetupId ) AS TPH          

SELECT ProductCodeInterface from masters.Product P
inner join #tempProductHierarchy on P.ProductId=#TempProductHierarchy.ProductId

Instead of
SELECT ProductCodeInterface from masters.Product P
inner join masters.ProductHierarchyDetail PHD on P.ProductId=PHD.ProductId
where P.SetupId=@local_SetupId

Use NON Clustered Index
Use Non Clustered Index on temp tables for quicker Execution

Once you have created a temp table, set index on the primary key of the table – on which you will be performing the join operation.
In the example we have read the Product Hierarchy  table into a temp table and we have created a non-clustered  index onto the primary key i.e ProductId

 SELECT * into #TempProductHierarchy FROM
(SELECT ProductHierarchy,ProductHierarchyId,ProductId from ProductHierarchyDetails
where SetupId=@local_SetupId ) AS TPH                     

Create NonClustered Index IDX_TP4 On #TempProductHierarchy(ProductId)



Use With(NOLOCK)
NOLOCK typically (depending on your DB engine) means give me your data, and I don't care what state it is in, and don't bother holding it still while you read from it. It is all at once faster, less resource-intensive

Use NOLOCK on master tables and not everywhere.
Using NoLock may become dangerous sometimes, so check the query exec plan when in doubt.

Select * from  ProductHierarchy  WITH(NOLOCK)











Join On the InputParameter
This will reduce the operation size and the disk read

Join on input parameter instead of filtering in where condition.
As you can see here we have joined on  setupid i.e the input parameter instead of  joining on the setupid of the other table  and then filtering in where condition. 

SELECT * from trans.Promotion P
inner join masters.Product PP with(NOLOCK)   on PP.SetupId=@local_SetupId
inner join masters.Customer CC with(NOLOCK) on CC.SetupId=@local_SetupId

Instead Of
SELECT * from trans.Promotion P
inner join masters.Product PP with(NOLOCK)   on PP.SetupId=P.SetupId
inner join masters.Customer CC with(NOLOCK) on CC.SetupId=P.SetupId
Where PP.SetupId=@local_SetupId


Prevent the use of “Select *”

Causes Indexing issues and Binding issues

Dont use "SELECT *" in a SQL query

Insead use Select ProductId, ProductName from Products



Use EXISTS

To check if any data exists in a particular table, use EXISTS  instead of relying on Count its more effective.


SELECT OrderId,AmendVersion FROM trans.OrdersWHERE EXISTS (SELECT top 1 OrderId FROM trans.OrderExtract WHERE SetupId=1099)



Use Local Temp Tables (#TempTableName)







Prevent using Global hash tables (##)


SELECT * into #TempProduct FROM(SELECT ProductId,LevelId,ProductCodeInterface,Name from Product where SetupId=@local_SetupId and IsActive=1) AS TP                                          








Use Local Variables to Store the FunctionCall return

Prevent calling the string functions or date functions Over and over again, instead store ‘em in local variables  if you are going to reuse the value.

Declare @sampleString varchar(max) = 'nevermind the promotions'
Declare  @sizeOfString int
set @sizeOfString= len(@sampleString)
SELECT @sizeOfString




Use Try - Catch

BEGIN TRY
-- Logic / Query here
END TRY           
            
BEGIN CATCH           
 -----------------------------------------------------------------------           
           
  DECLARE           
      @ErrMsg  VARCHAR(255) -- Error Message           
     ,@ErrNo   INT    -- Error Number           
     ,@ErrSeverity INT    -- Error Severity           
     ,@ErrProc  VARCHAR(255) -- Error Procedure           
     ,@ErrLine  INT    -- Error Line           
               
  SELECT           
      @ErrMsg  = ERROR_MESSAGE()           
     ,@ErrNo   = ERROR_NUMBER()           
     ,@ErrSeverity = 17           
     ,@ErrProc  = ERROR_PROCEDURE()           
     ,@ErrLine  = ERROR_LINE()           
                           
  RAISERROR  (           
      @ErrMsg           
     ,@ErrSeverity           
     ,1           
     ,@ErrNo           
     ,@ErrLine           
     ,@ErrProc           
     )           
 -----------------------------------------------------------------------           
 END CATCH           
END           
           
           
           
     
 Use  SET NOCOUNT ON

Whenever we write any procedure and execute it a message appears in message window that shows number of rows affected with the statement written in the procedure.

When SET NOCOUNT is ON, the count is not returned.

SET NOCOUNT ON
Select PromotionId from Promotion 


Prevent Usage of DDL Statements

Do not try to use DDL statements inside a stored procedure that will reduces the chance to reuse the execution plan.
DDL statements like CREATE,ALTER,DROP,TRUNCATE etc.


Use Alias



If an alias is not present, the engine must resolve which tables own the specified columns. A short alias is parsed more quickly than a long table name or alias. If possible, reduce the alias to a single letter

--Wrong Statement
SELECT PromotionId , P.VersionedPromotionId, Name, PIE.InvestmentTypeId from Promotion P
Inner join PromotionInvestment PIE on PIE.VersionedPromotionId=P.VersionedPromotionId
where P.Name='Blah'

--Correct Statement
SELECT P.PromotionId , P.VersionedPromotionId, P.Name, PIE.InvestmentTypeId from Promotion P
Inner join PromotionInvestment PIE on PIE.VersionedPromotionId=P.VersionedPromotionId
where P.Name='Blah'



Don't use UPDATE instead of CASE

Take this scenario, for instance: You're inserting data into a temp table and need it to display a certain value if another value exists. Maybe you're pulling from the Customer table and you want anyone with more than $100,000 in orders to be labeled as "Preferred." Thus, you insert the data into the table and run an UPDATE statement to set the CustomerRank column to "Preferred" for anyone who has more than $100,000 in orders. The problem is that the UPDATE statement is logged, which means it has to write twice for every single write to the table. The way around this, of course, is to use an inline CASE statement in the SQL query itself. This tests every row for the order amount condition and sets the "Preferred" label before it's written to the table.






Avoid Functions on RHS

Dont use this

select *
from Promotion
where YEAR(StartDate) = 2015
and  MONTH(StartDate) = 6 

Use this

Select *
From Promotion
Where StartDate between '6/1/2015'
    and '6/30/2015'



 Specify optimizer hints in SELECT

most cases the query optimizer will pick the appropriate index for a particular table based on statistics, sometimes it is better to specify the index name in your SELECT query.
Do not use this unless you know what you are doing.

SELECT *
FROM Promotion
WITH ( Index(IdxPromotionId))
WHERE Name = 'blah'
and Setupid=1099 




Hope these tips will help you prevent and solve the timeout exception  you face. If you want to add any please mention in the comments.