示例#1
0
        public bool IncrementClock(WriteTransaction txn, Func <VectorClock, VectorClock> clock)
        {
            var lastClock = GetLastClock(txn);
            var newClock  = clock(lastClock);

            return(SetLastClock(txn, newClock));
        }
示例#2
0
 protected Table(WriteTransaction txn, string tableName, DatabaseOpenFlags flags)
 {
     Database = txn.Transaction.OpenDatabase(tableName, new DatabaseConfiguration {
         Flags = flags
     });
     txn.Commit();
 }
示例#3
0
        public bool IncrementCounters(WriteTransaction txn, Action <ReplicaCounters> countersUpdater)
        {
            var counters = GetCounters(txn);

            countersUpdater(counters);
            return(SetCounters(txn, counters));
        }
示例#4
0
        public InsertResult RunInsert(IComparable[] row, string tableName, string dml = null)
        {
            try
            {
                TableDefinition tableDef = _schemaFetcher.GetTableDefinition(tableName);

                long?firstAvailableAddress = null;
                lock (_reader)
                {
                    firstAvailableAddress = _reader.GetFirstAvailableDataAddress(tableDef.DataAddress, tableDef.GetRowSizeInBytes());

                    var writeTransaction = new WriteTransaction
                    {
                        Data             = row,
                        TableDefinition  = tableDef,
                        AddressToWriteTo = (long)firstAvailableAddress,
                        Query            = dml
                    };

                    return(_lockManager.ProcessWriteTransaction(writeTransaction));
                }
            }
            catch (Exception ex)
            {
                return(new InsertResult {
                    Successful = false, ErrorMessage = ex.Message
                });
            }
        }
示例#5
0
        private (ulong, VectorClock) IncrementClock(WriteTransaction txn)
        {
            var clock = _incrementClock(txn);
            var posn  = clock.GetReplicaValue(_replicaId);

            if (!posn.HasValue)
            {
                throw new EventLogException($"IncrementClock MUST return a new Pos for current replica {_replicaId}. '{clock}'");
            }
            return(posn.Value, clock);
        }
示例#6
0
        public InsertResult ProcessWriteTransaction(WriteTransaction writeTransaction)
        {
            lock (_tableLocks[writeTransaction.TableDefinition.DataAddress])
            {
                IComparable identity = _writer.WriteRow(writeTransaction.Data, writeTransaction.TableDefinition, writeTransaction.AddressToWriteTo, writeTransaction.UpdateObjectCount);

                return(new InsertResult {
                    Successful = true, IdentityValue = identity
                });
            }
        }
示例#7
0
        public bool AddLogEvents(WriteTransaction txn, WriteLogEvent logEvent)
        {
            var replicaValue = logEvent.LocallySaved.GetReplicaValue(_replicaId);

            if (!replicaValue.HasValue)
            {
                throw new ArgumentException(nameof(logEvent), $"VectorClock for the event is not properly prepared and empty for this replicaId: '{_replicaId}'");
            }

            return(txn.Add(_table, ToTableKey(replicaValue.Value), ToTableValue(logEvent)));
        }
示例#8
0
        private void RemoveExpired(WriteTransaction txn, TableKey tableKey, Timestamp keyExpiry)
        {
            //_expirationQueue(txn, _kvTable, key, keyExpiry);
            var currentClock = _currentClock();
            var metadata     = new KvMetadata
            {
                Status         = Expired,
                Expiry         = keyExpiry,
                Action         = Updated,
                Originated     = currentClock,
                LocallyUpdated = currentClock
            };

            txn.Delete(_kvTable, tableKey); // TODO: Check and fail on not successful return codes
            _metadataTable.AddOrUpdate(txn, tableKey, metadata);
            // _kvUpdateHandler(txn, ToDeleteLogEvent(key, metadata)); // TODO: Add EXPIRY-s to the replication log?
        }
示例#9
0
 public bool SetLastClock(WriteTransaction txn, string replicaId, VectorClock clock) =>
 txn.AddOrUpdate(_table, ToClockTableKey(replicaId), ToClockTableValue(clock));
示例#10
0
        private bool CheckAndRemoveIfExpired(KvKey key, VectorClock currentClock, KvMetadata metadataToCheck, WriteTransaction txn = null)
        {
            if (metadataToCheck == null || metadataToCheck.Status == Active && currentClock.TicksOffsetUtc < metadataToCheck.Expiry.TicksOffsetUtc)
            {
                return(true);
            }

            if (metadataToCheck.Status == Active && currentClock.TicksOffsetUtc < metadataToCheck.Expiry.TicksOffsetUtc)
            {
                if (txn != null)
                {
                    RemoveExpired(txn, ToTableKey(key), metadataToCheck.Expiry);
                }
                else
                {
                    _lmdb.WriteAsync(tx => RemoveExpired(tx, ToTableKey(key), metadataToCheck.Expiry), false);
                }
            }

            return(false);
        }
示例#11
0
        /// <summary>
        /// this checks if the new key is still available,
        /// and makes sure it will not be used as a default key anymore
        /// </summary>
        /// <param name="AFieldPartnerKey"></param>
        /// <param name="AOriginalDefaultKey">this has been previously retrieved from GetNewPartnerKey</param>
        /// <param name="ANewPartnerKey">the user proposes this key for a new partner; the function can change it and return a valid value, or -1</param>
        /// <param name="ADataBase"></param>
        /// <returns>whether or not ANewPartnerKey has a valid new partner key;
        /// if it cannot be assigned, the function returns false, and ANewPartnerKey is -1
        /// </returns>
        public static bool SubmitNewPartnerKey(System.Int64 AFieldPartnerKey, System.Int64 AOriginalDefaultKey, ref System.Int64 ANewPartnerKey, TDataBase ADataBase = null)
        {
            bool                ReturnValue = true;
            TDBTransaction      ReadTransaction;
            TDBTransaction      WriteTransaction;
            Boolean             NewTransaction;
            PPartnerLedgerTable PartnerLedgerDT;

            TDataBase db = DBAccess.Connect("SubmitNewPartnerKey", ADataBase);

            System.Int64 CurrentDefaultPartnerKey;

            if (ANewPartnerKey == AOriginalDefaultKey)
            {
                // The user has selected the default
                ReadTransaction = db.GetNewOrExistingTransaction(IsolationLevel.RepeatableRead,
                                                                 out NewTransaction);

                try
                {
                    // Fetch the partner ledger record to update the last key

                    PartnerLedgerDT          = PPartnerLedgerAccess.LoadByPrimaryKey(AFieldPartnerKey, ReadTransaction);
                    CurrentDefaultPartnerKey = PartnerLedgerDT[0].PartnerKey + PartnerLedgerDT[0].LastPartnerId + 1;

                    if (ANewPartnerKey != CurrentDefaultPartnerKey)
                    {
                        // Someone else has updated this since, so we will use the new default
                        ANewPartnerKey = CurrentDefaultPartnerKey;
                    }

                    // Now check that this does not exist, and increment until we
                    // find one which does not
                    while (PPartnerAccess.Exists(ANewPartnerKey, ReadTransaction))
                    {
                        ANewPartnerKey = ANewPartnerKey + 1;
                    }
                }
                finally
                {
                    if (NewTransaction)
                    {
                        ReadTransaction.Rollback();

                        if (TLogging.DebugLevel >= TLogging.DEBUGLEVEL_TRACE)
                        {
                            Console.WriteLine("TNewPartnerKey.SubmitNewPartnerKey: rolled back own transaction.");
                        }
                    }
                }

                PartnerLedgerDT[0].LastPartnerId = (int)(ANewPartnerKey - PartnerLedgerDT[0].PartnerKey);

                WriteTransaction = db.GetNewOrExistingTransaction(IsolationLevel.Serializable,
                                                                  out NewTransaction);

                try
                {
                    PPartnerLedgerAccess.SubmitChanges(PartnerLedgerDT, WriteTransaction);

                    if (NewTransaction)
                    {
                        WriteTransaction.Commit();
                    }
                }
                catch (Exception Exc)
                {
                    TLogging.Log("An Exception occured during the submission of a new PartnerKey:" + Environment.NewLine + Exc.ToString());

                    if (NewTransaction)
                    {
                        WriteTransaction.Rollback();
                    }

                    throw;
                }
            }
            // end of: The user has selected the default
            else
            {
                ReadTransaction = db.GetNewOrExistingTransaction(IsolationLevel.RepeatableRead,
                                                                 out NewTransaction);

                try
                {
                    // check if the Partner Key is already being used
                    if (PPartnerAccess.Exists(ANewPartnerKey, ReadTransaction))
                    {
                        ANewPartnerKey = -1;
                        ReturnValue    = false;
                    }
                }
                finally
                {
                    if (NewTransaction)
                    {
                        ReadTransaction.Rollback();

                        if (TLogging.DebugLevel >= TLogging.DEBUGLEVEL_TRACE)
                        {
                            Console.WriteLine("TNewPartnerKey.SubmitNewPartnerKey: rolled back own transaction.");
                        }
                    }
                }
            }

            if (ADataBase == null)
            {
                db.CloseDBConnection();
            }

            return(ReturnValue);
        }
示例#12
0
 internal Table(WriteTransaction txn, string tableName) : this(txn, tableName, DatabaseOpenFlags.Create)
 {
 }
示例#13
0
 public bool SetLastClock(WriteTransaction txn, VectorClock clock) =>
 txn.AddOrUpdate(_table, _clockKey, ToClockTableValue(clock));
示例#14
0
 public bool SetCounters(WriteTransaction txn, ReplicaCounters counters) =>
 txn.AddOrUpdate(_table, _countersKey, ToCountersTableValue(counters));
示例#15
0
 public void Erase(WriteTransaction txn, KvKey key) => txn.Delete(_table, ToTableKey(key));
示例#16
0
 public bool AddOrUpdate(WriteTransaction txn, TableKey key, KvMetadata metadata) =>
 txn.AddOrUpdate(_table, key, ToTableValue(metadata));
示例#17
0
        public CreateFakeDatabaseContext()
        {
            string databaseName = Guid.NewGuid().ToString();

            _context = TestContextCreater.Create(databaseName);

            _context.Employees.Add(new Employee()
            {
                CardUid = "04346C824D5380",
                Balance = 10,
                Email   = "*****@*****.**"
            });

            _context.Employees.Add(new Employee()
            {
                CardUid = "99999999999999",
                Balance = 0,
                Email   = "*****@*****.**"
            });

            var terminals = new Faker <Terminal>()
                            .RuleFor(x => x.TerminalId, x => Guid.NewGuid().ToString())
                            .Generate(10);

            _context.Terminals.Add(new Terminal()
            {
                TerminalId = "04346C824D538012",
                ProductId  = 1
            });

            _context.Terminals.AddRange(terminals);

            var products = new Faker <Product>()
                           .RuleFor(x => x.ProductId, x => x.IndexFaker + 1)
                           .RuleFor(x => x.Productname, x => x.Commerce.ProductName())
                           .RuleFor(x => x.ProductDescription, x => x.Lorem.Sentence())
                           .RuleFor(x => x.ProductPrice, x => Convert.ToDecimal((x.Commerce.Price(0.5m, 2m))))
                           .RuleFor(x => x.Terminal, x => x.PickRandom(terminals))
                           .Generate(10);

            _context.Products.AddRange(products);

            var loggerFactory = new LoggerFactory();

            var getBalance = new GetBalance(_context);

            _checkBalance = new CheckBalance(getBalance, loggerFactory);

            var getProduct = new GetProduct(_context);

            _checkTerminal = new CheckTerminal(getProduct, loggerFactory);

            var writeTransaction = new WriteTransaction(_context, loggerFactory);

            _processPayment = new ProcessPayment(writeTransaction);

            var writeNewcard = new WriteNewCard(_context, loggerFactory);

            _newCardScanned = new NewCardScanned(writeNewcard, getProduct);

            _context.SaveChanges();
        }
示例#18
0
 public bool SetLastPos(WriteTransaction txn, string replicaId, ulong pos) =>
 txn.AddOrUpdate(_table, ToPosTableKey(replicaId), ToPosTableValue(pos));
示例#19
0
        private object RunUpdateStatement(string sql)
        {
            List <KeyValuePair <string, string> > columnToValue = _updateParser.GetUpdates(sql);

            var tableName = _updateParser.GetTableName(sql);

            var tableDef = _schemaFetcher.GetTableDefinition(tableName);

            PredicateStep predicateStep = _updateParser.ParsePredicates(sql);

            var predicateOperations = _predicateParser.BuildPredicateOperations(tableDef, predicateStep.Predicates);

            var selects = tableDef.ColumnDefinitions
                          .Select(x => new SelectColumnDto(x)).OrderBy(x => x.Index).ToList();

            selects.ForEach(x => x.IsInSelect = true);

            var readTransaction = new ReadTransaction
            {
                TableDefinition     = tableDef,
                Selects             = selects,
                PredicateOperations = predicateOperations
            };

            var selectData = _lockManager.ProcessReadTransaction(readTransaction);

            var columnDefs = new List <ColumnDefinition>();

            foreach (var col in columnToValue)
            {
                var colDef = tableDef.ColumnDefinitions.Where(x => x.ColumnName.ToLower() == col.Key).Single();

                columnDefs.Add(colDef);
            }

            Dictionary <int, IComparable> indexToValue = new Dictionary <int, IComparable>();

            foreach (var columnNameToValue in columnToValue)
            {
                var colDef = tableDef.ColumnDefinitions.Single(x => x.ColumnName.ToLower() == columnNameToValue.Key);

                indexToValue[colDef.Index] = _stringParser.ConvertToType(columnNameToValue.Value, colDef.Type);
            }

            foreach (var colDef in columnDefs)
            {
                foreach (var row in selectData.Rows)
                {
                    row[colDef.Index] = indexToValue[colDef.Index];
                }
            }

            //each row is updated as its own transaction - not ideal for update - not atomic
            for (int i = 0; i < selectData.Rows.Count; i++)
            {
                var writeTransaction = new WriteTransaction
                {
                    Data              = selectData.Rows[i].ToArray(),
                    TableDefinition   = tableDef,
                    AddressToWriteTo  = selectData.RowLocations[i],
                    Query             = sql,
                    UpdateObjectCount = false
                };

                _lockManager.ProcessWriteTransaction(writeTransaction);
            }

            return(new object());
        }
示例#20
0
 public void AddExpiryRecords(WriteTransaction txn, (Timestamp, TableKey)[] expiryKeys) =>
示例#21
0
 public DupTable(WriteTransaction txn, string tableName) : base(txn, tableName, DatabaseOpenFlags.Create | DatabaseOpenFlags.DuplicatesSort)
 {
 }
示例#22
0
        public bool IncrementCounters(WriteTransaction txn,
                                      uint addsCounter      = 0, uint deletesCounter        = 0, uint copysCounter = 0,
                                      uint getCounter       = 0, uint containsCounter       = 0,
                                      uint keySearchCounter = 0, uint metadataSearchCounter = 0, uint pageSearchCounter = 0,
                                      uint largestKeySize   = 0, uint largestValueSize      = 0,
                                      uint replicatedAdds   = 0, uint replicatedDeletes     = 0)
        {
            var counters = GetCounters(txn);

            if (addsCounter != 0)
            {
                counters.AddsCounter += addsCounter;
            }
            if (deletesCounter != 0)
            {
                counters.DeletesCounter += deletesCounter;
            }
            if (copysCounter != 0)
            {
                counters.CopysCounter += copysCounter;
            }

            if (getCounter != 0)
            {
                counters.GetCounter += getCounter;
            }
            if (containsCounter != 0)
            {
                counters.ContainsCounter += containsCounter;
            }
            if (keySearchCounter != 0)
            {
                counters.KeySearchCounter += keySearchCounter;
            }
            if (pageSearchCounter != 0)
            {
                counters.PageSearchCounter += pageSearchCounter;
            }
            if (metadataSearchCounter != 0)
            {
                counters.MetadataSearchCounter += metadataSearchCounter;
            }

            if (largestKeySize != 0)
            {
                counters.LargestKeySize += largestKeySize;
            }
            if (largestValueSize != 0)
            {
                counters.LargestValueSize += largestValueSize;
            }

            if (replicatedAdds != 0)
            {
                counters.ReplicatedAdds += replicatedAdds;
            }
            if (replicatedDeletes != 0)
            {
                counters.ReplicatedDeletes += replicatedDeletes;
            }

            return(SetCounters(txn, counters));
        }