166 lines
6.0 KiB
Go
166 lines
6.0 KiB
Go
// Copyright (C) MongoDB, Inc. 2017-present.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package options
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
|
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
|
)
|
|
|
|
// Collation allows users to specify language-specific rules for string comparison, such as
|
|
// rules for lettercase and accent marks.
|
|
type Collation struct {
|
|
Locale string `bson:",omitempty"` // The locale
|
|
CaseLevel bool `bson:",omitempty"` // The case level
|
|
CaseFirst string `bson:",omitempty"` // The case ordering
|
|
Strength int `bson:",omitempty"` // The number of comparison levels to use
|
|
NumericOrdering bool `bson:",omitempty"` // Whether to order numbers based on numerical order and not collation order
|
|
Alternate string `bson:",omitempty"` // Whether spaces and punctuation are considered base characters
|
|
MaxVariable string `bson:",omitempty"` // Which characters are affected by alternate: "shifted"
|
|
Normalization bool `bson:",omitempty"` // Causes text to be normalized into Unicode NFD
|
|
Backwards bool `bson:",omitempty"` // Causes secondary differences to be considered in reverse order, as it is done in the French language
|
|
}
|
|
|
|
// ToDocument converts the Collation to a bson.Raw.
|
|
func (co *Collation) ToDocument() bson.Raw {
|
|
idx, doc := bsoncore.AppendDocumentStart(nil)
|
|
if co.Locale != "" {
|
|
doc = bsoncore.AppendStringElement(doc, "locale", co.Locale)
|
|
}
|
|
if co.CaseLevel {
|
|
doc = bsoncore.AppendBooleanElement(doc, "caseLevel", true)
|
|
}
|
|
if co.CaseFirst != "" {
|
|
doc = bsoncore.AppendStringElement(doc, "caseFirst", co.CaseFirst)
|
|
}
|
|
if co.Strength != 0 {
|
|
doc = bsoncore.AppendInt32Element(doc, "strength", int32(co.Strength))
|
|
}
|
|
if co.NumericOrdering {
|
|
doc = bsoncore.AppendBooleanElement(doc, "numericOrdering", true)
|
|
}
|
|
if co.Alternate != "" {
|
|
doc = bsoncore.AppendStringElement(doc, "alternate", co.Alternate)
|
|
}
|
|
if co.MaxVariable != "" {
|
|
doc = bsoncore.AppendStringElement(doc, "maxVariable", co.MaxVariable)
|
|
}
|
|
if co.Normalization {
|
|
doc = bsoncore.AppendBooleanElement(doc, "normalization", true)
|
|
}
|
|
if co.Backwards {
|
|
doc = bsoncore.AppendBooleanElement(doc, "backwards", true)
|
|
}
|
|
doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
|
|
return doc
|
|
}
|
|
|
|
// CursorType specifies whether a cursor should close when the last data is retrieved. See
|
|
// NonTailable, Tailable, and TailableAwait.
|
|
type CursorType int8
|
|
|
|
const (
|
|
// NonTailable specifies that a cursor should close after retrieving the last data.
|
|
NonTailable CursorType = iota
|
|
// Tailable specifies that a cursor should not close when the last data is retrieved and can be resumed later.
|
|
Tailable
|
|
// TailableAwait specifies that a cursor should not close when the last data is retrieved and
|
|
// that it should block for a certain amount of time for new data before returning no data.
|
|
TailableAwait
|
|
)
|
|
|
|
// ReturnDocument specifies whether a findAndUpdate operation should return the document as it was
|
|
// before the update or as it is after the update.
|
|
type ReturnDocument int8
|
|
|
|
const (
|
|
// Before specifies that findAndUpdate should return the document as it was before the update.
|
|
Before ReturnDocument = iota
|
|
// After specifies that findAndUpdate should return the document as it is after the update.
|
|
After
|
|
)
|
|
|
|
// FullDocument specifies how a change stream should return the modified document.
|
|
type FullDocument string
|
|
|
|
const (
|
|
// Default does not include a document copy.
|
|
Default FullDocument = "default"
|
|
// Off is the same as sending no value for fullDocumentBeforeChange.
|
|
Off FullDocument = "off"
|
|
// Required is the same as WhenAvailable but raises a server-side error if the post-image is not available.
|
|
Required FullDocument = "required"
|
|
// UpdateLookup includes a delta describing the changes to the document and a copy of the entire document that
|
|
// was changed.
|
|
UpdateLookup FullDocument = "updateLookup"
|
|
// WhenAvailable includes a post-image of the the modified document for replace and update change events
|
|
// if the post-image for this event is available.
|
|
WhenAvailable FullDocument = "whenAvailable"
|
|
)
|
|
|
|
// ArrayFilters is used to hold filters for the array filters CRUD option. If a registry is nil, bson.DefaultRegistry
|
|
// will be used when converting the filter interfaces to BSON.
|
|
type ArrayFilters struct {
|
|
Registry *bsoncodec.Registry // The registry to use for converting filters. Defaults to bson.DefaultRegistry.
|
|
Filters []interface{} // The filters to apply
|
|
}
|
|
|
|
// ToArray builds a []bson.Raw from the provided ArrayFilters.
|
|
func (af *ArrayFilters) ToArray() ([]bson.Raw, error) {
|
|
registry := af.Registry
|
|
if registry == nil {
|
|
registry = bson.DefaultRegistry
|
|
}
|
|
filters := make([]bson.Raw, 0, len(af.Filters))
|
|
for _, f := range af.Filters {
|
|
filter, err := bson.MarshalWithRegistry(registry, f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filters = append(filters, filter)
|
|
}
|
|
return filters, nil
|
|
}
|
|
|
|
// ToArrayDocument builds a BSON array for the array filters CRUD option. If the registry for af is nil,
|
|
// bson.DefaultRegistry will be used when converting the filter interfaces to BSON.
|
|
func (af *ArrayFilters) ToArrayDocument() (bson.Raw, error) {
|
|
registry := af.Registry
|
|
if registry == nil {
|
|
registry = bson.DefaultRegistry
|
|
}
|
|
|
|
idx, arr := bsoncore.AppendArrayStart(nil)
|
|
for i, f := range af.Filters {
|
|
filter, err := bson.MarshalWithRegistry(registry, f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
arr = bsoncore.AppendDocumentElement(arr, strconv.Itoa(i), filter)
|
|
}
|
|
arr, _ = bsoncore.AppendArrayEnd(arr, idx)
|
|
return arr, nil
|
|
}
|
|
|
|
// MarshalError is returned when attempting to transform a value into a document
|
|
// results in an error.
|
|
type MarshalError struct {
|
|
Value interface{}
|
|
Err error
|
|
}
|
|
|
|
// Error implements the error interface.
|
|
func (me MarshalError) Error() string {
|
|
return fmt.Sprintf("cannot transform type %s to a bson.Raw", reflect.TypeOf(me.Value))
|
|
}
|