private static string GetValueForField(FieldDefinition fieldDefinition, IInternalState state) { string format = fieldDefinition.Format; var columnDescriber = new ColumnDescriber(fieldDefinition.Name, fieldDefinition.Table); if(fieldDefinition.Type.IsIn(FieldDefinitionType.DateTime)) { var dateTime = state.Get<DateTime?>(columnDescriber); if (!dateTime.HasValue) return fieldDefinition.Default; // DateTime needs a format specifier return !format.IsNullOrEmpty() ? dateTime.Value.ToString(format, CultureInfo.InvariantCulture) : dateTime.Value.ToShortDateString(); } if(fieldDefinition.Type.IsIn(FieldDefinitionType.Amount, FieldDefinitionType.InvertedAmount, FieldDefinitionType.Decimal)) { var money = state.Get<Money>(columnDescriber); if (money.IsEmpty) return fieldDefinition.Default; if (fieldDefinition.Type == FieldDefinitionType.InvertedAmount) money *= -1; return ToString(money, format); } if(fieldDefinition.Type.IsIn(FieldDefinitionType.Int16, FieldDefinitionType.Int32, FieldDefinitionType.Int64)) { var value = state.Get<long?>(columnDescriber); return !value.HasValue ? fieldDefinition.Default : ToString(value, format); } return !state.Get<string>(columnDescriber).IsNullOrEmpty() ? state.Get<string>(columnDescriber) : fieldDefinition.Default; }
/// <summary> /// Save the specified data of <see cref="IInternalState"/> into database. /// </summary> /// <param name="query">The <see cref="IAdfQuery"/> that defines the datasource name and query statement.</param> /// <param name="data">The data of <see cref="IInternalState"/> that needs to be saved.</param> /// <returns>True if data is successfully saved; otherwise, false. /// This method also returns false if <see cref="IAdfQuery"/> or <see cref="IInternalState"/> is null.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="System.Data.DBConcurrencyException">An attempt to execute an INSERT, UPDATE, or DELETE statement resulted in zero records affected.</exception> public bool Save(IAdfQuery query, IInternalState data) { var result = false; if (query == null || data == null) return false; if (!data.IsAltered) return true; var rowState = data as RowState; if (rowState == null) return false; var row = rowState.BuildUpDataRow(); if (row == null) return false; IDbConnection connection = Provider.GetConnection(DataSource); IDbDataAdapter da = Provider.SetUpAdapter(DataSource, connection, query); try { if (connection.State == ConnectionState.Closed) connection.Open(); IDbTransaction transaction = Provider.GetTransaction(DataSource); if (transaction != null) da.SelectCommand.Transaction = transaction; var autoincrement = row.Table.Columns.Cast<DataColumn>().FirstOrDefault(column => column.AutoIncrement); if (autoincrement != null) { da.InsertCommand.CommandText += "; if (IsNumeric(SCOPE_IDENTITY()) = 1) select SCOPE_IDENTITY() as " + autoincrement.ColumnName; } var count = Provider.Update(da, row); // The count should never be more than 1, since we request to update only 1 record. If the count is more than 1, // it means that the Provider updates the DataSet instead of the DataRow. if (count != 1) throw new DataException(string.Format("Saving {0} ({1}) changed {2} rows", query.LeadTable(), rowState.ID, count)); rowState.AcceptChanges(); result = true; } catch (Exception exception) { Provider.HandleException(exception, DataSource, query); } finally { if (da.SelectCommand.Transaction == null) connection.Close(); } return result; }
public static Record Create(this RecordDefinition recordDefinition, IInternalState state) { return new Record {DomainObjectName = recordDefinition.DomainObjectName, State = state }; }
private static string CreateLine(RecordDefinition recordDefinition, IInternalState state) { var columns = new List<string>(); int currentPosition = 0; foreach (FieldDefinition fieldDefinition in recordDefinition.Fields) { while (currentPosition < fieldDefinition.StartPosition) { columns.Add(string.Empty); currentPosition++; } columns.Add(GetValueForField(fieldDefinition, state)); currentPosition++; } return string.Join(recordDefinition.FieldSeparator, columns); }
/// <summary> /// Save the specified data of <see cref="IInternalState"/> into database. /// </summary> /// <param name="query">The <see cref="IAdfQuery"/> that defines the datasource name and query statement.</param> /// <param name="data">The data of <see cref="IInternalState"/> that needs to be saved.</param> /// <returns>True if data is successfully saved; otherwise, false. /// This method also returns false if <see cref="IAdfQuery"/> or <see cref="IInternalState"/> is null.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="System.Data.DBConcurrencyException">An attempt to execute an INSERT, UPDATE, or DELETE statement resulted in zero records affected.</exception> public bool Save(IAdfQuery query, IInternalState data) { var result = false; if (query == null || data == null) return false; if (!data.IsAltered) return true; var row = data as RowState; if (row == null) return false; var set = row.BuildUpDataSet(); if (set == null) return false; IDbConnection connection = Provider.GetConnection(DataSource); IDbDataAdapter da = Provider.SetUpAdapter(DataSource, connection, query); try { if (connection.State == ConnectionState.Closed) connection.Open(); IDbTransaction transaction = Provider.GetTransaction(DataSource); if (transaction != null) da.SelectCommand.Transaction = transaction; var autoincrement = set.Tables[0].Columns.Cast<DataColumn>().FirstOrDefault(column => column.AutoIncrement); if (autoincrement != null) { da.InsertCommand.CommandText += "; if (IsNumeric(SCOPE_IDENTITY()) = 1) select SCOPE_IDENTITY() as " + autoincrement.ColumnName; } var count = da.Update(set); // this DataRow keeps a reference to his DataSet, possibly containing more items (results of a query), // so updating the DataSet will save also other rows if they are modified! // Bug: this is a serious bug, should be fixed as soon as possible! if (count != 1) throw new DataException(string.Format("Saving {0} ({1}) changed {2} rows", query.LeadTable(), row.ID, count)); set.AcceptChanges(); row.AcceptChanges(); result = true; } catch (Exception exception) { Provider.HandleException(exception, DataSource, query); } finally { if (da.SelectCommand.Transaction == null) connection.Close(); } return result; }
/// <summary> /// Saved the specified data of <see cref="IInternalState"/> into database. /// </summary> /// <param name="datasource">the datasource to run the query against</param> /// <param name="query">The <see cref="IAdfQuery"/> that defines the datasource name and query statement.</param> /// <param name="state">The data of <see cref="IInternalState"/> that needs to be saved.</param> /// <returns>True if data is successfully saved; otherwise, false. /// This method also returns false if <see cref="IAdfQuery"/> or <see cref="IInternalState"/> is null.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> public static bool Save(DataSources datasource, IAdfQuery query, IInternalState state) { using (new TracingScope()) { return query != null && state != null && GetHandler(datasource).Save(query, state); } }
/// <summary> /// Save the specified data of <see cref="IInternalState"/> into database. /// </summary> /// <param name="query">The <see cref="IAdfQuery"/> that defines the datasource name and query statement.</param> /// <param name="data">The data of <see cref="IInternalState"/> that needs to be saved.</param> /// <returns>True if data is successfully saved; otherwise, false. /// This method also returns false if <see cref="IAdfQuery"/> or <see cref="IInternalState"/> is null.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="System.Data.DBConcurrencyException">An attempt to execute an INSERT, UPDATE, or DELETE statement resulted in zero records affected.</exception> public bool Save(IAdfQuery query, IInternalState data) { if (query == null) throw new ArgumentNullException("query"); if (data == null) throw new ArgumentNullException("data"); if (!data.IsAltered) return true; var state = data as DictionaryState; if (state == null) throw new InvalidOperationException("State is not a " + typeof(DictionaryState)); var table = query.Tables[0]; var q = new AdfQuery() .From(table); q.QueryType = state.IsNew ? QueryType.Insert : QueryType.Update; foreach (var col in state) { if (col.Key.IsAutoIncrement || col.Key.IsTimestamp) continue; // auto increment fields are not saved if (col.Key.IsIdentity && !state.IsNew) continue; // primary key is not saved when object is not new q.Selects.Add(new Expression { Column = col.Key, Type = ExpressionType.Column }); q.Wheres.Add(new Where { Column = col.Key, Parameter = new Parameter(col.Value, ParameterType.QueryParameter) }); } if (!state.IsNew) { var timestamp = state.Keys.FirstOrDefault(col => col.IsTimestamp); if (timestamp == null) throw new InvalidOperationException("Cannot save this state as it does not have a timestamp"); q .Where(timestamp).IsEqual(state[timestamp]) .Where(state.PrimaryKey).IsEqual(state[state.PrimaryKey]); } return RunSave(state, q); }
/// <summary> /// Save the data into SmartReference table. /// </summary> /// <param name="state">The data of <see cref="IInternalState"/> that needs to be saved.</param> /// <returns>True if record saved successfully; otherwise, false.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> public static bool Save(IInternalState state) { if (state == null) throw new ArgumentNullException("state"); return new AdfQuery() .Select() .From(SmartReferenceDescriber.Table) .Save(DataSource, state); }
/// <summary> /// Delete the record from SmartReference table. /// </summary> /// <param name="state">The data of <see cref="IInternalState"/> that needs to be removed.</param> /// <returns>True if record deleted successfully; otherwise, false.</returns> /// <exception cref="System.InvalidOperationException">The current state of the connection is closed.</exception> public static bool Remove(IInternalState state) { if (state == null) throw new ArgumentNullException("state"); return new AdfQuery() .From(SmartReferenceDescriber.Table) .Where(SmartReferenceDescriber.Id).IsEqual(state.ID) .Remove(DataSource) == 1; }