public static bool RegisterTrackablePocoMap(Type trackablePocoType) { if (BsonClassMap.IsClassMapRegistered(trackablePocoType)) { return(false); } var classMap = new BsonClassMap(trackablePocoType); var pocoType = TrackableResolver.GetPocoType(trackablePocoType); // start with auto map classMap.AutoMap(); // ignore extra elements for smooth schema change classMap.SetIgnoreExtraElements(true); // unmap all members which T doesn't have var propertyNames = new HashSet <string>(pocoType.GetProperties().Select(p => p.Name)); var deletingMembers = classMap.DeclaredMemberMaps.Where(m => { var propertyInfo = m.MemberInfo as PropertyInfo; return(propertyInfo == null || propertyNames.Contains(propertyInfo.Name) == false); }).ToList(); foreach (var m in deletingMembers) { classMap.UnmapMember(m.MemberInfo); } // set default ignore for saving spaces foreach (var memberMap in classMap.DeclaredMemberMaps) { var mt = memberMap.MemberType; var defaultValue = mt.IsValueType ? Activator.CreateInstance(mt) : null; memberMap.SetDefaultValue(defaultValue); memberMap.SetIgnoreIfDefault(true); } // tell customized id to mongo-db var identityColumn = pocoType.GetProperties().FirstOrDefault( p => TrackablePropertyAttribute.GetParameter(p, "mongodb.identity") != null); if (identityColumn != null) { classMap.MapIdProperty(identityColumn.Name); } try { BsonClassMap.RegisterClassMap(classMap); } catch (ArgumentException) { // if duplicate key exists return(false); } return(true); }
public TrackableContainerSqlMapper(ISqlProvider sqlProvider, Tuple <string, object[]>[] mapperParameters) { _sqlProvider = sqlProvider; _trackableType = TrackableResolver.GetContainerTrackerType(typeof(T)); if (_trackableType == null) { throw new ArgumentException($"Cannot find tracker type of '{nameof(T)}'"); } _items = ConstructPropertyItems(sqlProvider, mapperParameters); }
public TrackableContainerRedisMapper(RedisTypeConverter typeConverter = null) { if (typeConverter == null) { typeConverter = RedisTypeConverter.Instance; } _trackableType = TrackableResolver.GetContainerTrackerType(typeof(T)); if (_trackableType == null) { throw new ArgumentException($"Cannot find tracker type of '{nameof(T)}'"); } _items = ConstructPropertyItems(typeConverter); }
public TrackableContainerHashesRedisMapper(RedisTypeConverter typeConverter = null) { if (typeConverter == null) { typeConverter = RedisTypeConverter.Instance; } _trackableType = TrackableResolver.GetContainerTrackerType(typeof(T)); if (_trackableType == null) { throw new ArgumentException($"Cannot find tracker type of '{nameof(T)}'"); } _items = ConstructPropertyItems(typeConverter); _fieldNameToItemMap = _items.ToDictionary(x => x.FieldName, y => y); }
CreatePocoUpdateFunc <TTrackablePoco>() { var pocoType = TrackableResolver.GetPocoType(typeof(TTrackablePoco)); if (pocoType == null) { return(null); } var genericMethod = typeof(TrackableMongoDbMapper).GetMethod( "GeneratePocoUpdateBson", BindingFlags.Static | BindingFlags.NonPublic); var method = genericMethod.MakeGenericMethod(pocoType, typeof(TTrackablePoco)); var mapper = Activator.CreateInstance(GetMapperType(typeof(TTrackablePoco))); var func = method.Invoke(null, new object[] { mapper }); return((Func <UpdateDefinition <BsonDocument>, TTrackablePoco, object[], UpdateDefinition <BsonDocument> >)func); }
public TrackablePocoRedisMapper(RedisTypeConverter typeConverter = null) { if (typeConverter == null) { typeConverter = RedisTypeConverter.Instance; } _trackableType = TrackableResolver.GetPocoTrackerType(typeof(T)); if (_trackableType == null) { throw new ArgumentException($"Cannot find type '{typeof(T).Name}'"); } _items = ConstructPropertyItems(typeConverter); _fieldNameToItemMap = _items.ToDictionary(x => x.FieldName, y => y); _propertyInfoToItemMap = _items.ToDictionary(x => x.PropertyInfo, y => y); }
public TrackablePocoMongoDbMapper() { _trackableType = TrackableResolver.GetPocoTrackerType(typeof(T)); TypeMapper.RegisterTrackablePocoMap(_trackableType); _propertyToMemberMap = new Dictionary <PropertyInfo, BsonMemberMap>(); var classMap = BsonClassMap.LookupClassMap(_trackableType); foreach (var property in typeof(T).GetProperties()) { if (property.Name.ToLower() == "id") { _idProperty = property; } var member = classMap.AllMemberMaps.FirstOrDefault(m => m.MemberInfo.Name == property.Name); if (member != null) { _propertyToMemberMap[property] = member; } } }
private static PropertyItem[] ConstructPropertyItems(ISqlProvider sqlProvider, Tuple <string, object[]>[] mapperParameters) { var trackerType = TrackerResolver.GetDefaultTracker(typeof(T)); var mapperParameterMap = mapperParameters.ToDictionary(x => x.Item1, x => x.Item2); var items = new List <PropertyItem>(); foreach (var property in typeof(T).GetProperties()) { var attr = property.GetCustomAttribute <TrackablePropertyAttribute>(); if (attr != null) { if (attr["sql.ignore"] != null) { continue; } } var item = new PropertyItem { Name = property.Name, PropertyInfo = property, TrackerPropertyInfo = trackerType.GetProperty(property.Name + "Tracker") }; if (item.TrackerPropertyInfo == null) { throw new ArgumentException($"Cannot find tracker type of '{property.Name}'"); } object[] mapperParameter; if (mapperParameterMap.TryGetValue(property.Name, out mapperParameter) == false) { throw new ArgumentException($"{property.Name} needs mapperParameter."); } if (TrackableResolver.IsTrackablePoco(property.PropertyType)) { typeof(TrackableContainerSqlMapper <T>) .GetMethod("BuildTrackablePocoProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(TrackableResolver.GetPocoType(property.PropertyType)) .Invoke(null, new object[] { sqlProvider, item, mapperParameter }); } else if (TrackableResolver.IsTrackableDictionary(property.PropertyType)) { typeof(TrackableContainerSqlMapper <T>) .GetMethod("BuildTrackableDictionaryProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(property.PropertyType.GetGenericArguments()) .Invoke(null, new object[] { sqlProvider, item, mapperParameter }); } else if (TrackableResolver.IsTrackableSet(property.PropertyType)) { typeof(TrackableContainerSqlMapper <T>) .GetMethod("BuildTrackableSetProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(property.PropertyType.GetGenericArguments()) .Invoke(null, new object[] { sqlProvider, item, mapperParameter }); } else { throw new InvalidOperationException("Cannot resolve property: " + property.Name); } items.Add(item); } return(items.ToArray()); }
public TrackablePocoSqlMapper(ISqlProvider sqlProvider, string tableName, ColumnDefinition[] headKeyColumnDefs = null) { _sqlProvider = sqlProvider; _trackableType = TrackableResolver.GetPocoTrackerType(typeof(T)); if (_trackableType == null) { throw new ArgumentException($"Cannot find type '{typeof(T).Name}'"); } _tableName = tableName; _tableEscapedName = _sqlProvider.EscapeName(tableName); var allColumns = new List <ColumnProperty>(); var headKeyColumns = new List <ColumnProperty>(); var primaryKeyColumns = new List <ColumnProperty>(); var valueColumns = new List <ColumnProperty>(); // add head key columns if (headKeyColumnDefs != null) { foreach (var headKeyColumnDef in headKeyColumnDefs) { var column = new ColumnProperty( name: headKeyColumnDef.Name, escapedName: _sqlProvider.EscapeName(headKeyColumnDef.Name), type: headKeyColumnDef.Type, length: headKeyColumnDef.Length, convertToSqlValue: _sqlProvider.GetConvertToSqlValueFunc(headKeyColumnDef.Type)); headKeyColumns.Add(column); primaryKeyColumns.Add(column); allColumns.Add(column); } } // while scan properties of T, construct primaryKey, value column information. var valueType = typeof(T); foreach (var property in valueType.GetProperties()) { var columnName = property.Name; var primaryKey = false; var isIdentity = false; var attr = property.GetCustomAttribute <TrackablePropertyAttribute>(); if (attr != null) { if (attr["sql.ignore"] != null) { continue; } columnName = attr["sql.column:"] ?? columnName; primaryKey = attr["sql.primary-key"] != null; isIdentity = attr["sql.identity"] != null; } var column = new ColumnProperty( name: columnName, escapedName: _sqlProvider.EscapeName(columnName), type: property.PropertyType, isIdentity: isIdentity, propertyInfo: property, convertToSqlValue: _sqlProvider.GetConvertToSqlValueFunc(property.PropertyType), convertFromDbValue: _sqlProvider.GetConvertFromDbValueFunc(property.PropertyType), extractToSqlValue: _sqlProvider.GetExtractToSqlValueFunc(property), installFromDbValue: _sqlProvider.GetInstallFromDbValueFunc(property)); if (primaryKey) { primaryKeyColumns.Add(column); } valueColumns.Add(column); allColumns.Add(column); if (isIdentity) { _identityColumn = column; } } if (primaryKeyColumns.Any() == false) { var idColumn = allColumns.FirstOrDefault(p => p.Name.ToLower() == "id"); if (idColumn != null) { primaryKeyColumns.Add(idColumn); } } if (primaryKeyColumns.Any() == false) { throw new ArgumentException("At lease one primary key should be provided."); } _allColumns = allColumns.ToArray(); _headKeyColumns = headKeyColumns.ToArray(); _primaryKeyColumns = primaryKeyColumns.ToArray(); _valueColumns = valueColumns.ToArray(); _valueColumnMap = _valueColumns.ToDictionary(x => x.PropertyInfo, y => y); _allColumnStringExceptIdentity = string.Join( ",", _allColumns.Where(c => c.IsIdentity == false).Select(c => c.EscapedName)); _allColumnStringExceptHead = string.Join( ",", _valueColumns.Select(c => c.EscapedName)); }
private static PropertyItem[] ConstructPropertyItems(RedisTypeConverter typeConverter) { var trackerType = TrackerResolver.GetDefaultTracker(typeof(T)); var items = new List <PropertyItem>(); foreach (var property in typeof(T).GetProperties()) { var keySuffix = ":" + property.Name; var attr = property.GetCustomAttribute <TrackablePropertyAttribute>(); if (attr != null) { if (attr["redis.ignore"] != null) { continue; } keySuffix = attr["redis.keysuffix:"] ?? keySuffix; } var item = new PropertyItem { Name = property.Name, KeySuffix = keySuffix, PropertyInfo = property, TrackerPropertyInfo = trackerType.GetProperty(property.Name + "Tracker") }; if (item.TrackerPropertyInfo == null) { throw new ArgumentException($"Cannot find tracker type of '{property.Name}'"); } if (TrackableResolver.IsTrackablePoco(property.PropertyType)) { typeof(TrackableContainerRedisMapper <T>) .GetMethod("BuildTrackablePocoProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(TrackableResolver.GetPocoType(property.PropertyType)) .Invoke(null, new object[] { item, typeConverter }); } else if (TrackableResolver.IsTrackableDictionary(property.PropertyType)) { typeof(TrackableContainerRedisMapper <T>) .GetMethod("BuildTrackableDictionaryProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(property.PropertyType.GetGenericArguments()) .Invoke(null, new object[] { item, typeConverter }); } else if (TrackableResolver.IsTrackableSet(property.PropertyType)) { typeof(TrackableContainerRedisMapper <T>) .GetMethod("BuildTrackableSetProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(property.PropertyType.GetGenericArguments()) .Invoke(null, new object[] { item, typeConverter }); } else if (TrackableResolver.IsTrackableList(property.PropertyType)) { typeof(TrackableContainerRedisMapper <T>) .GetMethod("BuildTrackableListProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(property.PropertyType.GetGenericArguments()) .Invoke(null, new object[] { item, typeConverter }); } else { throw new InvalidOperationException("Cannot resolve property: " + property.Name); } items.Add(item); } return(items.ToArray()); }
public TrackableContainerMongoDbMapper() { _trackableType = TrackableResolver.GetContainerTrackerType(typeof(T)); _items = ConstructPropertyItems(); }