blob: 37b1f89a9ac2b789f12feed989cb131259033d35 [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/result"
17 "github.com/mongodb/mongo-go-driver/x/network/wiremessage"
18)
19
20// KillCursors represents the killCursors command.
21//
22// The killCursors command kills a set of cursors.
23type KillCursors struct {
24 Clock *session.ClusterClock
25 NS Namespace
26 IDs []int64
27
28 result result.KillCursors
29 err error
30}
31
32// Encode will encode this command into a wire message for the given server description.
33func (kc *KillCursors) Encode(desc description.SelectedServer) (wiremessage.WireMessage, error) {
34 encoded, err := kc.encode(desc)
35 if err != nil {
36 return nil, err
37 }
38 return encoded.Encode(desc)
39}
40
41func (kc *KillCursors) encode(desc description.SelectedServer) (*Read, error) {
42 idVals := make([]bsonx.Val, 0, len(kc.IDs))
43 for _, id := range kc.IDs {
44 idVals = append(idVals, bsonx.Int64(id))
45 }
46 cmd := bsonx.Doc{
47 {"killCursors", bsonx.String(kc.NS.Collection)},
48 {"cursors", bsonx.Array(idVals)},
49 }
50
51 return &Read{
52 Clock: kc.Clock,
53 DB: kc.NS.DB,
54 Command: cmd,
55 }, nil
56}
57
58// Decode will decode the wire message using the provided server description. Errors during decoding
59// are deferred until either the Result or Err methods are called.
60func (kc *KillCursors) Decode(desc description.SelectedServer, wm wiremessage.WireMessage) *KillCursors {
61 rdr, err := (&Read{}).Decode(desc, wm).Result()
62 if err != nil {
63 kc.err = err
64 return kc
65 }
66 return kc.decode(desc, rdr)
67}
68
69func (kc *KillCursors) decode(desc description.SelectedServer, rdr bson.Raw) *KillCursors {
70 err := bson.Unmarshal(rdr, &kc.result)
71 if err != nil {
72 kc.err = err
73 return kc
74 }
75 return kc
76}
77
78// Result returns the result of a decoded wire message and server description.
79func (kc *KillCursors) Result() (result.KillCursors, error) {
80 if kc.err != nil {
81 return result.KillCursors{}, kc.err
82 }
83
84 return kc.result, nil
85}
86
87// Err returns the error set on this command.
88func (kc *KillCursors) Err() error { return kc.err }
89
90// RoundTrip handles the execution of this command using the provided wiremessage.ReadWriter.
91func (kc *KillCursors) RoundTrip(ctx context.Context, desc description.SelectedServer, rw wiremessage.ReadWriter) (result.KillCursors, error) {
92 cmd, err := kc.encode(desc)
93 if err != nil {
94 return result.KillCursors{}, err
95 }
96
97 rdr, err := cmd.RoundTrip(ctx, desc, rw)
98 if err != nil {
99 return result.KillCursors{}, err
100 }
101
102 return kc.decode(desc, rdr).Result()
103}