예제 #1
0
        /// <summary>
        /// Gets the primary key value of a model.
        /// </summary>
        /// <param name="model">The model to get the primary key for.</param>
        /// <returns>The primary key of the model.</returns>
        public virtual int GetKey(ModelBase model)
        {
            if (PrimaryKeyProperty == null)
            {
                throw new InvalidOperationException("Could not determine primary key for " + GetType().Name);
            }

            return((int)model.GetValue(PrimaryKeyProperty));
        }
예제 #2
0
        /// <summary>
        /// Commits changes made to a model to a database.
        /// </summary>
        /// <param name="model">The model to commit.</param>
        /// <param name="database">The database to commit to.</param>
        /// <returns><c>true</c> if the model was committed, <c>false</c> if not.</returns>
        public bool Commit(ModelBase model, IDatabase database)
        {
            if (AreResultsReadOnly)
            {
                return(false);
            }

            object value           = model.GetValue(CollectionFilterKeyProperty);
            int    parentRecordKey = (value != null) ? (int)value : 0;

            return(UpdateRows((ICollection <TCollection>)model, parentRecordKey, database));
        }
예제 #3
0
 /// <summary>
 /// Gets the value from the model.
 /// </summary>
 protected virtual object GetValue(ModelBase model)
 {
     return(model.GetValue(Property));
 }
예제 #4
0
        private bool UpdateRow(ModelBase model, IDatabase database, string tableName, IEnumerable <int> tablePropertyKeys, ModelProperty whereProperty, string whereFieldName)
        {
            Debug.Assert(whereFieldName != null);

            var dataModel          = model as DataModelBase;
            var modifiedProperties = new List <ModelProperty>();

            foreach (var propertyKey in tablePropertyKeys)
            {
                var property = ModelProperty.GetPropertyForKey(propertyKey);
                if (dataModel == null || dataModel.UpdatedPropertyKeys.Contains(propertyKey))
                {
                    modifiedProperties.Add(property);
                }
            }

            if (modifiedProperties.Count > 0)
            {
                var builder = new StringBuilder();
                builder.Append("UPDATE ");
                builder.Append(tableName);
                builder.Append(" SET ");

                foreach (var property in modifiedProperties)
                {
                    var fieldMetadata = GetFieldMetadata(property);

                    builder.Append(fieldMetadata.FieldName);
                    builder.Append('=');

                    var value = model.GetValue(property);
                    value = CoerceValueToDatabase(property, fieldMetadata, value);
                    AppendQueryValue(builder, value, fieldMetadata, database);

                    builder.Append(", ");
                }

                builder.Length -= 2;

                builder.Append(" WHERE ");
                builder.Append(whereFieldName);
                builder.Append("=");

                var whereFieldMetadata = GetFieldMetadata(whereProperty);
                var whereValue         = model.GetValue(whereProperty);
                whereValue = CoerceValueToDatabase(whereProperty, whereFieldMetadata, whereValue);
                AppendQueryValue(builder, whereValue, whereFieldMetadata, database);

                try
                {
                    if (database.ExecuteCommand(builder.ToString()) != 1)
                    {
                        return(false);
                    }
                }
                catch (Exception)
                {
                    return(false);
                }
            }

            var refreshProperties = new List <ModelProperty>();

            foreach (var propertyKey in tablePropertyKeys)
            {
                var property      = ModelProperty.GetPropertyForKey(propertyKey);
                var fieldMetadata = GetFieldMetadata(property);
                if ((fieldMetadata.Attributes & InternalFieldAttributes.RefreshAfterCommit) != 0)
                {
                    refreshProperties.Add(property);
                    break;
                }
            }

            if (refreshProperties.Count > 0)
            {
                RefreshAfterCommit(model, database, refreshProperties, new[] { whereProperty });
            }

            return(true);
        }
예제 #5
0
        private void RefreshAfterCommit(ModelBase model, IDatabase database, IEnumerable <ModelProperty> refreshProperties, IEnumerable <ModelProperty> propertiesToMatch)
        {
            var builder = new StringBuilder();

            builder.Append("SELECT ");

            string tableName = null;

            foreach (var property in refreshProperties)
            {
                var fieldMetadata = GetFieldMetadata(property);
                if (fieldMetadata is AutoIncrementFieldMetadata)
                {
                    builder.Append("MAX(");
                    builder.Append(fieldMetadata.FieldName);
                    builder.Append(")");
                }
                else
                {
                    builder.Append(fieldMetadata.FieldName);
                }

                builder.Append(", ");

                if (tableName == null)
                {
                    tableName = GetTableName(fieldMetadata.FieldName);
                }
            }

            if (tableName == null)
            {
                return;
            }

            builder.Length -= 2;
            builder.Append(" FROM ");
            builder.Append(tableName);
            builder.Append(" WHERE ");

            foreach (var property in propertiesToMatch)
            {
                var fieldMetadata = GetFieldMetadata(property);
                var value         = model.GetValue(property);
                value = CoerceValueToDatabase(property, fieldMetadata, value);
                builder.Append('[');

                var foreignKeyMetadata = fieldMetadata as ForeignKeyFieldMetadata;
                if (foreignKeyMetadata != null)
                {
                    var fieldName = fieldMetadata.FieldName;
                    if (fieldName.Length < tableName.Length + 1 || fieldName[tableName.Length] != '.' || !fieldName.StartsWith(tableName))
                    {
                        fieldName = foreignKeyMetadata.RelatedField.FieldName;
                    }

                    builder.Append(fieldName);
                }
                else
                {
                    builder.Append(fieldMetadata.FieldName);
                }

                builder.Append(']');
                builder.Append('=');
                AppendQueryValue(builder, value, fieldMetadata, database);
                builder.Append(" AND ");
            }
            builder.Length -= 5;

            var queryString = builder.ToString();

            using (var query = database.PrepareQuery(queryString))
            {
                if (query.FetchRow())
                {
                    int index = 0;
                    foreach (var property in refreshProperties)
                    {
                        var fieldMetadata = GetFieldMetadata(property);
                        var value         = GetQueryValue(query, index, fieldMetadata);
                        value = CoerceValueFromDatabase(property, fieldMetadata, value);
                        model.SetValue(property, value);
                        index++;
                    }
                }
            }
        }
예제 #6
0
        private bool CreateRow(ModelBase model, IDatabase database, string tableName, IEnumerable <int> tablePropertyKeys, ModelProperty joinProperty, string joinFieldName)
        {
            bool onlyDefaults      = (joinFieldName != null);
            var  properties        = new List <ModelProperty>();
            var  refreshProperties = new List <ModelProperty>();

            foreach (var propertyKey in tablePropertyKeys)
            {
                var property      = ModelProperty.GetPropertyForKey(propertyKey);
                var fieldMetadata = GetFieldMetadata(property);
                if ((fieldMetadata.Attributes & InternalFieldAttributes.GeneratedByCreate) == 0)
                {
                    if (onlyDefaults && model.GetValue(property) != property.DefaultValue)
                    {
                        onlyDefaults = false;
                    }

                    properties.Add(property);
                }

                if ((fieldMetadata.Attributes & InternalFieldAttributes.RefreshAfterCommit) != 0)
                {
                    refreshProperties.Add(property);
                }
            }

            if (properties.Count == 0 || onlyDefaults)
            {
                return(true);
            }

            var builder = new StringBuilder();

            builder.Append("INSERT INTO ");
            builder.Append(tableName);
            builder.Append(" (");

            if (joinFieldName != null)
            {
                builder.Append('[');
                builder.Append(GetFieldName(joinFieldName));
                builder.Append("], ");
            }

            foreach (var property in properties)
            {
                var fieldMetadata = GetFieldMetadata(property);
                var fieldName     = GetFieldName(fieldMetadata.FieldName);
                builder.Append('[');
                builder.Append(fieldName);
                builder.Append("], ");
            }

            builder.Length -= 2;
            builder.Append(") VALUES (");

            if (joinFieldName != null)
            {
                var fieldMetadata = GetFieldMetadata(joinProperty);
                var value         = model.GetValue(joinProperty);
                value = CoerceValueToDatabase(joinProperty, fieldMetadata, value);
                AppendQueryValue(builder, value, GetFieldMetadata(joinProperty), database);
                builder.Append(", ");
            }

            var values = new TinyDictionary <FieldMetadata, object>();

            foreach (var property in properties)
            {
                var fieldMetadata = GetFieldMetadata(property);
                var value         = model.GetValue(property);

                object previousValue;
                if (values.TryGetValue(fieldMetadata, out previousValue))
                {
                    if (!Object.Equals(value, previousValue))
                    {
                        throw new InvalidOperationException("Cannot set " + fieldMetadata.FieldName + " to '" + previousValue + "' and '" + value + "'");
                    }
                }
                else
                {
                    value = CoerceValueToDatabase(property, fieldMetadata, value);
                    values[fieldMetadata] = value;

                    AppendQueryValue(builder, value, fieldMetadata, database);
                    builder.Append(", ");
                }
            }

            builder.Length -= 2;
            builder.Append(')');

            try
            {
                if (database.ExecuteCommand(builder.ToString()) == 0)
                {
                    return(false);
                }

                if (refreshProperties.Count > 0)
                {
                    RefreshAfterCommit(model, database, refreshProperties, properties);
                }

                return(true);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message + ": " + builder.ToString());
                return(false);
            }
        }
예제 #7
0
 /// <summary>
 /// Gets the primary key value of a model.
 /// </summary>
 /// <param name="model">The model to get the primary key for.</param>
 /// <returns>The primary key of the model.</returns>
 int IDatabaseModelMetadata.GetKey(ModelBase model)
 {
     return((int)model.GetValue(CollectionFilterKeyProperty));
 }