IEnumerable <IndexForColumn> indicesFromColumnImpl(MemberInfo mi) { EseColumnAttrubuteBase col = mi.getColumnAttributes().FirstOrDefault(); if (null == col) { throw new ArgumentException("Member {0} is not mapped to a column".formatWith(mi.Name)); } string colName = col.columnName; if (String.IsNullOrEmpty(colName)) { colName = mi.Name; } foreach (var kvp in m_indices) { sIndexInfo ii = kvp.Value; int ind = Array.IndexOf(ii.columnNames, colName); if (ind < 0) { continue; } bool primary = (ii.attrib is EsePrimaryIndexAttribute); bool dir = ii.columnDirections[ind]; yield return(new IndexForColumn(primary, kvp.Key, ii.attrib, ind, dir)); } }
/// <summary>This method is called before a table is actually opened. /// This is a good place to upgrade database schema, reconstruct indices, or engage in some other table schema management activity. /// None of that is implemented in the current version of the codebase, though. /// The current version just throws an exception if column schema's wrong, and completely ignores the indices schema.</summary> public void VerifyTableSchema(JET_SESID idSession, JET_DBID idDatabase) { // Verify the table exists { JET_TABLEID idTestTable; if (Api.TryOpenTable(idSession, idDatabase, m_tableName, OpenTableGrbit.None, out idTestTable)) { Api.JetCloseTable(idSession, idTestTable); } else { // Just create the table using (Transaction transaction = new Transaction(idSession)) { CreateTableAndIndices(idSession, idDatabase); transaction.Commit(CommitTransactionGrbit.None); } return; } } // Verify columns foreach (var i in m_columns) { Global.TryCatch(delegate() { JET_COLUMNDEF defDB; Api.JetGetColumnInfo(idSession, idDatabase, m_tableName, i.columnName, out defDB); JET_COLUMNDEF defCode = i.attrib.getColumnDef(); if (defCode.coltyp != defDB.coltyp) { throw new SerializationException("Wrong type."); } if (defCode.cp != defDB.cp) { throw new SerializationException("Wrong codepage."); } if (defCode.grbit != defDB.grbit) { throw new SerializationException("Flags mismatch."); } }, "Error while validating column '" + i.columnName + "'"); } // Verify indices // http://stackoverflow.com/a/2345746/126995 Dictionary <string, IndexInfo> dbIndices = Api.GetTableIndexes(idSession, idDatabase, m_tableName) .ToDictionary(ii => ii.Name); foreach (var kvp in m_indices) { sIndexInfo ind = kvp.Value; Global.TryCatch(() => { IndexInfo ii; if (!dbIndices.TryGetValue(kvp.Key, out ii)) { throw new SerializationException("The index was not found in the DB"); } JET_INDEXCREATE icreate = ind.attrib.getIndexDef(); if (!areEqual(ii.Grbit, icreate.grbit)) { throw new SerializationException("The index grbit doesn't match what's in the DB"); } string[] colsDatabase = ii.IndexSegments .Select(seg => seg.ColumnName) .ToArray(); string[] colsTypeInfo = getIndexedColumns(ind.attrib.strKey).ToArray(); if (!colsDatabase.SequenceEqual(colsTypeInfo)) { throw new SerializationException("The index is over the different column than what's in the DB"); } }, "Error while validating index '" + kvp.Key + "'"); } }