Example #1
0
        public static Value FromPropertyInfo(object poco, PropertyInfo prop, IEntityFactory entityFactory, IList <string> recursionPath)
        {
            if (prop == null)
            {
                throw new ArgumentNullException(nameof(prop), "Cannot build an entity Value without a property");
            }

            recursionPath.Add(prop.Name);

            if (prop.PropertyType.GetTypeInfo().IsInterface)
            {
                throw new NotSupportedException($"\"{poco.GetType().Name}.{string.Join(".", recursionPath)}\" has \"{prop.PropertyType.Name}\" as type, but that is just an interface and is therefore not supported");
            }

            var value = new Value
            {
                ExcludeFromIndexes = !prop.HasAttribute(typeof(IndexAttribute))
            };

            var propValue = prop.GetValue(poco);

            if (SetValue(prop.PropertyType.GetTypeOrUnderlyingNullableType(), value, propValue, entityFactory, recursionPath))
            {
                return(value);
            }

            throw new NotSupportedException($"The type {prop.PropertyType.Name} is not supported");
        }
Example #2
0
        private static bool SetValue(Type type, Value value, object propValue, IEntityFactory entityFactory, IList <string> recursionPath)
        {
            if (HandleNull(type, value, propValue, entityFactory))
            {
                return(true);
            }
            if (HandleEnum(type, value, propValue, entityFactory))
            {
                return(true);
            }
            if (HandleBinary(type, value, propValue, entityFactory))
            {
                return(true);
            }
            if (HandleString(type, value, propValue, entityFactory))
            {
                return(true);
            }
            if (HandleEnumerable(type, value, propValue, entityFactory, recursionPath))
            {
                return(true);
            }
            if (HandleBasicTypes(type, value, propValue, entityFactory))
            {
                return(true);
            }
            if (HandleComplexType(type, value, propValue, entityFactory, recursionPath))
            {
                return(true);
            }

            return(false);
        }
Example #3
0
        private static bool HandleString(Type type, Value value, object propValue, IEntityFactory entityFactory)
        {
            if (type == typeof(string))
            {
                value.StringValue = (string)propValue;
                return(true);
            }

            return(false);
        }
Example #4
0
        private static bool HandleComplexType(Type type, Value value, object propValue, IEntityFactory entityFactory, IList <string> recursionPath)
        {
            if (type.GetTypeInfo().IsClass)
            {
                value.EntityValue = entityFactory.EmbeddedEntityFromPoco(propValue, recursionPath);
                return(true);
            }

            return(false);
        }
Example #5
0
        private static bool HandleNull(Type type, Value value, object propValue, IEntityFactory entityFactory)
        {
            if (propValue == null)
            {
                value.NullValue = NullValue.NullValue;
                return(true);
            }

            return(false);
        }
Example #6
0
        private static bool HandleEnum(Type type, Value value, object propValue, IEntityFactory entityFactory)
        {
            if (type.GetTypeInfo().IsEnum)
            {
                value.StringValue = propValue.ToString();
                return(true);
            }

            return(false);
        }
Example #7
0
        private static bool HandleBinary(Type type, Value value, object propValue, IEntityFactory entityFactory)
        {
            if (type.Name.Equals("Byte[]"))
            {
                var theBytes = (byte[])propValue;
                value.BlobValue = ByteString.CopyFrom(theBytes, 0, theBytes.Length);
                return(true);
            }

            return(false);
        }
Example #8
0
        private object CreateObjectFromValue(Value value, Type requestedType)
        {
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.StringValue)
            {
                return(value.StringValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.IntegerValue)
            {
                if (requestedType == typeof(int) || requestedType == typeof(int?))
                {
                    return((int)value.IntegerValue);
                }
                if (requestedType.IsEnum)
                {
                    return((int)value.IntegerValue);
                }
                return(value.IntegerValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.BooleanValue)
            {
                return(value.BooleanValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.DoubleValue)
            {
                return(value.DoubleValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.TimestampValue)
            {
                return(value.TimestampValue.ToDateTime());
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.EntityValue)
            {
                if (value.EntityValue.Properties.ContainsKey(TypesMetadataLoader.InheritedTypePropertyName)) // Handle abstract class
                {
                    var inheritedTypeName = value.EntityValue.Properties[TypesMetadataLoader.InheritedTypePropertyName].StringValue;
                    var inheritedType     = _typesMetadataLoader.GetTypeMetadata(inheritedTypeName);
                    return(FromEntity(value.EntityValue, inheritedType));
                }
                return(FromEntity(value.EntityValue, requestedType));
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.ArrayValue)
            {
                var typeMetadata = _typesMetadataLoader.GetTypeMetadata(requestedType) as ListMetadata;
                var obj          = typeMetadata.Constructor();
                foreach (var item in value.ArrayValue.Values)
                {
                    typeMetadata.AddItem(obj, CreateObjectFromValue(item, typeMetadata.ItemsType));
                }

                return(obj);
            }
            return(null);
        }
Example #9
0
        private static bool HandleEnumerable(Type type, Value value, object propValue, IEntityFactory entityFactory, IList <string> recursionPath)
        {
            if (type.ImplementsInterface(typeof(IEnumerable)))
            {
                value.ExcludeFromIndexes = false; // Exclude from indexes cannot be set on a list value
                value.ArrayValue         = new ArrayValue();

                foreach (object item in (IEnumerable)propValue)
                {
                    var itemValue = new Value();
                    SetValue(item.GetType(), itemValue, item, entityFactory, recursionPath);

                    value.ArrayValue.Values.Add(itemValue);
                }
                return(true);
            }

            return(false);
        }
        private object CreateObjectFromValue(Value value, System.Type requestedType, System.Type thisEntityType = null)
        {
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.StringValue)
            {
                return(value.StringValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.IntegerValue)
            {
                if (requestedType == typeof(int) || requestedType == typeof(int?))
                {
                    return((int)value.IntegerValue);
                }
                if (requestedType.GetTypeInfo().IsEnum)
                {
                    return((int)value.IntegerValue);
                }
                return(value.IntegerValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.BooleanValue)
            {
                return(value.BooleanValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.DoubleValue)
            {
                return(value.DoubleValue);
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.TimestampValue)
            {
                if (requestedType == typeof(DateTimeOffset))
                {
                    return(value.TimestampValue.ToDateTimeOffset());
                }
                return(value.TimestampValue.ToDateTime());
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.EntityValue)
            {
                if (thisEntityType != null)
                {
                    return(FromEntity(value.EntityValue, thisEntityType));
                }
                return(FromEntity(value.EntityValue, requestedType));
            }
            if (value.ValueTypeCase == Value.ValueTypeOneofCase.ArrayValue)
            {
                var requestedTypeInfo = requestedType.GetTypeInfo();
                var isDictionary      = requestedTypeInfo.IsGenericType &&
                                        requestedTypeInfo.GetGenericTypeDefinition() == typeof(IDictionary <,>);

                if (isDictionary)
                {
                    var t1         = requestedType.GetGenericArguments()[0];
                    var t2         = requestedType.GetGenericArguments()[1];
                    var dictType   = typeof(Dictionary <,>).MakeGenericType(t1, t2);
                    var dictionary = (IDictionary)Activator.CreateInstance(dictType);

                    // TODO: Implement mapping of Dicitionary collection here.
                    foreach (var item in value.ArrayValue.Values)
                    {
                    }

                    return(dictionary);
                }

                var list        = (IList)Activator.CreateInstance(requestedType);
                var listArgType = requestedType.GetGenericArguments()[0];
                foreach (var item in value.ArrayValue.Values)
                {
                    list.Add(CreateObjectFromValue(item, listArgType));
                }

                return(list);
            }
            return(null);
        }
        private Value CreateValueFromObject(object obj, bool isExcludeFromIndex = false)
        {
            var value = new Value {
                ExcludeFromIndexes = isExcludeFromIndex
            };

            if (obj == null)
            {
                value.NullValue = NullValue.NullValue;
                return(value);
            }

            var type = obj.GetType();

            if (type == typeof(string))
            {
                value.StringValue = (string)obj;
            }
            else if (type == typeof(int))
            {
                value.IntegerValue = (int)obj;
            }
            else if (type == typeof(long))
            {
                value.IntegerValue = (long)obj;
            }
            else if (type == typeof(double))
            {
                value.DoubleValue = (double)obj;
            }
            else if (type == typeof(float))
            {
                value.DoubleValue = (float)obj;
            }
            else if (type == typeof(bool))
            {
                value.BooleanValue = (bool)obj;
            }
            else if (type == typeof(DateTime))
            {
                value.TimestampValue = ((DateTime)obj).ToTimestamp();
            }
            else if (type == typeof(DateTimeOffset))
            {
                value.TimestampValue = ((DateTimeOffset)obj).ToTimestamp();
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                value.IntegerValue = (int)obj;
            }
            else if (typeof(ICollection).IsAssignableFrom(type))
            {
                var list = obj as ICollection;
                value.ArrayValue = new ArrayValue();

                if (list != null) //TODO: Otherwise should add warn logs
                {
                    foreach (var item in list)
                    {
                        value.ArrayValue.Values.Add(CreateValueFromObject(item));
                    }
                }
            }
            else if (type.GetTypeInfo().IsClass)
            {
                value.EntityValue = new Entity();

                foreach (var property in type.GetRuntimeProperties())
                {
                    var propName  = property.Name;
                    var propValue = property.GetValue(obj);
                    value.EntityValue.Properties.Add(propName, CreateValueFromObject(propValue)); // TODO: Should call ToEntity - but should have depth consideration in regarding to the key
                }
            }

            return(value);
        }
Example #12
0
        private Value CreateValueFromObject(object obj, bool isExcludeFromIndex = false)
        {
            var value = new Value {
                ExcludeFromIndexes = isExcludeFromIndex
            };

            if (obj == null)
            {
                value.NullValue = NullValue.NullValue;
                return(value);
            }

            var type = obj.GetType();

            if (type == typeof(string))
            {
                value.StringValue = (string)obj;
            }
            else if (type == typeof(int))
            {
                value.IntegerValue = (int)obj;
            }
            else if (type == typeof(long))
            {
                value.IntegerValue = (long)obj;
            }
            else if (type == typeof(double))
            {
                value.DoubleValue = (double)obj;
            }
            else if (type == typeof(float))
            {
                value.DoubleValue = (float)obj;
            }
            else if (type == typeof(bool))
            {
                value.BooleanValue = (bool)obj;
            }
            else if (type == typeof(DateTime))
            {
                value.TimestampValue = ((DateTime)obj).ToTimestamp();
            }
            else if (type.IsEnum)
            {
                value.IntegerValue = (int)obj;
            }
            else if (typeof(ICollection).IsAssignableFrom(type))
            {
                var list = obj as ICollection;
                value.ArrayValue = new ArrayValue();
                var listType = _typesMetadataLoader.GetTypeMetadata(type);
                if (listType != null && list != null) //TODO: Otherwise should add warn logs
                {
                    foreach (var item in list)
                    {
                        value.ArrayValue.Values.Add(CreateValueFromObject(item));
                    }
                }
            }
            else if (type.IsClass)
            {
                value.EntityValue = new Entity();
                var classMetadata = _typesMetadataLoader.GetTypeMetadata(type);
                if (classMetadata != null)
                {
                    if (!string.IsNullOrEmpty(classMetadata.InheritedClassType))
                    {
                        value.EntityValue.Properties.Add(TypesMetadataLoader.InheritedTypePropertyName, classMetadata.InheritedClassType);
                    }

                    foreach (var property in classMetadata.PropertiesInfo)
                    {
                        var val = property.Value.Get(obj);
                        value.EntityValue.Properties.Add(property.Key, CreateValueFromObject(val, IsExcludeColumnFromIndex(property.Value.CustomAttributes))); // TODO: Should call ToEntity - but should have depth consideration in regarding to the key
                    }
                }
            }

            return(value);
        }
        protected override void ProcessRecord()
        {
            base.ProcessRecord();
            var db         = DatastoreDb.Create(Project);
            var keyFactory = db.CreateKeyFactory(Kind);

            _gKey = string.IsNullOrEmpty(Key) ? keyFactory.CreateIncompleteKey() : keyFactory.CreateKey(Key);

            var entity = new Entity();

            entity.Key = _gKey;
            foreach (var k in Properties.Keys)
            {
                var val = new Value();

                switch (Properties[k])
                {// I'm surprised there's no built in method in Value to handle this scenario
                case NullValue c:
                {
                    val.NullValue = c;
                    break;
                }

                case bool c:
                {
                    val.BooleanValue = c;
                    break;
                }

                case int c:
                {
                    val.IntegerValue = (long)c;
                    break;
                }

                case long c:
                {
                    val.IntegerValue = c;
                    break;
                }

                case float c:
                {
                    val.DoubleValue = (double)c;
                    break;
                }

                case double c:
                {
                    val.DoubleValue = c;
                    break;
                }

                case Timestamp c:
                {
                    val.TimestampValue = c;
                    break;
                }

                case DateTime c:
                {
                    val.TimestampValue = c.ToTimestamp();
                    break;
                }

                case Cloud.Datastore.V1.Key c:
                {
                    val.KeyValue = c;
                    break;
                }

                case string c:
                {
                    val.StringValue = c;
                    break;
                }

                case byte[] c:
                {
                    if (c.Length > 1000000)
                    {
                        var e  = new ArgumentException("Max byte count exceeded");
                        var er = new ErrorRecord(e, "ByteCountLimitExceeded", ErrorCategory.InvalidData, Properties);
                        ThrowTerminatingError(er);
                    }

                    val.BlobValue = ByteString.CopyFrom(c);
                    break;
                }

                case LatLng c:
                {
                    val.GeoPointValue = c;
                    break;
                }

                case Entity c:
                {
                    val.EntityValue = c;
                    break;
                }

                case ArrayValue c:
                {
                    val.ArrayValue = c;
                    break;
                }

                default:
                {
                    // It's either this or throw - not sure of best approach
                    WriteWarning($"Unexpected type in properties dictionary: {Properties[k].GetType().FullName}");
                    val.StringValue = Properties[k].ToString();
                    break;
                }
                }

                entity.Properties.Add(k.ToString(), val);
            }

            WriteObject(entity);
        }
Example #14
0
        private static bool HandleBasicTypes(Type type, Value value, object propValue, IEntityFactory entityFactory)
        {
            switch (type.Name)
            {
            case "Char":
                value.StringValue = propValue.ToString();
                break;

            case "Boolean":
                value.BooleanValue = (bool)propValue;
                break;

            case "Byte":
                value.IntegerValue = (byte)propValue;
                break;

            case "Int16":
                value.IntegerValue = (short)propValue;
                break;

            case "Int32":
                value.IntegerValue = (int)propValue;
                break;

            case "Int64":
                value.IntegerValue = (long)propValue;
                break;

            case "Single":
                value.DoubleValue = double.Parse(propValue.ToString());
                break;

            case "Double":
                value.DoubleValue = (double)propValue;
                break;

            case "Decimal":
                var dec      = (decimal)propValue;
                var integral = Convert.ToInt64(decimal.Truncate(dec));
                var fraction = Convert.ToDouble(dec % 1m);
                value.EntityValue = new Entity
                {
                    ["integral"] = new Value
                    {
                        IntegerValue       = integral,
                        ExcludeFromIndexes = true
                    },
                    ["fraction"] = new Value
                    {
                        DoubleValue        = fraction,
                        ExcludeFromIndexes = true
                    }
                };
                break;

            case "DateTime":
                value.TimestampValue = Timestamp.FromDateTime((DateTime)propValue);
                break;

            case "DateTimeOffset":
                value.TimestampValue = Timestamp.FromDateTimeOffset((DateTimeOffset)propValue);
                break;

            case "TimeSpan":
                value.IntegerValue = ((TimeSpan)propValue).Ticks;
                break;

            default:
                return(false);
            }

            return(true);
        }