コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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;
                }
            }
        }
コード例 #8
0
        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());
        }
コード例 #9
0
        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));
        }
コード例 #10
0
        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());
        }
コード例 #11
0
        public TrackableContainerMongoDbMapper()
        {
            _trackableType = TrackableResolver.GetContainerTrackerType(typeof(T));

            _items = ConstructPropertyItems();
        }