Пример #1
0
        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;
            }));
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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;
            }));
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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().ConfigureAwait(false))
                    {
                        await lsmResult.FetchAsync(reader).ConfigureAwait(false);
                    }

                    // 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);
            }
        }
        /// <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.GetColumnSchema()[1]["ColumnName"].ToString());

                    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));
        }
        /// <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.GetColumnSchema()[1]["ColumnName"].ToString());

                    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());
        }