Don Newton | 379ae25 | 2019-04-01 12:17:06 -0400 | [diff] [blame^] | 1 | // 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 | |
| 7 | package wiremessage |
| 8 | |
| 9 | import ( |
| 10 | "errors" |
| 11 | "fmt" |
| 12 | "github.com/mongodb/mongo-go-driver/x/bsonx" |
| 13 | ) |
| 14 | |
| 15 | // KillCursors represents the OP_KILL_CURSORS message of the MongoDB wire protocol. |
| 16 | type KillCursors struct { |
| 17 | MsgHeader Header |
| 18 | Zero int32 |
| 19 | NumberOfCursorIDs int32 |
| 20 | CursorIDs []int64 |
| 21 | |
| 22 | DatabaseName string |
| 23 | CollectionName string |
| 24 | } |
| 25 | |
| 26 | // MarshalWireMessage implements the Marshaler and WireMessage interfaces. |
| 27 | func (kc KillCursors) MarshalWireMessage() ([]byte, error) { |
| 28 | b := make([]byte, 0, kc.Len()) |
| 29 | return kc.AppendWireMessage(b) |
| 30 | } |
| 31 | |
| 32 | // ValidateWireMessage implements the Validator and WireMessage interfaces. |
| 33 | func (kc KillCursors) ValidateWireMessage() error { |
| 34 | if int(kc.MsgHeader.MessageLength) != kc.Len() { |
| 35 | return errors.New("incorrect header: message length is not correct") |
| 36 | } |
| 37 | if kc.MsgHeader.OpCode != OpKillCursors { |
| 38 | return errors.New("incorrect header: op code is not OpGetMore") |
| 39 | } |
| 40 | if kc.NumberOfCursorIDs != int32(len(kc.CursorIDs)) { |
| 41 | return errors.New("incorrect number of cursor IDs") |
| 42 | } |
| 43 | |
| 44 | return nil |
| 45 | } |
| 46 | |
| 47 | // AppendWireMessage implements the Appender and WireMessage interfaces. |
| 48 | func (kc KillCursors) AppendWireMessage(b []byte) ([]byte, error) { |
| 49 | var err error |
| 50 | err = kc.MsgHeader.SetDefaults(kc.Len(), OpKillCursors) |
| 51 | |
| 52 | b = kc.MsgHeader.AppendHeader(b) |
| 53 | b = appendInt32(b, kc.Zero) |
| 54 | b = appendInt32(b, kc.NumberOfCursorIDs) |
| 55 | for _, id := range kc.CursorIDs { |
| 56 | b = appendInt64(b, id) |
| 57 | } |
| 58 | |
| 59 | return b, err |
| 60 | } |
| 61 | |
| 62 | // String implements the fmt.Stringer interface. |
| 63 | func (kc KillCursors) String() string { |
| 64 | return fmt.Sprintf( |
| 65 | `OP_KILL_CURSORS{MsgHeader: %s, Zero: %d, Number of Cursor IDS: %d, Cursor IDs: %v}`, |
| 66 | kc.MsgHeader, kc.Zero, kc.NumberOfCursorIDs, kc.CursorIDs, |
| 67 | ) |
| 68 | } |
| 69 | |
| 70 | // Len implements the WireMessage interface. |
| 71 | func (kc KillCursors) Len() int { |
| 72 | // Header + Zero + Number IDs + 8 * Number IDs |
| 73 | return 16 + 4 + 4 + int(kc.NumberOfCursorIDs*8) |
| 74 | } |
| 75 | |
| 76 | // UnmarshalWireMessage implements the Unmarshaler interface. |
| 77 | func (kc *KillCursors) UnmarshalWireMessage([]byte) error { |
| 78 | panic("not implemented") |
| 79 | } |
| 80 | |
| 81 | // CommandDocument creates a BSON document representing this command. |
| 82 | func (kc KillCursors) CommandDocument() bsonx.Doc { |
| 83 | cursors := make([]bsonx.Val, len(kc.CursorIDs)) |
| 84 | for i, id := range kc.CursorIDs { |
| 85 | cursors[i] = bsonx.Int64(id) |
| 86 | } |
| 87 | |
| 88 | return bsonx.Doc{ |
| 89 | {"killCursors", bsonx.String(kc.CollectionName)}, |
| 90 | {"cursors", bsonx.Array(cursors)}, |
| 91 | } |
| 92 | } |