コード例 #1
0
        public FactID InsertFact(FactMemento fact, int typeId)
        {
            _session.Command.CommandText = "INSERT Fact (FKTypeID, Data, Hashcode) VALUES (@TypeID, @Data, @Hashcode)";
            AddParameter("@TypeID", typeId);
            AddParameter("@Data", fact.Data);
            AddParameter("@Hashcode", fact.GetHashCode());
            _session.Command.ExecuteNonQuery();
            _session.Command.Parameters.Clear();

            _session.Command.CommandText = "SELECT @@IDENTITY";
            decimal result = (decimal)_session.Command.ExecuteScalar();

            _session.Command.Parameters.Clear();
            return(new FactID {
                key = (Int64)result
            });
        }
コード例 #2
0
        public List <IdentifiedFactMemento> GetEqualFactsByHashCode(FactMemento memento, bool readCommitted, int typeId)
        {
            _session.Command.CommandText = HEAD_SELECT +
                                           (readCommitted ? "" : "WITH (NOLOCK) ") +
                                           "WHERE f.FKTypeID = @TypeID AND f.Hashcode = @Hashcode " +
                                           TAIL_JOIN +
                                           "ORDER BY ff.FactID, p.PredecessorID";
            AddParameter("@TypeID", typeId);
            AddParameter("@Hashcode", memento.GetHashCode());
            using (var loader = new Loader(_session.Command.ExecuteReader()))
            {
                _session.Command.Parameters.Clear();

                return(loader.LoadMementos()
                       .Where(im => im.Memento.Equals(memento))
                       .ToList());
            }
        }
コード例 #3
0
        private List <IdentifiedFactMemento> FindExistingFacts(FactMemento memento, Session session, bool readCommitted)
        {
            int typeId = SaveType(session, memento.FactType);

            // Load all candidates that have the same hash code.
            session.Command.CommandText = HEAD_SELECT +
                                          (readCommitted ? "" : "WITH (NOLOCK) ") +
                                          "WHERE f.FKTypeID = @TypeID AND f.Hashcode = @Hashcode " +
                                          TAIL_JOIN +
                                          "ORDER BY ff.FactID, p.PredecessorID";
            AddParameter(session.Command, "@TypeID", typeId);
            AddParameter(session.Command, "@Hashcode", memento.GetHashCode());
            using (IDataReader factReader = session.Command.ExecuteReader())
            {
                session.Command.Parameters.Clear();

                return(LoadMementosFromReader(factReader).Where(im => im.Memento.Equals(memento)).ToList());
            }
        }
コード例 #4
0
        public FactID Save(string domain, FactMemento fact, Guid clientGuid)
        {
            // Retry on concurrency failure.
            while (true)
            {
                using (var session = new Session(_connectionString))
                {
                    session.BeginTransaction();

                    // First see if the fact is already in storage.
                    FactID id;
                    if (FindExistingFact(fact, out id, session, readCommitted: true))
                    {
                        return(id);
                    }

                    // It isn't there, so store it.
                    int typeId = SaveType(session, fact.FactType);
                    session.Command.CommandText = "INSERT Fact (FKTypeID, Data, Hashcode) VALUES (@TypeID, @Data, @Hashcode)";
                    AddParameter(session.Command, "@TypeID", typeId);
                    AddParameter(session.Command, "@Data", fact.Data);
                    AddParameter(session.Command, "@Hashcode", fact.GetHashCode());
                    session.Command.ExecuteNonQuery();
                    session.Command.Parameters.Clear();

                    session.Command.CommandText = "SELECT @@IDENTITY";
                    decimal result = (decimal)session.Command.ExecuteScalar();
                    session.Command.Parameters.Clear();
                    id.key = (Int64)result;

                    // Store the predecessors.
                    foreach (PredecessorMemento predecessor in fact.Predecessors)
                    {
                        int roleId = SaveRole(session, predecessor.Role);
                        session.Command.CommandText = "INSERT Predecessor (FKFactID, FKRoleID, FKPredecessorFactID, IsPivot) VALUES (@FactID, @RoleID, @PredecessorFactID, @IsPivot)";
                        AddParameter(session.Command, "@FactID", id.key);
                        AddParameter(session.Command, "@RoleID", roleId);
                        AddParameter(session.Command, "@PredecessorFactID", predecessor.ID.key);
                        AddParameter(session.Command, "@IsPivot", predecessor.IsPivot);
                        session.Command.ExecuteNonQuery();
                        session.Command.Parameters.Clear();
                    }

                    // Store a message for each pivot.
                    FactID newFactId = id;
                    List <MessageMemento> pivotMessages = fact.Predecessors
                                                          .Where(predecessor => predecessor.IsPivot)
                                                          .Select(predecessor => new MessageMemento(predecessor.ID, newFactId))
                                                          .ToList();

                    // Store messages for each non-pivot. This fact belongs to all predecessors' pivots.
                    string[] nonPivots = fact.Predecessors
                                         .Where(predecessor => !predecessor.IsPivot)
                                         .Select(predecessor => predecessor.ID.key.ToString())
                                         .ToArray();
                    List <MessageMemento> nonPivotMessages;
                    if (nonPivots.Length > 0)
                    {
                        string nonPivotGroup = string.Join(",", nonPivots);
                        session.Command.CommandText = string.Format(
                            "SELECT DISTINCT PivotId FROM Message WHERE FactId IN ({0})",
                            nonPivotGroup);
                        List <FactID> predecessorsPivots;
                        using (IDataReader predecessorPivotReader = session.Command.ExecuteReader())
                        {
                            session.Command.Parameters.Clear();
                            predecessorsPivots = LoadIDsFromReader(predecessorPivotReader).ToList();
                        }

                        nonPivotMessages = predecessorsPivots
                                           .Select(predecessorPivot => new MessageMemento(predecessorPivot, newFactId))
                                           .ToList();
                    }
                    else
                    {
                        nonPivotMessages = new List <MessageMemento>();
                    }

                    int clientId = SaveClient(session, clientGuid);
                    var messages = pivotMessages.Union(nonPivotMessages).Distinct().ToList();
                    SaveMessages(session, messages, clientId);

                    // Optimistic concurrency check.
                    // Make sure we don't find more than one.
                    var existingFacts = FindExistingFacts(fact, session, readCommitted: false);
                    if (existingFacts.Count == 1)
                    {
                        session.Commit();

                        if (messages.Any() && PivotAffected != null)
                        {
                            foreach (var message in messages)
                            {
                                PivotAffected(domain, message.PivotId);
                            }
                        }
                        return(id);
                    }
                    else
                    {
                        _retried = true;
                    }
                }
            }
        }
コード例 #5
0
        public FactID InsertFact(FactMemento fact, int typeId)
        {
            _session.Command.CommandText = "INSERT Fact (FKTypeID, Data, Hashcode) VALUES (@TypeID, @Data, @Hashcode)";
            AddParameter("@TypeID", typeId);
            AddParameter("@Data", fact.Data);
            AddParameter("@Hashcode", fact.GetHashCode());
            _session.Command.ExecuteNonQuery();
            _session.Command.Parameters.Clear();

            _session.Command.CommandText = "SELECT @@IDENTITY";
            decimal result = (decimal)_session.Command.ExecuteScalar();
            _session.Command.Parameters.Clear();
            return new FactID { key = (Int64)result };
        }
コード例 #6
0
        public List<IdentifiedFactMemento> GetEqualFactsByHashCode(FactMemento memento, bool readCommitted, int typeId)
        {
            _session.Command.CommandText = HEAD_SELECT +
                (readCommitted ? "" : "WITH (NOLOCK) ") +
                "WHERE f.FKTypeID = @TypeID AND f.Hashcode = @Hashcode " +
                TAIL_JOIN +
                "ORDER BY ff.FactID, p.PredecessorID";
            AddParameter("@TypeID", typeId);
            AddParameter("@Hashcode", memento.GetHashCode());
            using (var loader = new Loader(_session.Command.ExecuteReader()))
            {
                _session.Command.Parameters.Clear();

                return loader.LoadMementos()
                    .Where(im => im.Memento.Equals(memento))
                    .ToList();
            }
        }