Skip to content

Commit dfde865

Browse files
committed
Merge branch 'development' into bugfix/mapete94-index-int64-fields
* 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
2 parents 74bdb34 + 25200e4 commit dfde865

File tree

5 files changed

+284
-23
lines changed

5 files changed

+284
-23
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ env:
2222
- GO=1.6 MONGODB=x86_64-3.2.12
2323
- GO=1.7 MONGODB=x86_64-3.2.12
2424
- GO=1.8.x MONGODB=x86_64-3.2.12
25+
- GO=1.6 MONGODB=x86_64-3.2.16
26+
- GO=1.7 MONGODB=x86_64-3.2.16
27+
- GO=1.8.x MONGODB=x86_64-3.2.16
2528

2629
install:
2730
- eval "$(gimme $GO)"

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
1717
* Hides SASL warnings ([details](https://github.com/globalsign/mgo/pull/7))
1818
* Support for partial indexes ([detials](https://github.com/domodwyer/mgo/commit/5efe8eccb028238d93c222828cae4806aeae9f51))
1919
* Fixes timezone handling ([details](https://github.com/go-mgo/mgo/pull/464))
20-
* Integration tests run against newest MongoDB 3.2 releases ([details](https://github.com/globalsign/mgo/pull/4))
20+
* 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))
2121
* 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))
22-
* Fixes cursor timeouts ([detials](https://jira.mongodb.org/browse/SERVER-24899))
22+
* Fixes cursor timeouts ([details](https://jira.mongodb.org/browse/SERVER-24899))
2323
* Support index hints and timeouts for count queries ([details](https://github.com/globalsign/mgo/pull/17))
2424
* Don't panic when handling indexed `int64` fields ([detials](https://github.com/go-mgo/mgo/issues/475))
25+
* Allow dropping all indexes on a collection ([details](https://github.com/globalsign/mgo/pull/25))
26+
* Annotates log entries/profiler output with optional appName on 3.4+ ([details](https://github.com/globalsign/mgo/pull/28))
2527

2628
---
2729

@@ -31,6 +33,7 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili
3133
* @cezarsa
3234
* @drichelson
3335
* @eaglerayp
36+
* @feliixx
3437
* @fmpwizard
3538
* @jameinel
3639
* @mapete94

cluster.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"errors"
3131
"fmt"
3232
"net"
33+
"runtime"
3334
"strconv"
3435
"strings"
3536
"sync"
@@ -61,16 +62,18 @@ type mongoCluster struct {
6162
cachedIndex map[string]bool
6263
sync chan bool
6364
dial dialer
65+
appName string
6466
}
6567

66-
func newCluster(userSeeds []string, direct, failFast bool, dial dialer, setName string) *mongoCluster {
68+
func newCluster(userSeeds []string, direct, failFast bool, dial dialer, setName string, appName string) *mongoCluster {
6769
cluster := &mongoCluster{
6870
userSeeds: userSeeds,
6971
references: 1,
7072
direct: direct,
7173
failFast: failFast,
7274
dial: dial,
7375
setName: setName,
76+
appName: appName,
7477
}
7578
cluster.serverSynced.L = cluster.RWMutex.RLocker()
7679
cluster.sync = make(chan bool, 1)
@@ -144,7 +147,17 @@ func (cluster *mongoCluster) isMaster(socket *mongoSocket, result *isMasterResul
144147
// Monotonic let's it talk to a slave and still hold the socket.
145148
session := newSession(Monotonic, cluster, 10*time.Second)
146149
session.setSocket(socket)
147-
err := session.Run("ismaster", result)
150+
151+
// provide some meta infos on the client,
152+
// see https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.rst#connection-handshake
153+
// for details
154+
metaInfo := bson.M{"driver": bson.M{"name": "mgo", "version": "globalsign"},
155+
"os": bson.M{"type": runtime.GOOS, "architecture": runtime.GOARCH}}
156+
157+
if cluster.appName != "" {
158+
metaInfo["application"] = bson.M{"name": cluster.appName}
159+
}
160+
err := session.Run(bson.D{{"isMaster", 1}, {"client", metaInfo}}, result)
148161
session.Close()
149162
return err
150163
}

session.go

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ const (
157157
// topology.
158158
//
159159
// Dial will timeout after 10 seconds if a server isn't reached. The returned
160-
// session will timeout operations after one minute by default if servers
161-
// aren't available. To customize the timeout, see DialWithTimeout,
162-
// SetSyncTimeout, and SetSocketTimeout.
160+
// session will timeout operations after one minute by default if servers aren't
161+
// available. To customize the timeout, see DialWithTimeout, SetSyncTimeout, and
162+
// SetSocketTimeout.
163163
//
164164
// This method is generally called just once for a given cluster. Further
165165
// sessions to the same cluster are then established using the New or Copy
@@ -184,8 +184,8 @@ const (
184184
// If the port number is not provided for a server, it defaults to 27017.
185185
//
186186
// The username and password provided in the URL will be used to authenticate
187-
// into the database named after the slash at the end of the host names, or
188-
// into the "admin" database if none is provided. The authentication information
187+
// into the database named after the slash at the end of the host names, or into
188+
// the "admin" database if none is provided. The authentication information
189189
// will persist in sessions obtained through the New method as well.
190190
//
191191
// The following connection options are supported after the question mark:
@@ -235,6 +235,10 @@ const (
235235
// Defines the per-server socket pool limit. Defaults to 4096.
236236
// See Session.SetPoolLimit for details.
237237
//
238+
// appName=<appName>
239+
//
240+
// The identifier of this client application. This parameter is used to
241+
// annotate logs / profiler output and cannot exceed 128 bytes.
238242
//
239243
// Relevant documentation:
240244
//
@@ -279,6 +283,7 @@ func ParseURL(url string) (*DialInfo, error) {
279283
source := ""
280284
setName := ""
281285
poolLimit := 0
286+
appName := ""
282287
readPreferenceMode := Primary
283288
var readPreferenceTagSets []bson.D
284289
for _, opt := range uinfo.options {
@@ -296,6 +301,11 @@ func ParseURL(url string) (*DialInfo, error) {
296301
if err != nil {
297302
return nil, errors.New("bad value for maxPoolSize: " + opt.value)
298303
}
304+
case "appName":
305+
if len(opt.value) > 128 {
306+
return nil, errors.New("appName too long, must be < 128 bytes: " + opt.value)
307+
}
308+
appName = opt.value
299309
case "readPreference":
300310
switch opt.value {
301311
case "nearest":
@@ -350,6 +360,7 @@ func ParseURL(url string) (*DialInfo, error) {
350360
Service: service,
351361
Source: source,
352362
PoolLimit: poolLimit,
363+
AppName: appName,
353364
ReadPreference: &ReadPreference{
354365
Mode: readPreferenceMode,
355366
TagSets: readPreferenceTagSets,
@@ -409,6 +420,9 @@ type DialInfo struct {
409420
// See Session.SetPoolLimit for details.
410421
PoolLimit int
411422

423+
// The identifier of the client application which ran the operation.
424+
AppName string
425+
412426
// ReadPreference defines the manner in which servers are chosen. See
413427
// Session.SetMode and Session.SelectServers.
414428
ReadPreference *ReadPreference
@@ -472,7 +486,7 @@ func DialWithInfo(info *DialInfo) (*Session, error) {
472486
}
473487
addrs[i] = addr
474488
}
475-
cluster := newCluster(addrs, info.Direct, info.FailFast, dialer{info.Dial, info.DialServer}, info.ReplicaSetName)
489+
cluster := newCluster(addrs, info.Direct, info.FailFast, dialer{info.Dial, info.DialServer}, info.ReplicaSetName, info.AppName)
476490
session := newSession(Eventual, cluster, info.Timeout)
477491
session.defaultdb = info.Database
478492
if session.defaultdb == "" {
@@ -652,6 +666,30 @@ func (db *Database) C(name string) *Collection {
652666
return &Collection{db, name, db.Name + "." + name}
653667
}
654668

669+
// CreateView creates a view as the result of the applying the specified
670+
// aggregation pipeline to the source collection or view. Views act as
671+
// read-only collections, and are computed on demand during read operations.
672+
// MongoDB executes read operations on views as part of the underlying aggregation pipeline.
673+
//
674+
// For example:
675+
//
676+
// db := session.DB("mydb")
677+
// db.CreateView("myview", "mycoll", []bson.M{{"$match": bson.M{"c": 1}}}, nil)
678+
// view := db.C("myview")
679+
//
680+
// Relevant documentation:
681+
//
682+
// https://docs.mongodb.com/manual/core/views/
683+
// https://docs.mongodb.com/manual/reference/method/db.createView/
684+
//
685+
func (db *Database) CreateView(view string, source string, pipeline interface{}, collation *Collation) error {
686+
command := bson.D{{"create", view}, {"viewOn", source}, {"pipeline", pipeline}}
687+
if collation != nil {
688+
command = append(command, bson.DocElem{"collation", collation})
689+
}
690+
return db.Run(command, nil)
691+
}
692+
655693
// With returns a copy of db that uses session s.
656694
func (db *Database) With(s *Session) *Database {
657695
newdb := *db
@@ -1499,6 +1537,29 @@ func (c *Collection) DropIndexName(name string) error {
14991537
return nil
15001538
}
15011539

1540+
// DropAllIndexes drops all the indexes from the c collection
1541+
func (c *Collection) DropAllIndexes() error {
1542+
session := c.Database.Session
1543+
session.ResetIndexCache()
1544+
1545+
session = session.Clone()
1546+
defer session.Close()
1547+
1548+
db := c.Database.With(session)
1549+
result := struct {
1550+
ErrMsg string
1551+
Ok bool
1552+
}{}
1553+
err := db.Run(bson.D{{"dropIndexes", c.Name}, {"index", "*"}}, &result)
1554+
if err != nil {
1555+
return err
1556+
}
1557+
if !result.Ok {
1558+
return errors.New(result.ErrMsg)
1559+
}
1560+
return nil
1561+
}
1562+
15021563
// nonEventual returns a clone of session and ensures it is not Eventual.
15031564
// This guarantees that the server that is used for queries may be reused
15041565
// afterwards when a cursor is received.
@@ -1512,19 +1573,6 @@ func (session *Session) nonEventual() *Session {
15121573

15131574
// Indexes returns a list of all indexes for the collection.
15141575
//
1515-
// For example, this snippet would drop all available indexes:
1516-
//
1517-
// indexes, err := collection.Indexes()
1518-
// if err != nil {
1519-
// return err
1520-
// }
1521-
// for _, index := range indexes {
1522-
// err = collection.DropIndex(index.Key...)
1523-
// if err != nil {
1524-
// return err
1525-
// }
1526-
// }
1527-
//
15281576
// See the EnsureIndex method for more details on indexes.
15291577
func (c *Collection) Indexes() (indexes []Index, err error) {
15301578
cloned := c.Database.Session.nonEventual()

0 commit comments

Comments
 (0)