seba-365 - implemented dep
Change-Id: Ia6226d50e7615935a0c8876809a687427ff88c22
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/mongo/driver/session/client_session.go b/vendor/github.com/mongodb/mongo-go-driver/x/mongo/driver/session/client_session.go
new file mode 100644
index 0000000..405d507
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/mongo/driver/session/client_session.go
@@ -0,0 +1,347 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package session
+
+import (
+ "errors"
+
+ "github.com/mongodb/mongo-go-driver/bson"
+ "github.com/mongodb/mongo-go-driver/bson/primitive"
+ "github.com/mongodb/mongo-go-driver/mongo/readconcern"
+ "github.com/mongodb/mongo-go-driver/mongo/readpref"
+ "github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+ "github.com/mongodb/mongo-go-driver/x/mongo/driver/uuid"
+)
+
+// ErrSessionEnded is returned when a client session is used after a call to endSession().
+var ErrSessionEnded = errors.New("ended session was used")
+
+// ErrNoTransactStarted is returned if a transaction operation is called when no transaction has started.
+var ErrNoTransactStarted = errors.New("no transaction started")
+
+// ErrTransactInProgress is returned if startTransaction() is called when a transaction is in progress.
+var ErrTransactInProgress = errors.New("transaction already in progress")
+
+// ErrAbortAfterCommit is returned when abort is called after a commit.
+var ErrAbortAfterCommit = errors.New("cannot call abortTransaction after calling commitTransaction")
+
+// ErrAbortTwice is returned if abort is called after transaction is already aborted.
+var ErrAbortTwice = errors.New("cannot call abortTransaction twice")
+
+// ErrCommitAfterAbort is returned if commit is called after an abort.
+var ErrCommitAfterAbort = errors.New("cannot call commitTransaction after calling abortTransaction")
+
+// ErrUnackWCUnsupported is returned if an unacknowledged write concern is supported for a transaciton.
+var ErrUnackWCUnsupported = errors.New("transactions do not support unacknowledged write concerns")
+
+// Type describes the type of the session
+type Type uint8
+
+// These constants are the valid types for a client session.
+const (
+ Explicit Type = iota
+ Implicit
+)
+
+// State indicates the state of the FSM.
+type state uint8
+
+// Client Session states
+const (
+ None state = iota
+ Starting
+ InProgress
+ Committed
+ Aborted
+)
+
+// Client is a session for clients to run commands.
+type Client struct {
+ *Server
+ ClientID uuid.UUID
+ ClusterTime bson.Raw
+ Consistent bool // causal consistency
+ OperationTime *primitive.Timestamp
+ SessionType Type
+ Terminated bool
+ RetryingCommit bool
+ Committing bool
+ Aborting bool
+ RetryWrite bool
+
+ // options for the current transaction
+ // most recently set by transactionopt
+ CurrentRc *readconcern.ReadConcern
+ CurrentRp *readpref.ReadPref
+ CurrentWc *writeconcern.WriteConcern
+
+ // default transaction options
+ transactionRc *readconcern.ReadConcern
+ transactionRp *readpref.ReadPref
+ transactionWc *writeconcern.WriteConcern
+
+ pool *Pool
+ state state
+}
+
+func getClusterTime(clusterTime bson.Raw) (uint32, uint32) {
+ if clusterTime == nil {
+ return 0, 0
+ }
+
+ clusterTimeVal, err := clusterTime.LookupErr("$clusterTime")
+ if err != nil {
+ return 0, 0
+ }
+
+ timestampVal, err := bson.Raw(clusterTimeVal.Value).LookupErr("clusterTime")
+ if err != nil {
+ return 0, 0
+ }
+
+ return timestampVal.Timestamp()
+}
+
+// MaxClusterTime compares 2 clusterTime documents and returns the document representing the highest cluster time.
+func MaxClusterTime(ct1, ct2 bson.Raw) bson.Raw {
+ epoch1, ord1 := getClusterTime(ct1)
+ epoch2, ord2 := getClusterTime(ct2)
+
+ if epoch1 > epoch2 {
+ return ct1
+ } else if epoch1 < epoch2 {
+ return ct2
+ } else if ord1 > ord2 {
+ return ct1
+ } else if ord1 < ord2 {
+ return ct2
+ }
+
+ return ct1
+}
+
+// NewClientSession creates a Client.
+func NewClientSession(pool *Pool, clientID uuid.UUID, sessionType Type, opts ...*ClientOptions) (*Client, error) {
+ c := &Client{
+ Consistent: true, // set default
+ ClientID: clientID,
+ SessionType: sessionType,
+ pool: pool,
+ }
+
+ mergedOpts := mergeClientOptions(opts...)
+ if mergedOpts.CausalConsistency != nil {
+ c.Consistent = *mergedOpts.CausalConsistency
+ }
+ if mergedOpts.DefaultReadPreference != nil {
+ c.transactionRp = mergedOpts.DefaultReadPreference
+ }
+ if mergedOpts.DefaultReadConcern != nil {
+ c.transactionRc = mergedOpts.DefaultReadConcern
+ }
+ if mergedOpts.DefaultWriteConcern != nil {
+ c.transactionWc = mergedOpts.DefaultWriteConcern
+ }
+
+ servSess, err := pool.GetSession()
+ if err != nil {
+ return nil, err
+ }
+
+ c.Server = servSess
+
+ return c, nil
+}
+
+// AdvanceClusterTime updates the session's cluster time.
+func (c *Client) AdvanceClusterTime(clusterTime bson.Raw) error {
+ if c.Terminated {
+ return ErrSessionEnded
+ }
+ c.ClusterTime = MaxClusterTime(c.ClusterTime, clusterTime)
+ return nil
+}
+
+// AdvanceOperationTime updates the session's operation time.
+func (c *Client) AdvanceOperationTime(opTime *primitive.Timestamp) error {
+ if c.Terminated {
+ return ErrSessionEnded
+ }
+
+ if c.OperationTime == nil {
+ c.OperationTime = opTime
+ return nil
+ }
+
+ if opTime.T > c.OperationTime.T {
+ c.OperationTime = opTime
+ } else if (opTime.T == c.OperationTime.T) && (opTime.I > c.OperationTime.I) {
+ c.OperationTime = opTime
+ }
+
+ return nil
+}
+
+// UpdateUseTime updates the session's last used time.
+// Must be called whenver this session is used to send a command to the server.
+func (c *Client) UpdateUseTime() error {
+ if c.Terminated {
+ return ErrSessionEnded
+ }
+ c.updateUseTime()
+ return nil
+}
+
+// EndSession ends the session.
+func (c *Client) EndSession() {
+ if c.Terminated {
+ return
+ }
+
+ c.Terminated = true
+ c.pool.ReturnSession(c.Server)
+
+ return
+}
+
+// TransactionInProgress returns true if the client session is in an active transaction.
+func (c *Client) TransactionInProgress() bool {
+ return c.state == InProgress
+}
+
+// TransactionStarting returns true if the client session is starting a transaction.
+func (c *Client) TransactionStarting() bool {
+ return c.state == Starting
+}
+
+// TransactionRunning returns true if the client session has started the transaction
+// and it hasn't been committed or aborted
+func (c *Client) TransactionRunning() bool {
+ return c.state == Starting || c.state == InProgress
+}
+
+// TransactionCommitted returns true of the client session just committed a transaciton.
+func (c *Client) TransactionCommitted() bool {
+ return c.state == Committed
+}
+
+// CheckStartTransaction checks to see if allowed to start transaction and returns
+// an error if not allowed
+func (c *Client) CheckStartTransaction() error {
+ if c.state == InProgress || c.state == Starting {
+ return ErrTransactInProgress
+ }
+ return nil
+}
+
+// StartTransaction initializes the transaction options and advances the state machine.
+// It does not contact the server to start the transaction.
+func (c *Client) StartTransaction(opts *TransactionOptions) error {
+ err := c.CheckStartTransaction()
+ if err != nil {
+ return err
+ }
+
+ c.IncrementTxnNumber()
+ c.RetryingCommit = false
+
+ if opts != nil {
+ c.CurrentRc = opts.ReadConcern
+ c.CurrentRp = opts.ReadPreference
+ c.CurrentWc = opts.WriteConcern
+ }
+
+ if c.CurrentRc == nil {
+ c.CurrentRc = c.transactionRc
+ }
+
+ if c.CurrentRp == nil {
+ c.CurrentRp = c.transactionRp
+ }
+
+ if c.CurrentWc == nil {
+ c.CurrentWc = c.transactionWc
+ }
+
+ if !writeconcern.AckWrite(c.CurrentWc) {
+ c.clearTransactionOpts()
+ return ErrUnackWCUnsupported
+ }
+
+ c.state = Starting
+ return nil
+}
+
+// CheckCommitTransaction checks to see if allowed to commit transaction and returns
+// an error if not allowed.
+func (c *Client) CheckCommitTransaction() error {
+ if c.state == None {
+ return ErrNoTransactStarted
+ } else if c.state == Aborted {
+ return ErrCommitAfterAbort
+ }
+ return nil
+}
+
+// CommitTransaction updates the state for a successfully committed transaction and returns
+// an error if not permissible. It does not actually perform the commit.
+func (c *Client) CommitTransaction() error {
+ err := c.CheckCommitTransaction()
+ if err != nil {
+ return err
+ }
+ c.state = Committed
+ return nil
+}
+
+// CheckAbortTransaction checks to see if allowed to abort transaction and returns
+// an error if not allowed.
+func (c *Client) CheckAbortTransaction() error {
+ if c.state == None {
+ return ErrNoTransactStarted
+ } else if c.state == Committed {
+ return ErrAbortAfterCommit
+ } else if c.state == Aborted {
+ return ErrAbortTwice
+ }
+ return nil
+}
+
+// AbortTransaction updates the state for a successfully committed transaction and returns
+// an error if not permissible. It does not actually perform the abort.
+func (c *Client) AbortTransaction() error {
+ err := c.CheckAbortTransaction()
+ if err != nil {
+ return err
+ }
+ c.state = Aborted
+ c.clearTransactionOpts()
+ return nil
+}
+
+// ApplyCommand advances the state machine upon command execution.
+func (c *Client) ApplyCommand() {
+ if c.Committing {
+ // Do not change state if committing after already committed
+ return
+ }
+ if c.state == Starting {
+ c.state = InProgress
+ } else if c.state == Committed || c.state == Aborted {
+ c.clearTransactionOpts()
+ c.state = None
+ }
+}
+
+func (c *Client) clearTransactionOpts() {
+ c.RetryingCommit = false
+ c.Aborting = false
+ c.Committing = false
+ c.CurrentWc = nil
+ c.CurrentRp = nil
+ c.CurrentRc = nil
+}