/// <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)); }
/// <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)); }
/// <summary> /// Gets the value from the model. /// </summary> protected virtual object GetValue(ModelBase model) { return(model.GetValue(Property)); }
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); }
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++; } } } }
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); } }
/// <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)); }