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