1// Copyright (C) MongoDB, Inc. 2019-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// Code generated by operationgen. DO NOT EDIT.
8
9package operation
10
11import (
12	"context"
13	"errors"
14	"fmt"
15
16	"go.mongodb.org/mongo-driver/bson"
17	"go.mongodb.org/mongo-driver/event"
18	"go.mongodb.org/mongo-driver/mongo/description"
19	"go.mongodb.org/mongo-driver/mongo/readpref"
20	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
21	"go.mongodb.org/mongo-driver/x/mongo/driver"
22	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
23)
24
25// ListDatabases performs a listDatabases operation.
26type ListDatabases struct {
27	filter              bsoncore.Document
28	authorizedDatabases *bool
29	nameOnly            *bool
30	session             *session.Client
31	clock               *session.ClusterClock
32	monitor             *event.CommandMonitor
33	database            string
34	deployment          driver.Deployment
35	readPreference      *readpref.ReadPref
36	retry               *driver.RetryMode
37	selector            description.ServerSelector
38	crypt               *driver.Crypt
39
40	result ListDatabasesResult
41}
42
43type ListDatabasesResult struct {
44	// An array of documents, one document for each database
45	Databases []databaseRecord
46	// The sum of the size of all the database files on disk in bytes.
47	TotalSize int64
48}
49
50type databaseRecord struct {
51	Name       string
52	SizeOnDisk int64 `bson:"sizeOnDisk"`
53	Empty      bool
54}
55
56func buildListDatabasesResult(response bsoncore.Document, srvr driver.Server) (ListDatabasesResult, error) {
57	elements, err := response.Elements()
58	if err != nil {
59		return ListDatabasesResult{}, err
60	}
61	ir := ListDatabasesResult{}
62	for _, element := range elements {
63		switch element.Key() {
64
65		case "totalSize":
66			var ok bool
67			ir.TotalSize, ok = element.Value().AsInt64OK()
68			if !ok {
69				err = fmt.Errorf("response field 'totalSize' is type int64, but received BSON type %s: %s", element.Value().Type, element.Value())
70			}
71
72		case "databases":
73			// TODO: Make operationgen handle array results.
74			arr, ok := element.Value().ArrayOK()
75			if !ok {
76				err = fmt.Errorf("response field 'databases' is type array, but received BSON type %s", element.Value().Type)
77				continue
78			}
79
80			var tmp bsoncore.Document
81			marshalErr := bson.Unmarshal(arr, &tmp)
82			if marshalErr != nil {
83				err = marshalErr
84				continue
85			}
86			records, marshalErr := tmp.Elements()
87			if marshalErr != nil {
88				err = marshalErr
89				continue
90			}
91
92			ir.Databases = make([]databaseRecord, len(records))
93			for i, val := range records {
94				valueDoc, ok := val.Value().DocumentOK()
95				if !ok {
96					err = fmt.Errorf("'databases' element is type document, but received BSON type %s", val.Value().Type)
97					continue
98				}
99
100				elems, marshalErr := valueDoc.Elements()
101				if marshalErr != nil {
102					err = marshalErr
103					continue
104				}
105				for _, elem := range elems {
106					switch elem.Key() {
107
108					case "name":
109						ir.Databases[i].Name, ok = elem.Value().StringValueOK()
110						if !ok {
111							err = fmt.Errorf("response field 'name' is type string, but received BSON type %s", elem.Value().Type)
112							continue
113						}
114
115					case "sizeOnDisk":
116						ir.Databases[i].SizeOnDisk, ok = elem.Value().AsInt64OK()
117						if !ok {
118							err = fmt.Errorf("response field 'sizeOnDisk' is type int64, but received BSON type %s", elem.Value().Type)
119							continue
120						}
121
122					case "empty":
123						ir.Databases[i].Empty, ok = elem.Value().BooleanOK()
124						if !ok {
125							err = fmt.Errorf("response field 'empty' is type bool, but received BSON type %s", elem.Value().Type)
126							continue
127						}
128					}
129				}
130			}
131		}
132	}
133	return ir, err
134}
135
136// NewListDatabases constructs and returns a new ListDatabases.
137func NewListDatabases(filter bsoncore.Document) *ListDatabases {
138	return &ListDatabases{
139		filter: filter,
140	}
141}
142
143// Result returns the result of executing this operation.
144func (ld *ListDatabases) Result() ListDatabasesResult { return ld.result }
145
146func (ld *ListDatabases) processResponse(response bsoncore.Document, srvr driver.Server, desc description.Server, _ int) error {
147	var err error
148
149	ld.result, err = buildListDatabasesResult(response, srvr)
150	return err
151
152}
153
154// Execute runs this operations and returns an error if the operaiton did not execute successfully.
155func (ld *ListDatabases) Execute(ctx context.Context) error {
156	if ld.deployment == nil {
157		return errors.New("the ListDatabases operation must have a Deployment set before Execute can be called")
158	}
159
160	return driver.Operation{
161		CommandFn:         ld.command,
162		ProcessResponseFn: ld.processResponse,
163
164		Client:         ld.session,
165		Clock:          ld.clock,
166		CommandMonitor: ld.monitor,
167		Database:       ld.database,
168		Deployment:     ld.deployment,
169		ReadPreference: ld.readPreference,
170		RetryMode:      ld.retry,
171		Type:           driver.Read,
172		Selector:       ld.selector,
173		Crypt:          ld.crypt,
174	}.Execute(ctx, nil)
175
176}
177
178func (ld *ListDatabases) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
179	dst = bsoncore.AppendInt32Element(dst, "listDatabases", 1)
180	if ld.filter != nil {
181
182		dst = bsoncore.AppendDocumentElement(dst, "filter", ld.filter)
183	}
184	if ld.nameOnly != nil {
185
186		dst = bsoncore.AppendBooleanElement(dst, "nameOnly", *ld.nameOnly)
187	}
188	if ld.authorizedDatabases != nil {
189
190		dst = bsoncore.AppendBooleanElement(dst, "authorizedDatabases", *ld.authorizedDatabases)
191	}
192
193	return dst, nil
194}
195
196// Filter determines what results are returned from listDatabases.
197func (ld *ListDatabases) Filter(filter bsoncore.Document) *ListDatabases {
198	if ld == nil {
199		ld = new(ListDatabases)
200	}
201
202	ld.filter = filter
203	return ld
204}
205
206// NameOnly specifies whether to only return database names.
207func (ld *ListDatabases) NameOnly(nameOnly bool) *ListDatabases {
208	if ld == nil {
209		ld = new(ListDatabases)
210	}
211
212	ld.nameOnly = &nameOnly
213	return ld
214}
215
216// AuthorizedDatabases specifies whether to only return databases which the user is authorized to use."
217func (ld *ListDatabases) AuthorizedDatabases(authorizedDatabases bool) *ListDatabases {
218	if ld == nil {
219		ld = new(ListDatabases)
220	}
221
222	ld.authorizedDatabases = &authorizedDatabases
223	return ld
224}
225
226// Session sets the session for this operation.
227func (ld *ListDatabases) Session(session *session.Client) *ListDatabases {
228	if ld == nil {
229		ld = new(ListDatabases)
230	}
231
232	ld.session = session
233	return ld
234}
235
236// ClusterClock sets the cluster clock for this operation.
237func (ld *ListDatabases) ClusterClock(clock *session.ClusterClock) *ListDatabases {
238	if ld == nil {
239		ld = new(ListDatabases)
240	}
241
242	ld.clock = clock
243	return ld
244}
245
246// CommandMonitor sets the monitor to use for APM events.
247func (ld *ListDatabases) CommandMonitor(monitor *event.CommandMonitor) *ListDatabases {
248	if ld == nil {
249		ld = new(ListDatabases)
250	}
251
252	ld.monitor = monitor
253	return ld
254}
255
256// Database sets the database to run this operation against.
257func (ld *ListDatabases) Database(database string) *ListDatabases {
258	if ld == nil {
259		ld = new(ListDatabases)
260	}
261
262	ld.database = database
263	return ld
264}
265
266// Deployment sets the deployment to use for this operation.
267func (ld *ListDatabases) Deployment(deployment driver.Deployment) *ListDatabases {
268	if ld == nil {
269		ld = new(ListDatabases)
270	}
271
272	ld.deployment = deployment
273	return ld
274}
275
276// ReadPreference set the read prefernce used with this operation.
277func (ld *ListDatabases) ReadPreference(readPreference *readpref.ReadPref) *ListDatabases {
278	if ld == nil {
279		ld = new(ListDatabases)
280	}
281
282	ld.readPreference = readPreference
283	return ld
284}
285
286// ServerSelector sets the selector used to retrieve a server.
287func (ld *ListDatabases) ServerSelector(selector description.ServerSelector) *ListDatabases {
288	if ld == nil {
289		ld = new(ListDatabases)
290	}
291
292	ld.selector = selector
293	return ld
294}
295
296// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based
297// on how the operation is set.
298func (ld *ListDatabases) Retry(retry driver.RetryMode) *ListDatabases {
299	if ld == nil {
300		ld = new(ListDatabases)
301	}
302
303	ld.retry = &retry
304	return ld
305}
306
307// Crypt sets the Crypt object to use for automatic encryption and decryption.
308func (ld *ListDatabases) Crypt(crypt *driver.Crypt) *ListDatabases {
309	if ld == nil {
310		ld = new(ListDatabases)
311	}
312
313	ld.crypt = crypt
314	return ld
315}
316