public virtual IStoreResults ExecuteOperation(string operationName, XElement operationData)
        {
            return(SqlUtils.WithSqlExceptionHandling <IStoreResults>(() =>
            {
                SqlResults results = new SqlResults();

                using (SqlCommand cmd = _conn.CreateCommand())
                    using (XmlReader input = operationData.CreateReader())
                    {
                        cmd.Transaction = _tran;
                        cmd.CommandText = operationName;
                        cmd.CommandType = CommandType.StoredProcedure;

                        SqlUtils.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, -1, new SqlXml(input));

                        SqlParameter result = SqlUtils.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            results.Fetch(reader);
                        }

                        // Output parameter will be used to specify the outcome.
                        results.Result = (StoreResult)result.Value;
                    }

                return results;
            }));
        }
        /// <summary>
        /// Execute the operation against GSM in the current transaction scope.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>
        /// Results of the operation.
        /// </returns>
        public override IStoreResults DoGlobalExecute(IStoreTransactionScope ts)
        {
            IStoreResults result = ts.ExecuteCommandSingle(SqlUtils.CheckIfExistsGlobalScript.Single());

            SqlResults returnedResult = new SqlResults();

            // If we did not find some store deployed.
            if (result.StoreVersion == null)
            {
                returnedResult.Result = StoreResult.Failure;
            }
            else
            {
                // DEVNOTE(wbasheer): We need to have a way of erroring out if versions do not match.
                // we can potentially call upgrade here to get to latest version. Should this be exposed as a new parameter ?
                returnedResult.Result = StoreResult.Success;
            }

            return(returnedResult);
        }
        /// <summary>
        /// Execute the operation against GSM in the current transaction scope.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>
        /// Results of the operation.
        /// </returns>
        public override IStoreResults DoGlobalExecute(IStoreTransactionScope ts)
        {
            IStoreResults result = ts.ExecuteCommandSingle(SqlUtils.CheckIfExistsGlobalScript.Single());

            SqlResults returnedResult = new SqlResults();

            // If we did not find some store deployed.
            if (result.StoreVersion == null)
            {
                returnedResult.Result = StoreResult.Failure;
            }
            else
            {
                // DEVNOTE(wbasheer): We need to have a way of erroring out if versions do not match.
                // we can potentially call upgrade here to get to latest version. Should this be exposed as a new parameter ?
                returnedResult.Result = StoreResult.Success;
            }

            return returnedResult;
        }
        public virtual IStoreResults ExecuteCommandSingle(StringBuilder command)
        {
            return(SqlUtils.WithSqlExceptionHandling <IStoreResults>(() =>
            {
                SqlResults results = new SqlResults();

                using (SqlCommand cmd = _conn.CreateCommand())
                {
                    cmd.Transaction = _tran;
                    cmd.CommandText = command.ToString();
                    cmd.CommandType = CommandType.Text;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        results.Fetch(reader);
                    }
                }

                return results;
            }));
        }
Example #5
0
        /// <summary>
        /// Populates instance of SqlResults using rows from SqlDataReader.
        /// </summary>
        /// <param name="reader">SqlDataReader whose rows are to be read.</param>
        internal void Fetch(SqlDataReader reader)
        {
            do
            {
                if (reader.FieldCount > 0)
                {
                    SqlResultType resultType = SqlResults.SqlResultTypeFromColumnName(reader.GetName(1));

                    switch (resultType)
                    {
                    case SqlResultType.ShardMap:
                        while (reader.Read())
                        {
                            _ssm.Add(new SqlShardMap(reader, 1));
                        }
                        break;

                    case SqlResultType.Shard:
                        while (reader.Read())
                        {
                            _ss.Add(new SqlShard(reader, 1));
                        }
                        break;

                    case SqlResultType.ShardMapping:
                        while (reader.Read())
                        {
                            _sm.Add(new SqlMapping(reader, 1));
                        }
                        break;

                    case SqlResultType.ShardLocation:
                        while (reader.Read())
                        {
                            _sl.Add(new SqlLocation(reader, 1));
                        }
                        break;

                    case SqlResultType.SchemaInfo:
                        while (reader.Read())
                        {
                            _si.Add(new SqlSchemaInfo(reader, 1));
                        }
                        break;

                    case SqlResultType.StoreVersion:
                        while (reader.Read())
                        {
                            _version = new SqlVersion(reader, 1);
                        }
                        break;

                    case SqlResultType.Operation:
                        while (reader.Read())
                        {
                            _ops.Add(new SqlLogEntry(reader, 1));
                        }
                        break;

                    default:
                        // This code is unreachable, since the all values of the SqlResultType enum are explicitly handled above.
                        Debug.Assert(false);
                        break;
                    }
                }
            }while (reader.NextResult());
        }
        /// <summary>
        /// Asynchronously performs validation that the local representation is as 
        /// up-to-date as the representation on the backing data store.
        /// </summary>
        /// <param name="conn">Connection used for validation.</param>
        /// <param name="manager">ShardMapManager reference.</param>
        /// <param name="shardMap">Shard map for the shard.</param>
        /// <param name="shard">Shard to validate.</param>
        /// <returns>A task to await validation completion</returns>
        internal static async Task ValidateShardAsync(
            SqlConnection conn,
            ShardMapManager manager,
            IStoreShardMap shardMap,
            IStoreShard shard
            )
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            SqlResults lsmResult = new SqlResults();

            XElement xeValidate = StoreOperationRequestBuilder.ValidateShardLocal(shardMap.Id, shard.Id, shard.Version);

            using (SqlCommand cmd = conn.CreateCommand())
            using (XmlReader input = xeValidate.CreateReader())
            {
                cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardLocal;
                cmd.CommandType = CommandType.StoredProcedure;

                SqlUtils.AddCommandParameter(
                    cmd,
                    "@input",
                    SqlDbType.Xml,
                    ParameterDirection.Input,
                    0,
                    new SqlXml(input));

                SqlParameter resultParam = SqlUtils.AddCommandParameter(
                    cmd,
                    "@result",
                    SqlDbType.Int,
                    ParameterDirection.Output,
                    0,
                    0);

                using (SqlDataReader reader = await cmd.ExecuteReaderAsync())
                {
                    await lsmResult.FetchAsync(reader);
                }

                // Output parameter will be used to specify the outcome.
                lsmResult.Result = (StoreResult)resultParam.Value;
            }

            stopwatch.Stop();

            Tracer.TraceInfo(
                TraceSourceConstants.ComponentNames.Shard,
                "ValidateShardAsync",
                "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}",
                shard.Location,
                conn.ConnectionString,
                lsmResult.Result,
                stopwatch.Elapsed);

            if (lsmResult.Result != StoreResult.Success)
            {
                if (lsmResult.Result == StoreResult.ShardMapDoesNotExist)
                {
                    manager.Cache.DeleteShardMap(shardMap);
                }

                // Possible errors are:
                // StoreResult.ShardMapDoesNotExist
                // StoreResult.ShardDoesNotExist
                // StoreResult.ShardVersionMismatch
                // StoreResult.StoreVersionMismatch
                // StoreResult.MissingParametersForStoredProcedure
                throw StoreOperationErrorHandler.OnValidationErrorLocal(
                    lsmResult,
                    shardMap,
                    shard.Location,
                    "ValidateShardAsync",
                    StoreOperationRequestBuilder.SpValidateShardLocal);
            }
        }
        public virtual IStoreResults ExecuteCommandSingle(StringBuilder command)
        {
            return SqlUtils.WithSqlExceptionHandling<IStoreResults>(() =>
            {
                SqlResults results = new SqlResults();

                using (SqlCommand cmd = _conn.CreateCommand())
                {
                    cmd.Transaction = _tran;
                    cmd.CommandText = command.ToString();
                    cmd.CommandType = CommandType.Text;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        results.Fetch(reader);
                    }
                }

                return results;
            });
        }
Example #8
0
        /// <summary>
        /// Removes range mapping within existing range mapping.
        /// </summary>
        /// <param name="ssm">Shard map to remove range mapping to.</param>
        /// <param name="sm">Shard mapping to remove range from.</param>
        /// <param name="range">Range to remove.</param>
        /// <param name="lockOwnerId">Lock owner id of this mapping</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults RemoveRangeWithinRangeMappingGlobal(IStoreShardMap ssm, IStoreMapping sm, ShardRange range, Guid lockOwnerId)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_removeRangeShardMappingWithinRangeGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", sm.ShardMapId.ToString()),
                        new XElement("lo_id", lockOwnerId.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("m_id", sm.Id.ToString()),
                        new XElement("m_min_value", StringUtils.ByteArrayToString(range.Low.RawValue)),
                        new XElement("m_max_value",
                            (range.High == null) ? null : StringUtils.ByteArrayToString(range.High.RawValue),
                            new XAttribute("is_null", (range.High == null) ? "true" : "false")
                            ),
                        new XElement("m_version", sm.Version.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_RangeShardMap_AddRemoveRange_SqlException,
                    se,
                    "RemoveRange",
                    ssm.Name);
            }
        }
Example #9
0
        /// <summary>
        /// Adds a shard to Global ShardMap.
        /// </summary>
        /// <param name="ssm">Shard map to add shard to.</param>
        /// <param name="ss">Shard to store.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults AddShardGlobal(IStoreShardMap ssm, IStoreShard ss)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_addShardGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("s_id", ss.Id.ToString()),
                        new XElement("s_datasource", ss.Location.DataSource),
                        new XElement("s_database", ss.Location.Database),
                        new XElement("s_version", ss.Version.ToString()),
                        new XElement("s_status", ss.Status.ToString()),
                        new XElement("s_custom", (ss.Custom == null) ? null : StringUtils.ByteArrayToString(ss.Custom),
                            new XAttribute("is_null", (ss.Custom == null) ? "true" : "false")
                            )
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_ShardMap_GlobalOperation_SqlException,
                    se,
                    "Add",
                    ssm.Name);
            }
        }
Example #10
0
        /// <summary>
        /// Adds a shard map entry to Local Shard data source.
        /// </summary>
        /// <param name="ss">Shard where shard map is being added.</param>
        /// <param name="ssm">ShardMap to be added.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults AddShardMapLocal(IStoreShard ss, IStoreShardMap ssm)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(ss.Location))
                {
                    cmd.CommandText = @"__ShardManagement.smm_addShardMapLocal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("sm_name", ssm.Name),
                        new XElement("sm_kind", ((int)ssm.Kind).ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("sm_status", ((int)ssm.Status).ToString()),
                        new XElement("sm_keykind", ((int)ssm.KeyKind).ToString()),
                        new XElement("sm_hashkind", ((int)ssm.HashKind).ToString()),
                        new XElement("s_id", ss.Id.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_ShardMap_LocalOperation_SqlException,
                    se,
                    "Add",
                    ssm.Name,
                    ss.Location);
            }
        }
Example #11
0
        /// <summary>
        /// Kills all local sessions at the given location whose patterns match the given
        /// <paramref name="mappingPattern"/>.
        /// </summary>
        /// <param name="location">Location at which to kill sessions.</param>
        /// <param name="shardMapName">Name of shard map.</param>
        /// <param name="mappingPattern">Pattern of the mapping.</param>
        /// <returns>Result of kill operations.</returns>
        public virtual IStoreResults KillSessionsForMappingLocal(ShardLocation location, string shardMapName, string mappingPattern)
        {
            try
            {
                SqlConnectionStringBuilder lcsb = new SqlConnectionStringBuilder(this.credentials.ConnectionStringShard.ConnectionString);

                lcsb.DataSource = location.DataSource;
                lcsb.InitialCatalog = location.Database;

                using (SqlConnection conn = new SqlConnection(lcsb.ConnectionString))
                {
                    conn.Open();

                    SqlResults result = new SqlResults();

                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = @"__ShardManagement.smm_KillSessionsForMappingLocal";
                        cmd.CommandType = CommandType.StoredProcedure;

                        XElement input = new XElement(cmd.CommandText,
                            new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                            new XElement("pattern", mappingPattern));

                        SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
                        SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            result.Fetch(reader);
                        }

                        // Output parameter will be used to specify the outcome.
                        result.Result = (StoreResult)resultParam.Value;
                    }

                    return result;
                }
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_KillSessionsForMapping_SqlException,
                    se,
                    location,
                    shardMapName);
            }
        }
Example #12
0
        /// <summary>
        /// Update mapping in local ShardMap.
        /// </summary>
        /// <param name="location">Location of shard.</param>
        /// <param name="smOld">Old snapshot of shard mapping in cache before update.</param>
        /// <param name="smNew">Updated shard mapping.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults UpdateMappingLocal(ShardLocation location, IStoreMapping smOld, IStoreMapping smNew)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
                {
                    cmd.CommandText = @"__ShardManagement.smm_updateShardMappingLocal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                        new XElement("sm_id", smNew.ShardMapId.ToString()),
                        new XElement("s_id", smNew.StoreShard.Id.ToString()),
                        new XElement("m_id", smNew.Id.ToString()),
                        new XElement("m_old_version", smOld.Version.ToString()),
                        new XElement("m_min_value", StringUtils.ByteArrayToString(smNew.MinValue)),
                        new XElement("m_max_value",
                            (smNew.MaxValue == null) ? null : StringUtils.ByteArrayToString(smNew.MaxValue),
                            new XAttribute("is_null", (smNew.MaxValue == null) ? "true" : "false")
                            ),
                        new XElement("m_version", smNew.Version.ToString()),
                        new XElement("m_status", smNew.Status.ToString()),
                        new XElement("m_custom", (smNew.Custom == null) ? null : StringUtils.ByteArrayToString(smNew.Custom),
                            new XAttribute("is_null", (smNew.Custom == null) ? "true" : "false")
                            )
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_UpdateMappingLocal_SqlException,
                    se,
                    "UpdateMapping",
                    location);
            }
        }
Example #13
0
        /// <summary>
        /// Merges the given range mappings into a single mapping.
        /// </summary>
        /// <param name="location">Location of shard.</param>
        /// <param name="smLeft">Left store mapping to merge.</param>
        /// <param name="smRight">Right store mapping to merge.</param>
        /// <param name="smMerged">Store mapping resulting from merge operation.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults MergeRangeMappingsLocal(ShardLocation location, IStoreMapping smLeft, IStoreMapping smRight, IStoreMapping smMerged)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
                {
                    cmd.CommandText = @"__ShardManagement.smm_mergeRangeShardMappingsLocal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", smLeft.ShardMapId.ToString()),
                        new XElement("m_id_left", smLeft.Id.ToString()),
                        new XElement("m_version_left", smLeft.Version.ToString()),
                        new XElement("m_id_right", smRight.Id.ToString()),
                        new XElement("m_version_right", smRight.Version.ToString()),
                        new XElement("m_id_new", smMerged.Id.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_RangeShardMap_MergeReplaceLocal_SqlException,
                    se,
                    "MergeRangeMappings",
                    location);
            }
        }
Example #14
0
        /// <summary>
        /// Replace range mapping in Local ShardMap with upto 3 new mappings.
        /// </summary>
        /// <param name="location">Location of shard.</param>
        /// <param name="smOld">Original store mapping.</param>
        /// <param name="smList">List of store mappings to add.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults ReplaceRangeMappingLocal(ShardLocation location, IStoreMapping smOld, IEnumerable<IStoreMapping> smList)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
                {
                    XElement[] xe = new XElement[3];

                    using (IEnumerator<IStoreMapping> smEnum = smList.GetEnumerator())
                    {
                        for (int i = 1; i <= 3; i++)
                        {
                            string index = i.ToString(CultureInfo.InvariantCulture);

                            IStoreMapping mapping = smEnum.MoveNext() ? smEnum.Current : null;

                            xe[i - 1] = new XElement("root",
                                new XElement("m_id_" + index, (mapping == null) ? null : mapping.Id.ToString(),
                                    new XAttribute("is_null", (mapping == null) ? "true" : "false" )
                                    ),
                                new XElement("m_min_value_" + index, (mapping == null) ? null : StringUtils.ByteArrayToString(mapping.MinValue),
                                    new XAttribute("is_null", (mapping == null) ? "true" : "false" )
                                    ),
                                new XElement("m_max_value_" + index, (mapping == null) ? null : ((mapping.MaxValue == null) ? null : StringUtils.ByteArrayToString(mapping.MaxValue)),
                                    new XAttribute("is_null", (mapping == null) ? "true" : ((mapping.MaxValue == null) ? "true" : "false" ))
                                    )
                                );
                        }
                    }

                    cmd.CommandText = @"__ShardManagement.smm_replaceRangeShardMappingsLocal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                        new XElement("sm_id", smOld.ShardMapId.ToString()),
                        new XElement("m_id", smOld.Id.ToString()),
                        new XElement("m_version", smOld.Version.ToString()),
                        xe[0].Elements(),
                        xe[1].Elements(),
                        xe[2].Elements()
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_RangeShardMap_MergeReplaceLocal_SqlException,
                    se,
                    "ReplaceRangeMappings",
                    location);
            }
        }
Example #15
0
        /// <summary>
        /// Locks or unlocks the given range mapping
        /// </summary>
        /// <param name="ssm">Shard map to add mapping to.</param>
        /// <param name="sm">Shard mapping to store.</param>
        /// <param name="lockOwnerId">The lock owner id of this mapping</param>
        /// <param name="lockOwnerIdOpType">Operation to perform on this mapping with the given lockOwnerId</param>
        /// <returns></returns>
        public virtual IStoreResults LockOrUnlockRangeMappingGlobal(IStoreShardMap ssm, IStoreMapping sm, Guid lockOwnerId, LockOwnerIdOpType lockOwnerIdOpType)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_lockOrUnlockShardMappingGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("m_id", sm.Id.ToString()),
                        new XElement("sm_id", sm.ShardMapId.ToString()),
                        new XElement("lo_id", lockOwnerId.ToString()),
                        new XElement("s_id", sm.StoreShard.Id.ToString()),
                        new XElement("m_version", sm.Version.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("lo_id_op_type", (int)lockOwnerIdOpType));

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_UpdateMappingGlobal_SqlException,
                    se,
                    "LockOrUnlockMapping",
                    sm.StoreShard.Location,
                    ssm.Name);
            }
        }
Example #16
0
        /// <summary>
        /// Splits given range mapping into 2 new mappings.
        /// </summary>
        /// <param name="ssm">Shard map to find mappings in.</param>
        /// <param name="sm">Store mapping to split.</param>
        /// <param name="splitPoint">Split point in the mapping.</param>
        /// <param name="lockOwnerId">Lock owner id of this mapping</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults SplitRangeMappingGlobal(IStoreShardMap ssm, IStoreMapping sm, ShardKey splitPoint, Guid lockOwnerId)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_splitRangeShardMappingGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("lo_id", lockOwnerId.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("m_id", sm.Id.ToString()),
                        new XElement("m_version", sm.Version.ToString()),
                        new XElement("split_point", StringUtils.ByteArrayToString(splitPoint.RawValue))
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_RangeShardMap_SplitMerge_SqlException,
                    se,
                    "Split",
                    ssm.Name);
            }
        }
Example #17
0
        /// <summary>
        /// Fetch all the schema info.
        /// </summary>
        /// <param name="siCollection">The schema info collection.</param>
        /// <returns>Storage operation result.</returns>
        public IStoreResults GetShardingSchemaInfoAll(out Dictionary<string, SqlXml> siCollection)
        {
            siCollection = new Dictionary<string, SqlXml>();

            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_getAllShardingSchemaInfo";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()));

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    result.Result = (StoreResult)resultParam.Value;


                    foreach (IStoreSchemaInfo si in result.StoreSchemaInfoCollection)
                    {
                        siCollection.Add(si.Name, si.ShardingSchemaInfo);
                    }

                    return result;
                }
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_SchemaInfo_SqlException,
                    se,
                    "retrieving",
                    "all persisted names");
            }
        }
Example #18
0
        /// <summary>
        /// Obtains all the ShardMaps from the Local ShardMapManager data source.
        /// </summary>
        /// <param name="location">Location of shard.</param>
        /// <returns>Result of the execution.</returns>
        public virtual IStoreResults GetShardMapsLocal(ShardLocation location)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
                {
                    cmd.CommandText = @"__ShardManagement.smm_getAllShardMapsLocal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("lsm_version", SqlStoreLsmVersion.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_GetShardMapsLocal_SqlException,
                    se,
                    location);
            }
        }
Example #19
0
        /// <summary>
        /// Adds or Attaches a shard map entry to Global ShardMapManager data source.
        /// </summary>
        /// <param name="ssm">ShardMap to be added.</param>
        /// <param name="isAttach">Whether we are adding or attaching.</param>
        /// <returns>Storage operation result.</returns>
        private static IStoreResults AddAttachShardMapGlobalHelper(IStoreShardMap ssm, bool isAttach)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_addShardMapGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("sm_name", ssm.Name),
                        new XElement("sm_kind", ((int)ssm.Kind).ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("sm_status", ((int)ssm.Status).ToString()),
                        new XElement("sm_keykind", ((int)ssm.KeyKind).ToString()),
                        new XElement("sm_hashkind", ((int)ssm.HashKind).ToString()),
                        new XElement("for_attach", isAttach.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_ShardMapManager_GlobalOperation_SqlException,
                    se,
                    isAttach ? "Attach" : "Add");
            }
        }
Example #20
0
        /// <summary>
        /// Obtains <paramref name="numShards"/>shards from the Global ShardMapManager data 
        /// source for a given shard map which specify the given status.
        /// </summary>
        /// <param name="ssm">Shard map to get shards for.</param>
        /// <param name="numShards">Optional number of shards to get.</param>
        /// <param name="status">Optional shard status to be matched.</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults GetShardsGlobal(IStoreShardMap ssm, int? numShards, int? status)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_getShardsGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;
                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("num_shards",
                                numShards.HasValue ? numShards.ToString() : null,
                                new XAttribute("is_null", numShards.HasValue ? "false" : "true")
                                ),
                        new XElement("s_status",
                            status.HasValue ? status.ToString() : null,
                            new XAttribute("is_null", status.HasValue ? "false" : "true")
                            )
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_GetShardsGlobal_SqlException,
                    se,
                    ssm.Name);
            }
        }
Example #21
0
        /// <summary>
        /// Add mapping to global ShardMap.
        /// </summary>
        /// <param name="ssm">Shard map to add mapping to.</param>
        /// <param name="sms">Shard mappings to store. (presume these are all in the same ShardLocation.</param>
        /// <returns>Storage operation result.</returns>
        private static IStoreResults BulkAddMappingGlobalHelper(IStoreShardMap ssm, IEnumerable<IStoreMapping> sms)
        {
            var result = new SqlResults();
            if (!sms.Any())
            {
                result.Result = StoreResult.Failure;
                return result;
            }

            DataTable schema;

            using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
            {
                cmd.CommandText = "select * from __ShardManagement.shard_mappings_global where 0 = 1";
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    schema = reader.GetSchemaTable();
                }
            }

            DataTable dt = new DataTable();

            foreach (DataRow drow in schema.Rows)
            {
                string columnName = System.Convert.ToString(drow["ColumnName"]);
                DataColumn column = new DataColumn(columnName, (Type)(drow["DataType"]));
                column.Unique = (bool)drow["IsUnique"];
                column.AllowDBNull = (bool)drow["AllowDBNull"];
                column.AutoIncrement = (bool)drow["IsAutoIncrement"];
                dt.Columns.Add(column);
            }

            foreach (var sm in sms)
            {
                DataRow row = dt.NewRow();
                row[0] = sm.Id;
                row[1] = sm.ShardMapId;
                row[2] = sm.MinValue;
                row[3] = sm.MaxValue;
                row[4] = sm.Version;
                row[5] = sm.Status;
                row[6] = sm.Custom;
                row[7] = sm.StoreShard.Id;
                dt.Rows.Add(row);
            }

            using (SqlBulkCopy bcp = SqlTransactionScopeGlobal.CreateBulkCopy())
            {
                bcp.DestinationTableName = "_shard_mappings_global";
                bcp.WriteToServer(dt);
            }

            result.Result = StoreResult.Success;
            return result;
        }
Example #22
0
        /// <summary>
        /// Removes a shard from Global ShardMap.
        /// </summary>
        /// <param name="ssm">Shard map to remove shard from.</param>
        /// <param name="ss">Shard to remove</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults RemoveShardGlobal(IStoreShardMap ssm, IStoreShard ss)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_removeShardGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_id", ssm.Id.ToString()),
                        new XElement("sm_version", ssm.Version.ToString()),
                        new XElement("s_id", ss.Id.ToString()),
                        new XElement("s_version", ss.Version.ToString())
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_ShardMap_GlobalOperation_SqlException,
                    se,
                    "Remove",
                    ssm.Name);
            }
        }
        /// <summary>
        /// Asynchronously performs validation that the local representation is as
        /// up-to-date as the representation on the backing data store.
        /// </summary>
        /// <param name="conn">Connection used for validation.</param>
        /// <param name="manager">ShardMapManager reference.</param>
        /// <param name="shardMap">Shard map for the shard.</param>
        /// <param name="shard">Shard to validate.</param>
        /// <returns>A task to await validation completion</returns>
        internal static async Task ValidateShardAsync(
            SqlConnection conn,
            ShardMapManager manager,
            IStoreShardMap shardMap,
            IStoreShard shard
            )
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            SqlResults lsmResult = new SqlResults();

            XElement xeValidate = StoreOperationRequestBuilder.ValidateShardLocal(shardMap.Id, shard.Id, shard.Version);

            using (SqlCommand cmd = conn.CreateCommand())
                using (XmlReader input = xeValidate.CreateReader())
                {
                    cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardLocal;
                    cmd.CommandType = CommandType.StoredProcedure;

                    SqlUtils.AddCommandParameter(
                        cmd,
                        "@input",
                        SqlDbType.Xml,
                        ParameterDirection.Input,
                        0,
                        new SqlXml(input));

                    SqlParameter resultParam = SqlUtils.AddCommandParameter(
                        cmd,
                        "@result",
                        SqlDbType.Int,
                        ParameterDirection.Output,
                        0,
                        0);

                    using (SqlDataReader reader = await cmd.ExecuteReaderAsync())
                    {
                        await lsmResult.FetchAsync(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    lsmResult.Result = (StoreResult)resultParam.Value;
                }

            stopwatch.Stop();

            Tracer.TraceInfo(
                TraceSourceConstants.ComponentNames.Shard,
                "ValidateShardAsync",
                "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}",
                shard.Location,
                conn.ConnectionString,
                lsmResult.Result,
                stopwatch.Elapsed);

            if (lsmResult.Result != StoreResult.Success)
            {
                if (lsmResult.Result == StoreResult.ShardMapDoesNotExist)
                {
                    manager.Cache.DeleteShardMap(shardMap);
                }

                // Possible errors are:
                // StoreResult.ShardMapDoesNotExist
                // StoreResult.ShardDoesNotExist
                // StoreResult.ShardVersionMismatch
                // StoreResult.StoreVersionMismatch
                // StoreResult.MissingParametersForStoredProcedure
                throw StoreOperationErrorHandler.OnValidationErrorLocal(
                          lsmResult,
                          shardMap,
                          shard.Location,
                          "ValidateShardAsync",
                          StoreOperationRequestBuilder.SpValidateShardLocal);
            }
        }
Example #24
0
        private static IStoreResults FindMappingByRangeLocalHelper(IStoreShardMap ssm, ShardRange range, IStoreShard shard, string storedProcName)
        {
            SqlResults result = new SqlResults();

            using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(shard.Location))
            {
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;

                XElement input = new XElement(storedProcName,
                    new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                    new XElement("sm_id", ssm.Id.ToString()),
                    new XElement("s_id", shard == null ? null : shard.Id.ToString(),
                        new XAttribute("is_null", (shard == null) ? "true" : "false")
                        ),
                    new XElement("m_min_value", range == null ? null : StringUtils.ByteArrayToString(range.Low.RawValue),
                        new XAttribute("is_null", (range == null) ? "true" : "false")
                        ),
                    new XElement("m_max_value", (range == null) ? null : StringUtils.ByteArrayToString(range.High.RawValue),
                        new XAttribute("is_null", (range == null) ? "true" : "false")
                        )
                    );

                SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    result.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                result.Result = (StoreResult)resultParam.Value;
            }

            return result;
        }
Example #25
0
        /// <summary>
        /// Delete a schma info entry with a given name.
        /// </summary>
        /// <param name="name">Name associated with the schma info.</param>
        /// <returns>Storage operation result.</returns>        
        public IStoreResults DeleteShardingSchemaInfo(string name)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_deleteShardingSchemaInfo";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("metadata_name", name));

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_SchemaInfo_SqlException,
                    se,
                    "deleting",
                    name);
            }
        }
Example #26
0
        /// <summary>
        /// find mappings in Local ShardMap.
        /// </summary>
        /// <param name="ssm">Shard map to find mappings in.</param>
        /// <param name="key">Key corresponding to a point mapping.</param>
        /// <param name="shard">Shard to find mappings in.</param>
        /// <returns>Storage operation result.</returns>
        private static IStoreResults FindMappingByKeyLocalHelper(IStoreShardMap ssm, ShardKey key, IStoreShard shard)
        {
            string storedProcName = "__ShardManagement.smm_getPointShardMappingLocal";
            SqlResults result = new SqlResults();

            using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(shard.Location))
            {
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;

                XElement input = new XElement(storedProcName,
                    new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                    new XElement("sm_id", ssm.Id.ToString()),
                    new XElement("s_id", shard.Id.ToString()),
                    new XElement("m_value", StringUtils.ByteArrayToString(key.RawValue))
                    );

                SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    result.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                result.Result = (StoreResult)resultParam.Value;
            }

            return result;
        }
Example #27
0
        private static IStoreResults AddMappingLocalHelper(ShardLocation location, IStoreMapping sm, string storedProcName)
        {
            SqlResults result = new SqlResults();

            using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
            {
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;

                XElement input = new XElement(storedProcName,
                    new XElement("lsm_version", SqlStoreLsmVersion.ToString()),
                    new XElement("sm_id", sm.ShardMapId.ToString()),
                    new XElement("s_id", sm.StoreShard.Id.ToString()),
                    new XElement("m_id", sm.Id.ToString()),
                    new XElement("m_min_value", StringUtils.ByteArrayToString(sm.MinValue)),
                    new XElement("m_max_value",
                        (sm.MaxValue == null) ? null : StringUtils.ByteArrayToString(sm.MaxValue),
                        new XAttribute("is_null", (sm.MaxValue == null) ? "true" : "false")
                        ),
                    new XElement("m_version", sm.Version.ToString()),
                    new XElement("m_status", sm.Status.ToString()),
                    new XElement("m_custom", (sm.Custom == null) ? null : StringUtils.ByteArrayToString(sm.Custom),
                        new XAttribute("is_null", (sm.Custom == null) ? "true" : "false")
                        )
                    );

                SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    result.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                result.Result = (StoreResult)resultParam.Value;
            }

            return result;
        }
        /// <summary>
        /// Performs validation that the local representation is as up-to-date
        /// as the representation on the backing data store.
        /// </summary>
        /// <param name="conn">Connection used for validation.</param>
        /// <param name="manager">ShardMapManager reference.</param>
        /// <param name="shardMap">Shard map for the mapping.</param>
        /// <param name="storeMapping">Mapping to validate.</param>
        internal static void ValidateMapping(
            SqlConnection conn,
            ShardMapManager manager,
            IStoreShardMap shardMap,
            IStoreMapping storeMapping)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            SqlResults lsmResult = new SqlResults();

            XElement xeValidate = StoreOperationRequestBuilder.ValidateShardMappingLocal(shardMap.Id, storeMapping.Id);

            using (SqlCommand cmd = conn.CreateCommand())
                using (XmlReader input = xeValidate.CreateReader())
                {
                    cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardMappingLocal;
                    cmd.CommandType = CommandType.StoredProcedure;

                    SqlUtils.AddCommandParameter(
                        cmd,
                        "@input",
                        SqlDbType.Xml,
                        ParameterDirection.Input,
                        0,
                        new SqlXml(input));

                    SqlParameter resultParam = SqlUtils.AddCommandParameter(
                        cmd,
                        "@result",
                        SqlDbType.Int,
                        ParameterDirection.Output,
                        0,
                        0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        lsmResult.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    lsmResult.Result = (StoreResult)resultParam.Value;
                }

            stopwatch.Stop();

            Tracer.TraceInfo(
                TraceSourceConstants.ComponentNames.Shard,
                "ValidateMapping",
                "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}",
                storeMapping.StoreShard.Location,
                conn.ConnectionString,
                lsmResult.Result,
                stopwatch.Elapsed);

            if (lsmResult.Result != StoreResult.Success)
            {
                if (lsmResult.Result == StoreResult.ShardMapDoesNotExist)
                {
                    manager.Cache.DeleteShardMap(shardMap);
                }
                else
                if (lsmResult.Result == StoreResult.MappingDoesNotExist)
                {
                    // Only evict from cache is mapping is no longer present,
                    // for Offline mappings, we don't even retry, so same request
                    // will continue to go to the LSM.
                    manager.Cache.DeleteMapping(storeMapping);
                }

                // Possible errors are:
                // StoreResult.ShardMapDoesNotExist
                // StoreResult.MappingDoesNotExist
                // StoreResult.MappingIsOffline
                // StoreResult.ShardVersionMismatch
                // StoreResult.StoreVersionMismatch
                // StoreResult.MissingParametersForStoredProcedure
                throw StoreOperationErrorHandler.OnValidationErrorLocal(
                          lsmResult,
                          shardMap,
                          storeMapping.StoreShard.Location,
                          "ValidateMapping",
                          StoreOperationRequestBuilder.SpValidateShardLocal);
            }

            Debug.Assert(lsmResult.Result == StoreResult.Success);
        }
Example #29
0
        private static IStoreResults RemoveMappingLocalHelper(ShardLocation location, IStoreMapping sm, bool force, string storedProcName)
        {
            SqlResults result = new SqlResults();

            using (SqlCommand cmd = SqlTransactionScopeLocal.CreateSqlCommand(location))
            {
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;

                XElement input = new XElement(storedProcName,
                    new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                    new XElement("sm_id", sm.ShardMapId.ToString()),
                    new XElement("m_id", sm.Id.ToString()),
                    new XElement("m_version", sm.Version.ToString()),
                    new XElement("force_remove", force ? "1" : "0")
                    );

                SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
                SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    result.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                result.Result = (StoreResult)resultParam.Value;
            }

            return result;
        }
        public virtual IStoreResults ExecuteOperation(string operationName, XElement operationData)
        {
            return SqlUtils.WithSqlExceptionHandling<IStoreResults>(() =>
            {
                SqlResults results = new SqlResults();

                using (SqlCommand cmd = _conn.CreateCommand())
                using (XmlReader input = operationData.CreateReader())
                {
                    cmd.Transaction = _tran;
                    cmd.CommandText = operationName;
                    cmd.CommandType = CommandType.StoredProcedure;

                    SqlUtils.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, -1, new SqlXml(input));

                    SqlParameter result = SqlUtils.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        results.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    results.Result = (StoreResult)result.Value;
                }

                return results;
            });
        }
Example #31
0
        private static IStoreResults FindMappingByKeyGlobalHelper(IStoreShardMap ssm, byte[] shardKey, string storedProcName)
        {
            SqlResults result = new SqlResults();

            using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
            {
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;

                XElement input = new XElement(storedProcName,
                    new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                    new XElement("sm_id", ssm.Id.ToString()),
                    new XElement("sm_version", ssm.Version.ToString()),
                    new XElement("s_key", StringUtils.ByteArrayToString(shardKey))
                    );

                SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
                SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    result.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                result.Result = (StoreResult)resultParam.Value;
            }

            return result;
        }
        /// <summary>
        /// Performs validation that the local representation is as up-to-date 
        /// as the representation on the backing data store.
        /// </summary>
        /// <param name="conn">Connection used for validation.</param>
        /// <param name="manager">ShardMapManager reference.</param>
        /// <param name="shardMap">Shard map for the mapping.</param>
        /// <param name="storeMapping">Mapping to validate.</param>
        internal static void ValidateMapping(
            SqlConnection conn,
            ShardMapManager manager,
            IStoreShardMap shardMap,
            IStoreMapping storeMapping)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            SqlResults lsmResult = new SqlResults();

            XElement xeValidate = StoreOperationRequestBuilder.ValidateShardMappingLocal(shardMap.Id, storeMapping.Id);

            using (SqlCommand cmd = conn.CreateCommand())
            using (XmlReader input = xeValidate.CreateReader())
            {
                cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardMappingLocal;
                cmd.CommandType = CommandType.StoredProcedure;

                SqlUtils.AddCommandParameter(
                    cmd,
                    "@input",
                    SqlDbType.Xml,
                    ParameterDirection.Input,
                    0,
                    new SqlXml(input));

                SqlParameter resultParam = SqlUtils.AddCommandParameter(
                    cmd,
                    "@result",
                    SqlDbType.Int,
                    ParameterDirection.Output,
                    0,
                    0);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    lsmResult.Fetch(reader);
                }

                // Output parameter will be used to specify the outcome.
                lsmResult.Result = (StoreResult)resultParam.Value;
            }

            stopwatch.Stop();

            Tracer.TraceInfo(
                TraceSourceConstants.ComponentNames.Shard,
                "ValidateMapping",
                "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}",
                storeMapping.StoreShard.Location,
                conn.ConnectionString,
                lsmResult.Result,
                stopwatch.Elapsed);

            if (lsmResult.Result != StoreResult.Success)
            {
                if (lsmResult.Result == StoreResult.ShardMapDoesNotExist)
                {
                    manager.Cache.DeleteShardMap(shardMap);
                }
                else
                if (lsmResult.Result == StoreResult.MappingDoesNotExist)
                {
                    // Only evict from cache is mapping is no longer present,
                    // for Offline mappings, we don't even retry, so same request
                    // will continue to go to the LSM.
                    manager.Cache.DeleteMapping(storeMapping);
                }

                // Possible errors are:
                // StoreResult.ShardMapDoesNotExist
                // StoreResult.MappingDoesNotExist
                // StoreResult.MappingIsOffline
                // StoreResult.ShardVersionMismatch
                // StoreResult.StoreVersionMismatch
                // StoreResult.MissingParametersForStoredProcedure
                throw StoreOperationErrorHandler.OnValidationErrorLocal(
                    lsmResult,
                    shardMap,
                    storeMapping.StoreShard.Location,
                    "ValidateMapping",
                    StoreOperationRequestBuilder.SpValidateShardLocal);
            }

            Debug.Assert(lsmResult.Result == StoreResult.Success);
        }
Example #33
0
        private static IStoreResults ValidateMappingHelper(SqlCommand cmd, IStoreMapping sm, string storedProcName)
        {
            SqlResults result = new SqlResults();

            cmd.CommandText = storedProcName;
            cmd.CommandType = CommandType.StoredProcedure;

            XElement input = new XElement(storedProcName,
                new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                new XElement("sm_id", sm.ShardMapId.ToString()),
                new XElement("m_id", sm.Id.ToString()),
                new XElement("m_version", sm.Version.ToString())
                );

            SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString()); 
            SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                result.Fetch(reader);
            }

            // Output parameter will be used to specify the outcome.
            result.Result = (StoreResult)resultParam.Value;

            return result;
        }
Example #34
0
        /// <summary>
        /// Asynchronously populates instance of SqlResults using rows from SqlDataReader.
        /// </summary>
        /// <param name="reader">SqlDataReader whose rows are to be read.</param>
        /// <returns>A task to await read completion</returns>
        internal async Task FetchAsync(SqlDataReader reader)
        {
            Func <Action, Task> ReadAsync = async(readAction) =>
            {
                while (await reader.ReadAsync().ConfigureAwait(false))
                {
                    readAction();
                }
            };

            do
            {
                if (reader.FieldCount > 0)
                {
                    SqlResultType resultType = SqlResults.SqlResultTypeFromColumnName(reader.GetName(1));

                    switch (resultType)
                    {
                    case SqlResultType.ShardMap:
                        await ReadAsync(() => _ssm.Add(new SqlShardMap(reader, 1))).ConfigureAwait(false);

                        break;

                    case SqlResultType.Shard:
                        await ReadAsync(() => _ss.Add(new SqlShard(reader, 1))).ConfigureAwait(false);

                        break;

                    case SqlResultType.ShardMapping:
                        await ReadAsync(() => _sm.Add(new SqlMapping(reader, 1))).ConfigureAwait(false);

                        break;

                    case SqlResultType.ShardLocation:
                        await ReadAsync(() => _sl.Add(new SqlLocation(reader, 1))).ConfigureAwait(false);

                        break;

                    case SqlResultType.SchemaInfo:
                        await ReadAsync(() => _si.Add(new SqlSchemaInfo(reader, 1))).ConfigureAwait(false);

                        break;

                    case SqlResultType.StoreVersion:
                        await ReadAsync(() => _version = new SqlVersion(reader, 1)).ConfigureAwait(false);

                        break;

                    case SqlResultType.Operation:
                        await ReadAsync(() => _ops.Add(new SqlLogEntry(reader, 1))).ConfigureAwait(false);

                        break;

                    default:
                        // This code is unreachable, since the all values of the SqlResultType enum are explicitly handled above.
                        Debug.Assert(false);
                        break;
                    }
                }
            }while (await reader.NextResultAsync().ConfigureAwait(false));
        }
Example #35
0
        /// <summary>
        /// Detaches a shard from Global ShardMap.
        /// </summary>
        /// <param name="location">Location of the shard.</param>
        /// <param name="shardmapName">Optional string to filter on shardmapName</param>
        /// <returns>Storage operation result.</returns>
        public virtual IStoreResults DetachShardGlobal(ShardLocation location, string shardmapName = null)
        {
            try
            {
                SqlResults result = new SqlResults();

                using (SqlCommand cmd = SqlTransactionScopeGlobal.CreateSqlCommand())
                {
                    cmd.CommandText = @"__ShardManagement.smm_detachShardGlobal";
                    cmd.CommandType = CommandType.StoredProcedure;

                    XElement input = new XElement(cmd.CommandText,
                        new XElement("gsm_version", SqlStoreGsmVersion.ToString()),
                        new XElement("sm_name", shardmapName,
                            new XAttribute("is_null", (null == shardmapName) ? "true" : "false")
                            ),
                        new XElement("s_datasource", location.DataSource),
                        new XElement("s_database", location.Database)
                        );

                    SqlStore.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, input.ToString());
                    SqlParameter resultParam = SqlStore.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        result.Fetch(reader);
                    }

                    // Output parameter will be used to specify the outcome.
                    result.Result = (StoreResult)resultParam.Value;
                }

                return result;
            }
            catch (SqlException se)
            {
                throw new StoreException(
                    Errors.SqlStore_ShardMapManager_GlobalOperation_SqlException,
                    se,
                    "DetachShard");
            }
        }