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 command
8
9import (
10	"context"
11
12	"go.mongodb.org/mongo-driver/bson"
13	"go.mongodb.org/mongo-driver/mongo/writeconcern"
14	"go.mongodb.org/mongo-driver/x/bsonx"
15	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
16	"go.mongodb.org/mongo-driver/x/network/description"
17	"go.mongodb.org/mongo-driver/x/network/wiremessage"
18)
19
20// DropCollection represents the drop command.
21//
22// The dropCollections command drops collection for a database.
23type DropCollection struct {
24	DB           string
25	Collection   string
26	WriteConcern *writeconcern.WriteConcern
27	Clock        *session.ClusterClock
28	Session      *session.Client
29
30	result bson.Raw
31	err    error
32}
33
34// Encode will encode this command into a wire message for the given server description.
35func (dc *DropCollection) Encode(desc description.SelectedServer) (wiremessage.WireMessage, error) {
36	cmd, err := dc.encode(desc)
37	if err != nil {
38		return nil, err
39	}
40
41	return cmd.Encode(desc)
42}
43
44func (dc *DropCollection) encode(desc description.SelectedServer) (*Write, error) {
45	cmd := bsonx.Doc{{"drop", bsonx.String(dc.Collection)}}
46
47	write := &Write{
48		Clock:   dc.Clock,
49		DB:      dc.DB,
50		Command: cmd,
51		Session: dc.Session,
52	}
53	if desc.WireVersion != nil && desc.WireVersion.Max >= 5 {
54		write.WriteConcern = dc.WriteConcern
55	}
56	return write, nil
57}
58
59// Decode will decode the wire message using the provided server description. Errors during decoding
60// are deferred until either the Result or Err methods are called.
61func (dc *DropCollection) Decode(desc description.SelectedServer, wm wiremessage.WireMessage) *DropCollection {
62	rdr, err := (&Write{}).Decode(desc, wm).Result()
63	if err != nil {
64		dc.err = err
65		return dc
66	}
67
68	return dc.decode(desc, rdr)
69}
70
71func (dc *DropCollection) decode(desc description.SelectedServer, rdr bson.Raw) *DropCollection {
72	dc.result = rdr
73	return dc
74}
75
76// Result returns the result of a decoded wire message and server description.
77func (dc *DropCollection) Result() (bson.Raw, error) {
78	if dc.err != nil {
79		return nil, dc.err
80	}
81
82	return dc.result, nil
83}
84
85// Err returns the error set on this command.
86func (dc *DropCollection) Err() error { return dc.err }
87
88// RoundTrip handles the execution of this command using the provided wiremessage.ReadWriter.
89func (dc *DropCollection) RoundTrip(ctx context.Context, desc description.SelectedServer, rw wiremessage.ReadWriter) (bson.Raw, error) {
90	cmd, err := dc.encode(desc)
91	if err != nil {
92		return nil, err
93	}
94
95	rdr, err := cmd.RoundTrip(ctx, desc, rw)
96	if err != nil {
97		return nil, err
98	}
99
100	return dc.decode(desc, rdr).Result()
101}
102