/// <summary> /// Create a LearningStoreXml from some data within a row of a /// LogableSqlCommand /// </summary> /// <param name="command">The LogableSqlCommand. The current position is /// not modified.</param> /// <param name="startingColumn">The index of the first column to be /// examined. On exit, this index contains the last column examined /// plus one.</param> /// <returns>The <Typ>LearningStoreXml</Typ>, or null if a /// value is not found.</returns> /// <remarks>Only examines one column. Assumes that the column contains /// an XML value. If the column is non-null, a LearningStoreXml /// is returned. If the column is null, null is returned. /// </remarks> private static LearningStoreXml ReadXmlColumns(LogableSqlCommand command, ref int startingColumn) { if (command.IsDBNull(startingColumn)) { startingColumn++; return(null); } else { SqlXml xml = command.GetSqlXml(startingColumn); startingColumn++; return(new LearningStoreXml(xml)); } }
/// <summary> /// Create a LearningStoreItemIdentifier from some data within a row of a /// LogableSqlCommand /// </summary> /// <param name="command">The LogableSqlCommand. The current position is /// not modified.</param> /// <param name="startingColumn">The index of the first column to be /// examined. On exit, this index contains the last column examined /// plus one.</param> /// <param name="itemType">Information about the identifier type to be /// created.</param> /// <returns>The<Typ>LearningStoreItemIdentifier</Typ>, or null if /// a value is not found.</returns> /// <remarks>Only examines one column. Assumes that the column contains /// an int64 value, containing the key of the Id. If the column is /// non-null, a LearningStoreItemIdentifier is returned. If the /// column is null, null is returned. /// </remarks> private static LearningStoreItemIdentifier ReadItemIdentifierColumns(LogableSqlCommand command, ref int startingColumn, LearningStoreItemType itemType) { if (command.IsDBNull(startingColumn)) { startingColumn++; return(null); } else { long idkey = command.GetInt64(startingColumn); startingColumn++; return(new LearningStoreItemIdentifier(itemType.Name, idkey)); } }
/// <summary> /// Create a LearningStoreItemIdentifier from a result within a LogableSqlCommand /// </summary> /// <param name="command">The LogableSqlCommand. On exit, the entire /// current result has been read.</param> /// <param name="itemType">Information about the item type that should be read.</param> /// <returns>The<Typ>LearningStoreItemIdentifier</Typ></returns> /// <remarks>Assumes that the result has one rows. Assumes that the /// columns within the row contain exactly the correct data /// for the <Mth>ReadItemIdentifierColumns</Mth> method.</remarks> public static LearningStoreItemIdentifier ReadItemIdentifierResult(LogableSqlCommand command, LearningStoreItemType itemType) { // Check input parameters if (command == null) { throw new LearningComponentsInternalException("LSTR1000"); } if (itemType == null) { throw new LearningComponentsInternalException("LSTR1010"); } if (!command.Read()) { throw new LearningComponentsInternalException("LSTR1020"); } // Start at the first column int startingColumn = 0; // Read the item LearningStoreItemIdentifier id = ReadItemIdentifierColumns(command, ref startingColumn, itemType); // Verify that the correct number of values are in the row if (command.GetFieldCount() != startingColumn) { throw new LearningComponentsInternalException("LSTR1030"); } if (command.Read()) { throw new LearningComponentsInternalException("LSTR1040"); } return(id); }
[SuppressMessage("Microsoft.Maintainability", "CA1502")] // Much of the complexity is due to simple switch statements public static DataTable ReadDataTableResult(LogableSqlCommand command, IList <LearningStoreViewColumn> columns, CultureInfo locale) { // Check input parameters if (command == null) { throw new LearningComponentsInternalException("LSTR1050"); } if (columns == null) { throw new LearningComponentsInternalException("LSTR1060"); } // Create the DataTable DataTable table = new DataTable(); table.Locale = locale; // Add the columns foreach (LearningStoreViewColumn column in columns) { Type t = null; switch (column.ValueType.TypeCode) { case LearningStoreValueTypeCode.Boolean: t = typeof(Boolean); break; case LearningStoreValueTypeCode.DateTime: t = typeof(DateTime); break; case LearningStoreValueTypeCode.Double: t = typeof(Double); break; case LearningStoreValueTypeCode.Enumeration: t = typeof(Int32); break; case LearningStoreValueTypeCode.Int32: t = typeof(Int32); break; case LearningStoreValueTypeCode.ItemIdentifier: t = typeof(LearningStoreItemIdentifier); break; case LearningStoreValueTypeCode.Single: t = typeof(Single); break; case LearningStoreValueTypeCode.String: t = typeof(String); break; case LearningStoreValueTypeCode.Xml: t = typeof(LearningStoreXml); break; case LearningStoreValueTypeCode.ByteArray: t = typeof(System.Byte[]); break; case LearningStoreValueTypeCode.Guid: t = typeof(Guid); break; default: throw new LearningComponentsInternalException("LSTR1070"); } table.Columns.Add(column.Name, t); } // Begin loading the data table.BeginLoadData(); // Enumerate through each row while (command.Read()) { // Remember the current input column index int inputColumnIndex = 0; // Create a new array that will hold the items object[] data = new object[columns.Count]; // Enumerate through each column for (int outputColumnIndex = 0; outputColumnIndex < columns.Count; outputColumnIndex++) { // Get the column LearningStoreViewColumn column = columns[outputColumnIndex]; // Read the value switch (column.ValueType.TypeCode) { case LearningStoreValueTypeCode.Boolean: case LearningStoreValueTypeCode.DateTime: case LearningStoreValueTypeCode.Double: case LearningStoreValueTypeCode.Int32: case LearningStoreValueTypeCode.Single: case LearningStoreValueTypeCode.String: case LearningStoreValueTypeCode.Guid: case LearningStoreValueTypeCode.Enumeration: case LearningStoreValueTypeCode.ByteArray: if (command.IsDBNull(inputColumnIndex)) { data[outputColumnIndex] = null; } else { data[outputColumnIndex] = command.GetValue(inputColumnIndex); } inputColumnIndex++; break; case LearningStoreValueTypeCode.ItemIdentifier: data[outputColumnIndex] = ReadItemIdentifierColumns(command, ref inputColumnIndex, column.ValueType.ReferencedItemType); break; case LearningStoreValueTypeCode.Xml: data[outputColumnIndex] = ReadXmlColumns(command, ref inputColumnIndex); break; default: throw new LearningComponentsInternalException("LSTR1080"); } } table.Rows.Add(data); } // Finish loading the data table.EndLoadData(); table.AcceptChanges(); return(table); }
/// <summary> /// Get the schema information for this store from the cache or from the database. /// </summary> /// <param name="connectionString">Connection string used to access the store.</param> /// <param name="impersonationBehavior">Identifies which <c>WindowsIdentity</c> is used to /// access the database when impersonation is involved.</param> /// <param name="debugLog">Location to which the debug log should be written, or /// null if there isn't a debug log.</param> /// <returns>The schema information.</returns> private static LearningStoreSchema GetSchemaInformationFromCache(string connectionString, ImpersonationBehavior impersonationBehavior, TextWriter debugLog) { // Try to find the connection in the cache lock (s_allSchemasLock) { LearningStoreSchema schema; if (s_allSchemas.TryGetValue(connectionString, out schema)) { return(schema); } } // Not found in the cache -- so go get it from the database // This try/catch block is here for security reasons. Search MSDN for // "WrapVulnerableFinallyClausesInOuterTry" to see details. try { WindowsImpersonationContext impersonationContext = null; try { // Impersonate if necessary if (impersonationBehavior == ImpersonationBehavior.UseOriginalIdentity) { // Not adding it to the disposer, since that could fail (e.g., OutOfMemoryException), // which could cause a security hole. Instead, we'll clean it up manually later. impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero); } using (Microsoft.LearningComponents.Disposer disposer = new Microsoft.LearningComponents.Disposer()) { // Create a connection SqlConnection connection = new SqlConnection(connectionString); disposer.Push(connection); connection.Open(); // Create a command to retrieve information from the configuration table LogableSqlCommand command = new LogableSqlCommand(connection, debugLog); disposer.Push(command); // Execute command.Execute( "SELECT EngineVersion,\r\n" + " SchemaDefinition\r\n" + "FROM Configuration\r\n"); // Read return values from the database if (!command.Read()) { throw new LearningComponentsInternalException("LSTR1500"); } if (command.GetFieldCount() != 2) { throw new LearningComponentsInternalException("LSTR1510"); } int engineVersion = command.GetInt32(0); SqlXml schemaXml = command.GetSqlXml(1); XPathDocument schemaDoc; using (XmlReader reader = schemaXml.CreateReader()) { schemaDoc = new XPathDocument(reader); } LearningStoreSchema newSchema = LearningStoreSchema.CreateSchema(schemaDoc); if (command.Read()) { throw new LearningComponentsInternalException("LSTR1520"); } if (command.NextResult()) { throw new LearningComponentsInternalException("LSTR1530"); } // Fail if a different engine created this if (engineVersion != LearningStore.EngineVersion) { throw new InvalidOperationException(LearningStoreStrings.IncompatibleEngineVersion); } // Save it in the cache lock (s_allSchemasLock) { LearningStoreSchema schema; if (s_allSchemas.TryGetValue(connectionString, out schema)) { return(schema); } s_allSchemas.Add(connectionString, newSchema); } return(newSchema); } } finally { if (impersonationContext != null) { impersonationContext.Dispose(); } } } catch { throw; } }