コード例 #1
0
        /// <summary>
        /// Applies the system property attribute to the property by renaming the property to the
        /// system property name.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="member">The <see cref="MemberInfo"/> that corresponds to the property.</param>
        private static void ApplySystemPropertyAttributes(JsonProperty property, MemberInfo member)
        {
            // Check for system property attributes
            MobileServiceSystemProperties systemProperties = MobileServiceSystemProperties.None;

            foreach (object attribute in member.GetCustomAttributes(true))
            {
                ISystemPropertyAttribute systemProperty = attribute as ISystemPropertyAttribute;
                if (systemProperty != null)
                {
                    if (systemProperties != MobileServiceSystemProperties.None)
                    {
                        throw new InvalidOperationException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                "A member can only have one system property attribute. The member '{0}' on type '{1}' has system property attributes '{2}' and '{3}'.",
                                                member.Name,
                                                member.DeclaringType.FullName,
                                                systemProperty.SystemProperty,
                                                systemProperties));
                    }

                    property.PropertyName = GetSystemPropertyString(systemProperty.SystemProperty);
                    systemProperties      = systemProperty.SystemProperty;
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Searches over the properties and their names to determine which system properties
        /// have been applied to the type, and then adds an entry into the system properties cache
        /// for the type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="properties">The JsonProperties of the type.</param>
        private void AddSystemPropertyCacheEntry(Type type, IEnumerable <JsonProperty> properties)
        {
            MobileServiceSystemProperties systemProperties = MobileServiceSystemProperties.None;

            foreach (JsonProperty property in properties)
            {
                MobileServiceSystemProperties systemProperty = MobileServiceSystemProperties.None;
                if (!property.Ignored &&
                    systemPropertyNameToEnum.TryGetValue(property.PropertyName, out systemProperty))
                {
                    // Make sure there is not already a property that has been associated with
                    // the system property.
                    if ((systemProperties & systemProperty) == systemProperty)
                    {
                        throw new InvalidOperationException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                "Only one member may have the property name '{0}' (regardless of casing) on type '{1}'.",
                                                property.PropertyName,
                                                type.FullName));
                    }
                    else
                    {
                        systemProperties |= systemProperty;
                    }
                }
            }

            this.systemPropertyCache[type] = systemProperties;
        }
コード例 #3
0
        /// <summary>
        /// Returns the system properties as a comma seperated list for a
        /// given type. Returns null if the type does not support system properties.
        /// </summary>
        /// <param name="type">The type for which to get the system properties.</param>
        /// <returns>
        /// The system properties as a comma seperated list for the given type or null
        /// if the type does not support system properties.
        /// </returns>
        public virtual MobileServiceSystemProperties ResolveSystemProperties(Type type)
        {
            MobileServiceSystemProperties systemProperties = MobileServiceSystemProperties.None;

            this.systemPropertyCache.TryGetValue(type, out systemProperties);
            return(systemProperties);
        }
コード例 #4
0
        /// <summary>
        /// Searches over the properties and their names to determine which system properties
        /// have been applied to the type, and then adds an entry into the system properties cache
        /// for the type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="properties">The JsonProperties of the type.</param>
        private void AddSystemPropertyCacheEntry(Type type, IEnumerable <JsonProperty> properties)
        {
            MobileServiceSystemProperties systemProperties = MobileServiceSystemProperties.None;

            foreach (JsonProperty property in properties)
            {
                MobileServiceSystemProperties systemProperty = MobileServiceSystemProperties.None;
                if (!property.Ignored &&
                    systemPropertyNameToEnum.TryGetValue(property.PropertyName, out systemProperty))
                {
                    // Make sure there is not already a property that has been associated with
                    // the system property.
                    if ((systemProperties & systemProperty) == systemProperty)
                    {
                        throw new InvalidOperationException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                Resources.MobileServiceContractResolver_SamePropertyName,
                                                property.PropertyName,
                                                type.FullName));
                    }
                    else
                    {
                        systemProperties |= systemProperty;
                    }
                }
            }

            this.systemPropertyCache[type] = systemProperties;
        }
コード例 #5
0
        /// <summary>
        /// Applies the system property attribute to the property by renaming the property to the
        /// system property name.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="member">The <see cref="MemberInfo"/> that corresponds to the property.</param>
        /// <param name="isIntegerIdType">Indicates if the type that the property is on, has an integer id type or not.</param>
        private static void ApplySystemPropertyAttributes(JsonProperty property, MemberInfo member, bool isIntegerIdType)
        {
            // Check for system property attributes
            MobileServiceSystemProperties systemProperties = MobileServiceSystemProperties.None;

            foreach (object attribute in member.GetCustomAttributes(true))
            {
                ISystemPropertyAttribute systemProperty = attribute as ISystemPropertyAttribute;
                if (systemProperty != null)
                {
                    if (isIntegerIdType)
                    {
                        throw new InvalidOperationException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                Resources.MobileServiceContractResolver_IntegerIdTypeWithSystemPropertyAttributes,
                                                member.DeclaringType.FullName,
                                                systemProperty.SystemProperty));
                    }

                    if (systemProperties != MobileServiceSystemProperties.None)
                    {
                        throw new InvalidOperationException(
                                  string.Format(CultureInfo.InvariantCulture,
                                                Resources.MobileServiceContractResolver_MultipleSystemPropertyAttributes,
                                                member.Name,
                                                member.DeclaringType.FullName,
                                                systemProperty.SystemProperty,
                                                systemProperties));
                    }

                    property.PropertyName = GetSystemPropertyString(systemProperty.SystemProperty);
                    systemProperties      = systemProperty.SystemProperty;
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Given a <see cref="MobileServiceSystemProperties"/> enum value, returns the string value with the
        /// correct casing and system property prefix.
        /// </summary>
        /// <param name="systemProperty">The system property.</param>
        /// <returns>A string of the system property with the correct casing and system property prefix.</returns>
        private static string GetSystemPropertyString(MobileServiceSystemProperties systemProperty)
        {
            string enumAsString       = systemProperty.ToString();
            char   firstLetterAsLower = char.ToLowerInvariant(enumAsString[0]);

            return(string.Format("{0}{1}{2}", MobileServiceSerializer.SystemPropertyPrefix, firstLetterAsLower, enumAsString.Substring(1)));
        }
コード例 #7
0
        /// <summary>
        /// Initializes a new instance of the MobileServiceTable class.
        /// </summary>
        /// <param name="tableName">
        /// The name of the table.
        /// </param>
        /// <param name="client">
        /// The <see cref="MobileServiceClient"/> associated with this table.
        /// </param>
        public MobileServiceTable(string tableName, MobileServiceClient client)
        {
            Debug.Assert(tableName != null);
            Debug.Assert(client != null);

            this.TableName           = tableName;
            this.MobileServiceClient = client;
            this.SystemProperties    = MobileServiceSystemProperties.None;
        }
        public async Task UpsertAsync(string tableName, IEnumerable <JObject> items, bool ignoreMissingColumns)
        {
            Arguments.IsNotNull(tableName, nameof(tableName));
            Arguments.IsNotNull(items, nameof(items));

            if (!tableName.StartsWith(MobileServiceLocalSystemTables.Prefix))
            {
                IDictionary <string, string> existingRecords = null;
                bool analyzeUpserts  = this.trackingContext.TrackingOptions.HasFlag(StoreTrackingOptions.DetectInsertsAndUpdates);
                bool supportsVersion = false;

                if (analyzeUpserts)
                {
                    MobileServiceSystemProperties systemProperties = await this.settings.GetSystemPropertiesAsync(tableName);

                    supportsVersion = systemProperties.HasFlag(MobileServiceSystemProperties.Version);

                    existingRecords = await GetItemsAsync(tableName, items.Select(i => this.objectReader.GetId(i)), supportsVersion);
                }

                await this.store.UpsertAsync(tableName, items, ignoreMissingColumns);

                foreach (var item in items)
                {
                    string itemId = this.objectReader.GetId(item);
                    LocalStoreOperationKind operationKind = LocalStoreOperationKind.Upsert;

                    if (analyzeUpserts)
                    {
                        if (existingRecords.ContainsKey(itemId))
                        {
                            operationKind = LocalStoreOperationKind.Update;

                            // If the update isn't a result of a local operation, check if the item exposes a version property
                            // and if we truly have a new version (an actual change) before tracking the change.
                            // This avoids update notifications for records that haven't changed, which would usually happen as a result of a pull
                            // operation, because of the logic used to pull changes.
                            if (this.trackingContext.Source != StoreOperationSource.Local && supportsVersion &&
                                string.Compare(existingRecords[itemId], item[MobileServiceSystemColumns.Version].ToString()) == 0)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            operationKind = LocalStoreOperationKind.Insert;
                        }
                    }

                    TrackStoreOperation(tableName, itemId, operationKind);
                }
            }
            else
            {
                await this.store.UpsertAsync(tableName, items, ignoreMissingColumns);
            }
        }
コード例 #9
0
        /// <summary>
        /// Initializes a new instance of the MobileServiceTable class.
        /// </summary>
        /// <param name="tableName">
        /// The name of the table.
        /// </param>
        /// <param name="client">
        /// The <see cref="MobileServiceClient"/> associated with this table.
        /// </param>
        public MobileServiceTable(string tableName, MobileServiceClient client)
        {
            Debug.Assert(tableName != null);
            Debug.Assert(client != null);

            this.TableName = tableName;
            this.MobileServiceClient = client;
            this.SystemProperties = MobileServiceSystemProperties.None;
        }
コード例 #10
0
        /// <summary>
        /// Checks if the given system property should be kept or removed from the returned item
        /// </summary>
        /// <param name="propertyName">
        /// Name of the system property to see if it should be removed
        /// </param>
        /// <param name="propertiesToKeep">
        /// The list of system properties to be kept
        /// </param>
        /// <param name="property">
        /// Type of the system property to check
        /// </param>
        /// <param name="systemPropertyName">
        /// Name of the actual system property to look for
        /// </param>
        private static bool IsKeptSystemProperty(string propertyName, MobileServiceSystemProperties propertiesToKeep, MobileServiceSystemProperties property, string systemPropertyName)
        {
            if ((propertiesToKeep & property) == property &&
                String.Equals(propertyName, systemPropertyName, StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            return(false);
        }
コード例 #11
0
        /// <summary>
        /// Adds the tables requested system properties to the parameters collection.
        /// </summary>
        /// <param name="systemProperties">The sytem properties to add.</param>
        /// <param name="parameters">The parameters collection.</param>
        /// <returns>
        /// The parameters collection with any requested system properties included.
        /// </returns>
        internal static IDictionary <string, string> AddSystemProperties(MobileServiceSystemProperties systemProperties, IDictionary <string, string> parameters)
        {
            // Make sure we have a case-insensitive parameters dictionary
            if (parameters != null)
            {
                parameters = new Dictionary <string, string>(parameters, StringComparer.OrdinalIgnoreCase);
            }

            // If there is already a user parameter for the system properties, just use it
            if (parameters == null || !parameters.ContainsKey(SystemPropertiesQueryParameterName))
            {
                string systemPropertiesString = GetSystemPropertiesString(systemProperties);
                if (systemPropertiesString != null)
                {
                    parameters = parameters ?? new Dictionary <string, string>();
                    parameters.Add(SystemPropertiesQueryParameterName, systemPropertiesString);
                }
            }

            return(parameters);
        }
コード例 #12
0
        /// <summary>
        /// Gets the system properties header value from the <see cref="MobileServiceSystemProperties"/>.
        /// </summary>
        /// <param name="properties">The system properties to set in the system properties header.</param>
        /// <returns>
        /// The system properties header value. Returns null if the systemProperty value is None.
        /// </returns>
        private static string GetSystemPropertiesString(MobileServiceSystemProperties properties)
        {
            if (properties == MobileServiceSystemProperties.None)
            {
                return(null);
            }
            if (properties == MobileServiceSystemProperties.All)
            {
                return("*");
            }

            string[] systemProperties = properties.ToString().Split(',');

            for (int i = 0; i < systemProperties.Length; i++)
            {
                string property           = systemProperties[i].Trim();
                char   firstLetterAsLower = char.ToLowerInvariant(property[0]);
                systemProperties[i] = MobileServiceSerializer.SystemPropertyPrefix + firstLetterAsLower + property.Substring(1);
            }

            string systemPropertiesString = string.Join(",", systemProperties);

            return(systemPropertiesString);
        }
コード例 #13
0
 /// <summary>
 /// Adds the tables requested system properties to the parameters collection.
 /// </summary>
 /// <param name="systemProperties">The sytem properties to add.</param>
 /// <param name="parameters">The parameters collection.</param>
 /// <returns>
 /// The parameters collection with any requested system properties included.
 /// </returns>
 internal static IDictionary<string, string> AddSystemProperties(MobileServiceSystemProperties systemProperties, IDictionary<string, string> parameters)
 {
     string systemPropertiesString = GetSystemPropertiesString(systemProperties);
     return AddSystemParameter(parameters, SystemPropertiesQueryParameterName, systemPropertiesString);
 }
コード例 #14
0
        /// <summary>
        /// Adds the tables requested system properties to the parameters collection.
        /// </summary>
        /// <param name="systemProperties">The sytem properties to add.</param>
        /// <param name="parameters">The parameters collection.</param>
        /// <returns>
        /// The parameters collection with any requested system properties included.
        /// </returns>
        internal static IDictionary <string, string> AddSystemProperties(MobileServiceSystemProperties systemProperties, IDictionary <string, string> parameters)
        {
            string systemPropertiesString = GetSystemPropertiesString(systemProperties);

            return(AddSystemParameter(parameters, SystemPropertiesQueryParameterName, systemPropertiesString));
        }
コード例 #15
0
        /// <summary>
        /// Gets the system properties header value from the <see cref="MobileServiceSystemProperties"/>.
        /// </summary>
        /// <param name="properties">The system properties to set in the system properties header.</param>
        /// <returns>
        /// The system properties header value. Returns null if the systemProperty value is None.
        /// </returns>
        private static string GetSystemPropertiesString(MobileServiceSystemProperties properties)
        {
            if (properties == MobileServiceSystemProperties.None)
            {
                return null;
            }
            if (properties == MobileServiceSystemProperties.All)
            {
                return "*";
            }

            string[] systemProperties = properties.ToString().Split(',');

            for (int i = 0; i < systemProperties.Length; i++)
            {
                string property = systemProperties[i].Trim();
                char firstLetterAsLower = char.ToLowerInvariant(property[0]);
                systemProperties[i] = MobileServiceSerializer.SystemPropertyPrefix + firstLetterAsLower + property.Substring(1);
            }

            string systemPropertiesString = string.Join(",", systemProperties);
            return systemPropertiesString;
        }
コード例 #16
0
        /// <summary>
        /// Adds the tables requested system properties to the parameters collection.
        /// </summary>
        /// <param name="systemProperties">The sytem properties to add.</param>
        /// <param name="parameters">The parameters collection.</param>
        /// <returns>
        /// The parameters collection with any requested system properties included.
        /// </returns>
        internal static IDictionary<string, string> AddSystemProperties(MobileServiceSystemProperties systemProperties, IDictionary<string, string> parameters)
        {
            // Make sure we have a case-insensitive parameters dictionary
            if (parameters != null)
            {
                parameters = new Dictionary<string, string>(parameters, StringComparer.OrdinalIgnoreCase);
            }

            // If there is already a user parameter for the system properties, just use it
            if (parameters == null || !parameters.ContainsKey(SystemPropertiesQueryParameterName))
            {
                string systemPropertiesString = GetSystemPropertiesString(systemProperties);
                if (systemPropertiesString != null)
                {
                    parameters = parameters ?? new Dictionary<string, string>();
                    parameters.Add(SystemPropertiesQueryParameterName, systemPropertiesString);
                }
            }

            return parameters;
        }
コード例 #17
0
 /// <summary>
 /// Given a <see cref="MobileServiceSystemProperty"/> enum value, returns the string value with the 
 /// correct casing and system property prefix.
 /// </summary>
 /// <param name="systemProperty">The system property.</param>
 /// <returns>A string of the system property with the correct casing and system property prefix.</returns>
 private static string GetSystemPropertyString(MobileServiceSystemProperties systemProperty)
 {
     string enumAsString = systemProperty.ToString();
     char firstLetterAsLower = char.ToLowerInvariant(enumAsString[0]);
     return string.Format("{0}{1}{2}", MobileServiceSerializer.SystemPropertyPrefix, firstLetterAsLower, enumAsString.Substring(1));
 }
コード例 #18
0
ファイル: TableDefinition.cs プロジェクト: phaufe/ZumoContrib
 public TableDefinition(IDictionary <string, ColumnDefinition> definition, MobileServiceSystemProperties systemProperties)
     : base(definition, StringComparer.OrdinalIgnoreCase)
 {
     this.SystemProperties = systemProperties;
 }
コード例 #19
0
        /// <summary>
        /// Removes all system properties from the instance
        /// if the instance is determined to have a string id and therefore be for table that
        /// supports system properties.
        /// </summary>
        /// <param name="instance">The instance to remove the system properties from.</param>
        /// <param name="version">Set to the value of the version system property before it is removed.</param>
        /// <param name="propertiesToKeep">The system properties to keep</param>        /// <returns>
        /// The instance with the system properties removed.
        /// </returns>
        public static JObject RemoveSystemProperties(JObject instance, out string version, MobileServiceSystemProperties propertiesToKeep = MobileServiceSystemProperties.None)
        {
            version = null;
            var systemProperties = new String[] { MobileServiceSerializer.CreatedAtSystemPropertyString, MobileServiceSerializer.DeletedSystemPropertyString, MobileServiceSerializer.VersionSystemPropertyString, MobileServiceSerializer.UpdatedAtSystemPropertyString }.AsEnumerable <String>();

            bool haveCloned = false;

            foreach (JProperty property in instance.Properties())
            {
                if (systemProperties.Contains(property.Name.ToLowerInvariant()))
                {
                    // We don't want to alter the original jtoken passed in by the caller
                    // so if we find a system property to remove, we have to clone first
                    if (!haveCloned)
                    {
                        instance   = instance.DeepClone() as JObject;
                        haveCloned = true;
                    }

                    if (String.Equals(property.Name, MobileServiceSystemColumns.Version, StringComparison.OrdinalIgnoreCase))
                    {
                        version = (string)instance[property.Name];
                        if ((propertiesToKeep & MobileServiceSystemProperties.Version) == MobileServiceSystemProperties.Version)
                        {
                            continue;
                        }
                    }
                    else if (propertiesToKeep == MobileServiceSystemProperties.All ||
                             IsKeptSystemProperty(property.Name, propertiesToKeep, MobileServiceSystemProperties.CreatedAt, MobileServiceSerializer.CreatedAtSystemPropertyString) ||
                             IsKeptSystemProperty(property.Name, propertiesToKeep, MobileServiceSystemProperties.UpdatedAt, MobileServiceSerializer.UpdatedAtSystemPropertyString))
                    {
                        continue;
                    }

                    instance.Remove(property.Name);
                }
            }

            return(instance);
        }