public IDbQueryable <T> Table <T>(LinqdbTransactionInternal transaction) { return(new IDbQueryable <T>() { _db = this, LDBTransaction = transaction }); }
public void Delete <T>(HashSet <int> ids, LinqdbTransactionInternal trans) { CheckTableInfo <T>(); HashSet <int> current_values = new HashSet <int>(); foreach (var v in ids) { current_values.Add(v); } if (current_values.Any()) { DeleteBatch <T>(current_values, trans); } }
public void DeleteBatch <T>(HashSet <int> ids, LinqdbTransactionInternal trans) { var _write_lock = GetTableWriteLock(typeof(T).Name); if (trans == null) { var table_info = GetTableInfo(typeof(T).Name); bool done = false; string error = null; var ilock = ModifyBatch.GetTableDeleteBatchLock(table_info.Name); lock (ilock) { if (!ModifyBatch._delete_batch.ContainsKey(table_info.Name)) { ModifyBatch._delete_batch[table_info.Name] = new DeleteData() { Callbacks = new List <Action <string> >(), ids = ids }; } else { ModifyBatch._delete_batch[table_info.Name].ids.UnionWith(ids); } ModifyBatch._delete_batch[table_info.Name].Callbacks.Add(f => { done = true; error = f; }); } bool lockAcquired = false; int maxWaitMs = 60000; DeleteData _delete_data = null; try { DateTime start = DateTime.Now; while (!done) { lockAcquired = Monitor.TryEnter(_write_lock, 0); if (lockAcquired) { if (done) { Monitor.Exit(_write_lock); lockAcquired = false; break; } else { break; } } Thread.Sleep(250); //if ((DateTime.Now - start).TotalMilliseconds > maxWaitMs) //{ // throw new LinqDbException("Linqdb: Delete waited too long to acquire write lock. Is the load too high?"); //} } if (done) { if (!string.IsNullOrEmpty(error)) { throw new LinqDbException(error); } else { return; } } //not done, but have write lock for the table lock (ilock) { _delete_data = ModifyBatch._delete_batch[table_info.Name]; var oval = new DeleteData(); ModifyBatch._delete_batch.TryRemove(table_info.Name, out oval); } if (_delete_data.ids.Any()) { using (WriteBatchWithConstraints batch = new WriteBatchWithConstraints()) { Dictionary <string, KeyValuePair <byte[], HashSet <int> > > string_cache = new Dictionary <string, KeyValuePair <byte[], HashSet <int> > >(); Dictionary <string, Tuple <IndexNewData, IndexDeletedData, IndexChangedData> > meta_index = BuildMetaOnIndex(table_info); DeleteBatch(_delete_data.ids, table_info, batch, null, string_cache, meta_index); WriteStringCacheToBatch(batch, string_cache, table_info, null); var snapshots_dic = InsertIndexChanges(table_info, meta_index); foreach (var snap in snapshots_dic) { var skey = MakeSnapshotKey(table_info.TableNumber, table_info.ColumnNumbers[snap.Key]); batch.Put(skey, Encoding.UTF8.GetBytes(snap.Value)); } leveld_db.Write(batch._writeBatch); } } foreach (var cb in _delete_data.Callbacks) { cb(null); } } catch (Exception ex) { if (_delete_data != null) { var additionalInfo = ex.Message; if (_delete_data.Callbacks.Count() > 1) { additionalInfo += " This error could belong to another entity which happened to be in the same batch."; } foreach (var cb in _delete_data.Callbacks) { cb(additionalInfo); } } throw; } finally { if (lockAcquired) { Monitor.Exit(_write_lock); } } } else { var type_name = typeof(T).Name; var table_info = GetTableInfo(type_name); if (!trans.data_to_delete.ContainsKey(type_name)) { trans.data_to_delete[type_name] = new KeyValuePair <TableInfo, HashSet <int> >(table_info, new HashSet <int>()); } trans.data_to_delete[type_name].Value.UnionWith(ids); } }
public void GenericUpdateIncrement <T, TKey>(Expression <Func <T, TKey> > keySelector, Dictionary <int, object> values, LinqdbTransactionInternal trans) { CheckTableInfo <T>(); var par = keySelector.Parameters.First(); var name = SharedUtils.GetPropertyName(keySelector.Body.ToString()); var table_info = GetTableInfo(typeof(T).Name); var info = new UpdateInfo() { TableNumber = table_info.TableNumber, ColumnNumber = table_info.ColumnNumbers[name], ColumnType = table_info.Columns[name], TableInfo = table_info, ColumnName = name }; var data = new Dictionary <int, object>(); foreach (var v in values) { data[v.Key] = v.Value; } UpdateIncrement <T>(info, data, table_info, trans); }
public void Update <T, TKey>(Expression <Func <T, TKey> > keySelector, Dictionary <int, string> values, LinqdbTransactionInternal trans) { GenericUpdate <T, TKey>(keySelector, values.ToDictionary(f => f.Key, f => (object)f.Value), trans, LinqDbTypes.string_); }
public void UpdateIncrement <T, TKey>(Expression <Func <T, TKey> > keySelector, Dictionary <int, int?> values, LinqdbTransactionInternal trans) { GenericUpdateIncrement <T, TKey>(keySelector, values.ToDictionary(f => f.Key, f => (object)f.Value), trans); }
public void UpdateBatchIncrement <T>(UpdateInfo info, Dictionary <int, object> values, TableInfo table_info, LinqdbTransactionInternal trans) { var _write_lock = GetTableWriteLock(typeof(T).Name); if (trans == null) { lock (_write_lock) { using (WriteBatchWithConstraints batch = new WriteBatchWithConstraints()) { Dictionary <string, KeyValuePair <byte[], HashSet <int> > > string_cache = new Dictionary <string, KeyValuePair <byte[], HashSet <int> > >(); Dictionary <string, Tuple <IndexNewData, IndexDeletedData, IndexChangedData> > meta_index = BuildMetaOnIndex(table_info); UpdateBatch(info, values, table_info, batch, string_cache, meta_index); WriteStringCacheToBatch(batch, string_cache, table_info, null); var snapshots_dic = InsertIndexChanges(table_info, meta_index); foreach (var snap in snapshots_dic) { var skey = MakeSnapshotKey(table_info.TableNumber, table_info.ColumnNumbers[snap.Key]); batch.Put(skey, Encoding.UTF8.GetBytes(snap.Value)); } leveld_db.Write(batch._writeBatch); } } } else { var type_name = typeof(T).Name; info.TableInfo = table_info; if (!trans.data_to_update.ContainsKey(type_name)) { trans.data_to_update[type_name] = new List <KeyValuePair <UpdateInfo, Dictionary <int, object> > >(); } trans.data_to_update[type_name].Add(new KeyValuePair <UpdateInfo, Dictionary <int, object> >(info, values)); } }
public void Update <T>(UpdateInfo info, Dictionary <int, object> values, TableInfo table_info, LinqdbTransactionInternal trans) { Dictionary <int, object> current_values = new Dictionary <int, object>(); foreach (var kv in values) { current_values[kv.Key] = kv.Value; } if (current_values.Any()) { UpdateBatch <T>(info, current_values, table_info, trans); } }