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