Exemplo n.º 1
0
 /// <summary>
 /// Updates row changes to database. Adds new rows, updates existing rows with changes and deletes rows that are marked to be deleted.
 ///             If row has any auto id columns defined those values are loaded from database after an insert.
 ///             When updating rows there are two ways that the row is identified. The first is using the concurrency setting on the table or the global setting 'Settings.UseConcurrenyChecking'. (Note the table overrides the global setting).
 ///             When this is ture the row is found by comparing all column values. If the row can't be found (i.e. Another process has altered the row) then a concurreny exception is thrown.
 ///             If Settings.UseConcurrenyChecking == false then the row is found by looking up primary key values. If the row doesn't have a primary key defined an exception is thrown.
 ///
 /// </summary>
 /// <param name="transaction"/><param name="discardRowAfterUpdate">If true the row is not updated internally when transaction is committed / rolled back.</param>
 public void Update(Transaction transaction, bool discardRowAfterUpdate)
 {
     if (transaction == null)
     {
         throw new CooqPreconditionException("transaction cannot be null");
     }
     if (this.mRowState == Record.RowStateEnum.DeletedAndCommitted)
     {
         throw new CooqPreconditionException("Row doesn't exist in database. You cannot call update on row that doesn't exist in the database.");
     }
     if (this.mRowState == Record.RowStateEnum.DeletePerformedNotYetCommitted)
     {
         throw new CooqPreconditionException("Row has already been deleted from the database and is waiting for transaction to be committed. You cannot update a deleted row more than once within a transaction.");
     }
     if (this.mRowState == Record.RowStateEnum.AddPerformedNotYetCommitted)
     {
         throw new CooqPreconditionException("Cannot call Update(...) more than once on a row within the same trasaction");
     }
     if (!this.mIsInit)
     {
         this.Init();
     }
     if (this.mUpdateTransaction == null)
     {
         this.mUpdateTransaction = transaction;
         if (!discardRowAfterUpdate)
         {
             transaction.CommitEvent   += new Transaction.CommitPerformed(this.Transaction_CommitEvent);
             transaction.RollbackEvent += new Transaction.RollbackPerformed(this.Transaction_RollbackEvent);
         }
     }
     else if (this.mUpdateTransaction != transaction)
     {
         throw new CooqDataAccessException("row.Update() has been called more than once on this row with a different transaction instance than before.");
     }
     if (this.table.Columns.Count == 0)
     {
         throw new CooqDataAccessException("Table has no fields defined. Cannot update row.");
     }
     if (this.mRowState == Record.RowStateEnum.AddPending)
     {
         InsertBuilder     insertBuilder = new InsertBuilder(this.table);
         List <ColumnBase> list          = new List <ColumnBase>();
         int index1 = 0;
         while (index1 < this.table.Columns.Count)
         {
             ColumnBase column = this.table.Columns[index1];
             if (column.IsAutoId)
             {
                 list.Add(column);
             }
             else
             {
                 object value = this.mCurrentData[index1];
                 if (value == Record.NOT_SET)
                 {
                     value = (object)null;
                 }
                 insertBuilder.SetInternal(column, value);
                 this.mPersistedData[index1] = value;
             }
             checked { ++index1; }
         }
         if (list.Count == 0)
         {
             insertBuilder.Execute(transaction);
         }
         else
         {
             IResult result = insertBuilder.Returning(list.ToArray()).Execute(transaction);
             if (list.Count > 1)
             {
                 throw new CooqDataAccessException("Only one auto id field is supported");
             }
             int index2 = 0;
             while (index2 < list.Count)
             {
                 ColumnBase column = list[index2];
                 int        index3 = this.table.Columns.IndexOf(column);
                 this.mCurrentData[index3]   = result.GetRow(column.Table, 0).GetValue(column);
                 this.mPersistedData[index3] = this.mCurrentData[index3];
                 checked { ++index2; }
             }
         }
         this.mRowState = Record.RowStateEnum.AddPerformedNotYetCommitted;
     }
     else if (this.mRowState == Record.RowStateEnum.DeletePending)
     {
         DeleteBuilder deleteBuilder      = new DeleteBuilder(this.table);
         Condition     condition          = null;
         bool?         concurrenyChecking = this.table.UseConcurrenyChecking;
         int           num;
         if (!concurrenyChecking.HasValue)
         {
             num = Settings.UseConcurrenyChecking ? 1 : 0;
         }
         else
         {
             concurrenyChecking = this.table.UseConcurrenyChecking;
             num = concurrenyChecking.Value ? 1 : 0;
         }
         bool flag1 = num != 0;
         bool flag2 = false;
         int  index = 0;
         while (index < this.table.Columns.Count)
         {
             ColumnBase pLeft = this.table.Columns[index];
             if (flag1 || pLeft.IsPrimaryKey)
             {
                 flag2 = true;
                 object pRight = this.mPersistedData[index];
                 if (pRight == Record.NOT_SET)
                 {
                     pRight = this.rowData[index];
                 }
                 if (condition == null)
                 {
                     condition = pRight != Record.NOT_SET ? (Condition) new ColumnCondition(pLeft, Operator.EQUALS, pRight) : (Condition) new IsNullCondition((ISelectable)pLeft);
                 }
                 else
                 {
                     condition &= pRight != Record.NOT_SET ? (Condition) new ColumnCondition(pLeft, Operator.EQUALS, pRight) : (Condition) new IsNullCondition((ISelectable)pLeft);
                 }
             }
             checked { ++index; }
         }
         if (!flag2)
         {
             throw new CooqDataAccessException("There are no primary keys set on row and use concurrency checking is turned off. Unable to delete.");
         }
         deleteBuilder.Where(condition);
         if (deleteBuilder.Execute(transaction).RowsEffected != 1)
         {
             throw new CooqDataAccessException("Row not updated. Possible data concurrency issue.");
         }
         this.mRowState = Record.RowStateEnum.DeletePerformedNotYetCommitted;
     }
     else
     {
         bool flag1  = false;
         int  index1 = 0;
         while (index1 < this.rowData.Length)
         {
             if (this.rowData[index1] is Record.NotSet)
             {
                 throw new CooqDataAccessException("Not all columns were loaded in row. Unable to update.");
             }
             if ((this.mPersistedData[index1] != null || this.mCurrentData[index1] != null) && (this.mPersistedData[index1] == null && this.mCurrentData[index1] != null || this.mPersistedData[index1] != null && this.mCurrentData[index1] == null || !this.mPersistedData[index1].Equals(this.mCurrentData[index1])))
             {
                 flag1 = true;
                 break;
             }
             checked { ++index1; }
         }
         if (flag1)
         {
             UpdateBuilder updateBuilder      = new UpdateBuilder(this.table);
             Condition     condition          = null;
             bool?         concurrenyChecking = this.table.UseConcurrenyChecking;
             int           num;
             if (!concurrenyChecking.HasValue)
             {
                 num = Settings.UseConcurrenyChecking ? 1 : 0;
             }
             else
             {
                 concurrenyChecking = this.table.UseConcurrenyChecking;
                 num = concurrenyChecking.Value ? 1 : 0;
             }
             bool flag2  = num != 0;
             bool flag3  = false;
             int  index2 = 0;
             while (index2 < this.table.Columns.Count)
             {
                 ColumnBase ColumnBase = this.table.Columns[index2];
                 if (!ColumnBase.IsAutoId && this.mPersistedData[index2] != this.mCurrentData[index2])
                 {
                     updateBuilder.SetInternal(ColumnBase, this.mCurrentData[index2]);
                 }
                 if (flag2 || ColumnBase.IsPrimaryKey)
                 {
                     flag3 = true;
                     object pRight = this.mPersistedData[index2];
                     if (pRight == Record.NOT_SET)
                     {
                         pRight = this.rowData[index2];
                     }
                     if (condition == null)
                     {
                         condition = pRight != null ? new ColumnCondition(ColumnBase, Operator.EQUALS, pRight) : (Condition) new IsNullCondition((ISelectable)ColumnBase);
                     }
                     else
                     {
                         condition &= pRight != null ? new ColumnCondition(ColumnBase, Operator.EQUALS, pRight) : (Condition) new IsNullCondition((ISelectable)ColumnBase);
                     }
                 }
                 this.mPersistedData[index2] = this.mCurrentData[index2];
                 checked { ++index2; }
             }
             if (!flag3)
             {
                 throw new CooqDataAccessException("There are no primary keys set on row and use concurrency checking is turned off. Unable to update.");
             }
             updateBuilder.Where(condition);
             if (updateBuilder.Execute(transaction).RowsEffected != 1)
             {
                 throw new CooqDataAccessException("Row not updated. Possible data concurrency issue.");
             }
         }
     }
 }