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>Parse index into columns that it's composed of.</summary> /// <param name="strKey">double-null-terminated string of null-delimited tokens</param> static IEnumerable <string> getIndexedColumns(string strKey) { // Check the key is double null-terminated. if (!strKey.EndsWith("\0\0")) { throw new SerializationException("the key must be double-null-terminated."); } // Verify each token within the key. strKey = strKey.Substring(0, strKey.Length - 2); string[] arrTokens = strKey.Split(new char[1] { '\0' }, StringSplitOptions.None); EseColumnAttrubuteBase[] indexedColumns = new EseColumnAttrubuteBase[arrTokens.Length]; for (int i = 0; i < arrTokens.Length; i++) { string strToken = arrTokens[i]; if (strToken[0] != '+' && strToken[0] != '-') { throw new SerializationException("direction specifier not found in the token '" + strToken + "'."); } string idColumn = strToken.Substring(1); yield return(idColumn); } }
void addColumnDefinition(MemberInfo f, EseColumnAttrubuteBase attr, bool isObsolete) { string strColumnName = attr.columnName; if (null == strColumnName) { strColumnName = f.Name; } if (!s_reName.IsMatch(strColumnName)) { throw new SerializationException("Invalid column name. " + s_strNameError); } ColumnInfo ci = new ColumnInfo(strColumnName, f, attr, isObsolete); m_columns.Add(ci); }
/// <summary></summary> /// <param name="_name">The name of the column.</param> /// <param name="member">Either FieldInfo or PropertyInfo of the member who has the _attr attribute applied.</param> /// <param name="_attr">The attribute.</param> /// <param name="obsolete">True if the column is also marked with [Obsolete] attribute.</param> public ColumnInfo(string _name, MemberInfo member, EseColumnAttrubuteBase _attr, bool obsolete) { m_columnName = _name; m_attribute = _attr; m_idColumn = JET_COLUMNID.Nil; this.isObsolete = obsolete; // http://www.palmmedia.de/Blog/2012/2/4/reflection-vs-compiled-expressions-vs-delegates-performance-comparision ParameterExpression targetExpObject = Expression.Parameter(typeof(object), "record"); // object record UnaryExpression targetExp = Expression.Convert(targetExpObject, member.DeclaringType); // (RecordType)record MemberExpression memberExp = null; if (member is FieldInfo) { FieldInfo field = member as FieldInfo; tpValue = field.FieldType; memberExp = Expression.Field(targetExp, field); // (((RecordType)record).field) } else if (member is PropertyInfo) { PropertyInfo property = member as PropertyInfo; tpValue = property.PropertyType; memberExp = Expression.Property(targetExp, property); // (((RecordType)record).property) } else { throw new ArgumentException(); } UnaryExpression memberExpObject = Expression.Convert(memberExp, typeof(object)); // (object)(((RecordType)record).property) this.getValue = Expression.Lambda <Func <object, object> >(memberExpObject, targetExpObject).Compile(); ParameterExpression valueExpObject = Expression.Parameter(typeof(object), "value"); // object value UnaryExpression valueExp = Expression.Convert(valueExpObject, tpValue); // (PropertyType)value BinaryExpression assignExp = Expression.Assign(memberExp, valueExp); // ((RecordType)record).property = (PropertyType)value this.setValue = Expression.Lambda <Action <object, object> >(assignExp, targetExpObject, valueExpObject).Compile(); }
void addColumn(MemberInfo f, Type tMember, EseColumnAttrubuteBase[] attributes, bool isObsolete) { Global.TryCatch(delegate() { if (null == attributes || attributes.Length <= 0) { return; } if (attributes.Length > 1) { throw new SerializationException("More then one ESE column attribute is applied to the field '" + f.Name + "'"); } EseColumnAttrubuteBase columnAttrBase = attributes[0]; // Verify the type Global.TryCatch(delegate() { columnAttrBase.verifyTypeSupport(tMember); }, "ESE column attribute '" + columnAttrBase.GetType().Name + "' is incompatible with field or property of type '" + tMember.Name + "'."); addColumnDefinition(f, columnAttrBase, isObsolete); }, "Error reflecting field '" + f.Name + "'."); }
void addIndices() { EseIndexAttribute[] arrAllIndexAttributes = recordType .getCustomAttributes <EseIndexAttribute>() .ToArray(); foreach (EseIndexAttribute attr in arrAllIndexAttributes) { // Check the name if (!s_reName.IsMatch(attr.strName)) { throw new SerializationException("Error adding index '" + attr.strName + "': invalid name. " + s_strNameError); } string[] columnNames; try { columnNames = getIndexedColumns(attr.strKey).ToArray(); } catch (SerializationException ex) { throw new SerializationException("Error adding index '" + attr.strName + "': " + ex.Message); } EseColumnAttrubuteBase[] indexedColumns = new EseColumnAttrubuteBase[columnNames.Length]; bool indexIsObsolete = false; for (int i = 0; i < columnNames.Length; i++) { string idColumn = columnNames[i]; ColumnInfo ci = m_columns.FirstOrDefault(c => c.columnName == idColumn); if (null == ci) { throw new SerializationException("Error adding index '" + attr.strName + "': column '" + idColumn + "' not found."); } indexedColumns[i] = ci.attrib; indexIsObsolete = indexIsObsolete | ci.isObsolete; } // Verify index name uniqueness. sIndexInfo tmp; if (m_indices.TryGetValue(attr.strName, out tmp)) { throw new SerializationException("Error adding index '" + attr.strName + "': index with this name already exists."); } // Verify the columns are indexable. attr.verifyColumnsSupport(indexedColumns); // Verify the conditional columns data. string consCols = attr.condition; if (!String.IsNullOrEmpty(consCols)) { string[] arrTokens = consCols.Split(new char[1] { '\0' }, StringSplitOptions.None); for (int i = 0; i < arrTokens.Length; i++) { string strToken = arrTokens[i]; if (strToken[0] != '+' && strToken[0] != '-') { throw new SerializationException("Error adding index '" + attr.strName + "': existence specifier not found in the conditional column token '" + strToken + "'."); } string idColumn = strToken.Substring(1); int iColumn = m_columns.FindIndex(c => c.columnName == idColumn); if (iColumn < 0) { throw new SerializationException("Error adding index '" + attr.strName + "': the condition column '" + idColumn + "' not found."); } } } m_indices.Add(attr.strName, new sIndexInfo(attr, columnNames, indexedColumns, indexIsObsolete)); } }