File: System\Activities\DurableInstancing\StoreUtilities.cs
Project: ndp\cdf\src\NetFx40\System.Activities.DurableInstancing\System.Activities.DurableInstancing.csproj (System.Activities.DurableInstancing)
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
 
namespace System.Activities.DurableInstancing
{
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Globalization;
    using System.Runtime;
    using System.Runtime.DurableInstancing;
    using System.Text;
    using System.Xml.Linq;
 
    static class StoreUtilities
    {
        public static readonly Version Version40 = new Version(4, 0, 0, 0);
        public static readonly Version Version45 = new Version(4, 5, 0, 0);
 
        public static Exception CheckRemainingResultSetForErrors(XName commandName, SqlDataReader reader)
        {
            Exception returnException = null;
 
            do
            {
                returnException = StoreUtilities.GetNextResultSet(commandName, reader);
            }
            while (returnException == null && reader.NextResult());
 
            return returnException;
        }
 
        public static Exception CheckResult(XName commandName, SqlDataReader reader)
        {
            Exception returnValue = null;
 
            CommandResult result = (CommandResult) reader.GetInt32(0);
            if (result != CommandResult.Success)
            {
                returnValue = StoreUtilities.GetError(commandName, result, reader);
            }
 
            return returnValue;
        }
 
        public static SqlConnection CreateConnection(string connectionString)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            connection.Open();
            return connection;
        }
 
        public static Exception GetError(XName commandName, CommandResult result, SqlDataReader reader)
        {
            Exception returnValue = null;
 
            if (result != CommandResult.Success)
            {
                switch (result)
                {
                    case CommandResult.InstanceAlreadyExists:
                        returnValue = new InstanceCollisionException(commandName, reader.GetGuid(1));
                        break;
                    case CommandResult.InstanceLockNotAcquired:
                        returnValue = new InstanceLockedException(commandName, reader.GetGuid(1), reader.GetGuid(2), ReadLockOwnerMetadata(reader));
                        break;
                    case CommandResult.InstanceNotFound:
                        returnValue = new InstanceNotReadyException(commandName, reader.GetGuid(1));
                        break;
                    case CommandResult.KeyAlreadyExists:
                        returnValue = new InstanceKeyCollisionException(commandName, Guid.Empty,
                            new InstanceKey(reader.GetGuid(1)), Guid.Empty);
                        break;
                    case CommandResult.KeyNotFound:
                        returnValue = new InstanceKeyNotReadyException(commandName, new InstanceKey(reader.GetGuid(1)));
                        break;
                    case CommandResult.InstanceLockLost:
                        returnValue = new InstanceLockLostException(commandName, reader.GetGuid(1));
                        break;
                    case CommandResult.InstanceCompleted:
                        returnValue = new InstanceCompleteException(commandName, reader.GetGuid(1));
                        break;
                    case CommandResult.KeyDisassociated:
                        returnValue = new InstanceKeyCompleteException(commandName, new InstanceKey(reader.GetGuid(1)));
                        break;
                    case CommandResult.StaleInstanceVersion:
                        returnValue = new InstanceLockLostException(commandName, reader.GetGuid(1));
                        break;
                    case CommandResult.HostLockExpired:
                        returnValue = new InstancePersistenceException(SR.HostLockExpired);
                        break;
                    case CommandResult.HostLockNotFound:
                        returnValue = new InstancePersistenceException(SR.HostLockNotFound);
                        break;
                    case CommandResult.CleanupInProgress:
                        returnValue = new InstancePersistenceCommandException(SR.CleanupInProgress);
                        break;
                    case CommandResult.InstanceAlreadyLockedToOwner:
                        returnValue = new InstanceAlreadyLockedToOwnerException(commandName, reader.GetGuid(1), reader.GetInt64(2));
                        break;
                    default:
                        returnValue = new InstancePersistenceCommandException(SR.UnknownSprocResult(result));
                        break;
                }
            }
 
            return returnValue;
        }
 
        public static Exception GetNextResultSet(XName commandName, SqlDataReader reader)
        {
            do
            {
                if (reader.Read())
                {
                    do
                    {
                        if (reader.FieldCount == 0)
                        {
                            continue;
                        }
 
                        string columnName = reader.GetName(0);
 
                        if (string.Compare("Result", columnName, StringComparison.Ordinal) == 0)
                        {
                            return StoreUtilities.CheckResult(commandName, reader);
                        }
                    }
                    while (reader.Read());
                }
            }
            while (reader.NextResult());
 
            return null;
        }
 
        public static void TraceSqlCommand(SqlCommand command, bool isStarting)
        {
            if (((isStarting && TD.StartSqlCommandExecuteIsEnabled()) ||
                (!isStarting && TD.EndSqlCommandExecuteIsEnabled())) && command != null)
            {
                StringBuilder traceString = new StringBuilder(SqlWorkflowInstanceStoreConstants.DefaultStringBuilderCapacity);
                bool firstItem = false;
 
                foreach (SqlParameter sqlParameter in command.Parameters)
                {
                    string value;
                    if ((sqlParameter.Value == DBNull.Value) || (sqlParameter.Value == null))
                    {
                        value = "Null";
                    }
                    else if (sqlParameter.DbType == System.Data.DbType.Binary)
                    {
                        value = "Binary";
                    }
                    else
                    {
                        value = sqlParameter.Value.ToString();
                    }
 
                    if (firstItem)
                    {
                        traceString.AppendFormat(CultureInfo.InvariantCulture, "{0}='{1}'", sqlParameter.ParameterName, value);
                        firstItem = false;
                    }
                    else
                    {
                        traceString.AppendFormat(CultureInfo.InvariantCulture, ", {0}='{1}'", sqlParameter.ParameterName, value);
                    }
 
                    traceString.AppendLine(command.CommandText);
                }
 
                if (isStarting)
                {
                    TD.StartSqlCommandExecute(traceString.ToString());
                }
                else
                {
                    TD.EndSqlCommandExecute(traceString.ToString());
                }
            }
        }
 
        static Dictionary<XName, object> ReadLockOwnerMetadata(SqlDataReader reader)
        {
            Dictionary<XName, object> lockOwnerProperties = new Dictionary<XName, object>();
            InstanceEncodingOption encodingOption = (InstanceEncodingOption)(reader.GetByte(3));
            byte[] serializedPrimitiveLockOwnerData = reader.IsDBNull(4) ? null : (byte[]) reader.GetValue(4);
            byte[] serializedComplexLockOwnerData = reader.IsDBNull(5) ? null : (byte[]) reader.GetValue(5);
            IObjectSerializer serializer = ObjectSerializerFactory.GetObjectSerializer(encodingOption);
            Dictionary<XName, object>[] lockOwnerPropertyBags = new Dictionary<XName, object>[2];
 
            if (serializedPrimitiveLockOwnerData != null)
            {
                lockOwnerPropertyBags[0] = (Dictionary<XName, object>)serializer.DeserializeValue(serializedPrimitiveLockOwnerData);
            }
 
            if (serializedComplexLockOwnerData != null)
            {
                lockOwnerPropertyBags[1] = serializer.DeserializePropertyBag(serializedComplexLockOwnerData);
            }
 
            foreach (Dictionary<XName, object> propertyBag in lockOwnerPropertyBags)
            {
                if (propertyBag != null)
                {
                    foreach (KeyValuePair<XName, object> property in propertyBag)
                    {
                        lockOwnerProperties.Add(property.Key, property.Value);
                    }
                }
            }
 
            return lockOwnerProperties;
        }
    }
}