Exemple #1
0
 public IDbQueryable <T> Table <T>(LinqdbTransactionInternal transaction)
 {
     return(new IDbQueryable <T>()
     {
         _db = this, LDBTransaction = transaction
     });
 }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
 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_);
 }
Exemple #6
0
 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);
 }
Exemple #7
0
        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));
            }
        }
Exemple #8
0
        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);
            }
        }