Skip to content

Commit

Permalink
Merge branch 'development' into bugfix/mapete94-index-int64-fields
Browse files Browse the repository at this point in the history
* development:
  add method CreateView() (#33)
  Update README to add appName (#32)
  send metadata during handshake (#28)
  readme: credit @feliixx for #25 (#26)
  add DropAllIndexes() method (#25)
  Run integration tests against 3.2.16 (#24)

# Conflicts:
#	README.md
  • Loading branch information
domodwyer committed Sep 11, 2017
2 parents 74bdb34 + 25200e4 commit dfde865
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ env:
- GO=1.6 MONGODB=x86_64-3.2.12
- GO=1.7 MONGODB=x86_64-3.2.12
- GO=1.8.x MONGODB=x86_64-3.2.12
- GO=1.6 MONGODB=x86_64-3.2.16
- GO=1.7 MONGODB=x86_64-3.2.16
- GO=1.8.x MONGODB=x86_64-3.2.16

install:
- eval "$(gimme $GO)"
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
* Hides SASL warnings ([details](https://github.com/globalsign/mgo/pull/7))
* Support for partial indexes ([detials](https://github.com/domodwyer/mgo/commit/5efe8eccb028238d93c222828cae4806aeae9f51))
* Fixes timezone handling ([details](https://github.com/go-mgo/mgo/pull/464))
* Integration tests run against newest MongoDB 3.2 releases ([details](https://github.com/globalsign/mgo/pull/4))
* Integration tests run against newest MongoDB 3.2 releases ([details](https://github.com/globalsign/mgo/pull/4), [more](https://github.com/globalsign/mgo/pull/24))
* Improved multi-document transaction performance ([details](https://github.com/globalsign/mgo/pull/10), [more](https://github.com/globalsign/mgo/pull/11), [more](https://github.com/globalsign/mgo/pull/16))
* Fixes cursor timeouts ([detials](https://jira.mongodb.org/browse/SERVER-24899))
* Fixes cursor timeouts ([details](https://jira.mongodb.org/browse/SERVER-24899))
* Support index hints and timeouts for count queries ([details](https://github.com/globalsign/mgo/pull/17))
* Don't panic when handling indexed `int64` fields ([detials](https://github.com/go-mgo/mgo/issues/475))
* Allow dropping all indexes on a collection ([details](https://github.com/globalsign/mgo/pull/25))
* Annotates log entries/profiler output with optional appName on 3.4+ ([details](https://github.com/globalsign/mgo/pull/28))

---

Expand All @@ -31,6 +33,7 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
* @cezarsa
* @drichelson
* @eaglerayp
* @feliixx
* @fmpwizard
* @jameinel
* @mapete94
Expand Down
17 changes: 15 additions & 2 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"errors"
"fmt"
"net"
"runtime"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -61,16 +62,18 @@ type mongoCluster struct {
cachedIndex map[string]bool
sync chan bool
dial dialer
appName string
}

func newCluster(userSeeds []string, direct, failFast bool, dial dialer, setName string) *mongoCluster {
func newCluster(userSeeds []string, direct, failFast bool, dial dialer, setName string, appName string) *mongoCluster {
cluster := &mongoCluster{
userSeeds: userSeeds,
references: 1,
direct: direct,
failFast: failFast,
dial: dial,
setName: setName,
appName: appName,
}
cluster.serverSynced.L = cluster.RWMutex.RLocker()
cluster.sync = make(chan bool, 1)
Expand Down Expand Up @@ -144,7 +147,17 @@ func (cluster *mongoCluster) isMaster(socket *mongoSocket, result *isMasterResul
// Monotonic let's it talk to a slave and still hold the socket.
session := newSession(Monotonic, cluster, 10*time.Second)
session.setSocket(socket)
err := session.Run("ismaster", result)

// provide some meta infos on the client,
// see https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.rst#connection-handshake
// for details
metaInfo := bson.M{"driver": bson.M{"name": "mgo", "version": "globalsign"},
"os": bson.M{"type": runtime.GOOS, "architecture": runtime.GOARCH}}

if cluster.appName != "" {
metaInfo["application"] = bson.M{"name": cluster.appName}
}
err := session.Run(bson.D{{"isMaster", 1}, {"client", metaInfo}}, result)
session.Close()
return err
}
Expand Down
86 changes: 67 additions & 19 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ const (
// topology.
//
// Dial will timeout after 10 seconds if a server isn't reached. The returned
// session will timeout operations after one minute by default if servers
// aren't available. To customize the timeout, see DialWithTimeout,
// SetSyncTimeout, and SetSocketTimeout.
// session will timeout operations after one minute by default if servers aren't
// available. To customize the timeout, see DialWithTimeout, SetSyncTimeout, and
// SetSocketTimeout.
//
// This method is generally called just once for a given cluster. Further
// sessions to the same cluster are then established using the New or Copy
Expand All @@ -184,8 +184,8 @@ const (
// If the port number is not provided for a server, it defaults to 27017.
//
// The username and password provided in the URL will be used to authenticate
// into the database named after the slash at the end of the host names, or
// into the "admin" database if none is provided. The authentication information
// into the database named after the slash at the end of the host names, or into
// the "admin" database if none is provided. The authentication information
// will persist in sessions obtained through the New method as well.
//
// The following connection options are supported after the question mark:
Expand Down Expand Up @@ -235,6 +235,10 @@ const (
// Defines the per-server socket pool limit. Defaults to 4096.
// See Session.SetPoolLimit for details.
//
// appName=<appName>
//
// The identifier of this client application. This parameter is used to
// annotate logs / profiler output and cannot exceed 128 bytes.
//
// Relevant documentation:
//
Expand Down Expand Up @@ -279,6 +283,7 @@ func ParseURL(url string) (*DialInfo, error) {
source := ""
setName := ""
poolLimit := 0
appName := ""
readPreferenceMode := Primary
var readPreferenceTagSets []bson.D
for _, opt := range uinfo.options {
Expand All @@ -296,6 +301,11 @@ func ParseURL(url string) (*DialInfo, error) {
if err != nil {
return nil, errors.New("bad value for maxPoolSize: " + opt.value)
}
case "appName":
if len(opt.value) > 128 {
return nil, errors.New("appName too long, must be < 128 bytes: " + opt.value)
}
appName = opt.value
case "readPreference":
switch opt.value {
case "nearest":
Expand Down Expand Up @@ -350,6 +360,7 @@ func ParseURL(url string) (*DialInfo, error) {
Service: service,
Source: source,
PoolLimit: poolLimit,
AppName: appName,
ReadPreference: &ReadPreference{
Mode: readPreferenceMode,
TagSets: readPreferenceTagSets,
Expand Down Expand Up @@ -409,6 +420,9 @@ type DialInfo struct {
// See Session.SetPoolLimit for details.
PoolLimit int

// The identifier of the client application which ran the operation.
AppName string

// ReadPreference defines the manner in which servers are chosen. See
// Session.SetMode and Session.SelectServers.
ReadPreference *ReadPreference
Expand Down Expand Up @@ -472,7 +486,7 @@ func DialWithInfo(info *DialInfo) (*Session, error) {
}
addrs[i] = addr
}
cluster := newCluster(addrs, info.Direct, info.FailFast, dialer{info.Dial, info.DialServer}, info.ReplicaSetName)
cluster := newCluster(addrs, info.Direct, info.FailFast, dialer{info.Dial, info.DialServer}, info.ReplicaSetName, info.AppName)
session := newSession(Eventual, cluster, info.Timeout)
session.defaultdb = info.Database
if session.defaultdb == "" {
Expand Down Expand Up @@ -652,6 +666,30 @@ func (db *Database) C(name string) *Collection {
return &Collection{db, name, db.Name + "." + name}
}

// CreateView creates a view as the result of the applying the specified
// aggregation pipeline to the source collection or view. Views act as
// read-only collections, and are computed on demand during read operations.
// MongoDB executes read operations on views as part of the underlying aggregation pipeline.
//
// For example:
//
// db := session.DB("mydb")
// db.CreateView("myview", "mycoll", []bson.M{{"$match": bson.M{"c": 1}}}, nil)
// view := db.C("myview")
//
// Relevant documentation:
//
// https://docs.mongodb.com/manual/core/views/
// https://docs.mongodb.com/manual/reference/method/db.createView/
//
func (db *Database) CreateView(view string, source string, pipeline interface{}, collation *Collation) error {
command := bson.D{{"create", view}, {"viewOn", source}, {"pipeline", pipeline}}
if collation != nil {
command = append(command, bson.DocElem{"collation", collation})
}
return db.Run(command, nil)
}

// With returns a copy of db that uses session s.
func (db *Database) With(s *Session) *Database {
newdb := *db
Expand Down Expand Up @@ -1499,6 +1537,29 @@ func (c *Collection) DropIndexName(name string) error {
return nil
}

// DropAllIndexes drops all the indexes from the c collection
func (c *Collection) DropAllIndexes() error {
session := c.Database.Session
session.ResetIndexCache()

session = session.Clone()
defer session.Close()

db := c.Database.With(session)
result := struct {
ErrMsg string
Ok bool
}{}
err := db.Run(bson.D{{"dropIndexes", c.Name}, {"index", "*"}}, &result)
if err != nil {
return err
}
if !result.Ok {
return errors.New(result.ErrMsg)
}
return nil
}

// nonEventual returns a clone of session and ensures it is not Eventual.
// This guarantees that the server that is used for queries may be reused
// afterwards when a cursor is received.
Expand All @@ -1512,19 +1573,6 @@ func (session *Session) nonEventual() *Session {

// Indexes returns a list of all indexes for the collection.
//
// For example, this snippet would drop all available indexes:
//
// indexes, err := collection.Indexes()
// if err != nil {
// return err
// }
// for _, index := range indexes {
// err = collection.DropIndex(index.Key...)
// if err != nil {
// return err
// }
// }
//
// See the EnsureIndex method for more details on indexes.
func (c *Collection) Indexes() (indexes []Index, err error) {
cloned := c.Database.Session.nonEventual()
Expand Down
Loading

0 comments on commit dfde865

Please sign in to comment.