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 7package wiremessage 8 9import ( 10 "errors" 11 "fmt" 12 "go.mongodb.org/mongo-driver/x/bsonx" 13) 14 15// KillCursors represents the OP_KILL_CURSORS message of the MongoDB wire protocol. 16type 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. 27func (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. 33func (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. 48func (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. 63func (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. 71func (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. 77func (kc *KillCursors) UnmarshalWireMessage([]byte) error { 78 panic("not implemented") 79} 80 81// CommandDocument creates a BSON document representing this command. 82func (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} 93