using System; using System.Collections.Generic; using System.Linq; using System.Text; using FLocal.Core; using FLocal.Core.DB; using FLocal.Core.DB.conditions; namespace FLocal.Common.actions { class InsertOrUpdateChange : AbstractChange { private int? id; private AbstractCondition condition; private Dictionary dataToInsert; private Dictionary dataToUpdate; public InsertOrUpdateChange(ISqlObjectTableSpec tableSpec, Dictionary dataToInsert, Dictionary dataToUpdate, AbstractCondition condition) : base(tableSpec, (from kvp in dataToInsert select kvp.Value).Union(from kvp in dataToUpdate select kvp.Value)) { this.id = null; this.condition = condition; this.dataToInsert = dataToInsert; this.dataToUpdate = dataToUpdate; } public override int? getId() { return this.id; } public override void Lock(Transaction transaction) { List ids = Config.instance.mainConnection.LoadIdsByConditions(transaction, this.tableSpec, this.condition, Diapasone.unlimited, new JoinSpec[0], new SortSpec[0], false); if(ids.Count > 1) { throw new CriticalException("Not unique"); } else if(ids.Count == 1) { this.id = int.Parse(ids[0]); Config.instance.mainConnection.lockRow(transaction, this.tableSpec, this.id.ToString()); } else { Config.instance.mainConnection.lockTable(transaction, this.tableSpec); ids = Config.instance.mainConnection.LoadIdsByConditions(transaction, this.tableSpec, this.condition, Diapasone.unlimited, new JoinSpec[0], new SortSpec[0], false); if(ids.Count > 1) { throw new CriticalException("Not unique"); } else if(ids.Count == 1) { this.id = int.Parse(ids[0]); } else { this.id = null; } } } protected override void doApply(Transaction transaction) { if(this.id.HasValue) { Dictionary row = Config.instance.mainConnection.LoadByIds(transaction, this.tableSpec, new List() { this.id.ToString() })[0]; Dictionary processedData = new Dictionary(); foreach(KeyValuePair kvp in this.dataToUpdate) { processedData[kvp.Key] = kvp.Value.getStringRepresentation(row[kvp.Key]); } Config.instance.mainConnection.update( transaction, this.tableSpec, this.id.ToString(), processedData ); } else { Dictionary processedData = new Dictionary(); foreach(KeyValuePair kvp in this.dataToInsert) { processedData[kvp.Key] = kvp.Value.getStringRepresentation(); } this.id = int.Parse(Config.instance.mainConnection.insert( transaction, this.tableSpec, processedData )); if(processedData.ContainsKey(this.tableSpec.idName)) { this.id = int.Parse(processedData[this.tableSpec.idName]); } } } } }