blob: ce016b1154e2bea611b2f207f28a90cd5f0c65b5 [file] [log] [blame]
Don Newton379ae252019-04-01 12:17:06 -04001// Copyright (C) MongoDB, Inc. 2017-present.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7package command
8
9import (
10 "context"
11
12 "github.com/mongodb/mongo-go-driver/bson"
13 "github.com/mongodb/mongo-go-driver/x/bsonx"
14 "github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
15 "github.com/mongodb/mongo-go-driver/x/network/description"
16 "github.com/mongodb/mongo-go-driver/x/network/wiremessage"
17)
18
19// GetMore represents the getMore command.
20//
21// The getMore command retrieves additional documents from a cursor.
22type GetMore struct {
23 ID int64
24 NS Namespace
25 Opts []bsonx.Elem
26 Clock *session.ClusterClock
27 Session *session.Client
28
29 result bson.Raw
30 err error
31}
32
33// Encode will encode this command into a wire message for the given server description.
34func (gm *GetMore) Encode(desc description.SelectedServer) (wiremessage.WireMessage, error) {
35 cmd, err := gm.encode(desc)
36 if err != nil {
37 return nil, err
38 }
39
40 return cmd.Encode(desc)
41}
42
43func (gm *GetMore) encode(desc description.SelectedServer) (*Read, error) {
44 cmd := bsonx.Doc{
45 {"getMore", bsonx.Int64(gm.ID)},
46 {"collection", bsonx.String(gm.NS.Collection)},
47 }
48
49 for _, opt := range gm.Opts {
50 switch opt.Key {
51 case "maxAwaitTimeMS":
52 cmd = append(cmd, bsonx.Elem{"maxTimeMs", opt.Value})
53 default:
54 cmd = append(cmd, opt)
55 }
56 }
57
58 return &Read{
59 Clock: gm.Clock,
60 DB: gm.NS.DB,
61 Command: cmd,
62 Session: gm.Session,
63 }, nil
64}
65
66// Decode will decode the wire message using the provided server description. Errors during decoding
67// are deferred until either the Result or Err methods are called.
68func (gm *GetMore) Decode(desc description.SelectedServer, wm wiremessage.WireMessage) *GetMore {
69 rdr, err := (&Read{}).Decode(desc, wm).Result()
70 if err != nil {
71 gm.err = err
72 return gm
73 }
74
75 return gm.decode(desc, rdr)
76}
77
78func (gm *GetMore) decode(desc description.SelectedServer, rdr bson.Raw) *GetMore {
79 gm.result = rdr
80 return gm
81}
82
83// Result returns the result of a decoded wire message and server description.
84func (gm *GetMore) Result() (bson.Raw, error) {
85 if gm.err != nil {
86 return nil, gm.err
87 }
88
89 return gm.result, nil
90}
91
92// Err returns the error set on this command.
93func (gm *GetMore) Err() error { return gm.err }
94
95// RoundTrip handles the execution of this command using the provided wiremessage.ReadWriter.
96func (gm *GetMore) RoundTrip(ctx context.Context, desc description.SelectedServer, rw wiremessage.ReadWriter) (bson.Raw, error) {
97 cmd, err := gm.encode(desc)
98 if err != nil {
99 return nil, err
100 }
101
102 rdr, err := cmd.RoundTrip(ctx, desc, rw)
103 if err != nil {
104 return nil, err
105 }
106
107 return gm.decode(desc, rdr).Result()
108}