" {
- break
- }
-
- f := runtime.FuncForPC(pc)
- if f == nil {
- break
- }
- name = f.Name()
-
- // testing.tRunner is the standard library function that calls
- // tests. Subtests are called directly by tRunner, without going through
- // the Test/Benchmark/Example function that contains the t.Run calls, so
- // with subtests we should break when we hit tRunner, without adding it
- // to the list of callers.
- if name == "testing.tRunner" {
- break
- }
-
- parts := strings.Split(file, "/")
- file = parts[len(parts)-1]
- if len(parts) > 1 {
- dir := parts[len(parts)-2]
- if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
- path, _ := filepath.Abs(file)
- callers = append(callers, fmt.Sprintf("%s:%d", path, line))
- }
- }
-
- // Drop the package
- segments := strings.Split(name, ".")
- name = segments[len(segments)-1]
- if isTest(name, "Test") ||
- isTest(name, "Benchmark") ||
- isTest(name, "Example") {
- break
- }
- }
-
- return callers
-}
-
-// Stolen from the `go test` tool.
-// isTest tells whether name looks like a test (or benchmark, according to prefix).
-// It is a Test (say) if there is a character after Test that is not a lower-case letter.
-// We don't want TesticularCancer.
-func isTest(name, prefix string) bool {
- if !strings.HasPrefix(name, prefix) {
- return false
- }
- if len(name) == len(prefix) { // "Test" is ok
- return true
- }
- r, _ := utf8.DecodeRuneInString(name[len(prefix):])
- return !unicode.IsLower(r)
-}
-
-func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
- if len(msgAndArgs) == 0 || msgAndArgs == nil {
- return ""
- }
- if len(msgAndArgs) == 1 {
- msg := msgAndArgs[0]
- if msgAsStr, ok := msg.(string); ok {
- return msgAsStr
- }
- return fmt.Sprintf("%+v", msg)
- }
- if len(msgAndArgs) > 1 {
- return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
- }
- return ""
-}
-
-// Aligns the provided message so that all lines after the first line start at the same location as the first line.
-// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab).
-// The longestLabelLen parameter specifies the length of the longest label in the output (required because this is the
-// basis on which the alignment occurs).
-func indentMessageLines(message string, longestLabelLen int) string {
- outBuf := new(bytes.Buffer)
-
- for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
- // no need to align first line because it starts at the correct location (after the label)
- if i != 0 {
- // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
- outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
- }
- outBuf.WriteString(scanner.Text())
- }
-
- return outBuf.String()
-}
-
-type failNower interface {
- FailNow()
-}
-
-// FailNow fails test
-func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- Fail(t, failureMessage, msgAndArgs...)
-
- // We cannot extend TestingT with FailNow() and
- // maintain backwards compatibility, so we fallback
- // to panicking when FailNow is not available in
- // TestingT.
- // See issue #263
-
- if t, ok := t.(failNower); ok {
- t.FailNow()
- } else {
- panic("test failed and t is missing `FailNow()`")
- }
- return false
-}
-
-// Fail reports a failure through
-func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- content := []labeledContent{
- {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
- {"Error", failureMessage},
- }
-
- // Add test name if the Go version supports it
- if n, ok := t.(interface {
- Name() string
- }); ok {
- content = append(content, labeledContent{"Test", n.Name()})
- }
-
- message := messageFromMsgAndArgs(msgAndArgs...)
- if len(message) > 0 {
- content = append(content, labeledContent{"Messages", message})
- }
-
- t.Errorf("\n%s", ""+labeledOutput(content...))
-
- return false
-}
-
-type labeledContent struct {
- label string
- content string
-}
-
-// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
-//
-// \t{{label}}:{{align_spaces}}\t{{content}}\n
-//
-// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
-// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
-// alignment is achieved, "\t{{content}}\n" is added for the output.
-//
-// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line.
-func labeledOutput(content ...labeledContent) string {
- longestLabel := 0
- for _, v := range content {
- if len(v.label) > longestLabel {
- longestLabel = len(v.label)
- }
- }
- var output string
- for _, v := range content {
- output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
- }
- return output
-}
-
-// IsType asserts that the specified objects are of the same type.
-func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
- return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
- }
-
- return true
-}
-
-// Equal asserts that two objects are equal.
-//
-// assert.Equal(t, 123, 123)
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses). Function equality
-// cannot be determined and will always fail.
-func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if err := validateEqualArgs(expected, actual); err != nil {
- return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
- expected, actual, err), msgAndArgs...)
- }
-
- if !ObjectsAreEqual(expected, actual) {
- diff := diff(expected, actual)
- expected, actual = formatUnequalValues(expected, actual)
- return Fail(t, fmt.Sprintf("Not equal: \n"+
- "expected: %s\n"+
- "actual : %s%s", expected, actual, diff), msgAndArgs...)
- }
-
- return true
-
-}
-
-// validateEqualArgs checks whether provided arguments can be safely used in the
-// Equal/NotEqual functions.
-func validateEqualArgs(expected, actual interface{}) error {
- if expected == nil && actual == nil {
- return nil
- }
-
- if isFunction(expected) || isFunction(actual) {
- return errors.New("cannot take func type as argument")
- }
- return nil
-}
-
-// formatUnequalValues takes two values of arbitrary types and returns string
-// representations appropriate to be presented to the user.
-//
-// If the values are not of like type, the returned strings will be prefixed
-// with the type name, and the value will be enclosed in parenthesis similar
-// to a type conversion in the Go grammar.
-func formatUnequalValues(expected, actual interface{}) (e string, a string) {
- if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
- return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)),
- fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual))
- }
- switch expected.(type) {
- case time.Duration:
- return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual)
- }
- return truncatingFormat(expected), truncatingFormat(actual)
-}
-
-// truncatingFormat formats the data and truncates it if it's too long.
-//
-// This helps keep formatted error messages lines from exceeding the
-// bufio.MaxScanTokenSize max line length that the go testing framework imposes.
-func truncatingFormat(data interface{}) string {
- value := fmt.Sprintf("%#v", data)
- max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed.
- if len(value) > max {
- value = value[0:max] + "<... truncated>"
- }
- return value
-}
-
-// EqualValues asserts that two objects are equal or convertible to the same types
-// and equal.
-//
-// assert.EqualValues(t, uint32(123), int32(123))
-func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- if !ObjectsAreEqualValues(expected, actual) {
- diff := diff(expected, actual)
- expected, actual = formatUnequalValues(expected, actual)
- return Fail(t, fmt.Sprintf("Not equal: \n"+
- "expected: %s\n"+
- "actual : %s%s", expected, actual, diff), msgAndArgs...)
- }
-
- return true
-
-}
-
-// NotNil asserts that the specified object is not nil.
-//
-// assert.NotNil(t, err)
-func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
- if !isNil(object) {
- return true
- }
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, "Expected value not to be nil.", msgAndArgs...)
-}
-
-// containsKind checks if a specified kind in the slice of kinds.
-func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
- for i := 0; i < len(kinds); i++ {
- if kind == kinds[i] {
- return true
- }
- }
-
- return false
-}
-
-// isNil checks if a specified object is nil or not, without Failing.
-func isNil(object interface{}) bool {
- if object == nil {
- return true
- }
-
- value := reflect.ValueOf(object)
- kind := value.Kind()
- isNilableKind := containsKind(
- []reflect.Kind{
- reflect.Chan, reflect.Func,
- reflect.Interface, reflect.Map,
- reflect.Ptr, reflect.Slice},
- kind)
-
- if isNilableKind && value.IsNil() {
- return true
- }
-
- return false
-}
-
-// Nil asserts that the specified object is nil.
-//
-// assert.Nil(t, err)
-func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
- if isNil(object) {
- return true
- }
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
-}
-
-// getLen try to get length of object.
-// return (false, 0) if impossible.
-func getLen(x interface{}) (ok bool, length int) {
- v := reflect.ValueOf(x)
- defer func() {
- if e := recover(); e != nil {
- ok = false
- }
- }()
- return true, v.Len()
-}
-
-// Len asserts that the specified object has specific length.
-// Len also fails if the object has a type that len() not accept.
-//
-// assert.Len(t, mySlice, 3)
-func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- ok, l := getLen(object)
- if !ok {
- return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
- }
-
- if l != length {
- return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
- }
- return true
-}
-
-// True asserts that the specified value is true.
-//
-// assert.True(t, myBool)
-func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
- if !value {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, "Should be true", msgAndArgs...)
- }
-
- return true
-
-}
-
-// False asserts that the specified value is false.
-//
-// assert.False(t, myBool)
-func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
- if value {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, "Should be false", msgAndArgs...)
- }
-
- return true
-
-}
-
-// NotEqual asserts that the specified values are NOT equal.
-//
-// assert.NotEqual(t, obj1, obj2)
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses).
-func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if err := validateEqualArgs(expected, actual); err != nil {
- return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
- expected, actual, err), msgAndArgs...)
- }
-
- if ObjectsAreEqual(expected, actual) {
- return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
- }
-
- return true
-
-}
-
-// NotEqualValues asserts that two objects are not equal even when converted to the same type
-//
-// assert.NotEqualValues(t, obj1, obj2)
-func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- if ObjectsAreEqualValues(expected, actual) {
- return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
- }
-
- return true
-}
-
-// containsElement try loop over the list check if the list includes the element.
-// return (false, false) if impossible.
-// return (true, false) if element was not found.
-// return (true, true) if element was found.
-func containsElement(list interface{}, element interface{}) (ok, found bool) {
-
- listValue := reflect.ValueOf(list)
- listType := reflect.TypeOf(list)
- if listType == nil {
- return false, false
- }
- listKind := listType.Kind()
- defer func() {
- if e := recover(); e != nil {
- ok = false
- found = false
- }
- }()
-
- if listKind == reflect.String {
- elementValue := reflect.ValueOf(element)
- return true, strings.Contains(listValue.String(), elementValue.String())
- }
-
- if listKind == reflect.Map {
- mapKeys := listValue.MapKeys()
- for i := 0; i < len(mapKeys); i++ {
- if ObjectsAreEqual(mapKeys[i].Interface(), element) {
- return true, true
- }
- }
- return true, false
- }
-
- for i := 0; i < listValue.Len(); i++ {
- if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
- return true, true
- }
- }
- return true, false
-
-}
-
-// Contains asserts that the specified string, list(array, slice...) or map contains the
-// specified substring or element.
-//
-// assert.Contains(t, "Hello World", "World")
-// assert.Contains(t, ["Hello", "World"], "World")
-// assert.Contains(t, {"Hello": "World"}, "Hello")
-func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- ok, found := containsElement(s, contains)
- if !ok {
- return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
- }
- if !found {
- return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...)
- }
-
- return true
-
-}
-
-// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
-// specified substring or element.
-//
-// assert.NotContains(t, "Hello World", "Earth")
-// assert.NotContains(t, ["Hello", "World"], "Earth")
-// assert.NotContains(t, {"Hello": "World"}, "Earth")
-func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- ok, found := containsElement(s, contains)
- if !ok {
- return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
- }
- if found {
- return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
- }
-
- return true
-
-}
-
-// isEmpty gets whether the specified object is considered empty or not.
-func isEmpty(object interface{}) bool {
-
- // get nil case out of the way
- if object == nil {
- return true
- }
-
- objValue := reflect.ValueOf(object)
-
- switch objValue.Kind() {
- // collection types are empty when they have no element
- case reflect.Chan, reflect.Map, reflect.Slice:
- return objValue.Len() == 0
- // pointers are empty if nil or if the value they point to is empty
- case reflect.Ptr:
- if objValue.IsNil() {
- return true
- }
- deref := objValue.Elem().Interface()
- return isEmpty(deref)
- // for all other types, compare against the zero value
- // array types are empty when they match their zero-initialized state
- default:
- zero := reflect.Zero(objValue.Type())
- return reflect.DeepEqual(object, zero.Interface())
- }
-}
-
-// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
-// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
-// the number of appearances of each of them in both lists should match.
-//
-// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
-func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if isEmpty(listA) && isEmpty(listB) {
- return true
- }
-
- if !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) {
- return false
- }
-
- extraA, extraB := diffLists(listA, listB)
-
- if len(extraA) == 0 && len(extraB) == 0 {
- return true
- }
-
- return Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...)
-}
-
-// isList checks that the provided value is array or slice.
-func isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) {
- kind := reflect.TypeOf(list).Kind()
- if kind != reflect.Array && kind != reflect.Slice {
- return Fail(t, fmt.Sprintf("%q has an unsupported type %s, expecting array or slice", list, kind),
- msgAndArgs...)
- }
- return true
-}
-
-// diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B.
-// If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and
-// 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored.
-func diffLists(listA, listB interface{}) ([]interface{}, []interface{}) {
- var extraA, extraB []interface{}
-
- aValue := reflect.ValueOf(listA)
- bValue := reflect.ValueOf(listB)
-
- aLen := aValue.Len()
- bLen := bValue.Len()
-
- // Mark indexes in bValue that we already used
- visited := make([]bool, bLen)
- for i := 0; i < aLen; i++ {
- element := aValue.Index(i).Interface()
- found := false
- for j := 0; j < bLen; j++ {
- if visited[j] {
- continue
- }
- if ObjectsAreEqual(bValue.Index(j).Interface(), element) {
- visited[j] = true
- found = true
- break
- }
- }
- if !found {
- extraA = append(extraA, element)
- }
- }
-
- for j := 0; j < bLen; j++ {
- if visited[j] {
- continue
- }
- extraB = append(extraB, bValue.Index(j).Interface())
- }
-
- return extraA, extraB
-}
-
-func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string {
- var msg bytes.Buffer
-
- msg.WriteString("elements differ")
- if len(extraA) > 0 {
- msg.WriteString("\n\nextra elements in list A:\n")
- msg.WriteString(spewConfig.Sdump(extraA))
- }
- if len(extraB) > 0 {
- msg.WriteString("\n\nextra elements in list B:\n")
- msg.WriteString(spewConfig.Sdump(extraB))
- }
- msg.WriteString("\n\nlistA:\n")
- msg.WriteString(spewConfig.Sdump(listA))
- msg.WriteString("\n\nlistB:\n")
- msg.WriteString(spewConfig.Sdump(listB))
-
- return msg.String()
-}
-
-// WithinDuration asserts that the two times are within duration delta of each other.
-//
-// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
-func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- dt := expected.Sub(actual)
- if dt < -delta || dt > delta {
- return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
- }
-
- return true
-}
-
-func toFloat(x interface{}) (float64, bool) {
- var xf float64
- xok := true
-
- switch xn := x.(type) {
- case uint:
- xf = float64(xn)
- case uint8:
- xf = float64(xn)
- case uint16:
- xf = float64(xn)
- case uint32:
- xf = float64(xn)
- case uint64:
- xf = float64(xn)
- case int:
- xf = float64(xn)
- case int8:
- xf = float64(xn)
- case int16:
- xf = float64(xn)
- case int32:
- xf = float64(xn)
- case int64:
- xf = float64(xn)
- case float32:
- xf = float64(xn)
- case float64:
- xf = xn
- case time.Duration:
- xf = float64(xn)
- default:
- xok = false
- }
-
- return xf, xok
-}
-
-// InDelta asserts that the two numerals are within delta of each other.
-//
-// assert.InDelta(t, math.Pi, 22/7.0, 0.01)
-func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- af, aok := toFloat(expected)
- bf, bok := toFloat(actual)
-
- if !aok || !bok {
- return Fail(t, "Parameters must be numerical", msgAndArgs...)
- }
-
- if math.IsNaN(af) && math.IsNaN(bf) {
- return true
- }
-
- if math.IsNaN(af) {
- return Fail(t, "Expected must not be NaN", msgAndArgs...)
- }
-
- if math.IsNaN(bf) {
- return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
- }
-
- dt := af - bf
- if dt < -delta || dt > delta {
- return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
- }
-
- return true
-}
-
-/*
- Errors
-*/
-
-// NoError asserts that a function returned no error (i.e. `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.NoError(t, err) {
-// assert.Equal(t, expectedObj, actualObj)
-// }
-func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
- if err != nil {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
- }
-
- return true
-}
-
-// Error asserts that a function returned an error (i.e. not `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.Error(t, err) {
-// assert.Equal(t, expectedError, err)
-// }
-func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
- if err == nil {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return Fail(t, "An error is expected but got nil.", msgAndArgs...)
- }
-
- return true
-}
-
-// EqualError asserts that a function returned an error (i.e. not `nil`)
-// and that it is equal to the provided error.
-//
-// actualObj, err := SomeFunction()
-// assert.EqualError(t, err, expectedErrorString)
-func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if !Error(t, theError, msgAndArgs...) {
- return false
- }
- expected := errString
- actual := theError.Error()
- // don't need to use deep equals here, we know they are both strings
- if expected != actual {
- return Fail(t, fmt.Sprintf("Error message not equal:\n"+
- "expected: %q\n"+
- "actual : %q", expected, actual), msgAndArgs...)
- }
- return true
-}
-
-// ErrorIs asserts that at least one of the errors in err's chain matches target.
-// This is a wrapper for errors.Is.
-func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if errors.Is(err, target) {
- return true
- }
-
- var expectedText string
- if target != nil {
- expectedText = target.Error()
- }
-
- chain := buildErrorChainString(err)
-
- return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
- "expected: %q\n"+
- "in chain: %s", expectedText, chain,
- ), msgAndArgs...)
-}
-
-// ErrorContains asserts that a function returned an error (i.e. not `nil`)
-// and that the error contains the specified substring.
-//
-// actualObj, err := SomeFunction()
-// assert.ErrorContains(t, err, expectedErrorSubString)
-func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if !Error(t, theError, msgAndArgs...) {
- return false
- }
-
- actual := theError.Error()
- if !strings.Contains(actual, contains) {
- return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...)
- }
-
- return true
-}
-
-func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
- t := reflect.TypeOf(v)
- k := t.Kind()
-
- if k == reflect.Ptr {
- t = t.Elem()
- k = t.Kind()
- }
- return t, k
-}
-
-// diff returns a diff of both values as long as both are of the same type and
-// are a struct, map, slice, array or string. Otherwise it returns an empty string.
-func diff(expected interface{}, actual interface{}) string {
- if expected == nil || actual == nil {
- return ""
- }
-
- et, ek := typeAndKind(expected)
- at, _ := typeAndKind(actual)
-
- if et != at {
- return ""
- }
-
- if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
- return ""
- }
-
- var e, a string
-
- switch et {
- case reflect.TypeOf(""):
- e = reflect.ValueOf(expected).String()
- a = reflect.ValueOf(actual).String()
- case reflect.TypeOf(time.Time{}):
- e = spewConfigStringerEnabled.Sdump(expected)
- a = spewConfigStringerEnabled.Sdump(actual)
- default:
- e = spewConfig.Sdump(expected)
- a = spewConfig.Sdump(actual)
- }
-
- diff, _ := GetUnifiedDiffString(UnifiedDiff{
- A: SplitLines(e),
- B: SplitLines(a),
- FromFile: "Expected",
- FromDate: "",
- ToFile: "Actual",
- ToDate: "",
- Context: 1,
- })
-
- return "\n\nDiff:\n" + diff
-}
-
-func isFunction(arg interface{}) bool {
- if arg == nil {
- return false
- }
- return reflect.TypeOf(arg).Kind() == reflect.Func
-}
-
-var spewConfig = spew.ConfigState{
- Indent: " ",
- DisablePointerAddresses: true,
- DisableCapacities: true,
- SortKeys: true,
- DisableMethods: true,
- MaxDepth: 10,
-}
-
-var spewConfigStringerEnabled = spew.ConfigState{
- Indent: " ",
- DisablePointerAddresses: true,
- DisableCapacities: true,
- SortKeys: true,
- MaxDepth: 10,
-}
-
-type tHelper interface {
- Helper()
-}
-
-// Eventually asserts that given condition will be met in waitFor time,
-// periodically checking target function each tick.
-//
-// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)
-func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
-
- ch := make(chan bool, 1)
-
- timer := time.NewTimer(waitFor)
- defer timer.Stop()
-
- ticker := time.NewTicker(tick)
- defer ticker.Stop()
-
- for tick := ticker.C; ; {
- select {
- case <-timer.C:
- return Fail(t, "Condition never satisfied", msgAndArgs...)
- case <-tick:
- tick = nil
- go func() { ch <- condition() }()
- case v := <-ch:
- if v {
- return true
- }
- tick = ticker.C
- }
- }
-}
-
-func buildErrorChainString(err error) string {
- if err == nil {
- return ""
- }
-
- e := errors.Unwrap(err)
- chain := fmt.Sprintf("%q", err.Error())
- for e != nil {
- chain += fmt.Sprintf("\n\t%q", e.Error())
- e = errors.Unwrap(e)
- }
- return chain
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/assert/difflib.go b/vendor/go.mongodb.org/mongo-driver/internal/assert/difflib.go
deleted file mode 100644
index e13a66a93..000000000
--- a/vendor/go.mongodb.org/mongo-driver/internal/assert/difflib.go
+++ /dev/null
@@ -1,766 +0,0 @@
-// Copied from https://github.com/pmezard/go-difflib/blob/5d4384ee4fb2527b0a1256a821ebfc92f91efefc/difflib/difflib.go
-
-// Copyright 2013 Patrick Mezard. All rights reserved. Use of this source code is
-// governed by a license that can be found in the THIRD-PARTY-NOTICES file.
-
-package assert
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "strings"
-)
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-func calculateRatio(matches, length int) float64 {
- if length > 0 {
- return 2.0 * float64(matches) / float64(length)
- }
- return 1.0
-}
-
-type Match struct {
- A int
- B int
- Size int
-}
-
-type OpCode struct {
- Tag byte
- I1 int
- I2 int
- J1 int
- J2 int
-}
-
-// SequenceMatcher compares sequence of strings. The basic
-// algorithm predates, and is a little fancier than, an algorithm
-// published in the late 1980's by Ratcliff and Obershelp under the
-// hyperbolic name "gestalt pattern matching". The basic idea is to find
-// the longest contiguous matching subsequence that contains no "junk"
-// elements (R-O doesn't address junk). The same idea is then applied
-// recursively to the pieces of the sequences to the left and to the right
-// of the matching subsequence. This does not yield minimal edit
-// sequences, but does tend to yield matches that "look right" to people.
-//
-// SequenceMatcher tries to compute a "human-friendly diff" between two
-// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the
-// longest *contiguous* & junk-free matching subsequence. That's what
-// catches peoples' eyes. The Windows(tm) windiff has another interesting
-// notion, pairing up elements that appear uniquely in each sequence.
-// That, and the method here, appear to yield more intuitive difference
-// reports than does diff. This method appears to be the least vulnerable
-// to syncing up on blocks of "junk lines", though (like blank lines in
-// ordinary text files, or maybe "" lines in HTML files). That may be
-// because this is the only method of the 3 that has a *concept* of
-// "junk" .
-//
-// Timing: Basic R-O is cubic time worst case and quadratic time expected
-// case. SequenceMatcher is quadratic time for the worst case and has
-// expected-case behavior dependent in a complicated way on how many
-// elements the sequences have in common; best case time is linear.
-type SequenceMatcher struct {
- a []string
- b []string
- b2j map[string][]int
- IsJunk func(string) bool
- autoJunk bool
- bJunk map[string]struct{}
- matchingBlocks []Match
- fullBCount map[string]int
- bPopular map[string]struct{}
- opCodes []OpCode
-}
-
-func NewMatcher(a, b []string) *SequenceMatcher {
- m := SequenceMatcher{autoJunk: true}
- m.SetSeqs(a, b)
- return &m
-}
-
-func NewMatcherWithJunk(a, b []string, autoJunk bool,
- isJunk func(string) bool) *SequenceMatcher {
-
- m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}
- m.SetSeqs(a, b)
- return &m
-}
-
-// SetSeqs sets the two sequences to be compared.
-func (m *SequenceMatcher) SetSeqs(a, b []string) {
- m.SetSeq1(a)
- m.SetSeq2(b)
-}
-
-// SetSeq1 sets the first sequence to be compared. The second sequence to be compared is
-// not changed.
-//
-// SequenceMatcher computes and caches detailed information about the second
-// sequence, so if you want to compare one sequence S against many sequences,
-// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
-// sequences.
-//
-// See also SetSeqs() and SetSeq2().
-func (m *SequenceMatcher) SetSeq1(a []string) {
- if &a == &m.a {
- return
- }
- m.a = a
- m.matchingBlocks = nil
- m.opCodes = nil
-}
-
-// SetSeq2 sets the second sequence to be compared. The first sequence to be compared is
-// not changed.
-func (m *SequenceMatcher) SetSeq2(b []string) {
- if &b == &m.b {
- return
- }
- m.b = b
- m.matchingBlocks = nil
- m.opCodes = nil
- m.fullBCount = nil
- m.chainB()
-}
-
-func (m *SequenceMatcher) chainB() {
- // Populate line -> index mapping
- b2j := map[string][]int{}
- for i, s := range m.b {
- indices := b2j[s]
- indices = append(indices, i)
- b2j[s] = indices
- }
-
- // Purge junk elements
- m.bJunk = map[string]struct{}{}
- if m.IsJunk != nil {
- junk := m.bJunk
- for s := range b2j {
- if m.IsJunk(s) {
- junk[s] = struct{}{}
- }
- }
- for s := range junk {
- delete(b2j, s)
- }
- }
-
- // Purge remaining popular elements
- popular := map[string]struct{}{}
- n := len(m.b)
- if m.autoJunk && n >= 200 {
- ntest := n/100 + 1
- for s, indices := range b2j {
- if len(indices) > ntest {
- popular[s] = struct{}{}
- }
- }
- for s := range popular {
- delete(b2j, s)
- }
- }
- m.bPopular = popular
- m.b2j = b2j
-}
-
-func (m *SequenceMatcher) isBJunk(s string) bool {
- _, ok := m.bJunk[s]
- return ok
-}
-
-// Find longest matching block in a[alo:ahi] and b[blo:bhi].
-//
-// If IsJunk is not defined:
-//
-// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
-//
-// alo <= i <= i+k <= ahi
-// blo <= j <= j+k <= bhi
-//
-// and for all (i',j',k') meeting those conditions,
-//
-// k >= k'
-// i <= i'
-// and if i == i', j <= j'
-//
-// In other words, of all maximal matching blocks, return one that
-// starts earliest in a, and of all those maximal matching blocks that
-// start earliest in a, return the one that starts earliest in b.
-//
-// If IsJunk is defined, first the longest matching block is
-// determined as above, but with the additional restriction that no
-// junk element appears in the block. Then that block is extended as
-// far as possible by matching (only) junk elements on both sides. So
-// the resulting block never matches on junk except as identical junk
-// happens to be adjacent to an "interesting" match.
-//
-// If no blocks match, return (alo, blo, 0).
-func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
- // CAUTION: stripping common prefix or suffix would be incorrect.
- // E.g.,
- // ab
- // acab
- // Longest matching block is "ab", but if common prefix is
- // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so
- // strip, so ends up claiming that ab is changed to acab by
- // inserting "ca" in the middle. That's minimal but unintuitive:
- // "it's obvious" that someone inserted "ac" at the front.
- // Windiff ends up at the same place as diff, but by pairing up
- // the unique 'b's and then matching the first two 'a's.
- besti, bestj, bestsize := alo, blo, 0
-
- // find longest junk-free match
- // during an iteration of the loop, j2len[j] = length of longest
- // junk-free match ending with a[i-1] and b[j]
- j2len := map[int]int{}
- for i := alo; i != ahi; i++ {
- // look at all instances of a[i] in b; note that because
- // b2j has no junk keys, the loop is skipped if a[i] is junk
- newj2len := map[int]int{}
- for _, j := range m.b2j[m.a[i]] {
- // a[i] matches b[j]
- if j < blo {
- continue
- }
- if j >= bhi {
- break
- }
- k := j2len[j-1] + 1
- newj2len[j] = k
- if k > bestsize {
- besti, bestj, bestsize = i-k+1, j-k+1, k
- }
- }
- j2len = newj2len
- }
-
- // Extend the best by non-junk elements on each end. In particular,
- // "popular" non-junk elements aren't in b2j, which greatly speeds
- // the inner loop above, but also means "the best" match so far
- // doesn't contain any junk *or* popular non-junk elements.
- for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
- m.a[besti-1] == m.b[bestj-1] {
- besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
- }
- for besti+bestsize < ahi && bestj+bestsize < bhi &&
- !m.isBJunk(m.b[bestj+bestsize]) &&
- m.a[besti+bestsize] == m.b[bestj+bestsize] {
- bestsize++
- }
-
- // Now that we have a wholly interesting match (albeit possibly
- // empty!), we may as well suck up the matching junk on each
- // side of it too. Can't think of a good reason not to, and it
- // saves post-processing the (possibly considerable) expense of
- // figuring out what to do with it. In the case of an empty
- // interesting match, this is clearly the right thing to do,
- // because no other kind of match is possible in the regions.
- for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
- m.a[besti-1] == m.b[bestj-1] {
- besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
- }
- for besti+bestsize < ahi && bestj+bestsize < bhi &&
- m.isBJunk(m.b[bestj+bestsize]) &&
- m.a[besti+bestsize] == m.b[bestj+bestsize] {
- bestsize++
- }
-
- return Match{A: besti, B: bestj, Size: bestsize}
-}
-
-// GetMatchingBlocks returns list of triples describing matching subsequences.
-//
-// Each triple is of the form (i, j, n), and means that
-// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
-// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
-// adjacent triples in the list, and the second is not the last triple in the
-// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
-// adjacent equal blocks.
-//
-// The last triple is a dummy, (len(a), len(b), 0), and is the only
-// triple with n==0.
-func (m *SequenceMatcher) GetMatchingBlocks() []Match {
- if m.matchingBlocks != nil {
- return m.matchingBlocks
- }
-
- var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
- matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
- match := m.findLongestMatch(alo, ahi, blo, bhi)
- i, j, k := match.A, match.B, match.Size
- if match.Size > 0 {
- if alo < i && blo < j {
- matched = matchBlocks(alo, i, blo, j, matched)
- }
- matched = append(matched, match)
- if i+k < ahi && j+k < bhi {
- matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
- }
- }
- return matched
- }
- matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
-
- // It's possible that we have adjacent equal blocks in the
- // matching_blocks list now.
- nonAdjacent := []Match{}
- i1, j1, k1 := 0, 0, 0
- for _, b := range matched {
- // Is this block adjacent to i1, j1, k1?
- i2, j2, k2 := b.A, b.B, b.Size
- if i1+k1 == i2 && j1+k1 == j2 {
- // Yes, so collapse them -- this just increases the length of
- // the first block by the length of the second, and the first
- // block so lengthened remains the block to compare against.
- k1 += k2
- } else {
- // Not adjacent. Remember the first block (k1==0 means it's
- // the dummy we started with), and make the second block the
- // new block to compare against.
- if k1 > 0 {
- nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
- }
- i1, j1, k1 = i2, j2, k2
- }
- }
- if k1 > 0 {
- nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
- }
-
- nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
- m.matchingBlocks = nonAdjacent
- return m.matchingBlocks
-}
-
-// GetOpCodes returns a list of 5-tuples describing how to turn a into b.
-//
-// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple
-// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
-// tuple preceding it, and likewise for j1 == the previous j2.
-//
-// The tags are characters, with these meanings:
-//
-// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2]
-//
-// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case.
-//
-// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
-//
-// 'e' (equal): a[i1:i2] == b[j1:j2]
-func (m *SequenceMatcher) GetOpCodes() []OpCode {
- if m.opCodes != nil {
- return m.opCodes
- }
- i, j := 0, 0
- matching := m.GetMatchingBlocks()
- opCodes := make([]OpCode, 0, len(matching))
- for _, m := range matching {
- // invariant: we've pumped out correct diffs to change
- // a[:i] into b[:j], and the next matching block is
- // a[ai:ai+size] == b[bj:bj+size]. So we need to pump
- // out a diff to change a[i:ai] into b[j:bj], pump out
- // the matching block, and move (i,j) beyond the match
- ai, bj, size := m.A, m.B, m.Size
- tag := byte(0)
- if i < ai && j < bj {
- tag = 'r'
- } else if i < ai {
- tag = 'd'
- } else if j < bj {
- tag = 'i'
- }
- if tag > 0 {
- opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
- }
- i, j = ai+size, bj+size
- // the list of matching blocks is terminated by a
- // sentinel with size 0
- if size > 0 {
- opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
- }
- }
- m.opCodes = opCodes
- return m.opCodes
-}
-
-// GetGroupedOpCodes isolates change clusters by eliminating ranges with no changes.
-//
-// Returns a generator of groups with up to n lines of context.
-// Each group is in the same format as returned by GetOpCodes().
-func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
- if n < 0 {
- n = 3
- }
- codes := m.GetOpCodes()
- if len(codes) == 0 {
- codes = []OpCode{{'e', 0, 1, 0, 1}}
- }
- // Fixup leading and trailing groups if they show no changes.
- if codes[0].Tag == 'e' {
- c := codes[0]
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
- }
- if codes[len(codes)-1].Tag == 'e' {
- c := codes[len(codes)-1]
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
- }
- nn := n + n
- groups := [][]OpCode{}
- group := []OpCode{}
- for _, c := range codes {
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- // End the current group and start a new one whenever
- // there is a large range with no changes.
- if c.Tag == 'e' && i2-i1 > nn {
- group = append(group, OpCode{c.Tag, i1, min(i2, i1+n),
- j1, min(j2, j1+n)})
- groups = append(groups, group)
- group = []OpCode{}
- i1, j1 = max(i1, i2-n), max(j1, j2-n)
- }
- group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
- }
- if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
- groups = append(groups, group)
- }
- return groups
-}
-
-// Ratio returns a measure of the sequences' similarity (float in [0,1]).
-//
-// Where T is the total number of elements in both sequences, and
-// M is the number of matches, this is 2.0*M / T.
-// Note that this is 1 if the sequences are identical, and 0 if
-// they have nothing in common.
-//
-// .Ratio() is expensive to compute if you haven't already computed
-// .GetMatchingBlocks() or .GetOpCodes(), in which case you may
-// want to try .QuickRatio() or .RealQuickRation() first to get an
-// upper bound.
-func (m *SequenceMatcher) Ratio() float64 {
- matches := 0
- for _, m := range m.GetMatchingBlocks() {
- matches += m.Size
- }
- return calculateRatio(matches, len(m.a)+len(m.b))
-}
-
-// QuickRatio returns an upper bound on ratio() relatively quickly.
-//
-// This isn't defined beyond that it is an upper bound on .Ratio(), and
-// is faster to compute.
-func (m *SequenceMatcher) QuickRatio() float64 {
- // viewing a and b as multisets, set matches to the cardinality
- // of their intersection; this counts the number of matches
- // without regard to order, so is clearly an upper bound
- if m.fullBCount == nil {
- m.fullBCount = map[string]int{}
- for _, s := range m.b {
- m.fullBCount[s] = m.fullBCount[s] + 1
- }
- }
-
- // avail[x] is the number of times x appears in 'b' less the
- // number of times we've seen it in 'a' so far ... kinda
- avail := map[string]int{}
- matches := 0
- for _, s := range m.a {
- n, ok := avail[s]
- if !ok {
- n = m.fullBCount[s]
- }
- avail[s] = n - 1
- if n > 0 {
- matches++
- }
- }
- return calculateRatio(matches, len(m.a)+len(m.b))
-}
-
-// RealQuickRatio returns an upper bound on ratio() very quickly.
-//
-// This isn't defined beyond that it is an upper bound on .Ratio(), and
-// is faster to compute than either .Ratio() or .QuickRatio().
-func (m *SequenceMatcher) RealQuickRatio() float64 {
- la, lb := len(m.a), len(m.b)
- return calculateRatio(min(la, lb), la+lb)
-}
-
-// Convert range to the "ed" format
-func formatRangeUnified(start, stop int) string {
- // Per the diff spec at http://www.unix.org/single_unix_specification/
- beginning := start + 1 // lines start numbering with one
- length := stop - start
- if length == 1 {
- return fmt.Sprintf("%d", beginning)
- }
- if length == 0 {
- beginning-- // empty ranges begin at line just before the range
- }
- return fmt.Sprintf("%d,%d", beginning, length)
-}
-
-// UnifiedDiff represents the unified diff parameters.
-type UnifiedDiff struct {
- A []string // First sequence lines
- FromFile string // First file name
- FromDate string // First file time
- B []string // Second sequence lines
- ToFile string // Second file name
- ToDate string // Second file time
- Eol string // Headers end of line, defaults to LF
- Context int // Number of context lines
-}
-
-// WriteUnifiedDiff compares two sequences of lines; generates the delta as
-// a unified diff.
-//
-// Unified diffs are a compact way of showing line changes and a few
-// lines of context. The number of context lines is set by 'n' which
-// defaults to three.
-//
-// By default, the diff control lines (those with ---, +++, or @@) are
-// created with a trailing newline. This is helpful so that inputs
-// created from file.readlines() result in diffs that are suitable for
-// file.writelines() since both the inputs and outputs have trailing
-// newlines.
-//
-// For inputs that do not have trailing newlines, set the lineterm
-// argument to "" so that the output will be uniformly newline free.
-//
-// The unidiff format normally has a header for filenames and modification
-// times. Any or all of these may be specified using strings for
-// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
-// The modification times are normally expressed in the ISO 8601 format.
-func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {
- buf := bufio.NewWriter(writer)
- defer buf.Flush()
- wf := func(format string, args ...interface{}) error {
- _, err := buf.WriteString(fmt.Sprintf(format, args...))
- return err
- }
- ws := func(s string) error {
- _, err := buf.WriteString(s)
- return err
- }
-
- if len(diff.Eol) == 0 {
- diff.Eol = "\n"
- }
-
- started := false
- m := NewMatcher(diff.A, diff.B)
- for _, g := range m.GetGroupedOpCodes(diff.Context) {
- if !started {
- started = true
- fromDate := ""
- if len(diff.FromDate) > 0 {
- fromDate = "\t" + diff.FromDate
- }
- toDate := ""
- if len(diff.ToDate) > 0 {
- toDate = "\t" + diff.ToDate
- }
- if diff.FromFile != "" || diff.ToFile != "" {
- err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol)
- if err != nil {
- return err
- }
- err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol)
- if err != nil {
- return err
- }
- }
- }
- first, last := g[0], g[len(g)-1]
- range1 := formatRangeUnified(first.I1, last.I2)
- range2 := formatRangeUnified(first.J1, last.J2)
- if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil {
- return err
- }
- for _, c := range g {
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- if c.Tag == 'e' {
- for _, line := range diff.A[i1:i2] {
- if err := ws(" " + line); err != nil {
- return err
- }
- }
- continue
- }
- if c.Tag == 'r' || c.Tag == 'd' {
- for _, line := range diff.A[i1:i2] {
- if err := ws("-" + line); err != nil {
- return err
- }
- }
- }
- if c.Tag == 'r' || c.Tag == 'i' {
- for _, line := range diff.B[j1:j2] {
- if err := ws("+" + line); err != nil {
- return err
- }
- }
- }
- }
- }
- return nil
-}
-
-// GetUnifiedDiffString is like WriteUnifiedDiff but returns the diff as a string.
-func GetUnifiedDiffString(diff UnifiedDiff) (string, error) {
- w := &bytes.Buffer{}
- err := WriteUnifiedDiff(w, diff)
- return w.String(), err
-}
-
-// Convert range to the "ed" format.
-func formatRangeContext(start, stop int) string {
- // Per the diff spec at http://www.unix.org/single_unix_specification/
- beginning := start + 1 // lines start numbering with one
- length := stop - start
- if length == 0 {
- beginning-- // empty ranges begin at line just before the range
- }
- if length <= 1 {
- return fmt.Sprintf("%d", beginning)
- }
- return fmt.Sprintf("%d,%d", beginning, beginning+length-1)
-}
-
-type ContextDiff UnifiedDiff
-
-// WriteContextDiff compares two sequences of lines; generates the delta as a context diff.
-//
-// Context diffs are a compact way of showing line changes and a few
-// lines of context. The number of context lines is set by diff.Context
-// which defaults to three.
-//
-// By default, the diff control lines (those with *** or ---) are
-// created with a trailing newline.
-//
-// For inputs that do not have trailing newlines, set the diff.Eol
-// argument to "" so that the output will be uniformly newline free.
-//
-// The context diff format normally has a header for filenames and
-// modification times. Any or all of these may be specified using
-// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate.
-// The modification times are normally expressed in the ISO 8601 format.
-// If not specified, the strings default to blanks.
-func WriteContextDiff(writer io.Writer, diff ContextDiff) error {
- buf := bufio.NewWriter(writer)
- defer buf.Flush()
- var diffErr error
- wf := func(format string, args ...interface{}) {
- _, err := buf.WriteString(fmt.Sprintf(format, args...))
- if diffErr == nil && err != nil {
- diffErr = err
- }
- }
- ws := func(s string) {
- _, err := buf.WriteString(s)
- if diffErr == nil && err != nil {
- diffErr = err
- }
- }
-
- if len(diff.Eol) == 0 {
- diff.Eol = "\n"
- }
-
- prefix := map[byte]string{
- 'i': "+ ",
- 'd': "- ",
- 'r': "! ",
- 'e': " ",
- }
-
- started := false
- m := NewMatcher(diff.A, diff.B)
- for _, g := range m.GetGroupedOpCodes(diff.Context) {
- if !started {
- started = true
- fromDate := ""
- if len(diff.FromDate) > 0 {
- fromDate = "\t" + diff.FromDate
- }
- toDate := ""
- if len(diff.ToDate) > 0 {
- toDate = "\t" + diff.ToDate
- }
- if diff.FromFile != "" || diff.ToFile != "" {
- wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol)
- wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol)
- }
- }
-
- first, last := g[0], g[len(g)-1]
- ws("***************" + diff.Eol)
-
- range1 := formatRangeContext(first.I1, last.I2)
- wf("*** %s ****%s", range1, diff.Eol)
- for _, c := range g {
- if c.Tag == 'r' || c.Tag == 'd' {
- for _, cc := range g {
- if cc.Tag == 'i' {
- continue
- }
- for _, line := range diff.A[cc.I1:cc.I2] {
- ws(prefix[cc.Tag] + line)
- }
- }
- break
- }
- }
-
- range2 := formatRangeContext(first.J1, last.J2)
- wf("--- %s ----%s", range2, diff.Eol)
- for _, c := range g {
- if c.Tag == 'r' || c.Tag == 'i' {
- for _, cc := range g {
- if cc.Tag == 'd' {
- continue
- }
- for _, line := range diff.B[cc.J1:cc.J2] {
- ws(prefix[cc.Tag] + line)
- }
- }
- break
- }
- }
- }
- return diffErr
-}
-
-// GetContextDiffString is like WriteContextDiff but returns the diff as a string.
-func GetContextDiffString(diff ContextDiff) (string, error) {
- w := &bytes.Buffer{}
- err := WriteContextDiff(w, diff)
- return w.String(), err
-}
-
-// SplitLines splits a string on "\n" while preserving them. The output can be used
-// as input for UnifiedDiff and ContextDiff structures.
-func SplitLines(s string) []string {
- lines := strings.SplitAfter(s, "\n")
- lines[len(lines)-1] += "\n"
- return lines
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/csot/csot.go b/vendor/go.mongodb.org/mongo-driver/internal/csot/csot.go
deleted file mode 100644
index 43801a5d4..000000000
--- a/vendor/go.mongodb.org/mongo-driver/internal/csot/csot.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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 csot
-
-import (
- "context"
- "time"
-)
-
-type timeoutKey struct{}
-
-// MakeTimeoutContext returns a new context with Client-Side Operation Timeout (CSOT) feature-gated behavior
-// and a Timeout set to the passed in Duration. Setting a Timeout on a single operation is not supported in
-// public API.
-//
-// TODO(GODRIVER-2348) We may be able to remove this function once CSOT feature-gated behavior becomes the
-// TODO default behavior.
-func MakeTimeoutContext(ctx context.Context, to time.Duration) (context.Context, context.CancelFunc) {
- // Only use the passed in Duration as a timeout on the Context if it
- // is non-zero and if the Context doesn't already have a timeout.
- cancelFunc := func() {}
- if _, deadlineSet := ctx.Deadline(); to != 0 && !deadlineSet {
- ctx, cancelFunc = context.WithTimeout(ctx, to)
- }
-
- // Add timeoutKey either way to indicate CSOT is enabled.
- return context.WithValue(ctx, timeoutKey{}, true), cancelFunc
-}
-
-func IsTimeoutContext(ctx context.Context) bool {
- return ctx.Value(timeoutKey{}) != nil
-}
-
-// ZeroRTTMonitor implements the RTTMonitor interface and is used internally for testing. It returns 0 for all
-// RTT calculations and an empty string for RTT statistics.
-type ZeroRTTMonitor struct{}
-
-// EWMA implements the RTT monitor interface.
-func (zrm *ZeroRTTMonitor) EWMA() time.Duration {
- return 0
-}
-
-// Min implements the RTT monitor interface.
-func (zrm *ZeroRTTMonitor) Min() time.Duration {
- return 0
-}
-
-// P90 implements the RTT monitor interface.
-func (zrm *ZeroRTTMonitor) P90() time.Duration {
- return 0
-}
-
-// Stats implements the RTT monitor interface.
-func (zrm *ZeroRTTMonitor) Stats() string {
- return ""
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/integtest/integtest.go b/vendor/go.mongodb.org/mongo-driver/internal/integtest/integtest.go
deleted file mode 100644
index c9048362b..000000000
--- a/vendor/go.mongodb.org/mongo-driver/internal/integtest/integtest.go
+++ /dev/null
@@ -1,285 +0,0 @@
-// 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 integtest
-
-import (
- "context"
- "errors"
- "fmt"
- "math"
- "os"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "testing"
-
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/require"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
-)
-
-var connectionString *connstring.ConnString
-var connectionStringOnce sync.Once
-var connectionStringErr error
-var liveTopology *topology.Topology
-var liveTopologyOnce sync.Once
-var liveTopologyErr error
-
-// AddOptionsToURI appends connection string options to a URI.
-func AddOptionsToURI(uri string, opts ...string) string {
- if !strings.ContainsRune(uri, '?') {
- if uri[len(uri)-1] != '/' {
- uri += "/"
- }
-
- uri += "?"
- } else {
- uri += "&"
- }
-
- for _, opt := range opts {
- uri += opt
- }
-
- return uri
-}
-
-// AddTLSConfigToURI checks for the environmental variable indicating that the tests are being run
-// on an SSL-enabled server, and if so, returns a new URI with the necessary configuration.
-func AddTLSConfigToURI(uri string) string {
- caFile := os.Getenv("MONGO_GO_DRIVER_CA_FILE")
- if len(caFile) == 0 {
- return uri
- }
-
- return AddOptionsToURI(uri, "ssl=true&sslCertificateAuthorityFile=", caFile)
-}
-
-// AddCompressorToURI checks for the environment variable indicating that the tests are being run with compression
-// enabled. If so, it returns a new URI with the necessary configuration
-func AddCompressorToURI(uri string) string {
- comp := os.Getenv("MONGO_GO_DRIVER_COMPRESSOR")
- if len(comp) == 0 {
- return uri
- }
-
- return AddOptionsToURI(uri, "compressors=", comp)
-}
-
-// AddTestServerAPIVersion adds the latest server API version in a ServerAPIOptions to passed-in opts.
-func AddTestServerAPIVersion(opts *options.ClientOptions) {
- if os.Getenv("REQUIRE_API_VERSION") == "true" {
- opts.SetServerAPIOptions(options.ServerAPI(driver.TestServerAPIVersion))
- }
-}
-
-// MonitoredTopology returns a new topology with the command monitor attached
-func MonitoredTopology(t *testing.T, dbName string, monitor *event.CommandMonitor) *topology.Topology {
- uri, err := MongoDBURI()
- if err != nil {
- t.Fatal(err)
- }
- cfg, err := topology.NewConfig(options.Client().ApplyURI(uri).SetMonitor(monitor), nil)
- if err != nil {
- t.Fatal(err)
- }
-
- monitoredTopology, err := topology.New(cfg)
- if err != nil {
- t.Fatal(err)
- } else {
- _ = monitoredTopology.Connect()
-
- err = operation.NewCommand(bsoncore.BuildDocument(nil, bsoncore.AppendInt32Element(nil, "dropDatabase", 1))).
- Database(dbName).ServerSelector(description.WriteSelector()).Deployment(monitoredTopology).Execute(context.Background())
-
- require.NoError(t, err)
- }
-
- return monitoredTopology
-}
-
-// Topology gets the globally configured topology.
-func Topology(t *testing.T) *topology.Topology {
- uri, err := MongoDBURI()
- require.NoError(t, err, "error constructing mongodb URI: %v", err)
- cfg, err := topology.NewConfig(options.Client().ApplyURI(uri), nil)
- require.NoError(t, err, "error constructing topology config: %v", err)
-
- liveTopologyOnce.Do(func() {
- var err error
- liveTopology, err = topology.New(cfg)
- if err != nil {
- liveTopologyErr = err
- } else {
- _ = liveTopology.Connect()
-
- err = operation.NewCommand(bsoncore.BuildDocument(nil, bsoncore.AppendInt32Element(nil, "dropDatabase", 1))).
- Database(DBName(t)).ServerSelector(description.WriteSelector()).Deployment(liveTopology).Execute(context.Background())
- require.NoError(t, err)
- }
- })
-
- if liveTopologyErr != nil {
- t.Fatal(liveTopologyErr)
- }
-
- return liveTopology
-}
-
-// TopologyWithCredential takes an "options.Credential" object and returns a connected topology.
-func TopologyWithCredential(t *testing.T, credential options.Credential) *topology.Topology {
- uri, err := MongoDBURI()
- if err != nil {
- t.Fatalf("error constructing mongodb URI: %v", err)
- }
- cfg, err := topology.NewConfig(options.Client().ApplyURI(uri).SetAuth(credential), nil)
- if err != nil {
- t.Fatalf("error constructing topology config: %v", err)
- }
- topology, err := topology.New(cfg)
- if err != nil {
- t.Fatal("Could not construct topology")
- }
- err = topology.Connect()
- if err != nil {
- t.Fatal("Could not start topology connection")
- }
- return topology
-}
-
-// ColName gets a collection name that should be unique
-// to the currently executing test.
-func ColName(t *testing.T) string {
- // Get this indirectly to avoid copying a mutex
- v := reflect.Indirect(reflect.ValueOf(t))
- name := v.FieldByName("name")
- return name.String()
-}
-
-// MongoDBURI will construct the MongoDB URI from the MONGODB_URI environment variable for testing. The default host is
-// "localhost" and the default port is "27017"
-func MongoDBURI() (string, error) {
- uri := os.Getenv("MONGODB_URI")
- if uri == "" {
- uri = "mongodb://localhost:27017"
- }
-
- uri = AddTLSConfigToURI(uri)
- uri = AddCompressorToURI(uri)
- uri, err := AddServerlessAuthCredentials(uri)
- return uri, err
-}
-
-// AddServerlessAuthCredentials will attempt to construct the serverless auth credentials for a URI.
-func AddServerlessAuthCredentials(uri string) (string, error) {
- if os.Getenv("SERVERLESS") != "serverless" {
- return uri, nil
- }
- user := os.Getenv("SERVERLESS_ATLAS_USER")
- if user == "" {
- return "", fmt.Errorf("serverless expects SERVERLESS_ATLAS_USER to be set")
- }
- password := os.Getenv("SERVERLESS_ATLAS_PASSWORD")
- if password == "" {
- return "", fmt.Errorf("serverless expects SERVERLESS_ATLAS_PASSWORD to be set")
- }
-
- var scheme string
- // remove the scheme
- switch {
- case strings.HasPrefix(uri, "mongodb+srv://"):
- scheme = "mongodb+srv://"
- case strings.HasPrefix(uri, "mongodb://"):
- scheme = "mongodb://"
- default:
- return "", errors.New(`scheme must be "mongodb" or "mongodb+srv"`)
- }
-
- uri = scheme + user + ":" + password + "@" + uri[len(scheme):]
- return uri, nil
-}
-
-// ConnString gets the globally configured connection string.
-func ConnString(t *testing.T) *connstring.ConnString {
- connectionStringOnce.Do(func() {
- uri, err := MongoDBURI()
- require.NoError(t, err, "error constructing mongodb URI: %v", err)
-
- connectionString, err = connstring.ParseAndValidate(uri)
- if err != nil {
- connectionStringErr = err
- }
- })
- if connectionStringErr != nil {
- t.Fatal(connectionStringErr)
- }
-
- return connectionString
-}
-
-func GetConnString() (*connstring.ConnString, error) {
- mongodbURI := os.Getenv("MONGODB_URI")
- if mongodbURI == "" {
- mongodbURI = "mongodb://localhost:27017"
- }
-
- mongodbURI = AddTLSConfigToURI(mongodbURI)
-
- cs, err := connstring.ParseAndValidate(mongodbURI)
- if err != nil {
- return nil, err
- }
-
- return cs, nil
-}
-
-// DBName gets the globally configured database name.
-func DBName(t *testing.T) string {
- return GetDBName(ConnString(t))
-}
-
-func GetDBName(cs *connstring.ConnString) string {
- if cs.Database != "" {
- return cs.Database
- }
-
- return fmt.Sprintf("mongo-go-driver-%d", os.Getpid())
-}
-
-// CompareVersions compares two version number strings (i.e. positive integers separated by
-// periods). Comparisons are done to the lesser precision of the two versions. For example, 3.2 is
-// considered equal to 3.2.11, whereas 3.2.0 is considered less than 3.2.11.
-//
-// Returns a positive int if version1 is greater than version2, a negative int if version1 is less
-// than version2, and 0 if version1 is equal to version2.
-func CompareVersions(t *testing.T, v1 string, v2 string) int {
- n1 := strings.Split(v1, ".")
- n2 := strings.Split(v2, ".")
-
- for i := 0; i < int(math.Min(float64(len(n1)), float64(len(n2)))); i++ {
- i1, err := strconv.Atoi(n1[i])
- require.NoError(t, err)
-
- i2, err := strconv.Atoi(n2[i])
- require.NoError(t, err)
-
- difference := i1 - i2
- if difference != 0 {
- return difference
- }
- }
-
- return 0
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/require/require.go b/vendor/go.mongodb.org/mongo-driver/internal/require/require.go
deleted file mode 100644
index 4854bbcd5..000000000
--- a/vendor/go.mongodb.org/mongo-driver/internal/require/require.go
+++ /dev/null
@@ -1,819 +0,0 @@
-// Copied from https://github.com/stretchr/testify/blob/1333b5d3bda8cf5aedcf3e1aaa95cac28aaab892/require/require.go
-
-// Copyright 2020 Mat Ryer, Tyler Bunnell and all contributors. All rights reserved.
-// Use of this source code is governed by an MIT-style license that can be found in
-// the THIRD-PARTY-NOTICES file.
-
-package require
-
-import (
- time "time"
-
- assert "go.mongodb.org/mongo-driver/internal/assert"
-)
-
-// TestingT is an interface wrapper around *testing.T
-type TestingT interface {
- Errorf(format string, args ...interface{})
- FailNow()
-}
-
-type tHelper interface {
- Helper()
-}
-
-// Contains asserts that the specified string, list(array, slice...) or map contains the
-// specified substring or element.
-//
-// assert.Contains(t, "Hello World", "World")
-// assert.Contains(t, ["Hello", "World"], "World")
-// assert.Contains(t, {"Hello": "World"}, "Hello")
-func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Contains(t, s, contains, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Containsf asserts that the specified string, list(array, slice...) or map contains the
-// specified substring or element.
-//
-// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
-// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
-// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
-func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Containsf(t, s, contains, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
-// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
-// the number of appearances of each of them in both lists should match.
-//
-// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
-func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.ElementsMatch(t, listA, listB, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
-// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
-// the number of appearances of each of them in both lists should match.
-//
-// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
-func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.ElementsMatchf(t, listA, listB, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Equal asserts that two objects are equal.
-//
-// assert.Equal(t, 123, 123)
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses). Function equality
-// cannot be determined and will always fail.
-func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Equal(t, expected, actual, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// EqualError asserts that a function returned an error (i.e. not `nil`)
-// and that it is equal to the provided error.
-//
-// actualObj, err := SomeFunction()
-// assert.EqualError(t, err, expectedErrorString)
-func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.EqualError(t, theError, errString, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
-// and that it is equal to the provided error.
-//
-// actualObj, err := SomeFunction()
-// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
-func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.EqualErrorf(t, theError, errString, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// EqualValues asserts that two objects are equal or convertible to the same types
-// and equal.
-//
-// assert.EqualValues(t, uint32(123), int32(123))
-func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.EqualValues(t, expected, actual, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// EqualValuesf asserts that two objects are equal or convertible to the same types
-// and equal.
-//
-// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted")
-func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.EqualValuesf(t, expected, actual, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Equalf asserts that two objects are equal.
-//
-// assert.Equalf(t, 123, 123, "error message %s", "formatted")
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses). Function equality
-// cannot be determined and will always fail.
-func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Equalf(t, expected, actual, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Error asserts that a function returned an error (i.e. not `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.Error(t, err) {
-// assert.Equal(t, expectedError, err)
-// }
-func Error(t TestingT, err error, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Error(t, err, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// ErrorContains asserts that a function returned an error (i.e. not `nil`)
-// and that the error contains the specified substring.
-//
-// actualObj, err := SomeFunction()
-// assert.ErrorContains(t, err, expectedErrorSubString)
-func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.ErrorContains(t, theError, contains, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)
-// and that the error contains the specified substring.
-//
-// actualObj, err := SomeFunction()
-// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted")
-func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.ErrorContainsf(t, theError, contains, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Errorf asserts that a function returned an error (i.e. not `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.Errorf(t, err, "error message %s", "formatted") {
-// assert.Equal(t, expectedErrorf, err)
-// }
-func Errorf(t TestingT, err error, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Errorf(t, err, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Eventually asserts that given condition will be met in waitFor time,
-// periodically checking target function each tick.
-//
-// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)
-func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Eventuallyf asserts that given condition will be met in waitFor time,
-// periodically checking target function each tick.
-//
-// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
-func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Fail reports a failure through
-func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Fail(t, failureMessage, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// FailNow fails test
-func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.FailNow(t, failureMessage, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// FailNowf fails test
-func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.FailNowf(t, failureMessage, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Failf reports a failure through
-func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Failf(t, failureMessage, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// False asserts that the specified value is false.
-//
-// assert.False(t, myBool)
-func False(t TestingT, value bool, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.False(t, value, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Falsef asserts that the specified value is false.
-//
-// assert.Falsef(t, myBool, "error message %s", "formatted")
-func Falsef(t TestingT, value bool, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Falsef(t, value, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Greater asserts that the first element is greater than the second
-//
-// assert.Greater(t, 2, 1)
-// assert.Greater(t, float64(2), float64(1))
-// assert.Greater(t, "b", "a")
-func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Greater(t, e1, e2, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// GreaterOrEqual asserts that the first element is greater than or equal to the second
-//
-// assert.GreaterOrEqual(t, 2, 1)
-// assert.GreaterOrEqual(t, 2, 2)
-// assert.GreaterOrEqual(t, "b", "a")
-// assert.GreaterOrEqual(t, "b", "b")
-func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.GreaterOrEqual(t, e1, e2, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// GreaterOrEqualf asserts that the first element is greater than or equal to the second
-//
-// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted")
-// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted")
-// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted")
-// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted")
-func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.GreaterOrEqualf(t, e1, e2, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Greaterf asserts that the first element is greater than the second
-//
-// assert.Greaterf(t, 2, 1, "error message %s", "formatted")
-// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted")
-// assert.Greaterf(t, "b", "a", "error message %s", "formatted")
-func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Greaterf(t, e1, e2, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// InDelta asserts that the two numerals are within delta of each other.
-//
-// assert.InDelta(t, math.Pi, 22/7.0, 0.01)
-func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// InDeltaf asserts that the two numerals are within delta of each other.
-//
-// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
-func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.InDeltaf(t, expected, actual, delta, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// IsType asserts that the specified objects are of the same type.
-func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.IsType(t, expectedType, object, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// IsTypef asserts that the specified objects are of the same type.
-func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.IsTypef(t, expectedType, object, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Len asserts that the specified object has specific length.
-// Len also fails if the object has a type that len() not accept.
-//
-// assert.Len(t, mySlice, 3)
-func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Len(t, object, length, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Lenf asserts that the specified object has specific length.
-// Lenf also fails if the object has a type that len() not accept.
-//
-// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
-func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Lenf(t, object, length, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Less asserts that the first element is less than the second
-//
-// assert.Less(t, 1, 2)
-// assert.Less(t, float64(1), float64(2))
-// assert.Less(t, "a", "b")
-func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Less(t, e1, e2, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// LessOrEqual asserts that the first element is less than or equal to the second
-//
-// assert.LessOrEqual(t, 1, 2)
-// assert.LessOrEqual(t, 2, 2)
-// assert.LessOrEqual(t, "a", "b")
-// assert.LessOrEqual(t, "b", "b")
-func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.LessOrEqual(t, e1, e2, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// LessOrEqualf asserts that the first element is less than or equal to the second
-//
-// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted")
-// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted")
-// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted")
-// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted")
-func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.LessOrEqualf(t, e1, e2, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Lessf asserts that the first element is less than the second
-//
-// assert.Lessf(t, 1, 2, "error message %s", "formatted")
-// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted")
-// assert.Lessf(t, "a", "b", "error message %s", "formatted")
-func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Lessf(t, e1, e2, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Negative asserts that the specified element is negative
-//
-// assert.Negative(t, -1)
-// assert.Negative(t, -1.23)
-func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Negative(t, e, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Negativef asserts that the specified element is negative
-//
-// assert.Negativef(t, -1, "error message %s", "formatted")
-// assert.Negativef(t, -1.23, "error message %s", "formatted")
-func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Negativef(t, e, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Nil asserts that the specified object is nil.
-//
-// assert.Nil(t, err)
-func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Nil(t, object, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Nilf asserts that the specified object is nil.
-//
-// assert.Nilf(t, err, "error message %s", "formatted")
-func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Nilf(t, object, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// NoError asserts that a function returned no error (i.e. `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.NoError(t, err) {
-// assert.Equal(t, expectedObj, actualObj)
-// }
-func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NoError(t, err, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// NoErrorf asserts that a function returned no error (i.e. `nil`).
-//
-// actualObj, err := SomeFunction()
-// if assert.NoErrorf(t, err, "error message %s", "formatted") {
-// assert.Equal(t, expectedObj, actualObj)
-// }
-func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NoErrorf(t, err, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
-// specified substring or element.
-//
-// assert.NotContains(t, "Hello World", "Earth")
-// assert.NotContains(t, ["Hello", "World"], "Earth")
-// assert.NotContains(t, {"Hello": "World"}, "Earth")
-func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotContains(t, s, contains, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
-// specified substring or element.
-//
-// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
-// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
-// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
-func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotContainsf(t, s, contains, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// NotEqual asserts that the specified values are NOT equal.
-//
-// assert.NotEqual(t, obj1, obj2)
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses).
-func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotEqual(t, expected, actual, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// NotEqualValues asserts that two objects are not equal even when converted to the same type
-//
-// assert.NotEqualValues(t, obj1, obj2)
-func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotEqualValues(t, expected, actual, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// NotEqualValuesf asserts that two objects are not equal even when converted to the same type
-//
-// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted")
-func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotEqualValuesf(t, expected, actual, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// NotEqualf asserts that the specified values are NOT equal.
-//
-// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
-//
-// Pointer variable equality is determined based on the equality of the
-// referenced values (as opposed to the memory addresses).
-func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotEqualf(t, expected, actual, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// NotNil asserts that the specified object is not nil.
-//
-// assert.NotNil(t, err)
-func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotNil(t, object, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// NotNilf asserts that the specified object is not nil.
-//
-// assert.NotNilf(t, err, "error message %s", "formatted")
-func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.NotNilf(t, object, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// Positive asserts that the specified element is positive
-//
-// assert.Positive(t, 1)
-// assert.Positive(t, 1.23)
-func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Positive(t, e, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Positivef asserts that the specified element is positive
-//
-// assert.Positivef(t, 1, "error message %s", "formatted")
-// assert.Positivef(t, 1.23, "error message %s", "formatted")
-func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Positivef(t, e, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// True asserts that the specified value is true.
-//
-// assert.True(t, myBool)
-func True(t TestingT, value bool, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.True(t, value, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// Truef asserts that the specified value is true.
-//
-// assert.Truef(t, myBool, "error message %s", "formatted")
-func Truef(t TestingT, value bool, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.Truef(t, value, msg, args...) {
- return
- }
- t.FailNow()
-}
-
-// WithinDuration asserts that the two times are within duration delta of each other.
-//
-// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
-func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// WithinDurationf asserts that the two times are within duration delta of each other.
-//
-// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
-func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
- return
- }
- t.FailNow()
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream_deployment.go b/vendor/go.mongodb.org/mongo-driver/mongo/change_stream_deployment.go
deleted file mode 100644
index 4dca59f91..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream_deployment.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 mongo
-
-import (
- "context"
-
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
-)
-
-type changeStreamDeployment struct {
- topologyKind description.TopologyKind
- server driver.Server
- conn driver.Connection
-}
-
-var _ driver.Deployment = (*changeStreamDeployment)(nil)
-var _ driver.Server = (*changeStreamDeployment)(nil)
-var _ driver.ErrorProcessor = (*changeStreamDeployment)(nil)
-
-func (c *changeStreamDeployment) SelectServer(context.Context, description.ServerSelector) (driver.Server, error) {
- return c, nil
-}
-
-func (c *changeStreamDeployment) Kind() description.TopologyKind {
- return c.topologyKind
-}
-
-func (c *changeStreamDeployment) Connection(context.Context) (driver.Connection, error) {
- return c.conn, nil
-}
-
-func (c *changeStreamDeployment) RTTMonitor() driver.RTTMonitor {
- return c.server.RTTMonitor()
-}
-
-func (c *changeStreamDeployment) ProcessError(err error, conn driver.Connection) driver.ProcessErrorResult {
- ep, ok := c.server.(driver.ErrorProcessor)
- if !ok {
- return driver.NoChange
- }
-
- return ep.ProcessError(err, conn)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/description.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/description.go
deleted file mode 100644
index e750e33b1..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/description.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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 description contains types and functions for describing the state of MongoDB clusters.
-package description // import "go.mongodb.org/mongo-driver/mongo/description"
-
-// Unknown is an unknown server or topology kind.
-const Unknown = 0
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_kind.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/server_kind.go
deleted file mode 100644
index b71d29d8b..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_kind.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 description
-
-// ServerKind represents the type of a single server in a topology.
-type ServerKind uint32
-
-// These constants are the possible types of servers.
-const (
- Standalone ServerKind = 1
- RSMember ServerKind = 2
- RSPrimary ServerKind = 4 + RSMember
- RSSecondary ServerKind = 8 + RSMember
- RSArbiter ServerKind = 16 + RSMember
- RSGhost ServerKind = 32 + RSMember
- Mongos ServerKind = 256
- LoadBalancer ServerKind = 512
-)
-
-// String returns a stringified version of the kind or "Unknown" if the kind is invalid.
-func (kind ServerKind) String() string {
- switch kind {
- case Standalone:
- return "Standalone"
- case RSMember:
- return "RSOther"
- case RSPrimary:
- return "RSPrimary"
- case RSSecondary:
- return "RSSecondary"
- case RSArbiter:
- return "RSArbiter"
- case RSGhost:
- return "RSGhost"
- case Mongos:
- return "Mongos"
- case LoadBalancer:
- return "LoadBalancer"
- }
-
- return "Unknown"
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go
deleted file mode 100644
index 176f0fb53..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go
+++ /dev/null
@@ -1,420 +0,0 @@
-// 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 description
-
-import (
- "encoding/json"
- "fmt"
- "math"
- "time"
-
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/tag"
-)
-
-// ServerSelector is an interface implemented by types that can perform server selection given a topology description
-// and list of candidate servers. The selector should filter the provided candidates list and return a subset that
-// matches some criteria.
-type ServerSelector interface {
- SelectServer(Topology, []Server) ([]Server, error)
-}
-
-// ServerSelectorFunc is a function that can be used as a ServerSelector.
-type ServerSelectorFunc func(Topology, []Server) ([]Server, error)
-
-// SelectServer implements the ServerSelector interface.
-func (ssf ServerSelectorFunc) SelectServer(t Topology, s []Server) ([]Server, error) {
- return ssf(t, s)
-}
-
-// serverSelectorInfo contains metadata concerning the server selector for the
-// purpose of publication.
-type serverSelectorInfo struct {
- Type string
- Data string `json:",omitempty"`
- Selectors []serverSelectorInfo `json:",omitempty"`
-}
-
-// String returns the JSON string representation of the serverSelectorInfo.
-func (sss serverSelectorInfo) String() string {
- bytes, _ := json.Marshal(sss)
-
- return string(bytes)
-}
-
-// serverSelectorInfoGetter is an interface that defines an info() method to
-// get the serverSelectorInfo.
-type serverSelectorInfoGetter interface {
- info() serverSelectorInfo
-}
-
-type compositeSelector struct {
- selectors []ServerSelector
-}
-
-func (cs *compositeSelector) info() serverSelectorInfo {
- csInfo := serverSelectorInfo{Type: "compositeSelector"}
-
- for _, sel := range cs.selectors {
- if getter, ok := sel.(serverSelectorInfoGetter); ok {
- csInfo.Selectors = append(csInfo.Selectors, getter.info())
- }
- }
-
- return csInfo
-}
-
-// String returns the JSON string representation of the compositeSelector.
-func (cs *compositeSelector) String() string {
- return cs.info().String()
-}
-
-// CompositeSelector combines multiple selectors into a single selector by applying them in order to the candidates
-// list.
-//
-// For example, if the initial candidates list is [s0, s1, s2, s3] and two selectors are provided where the first
-// matches s0 and s1 and the second matches s1 and s2, the following would occur during server selection:
-//
-// 1. firstSelector([s0, s1, s2, s3]) -> [s0, s1]
-// 2. secondSelector([s0, s1]) -> [s1]
-//
-// The final list of candidates returned by the composite selector would be [s1].
-func CompositeSelector(selectors []ServerSelector) ServerSelector {
- return &compositeSelector{selectors: selectors}
-}
-
-func (cs *compositeSelector) SelectServer(t Topology, candidates []Server) ([]Server, error) {
- var err error
- for _, sel := range cs.selectors {
- candidates, err = sel.SelectServer(t, candidates)
- if err != nil {
- return nil, err
- }
- }
- return candidates, nil
-}
-
-type latencySelector struct {
- latency time.Duration
-}
-
-// LatencySelector creates a ServerSelector which selects servers based on their average RTT values.
-func LatencySelector(latency time.Duration) ServerSelector {
- return &latencySelector{latency: latency}
-}
-
-func (latencySelector) info() serverSelectorInfo {
- return serverSelectorInfo{Type: "latencySelector"}
-}
-
-func (selector latencySelector) String() string {
- return selector.info().String()
-}
-
-func (selector *latencySelector) SelectServer(t Topology, candidates []Server) ([]Server, error) {
- if selector.latency < 0 {
- return candidates, nil
- }
- if t.Kind == LoadBalanced {
- // In LoadBalanced mode, there should only be one server in the topology and it must be selected.
- return candidates, nil
- }
-
- switch len(candidates) {
- case 0, 1:
- return candidates, nil
- default:
- min := time.Duration(math.MaxInt64)
- for _, candidate := range candidates {
- if candidate.AverageRTTSet {
- if candidate.AverageRTT < min {
- min = candidate.AverageRTT
- }
- }
- }
-
- if min == math.MaxInt64 {
- return candidates, nil
- }
-
- max := min + selector.latency
-
- viableIndexes := make([]int, 0, len(candidates))
- for i, candidate := range candidates {
- if candidate.AverageRTTSet {
- if candidate.AverageRTT <= max {
- viableIndexes = append(viableIndexes, i)
- }
- }
- }
- if len(viableIndexes) == len(candidates) {
- return candidates, nil
- }
- result := make([]Server, len(viableIndexes))
- for i, idx := range viableIndexes {
- result[i] = candidates[idx]
- }
- return result, nil
- }
-}
-
-type writeServerSelector struct{}
-
-// WriteSelector selects all the writable servers.
-func WriteSelector() ServerSelector {
- return writeServerSelector{}
-}
-
-func (writeServerSelector) info() serverSelectorInfo {
- return serverSelectorInfo{Type: "writeSelector"}
-}
-
-func (selector writeServerSelector) String() string {
- return selector.info().String()
-}
-
-func (writeServerSelector) SelectServer(t Topology, candidates []Server) ([]Server, error) {
- switch t.Kind {
- case Single, LoadBalanced:
- return candidates, nil
- default:
- // Determine the capacity of the results slice.
- selected := 0
- for _, candidate := range candidates {
- switch candidate.Kind {
- case Mongos, RSPrimary, Standalone:
- selected++
- }
- }
-
- // Append candidates to the results slice.
- result := make([]Server, 0, selected)
- for _, candidate := range candidates {
- switch candidate.Kind {
- case Mongos, RSPrimary, Standalone:
- result = append(result, candidate)
- }
- }
- return result, nil
- }
-}
-
-type readPrefServerSelector struct {
- rp *readpref.ReadPref
- isOutputAggregate bool
-}
-
-// ReadPrefSelector selects servers based on the provided read preference.
-func ReadPrefSelector(rp *readpref.ReadPref) ServerSelector {
- return readPrefServerSelector{
- rp: rp,
- isOutputAggregate: false,
- }
-}
-
-func (selector readPrefServerSelector) info() serverSelectorInfo {
- return serverSelectorInfo{
- Type: "readPrefSelector",
- Data: selector.rp.String(),
- }
-}
-
-func (selector readPrefServerSelector) String() string {
- return selector.info().String()
-}
-
-func (selector readPrefServerSelector) SelectServer(t Topology, candidates []Server) ([]Server, error) {
- if t.Kind == LoadBalanced {
- // In LoadBalanced mode, there should only be one server in the topology and it must be selected. We check
- // this before checking MaxStaleness support because there's no monitoring in this mode, so the candidate
- // server wouldn't have a wire version set, which would result in an error.
- return candidates, nil
- }
-
- switch t.Kind {
- case Single:
- return candidates, nil
- case ReplicaSetNoPrimary, ReplicaSetWithPrimary:
- return selectForReplicaSet(selector.rp, selector.isOutputAggregate, t, candidates)
- case Sharded:
- return selectByKind(candidates, Mongos), nil
- }
-
- return nil, nil
-}
-
-// OutputAggregateSelector selects servers based on the provided read preference
-// given that the underlying operation is aggregate with an output stage.
-func OutputAggregateSelector(rp *readpref.ReadPref) ServerSelector {
- return readPrefServerSelector{
- rp: rp,
- isOutputAggregate: true,
- }
-}
-
-func selectForReplicaSet(rp *readpref.ReadPref, isOutputAggregate bool, t Topology, candidates []Server) ([]Server, error) {
- if err := verifyMaxStaleness(rp, t); err != nil {
- return nil, err
- }
-
- // If underlying operation is an aggregate with an output stage, only apply read preference
- // if all candidates are 5.0+. Otherwise, operate under primary read preference.
- if isOutputAggregate {
- for _, s := range candidates {
- if s.WireVersion.Max < 13 {
- return selectByKind(candidates, RSPrimary), nil
- }
- }
- }
-
- switch rp.Mode() {
- case readpref.PrimaryMode:
- return selectByKind(candidates, RSPrimary), nil
- case readpref.PrimaryPreferredMode:
- selected := selectByKind(candidates, RSPrimary)
-
- if len(selected) == 0 {
- selected = selectSecondaries(rp, candidates)
- return selectByTagSet(selected, rp.TagSets()), nil
- }
-
- return selected, nil
- case readpref.SecondaryPreferredMode:
- selected := selectSecondaries(rp, candidates)
- selected = selectByTagSet(selected, rp.TagSets())
- if len(selected) > 0 {
- return selected, nil
- }
- return selectByKind(candidates, RSPrimary), nil
- case readpref.SecondaryMode:
- selected := selectSecondaries(rp, candidates)
- return selectByTagSet(selected, rp.TagSets()), nil
- case readpref.NearestMode:
- selected := selectByKind(candidates, RSPrimary)
- selected = append(selected, selectSecondaries(rp, candidates)...)
- return selectByTagSet(selected, rp.TagSets()), nil
- }
-
- return nil, fmt.Errorf("unsupported mode: %d", rp.Mode())
-}
-
-func selectSecondaries(rp *readpref.ReadPref, candidates []Server) []Server {
- secondaries := selectByKind(candidates, RSSecondary)
- if len(secondaries) == 0 {
- return secondaries
- }
- if maxStaleness, set := rp.MaxStaleness(); set {
- primaries := selectByKind(candidates, RSPrimary)
- if len(primaries) == 0 {
- baseTime := secondaries[0].LastWriteTime
- for i := 1; i < len(secondaries); i++ {
- if secondaries[i].LastWriteTime.After(baseTime) {
- baseTime = secondaries[i].LastWriteTime
- }
- }
-
- var selected []Server
- for _, secondary := range secondaries {
- estimatedStaleness := baseTime.Sub(secondary.LastWriteTime) + secondary.HeartbeatInterval
- if estimatedStaleness <= maxStaleness {
- selected = append(selected, secondary)
- }
- }
-
- return selected
- }
-
- primary := primaries[0]
-
- var selected []Server
- for _, secondary := range secondaries {
- estimatedStaleness := secondary.LastUpdateTime.Sub(secondary.LastWriteTime) - primary.LastUpdateTime.Sub(primary.LastWriteTime) + secondary.HeartbeatInterval
- if estimatedStaleness <= maxStaleness {
- selected = append(selected, secondary)
- }
- }
- return selected
- }
-
- return secondaries
-}
-
-func selectByTagSet(candidates []Server, tagSets []tag.Set) []Server {
- if len(tagSets) == 0 {
- return candidates
- }
-
- for _, ts := range tagSets {
- // If this tag set is empty, we can take a fast path because the empty list is a subset of all tag sets, so
- // all candidate servers will be selected.
- if len(ts) == 0 {
- return candidates
- }
-
- var results []Server
- for _, s := range candidates {
- // ts is non-empty, so only servers with a non-empty set of tags need to be checked.
- if len(s.Tags) > 0 && s.Tags.ContainsAll(ts) {
- results = append(results, s)
- }
- }
-
- if len(results) > 0 {
- return results
- }
- }
-
- return []Server{}
-}
-
-func selectByKind(candidates []Server, kind ServerKind) []Server {
- // Record the indices of viable candidates first and then append those to the returned slice
- // to avoid appending costly Server structs directly as an optimization.
- viableIndexes := make([]int, 0, len(candidates))
- for i, s := range candidates {
- if s.Kind == kind {
- viableIndexes = append(viableIndexes, i)
- }
- }
- if len(viableIndexes) == len(candidates) {
- return candidates
- }
- result := make([]Server, len(viableIndexes))
- for i, idx := range viableIndexes {
- result[i] = candidates[idx]
- }
- return result
-}
-
-func verifyMaxStaleness(rp *readpref.ReadPref, t Topology) error {
- maxStaleness, set := rp.MaxStaleness()
- if !set {
- return nil
- }
-
- if maxStaleness < 90*time.Second {
- return fmt.Errorf("max staleness (%s) must be greater than or equal to 90s", maxStaleness)
- }
-
- if len(t.Servers) < 1 {
- // Maybe we should return an error here instead?
- return nil
- }
-
- // we'll assume all candidates have the same heartbeat interval.
- s := t.Servers[0]
- idleWritePeriod := 10 * time.Second
-
- if maxStaleness < s.HeartbeatInterval+idleWritePeriod {
- return fmt.Errorf(
- "max staleness (%s) must be greater than or equal to the heartbeat interval (%s) plus idle write period (%s)",
- maxStaleness, s.HeartbeatInterval, idleWritePeriod,
- )
- }
-
- return nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/topology.go
deleted file mode 100644
index b082515e5..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// 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 description
-
-import (
- "fmt"
-
- "go.mongodb.org/mongo-driver/mongo/readpref"
-)
-
-// Topology contains information about a MongoDB cluster.
-type Topology struct {
- Servers []Server
- SetName string
- Kind TopologyKind
- // Deprecated: Use SessionTimeoutMinutesPtr instead.
- SessionTimeoutMinutes uint32
- SessionTimeoutMinutesPtr *int64
- CompatibilityErr error
-}
-
-// String implements the Stringer interface.
-func (t Topology) String() string {
- var serversStr string
- for _, s := range t.Servers {
- serversStr += "{ " + s.String() + " }, "
- }
- return fmt.Sprintf("Type: %s, Servers: [%s]", t.Kind, serversStr)
-}
-
-// Equal compares two topology descriptions and returns true if they are equal.
-func (t Topology) Equal(other Topology) bool {
- if t.Kind != other.Kind {
- return false
- }
-
- topoServers := make(map[string]Server)
- for _, s := range t.Servers {
- topoServers[s.Addr.String()] = s
- }
-
- otherServers := make(map[string]Server)
- for _, s := range other.Servers {
- otherServers[s.Addr.String()] = s
- }
-
- if len(topoServers) != len(otherServers) {
- return false
- }
-
- for _, server := range topoServers {
- otherServer := otherServers[server.Addr.String()]
-
- if !server.Equal(otherServer) {
- return false
- }
- }
-
- return true
-}
-
-// HasReadableServer returns true if the topology contains a server suitable for reading.
-//
-// If the Topology's kind is Single or Sharded, the mode parameter is ignored and the function contains true if any of
-// the servers in the Topology are of a known type.
-//
-// For replica sets, the function returns true if the cluster contains a server that matches the provided read
-// preference mode.
-func (t Topology) HasReadableServer(mode readpref.Mode) bool {
- switch t.Kind {
- case Single, Sharded:
- return hasAvailableServer(t.Servers, 0)
- case ReplicaSetWithPrimary:
- return hasAvailableServer(t.Servers, mode)
- case ReplicaSetNoPrimary, ReplicaSet:
- if mode == readpref.PrimaryMode {
- return false
- }
- // invalid read preference
- if !mode.IsValid() {
- return false
- }
-
- return hasAvailableServer(t.Servers, mode)
- }
- return false
-}
-
-// HasWritableServer returns true if a topology has a server available for writing.
-//
-// If the Topology's kind is Single or Sharded, this function returns true if any of the servers in the Topology are of
-// a known type.
-//
-// For replica sets, the function returns true if the replica set contains a primary.
-func (t Topology) HasWritableServer() bool {
- return t.HasReadableServer(readpref.PrimaryMode)
-}
-
-// hasAvailableServer returns true if any servers are available based on the read preference.
-func hasAvailableServer(servers []Server, mode readpref.Mode) bool {
- switch mode {
- case readpref.PrimaryMode:
- for _, s := range servers {
- if s.Kind == RSPrimary {
- return true
- }
- }
- return false
- case readpref.PrimaryPreferredMode, readpref.SecondaryPreferredMode, readpref.NearestMode:
- for _, s := range servers {
- if s.Kind == RSPrimary || s.Kind == RSSecondary {
- return true
- }
- }
- return false
- case readpref.SecondaryMode:
- for _, s := range servers {
- if s.Kind == RSSecondary {
- return true
- }
- }
- return false
- }
-
- // read preference is not specified
- for _, s := range servers {
- switch s.Kind {
- case Standalone,
- RSMember,
- RSPrimary,
- RSSecondary,
- RSArbiter,
- RSGhost,
- Mongos:
- return true
- }
- }
-
- return false
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_kind.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_kind.go
deleted file mode 100644
index 6d60c4d87..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_kind.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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 description
-
-// TopologyKind represents a specific topology configuration.
-type TopologyKind uint32
-
-// These constants are the available topology configurations.
-const (
- Single TopologyKind = 1
- ReplicaSet TopologyKind = 2
- ReplicaSetNoPrimary TopologyKind = 4 + ReplicaSet
- ReplicaSetWithPrimary TopologyKind = 8 + ReplicaSet
- Sharded TopologyKind = 256
- LoadBalanced TopologyKind = 512
-)
-
-// String implements the fmt.Stringer interface.
-func (kind TopologyKind) String() string {
- switch kind {
- case Single:
- return "Single"
- case ReplicaSet:
- return "ReplicaSet"
- case ReplicaSetNoPrimary:
- return "ReplicaSetNoPrimary"
- case ReplicaSetWithPrimary:
- return "ReplicaSetWithPrimary"
- case Sharded:
- return "Sharded"
- case LoadBalanced:
- return "LoadBalanced"
- }
-
- return "Unknown"
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_version.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_version.go
deleted file mode 100644
index e6674ea76..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/topology_version.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 description
-
-import (
- "fmt"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-// TopologyVersion represents a software version.
-type TopologyVersion struct {
- ProcessID primitive.ObjectID
- Counter int64
-}
-
-// NewTopologyVersion creates a TopologyVersion based on doc
-func NewTopologyVersion(doc bson.Raw) (*TopologyVersion, error) {
- elements, err := doc.Elements()
- if err != nil {
- return nil, err
- }
- var tv TopologyVersion
- var ok bool
- for _, element := range elements {
- switch element.Key() {
- case "processId":
- tv.ProcessID, ok = element.Value().ObjectIDOK()
- if !ok {
- return nil, fmt.Errorf("expected 'processId' to be a objectID but it's a BSON %s", element.Value().Type)
- }
- case "counter":
- tv.Counter, ok = element.Value().Int64OK()
- if !ok {
- return nil, fmt.Errorf("expected 'counter' to be an int64 but it's a BSON %s", element.Value().Type)
- }
- }
- }
- return &tv, nil
-}
-
-// CompareToIncoming compares the receiver, which represents the currently known TopologyVersion for a server, to an
-// incoming TopologyVersion extracted from a server command response.
-//
-// This returns -1 if the receiver version is less than the response, 0 if the versions are equal, and 1 if the
-// receiver version is greater than the response. This comparison is not commutative.
-func (tv *TopologyVersion) CompareToIncoming(responseTV *TopologyVersion) int {
- if tv == nil || responseTV == nil {
- return -1
- }
- if tv.ProcessID != responseTV.ProcessID {
- return -1
- }
- if tv.Counter == responseTV.Counter {
- return 0
- }
- if tv.Counter < responseTV.Counter {
- return -1
- }
- return 1
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/version_range.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/version_range.go
deleted file mode 100644
index 5d6270c52..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/version_range.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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 description
-
-import "fmt"
-
-// VersionRange represents a range of versions.
-type VersionRange struct {
- Min int32
- Max int32
-}
-
-// NewVersionRange creates a new VersionRange given a min and a max.
-func NewVersionRange(min, max int32) VersionRange {
- return VersionRange{Min: min, Max: max}
-}
-
-// Includes returns a bool indicating whether the supplied integer is included
-// in the range.
-func (vr VersionRange) Includes(v int32) bool {
- return v >= vr.Min && v <= vr.Max
-}
-
-// Equals returns a bool indicating whether the supplied VersionRange is equal.
-func (vr *VersionRange) Equals(other *VersionRange) bool {
- if vr == nil && other == nil {
- return true
- }
- if vr == nil || other == nil {
- return false
- }
- return vr.Min == other.Min && vr.Max == other.Max
-}
-
-// String implements the fmt.Stringer interface.
-func (vr VersionRange) String() string {
- return fmt.Sprintf("[%d, %d]", vr.Min, vr.Max)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/index_options_builder.go b/vendor/go.mongodb.org/mongo-driver/mongo/index_options_builder.go
deleted file mode 100644
index d12deaee2..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/index_options_builder.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// 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 mongo
-
-import (
- "go.mongodb.org/mongo-driver/bson"
-)
-
-// IndexOptionsBuilder specifies options for a new index.
-//
-// Deprecated: Use the IndexOptions type in the mongo/options package instead.
-type IndexOptionsBuilder struct {
- document bson.D
-}
-
-// NewIndexOptionsBuilder creates a new IndexOptionsBuilder.
-//
-// Deprecated: Use the Index function in mongo/options instead.
-func NewIndexOptionsBuilder() *IndexOptionsBuilder {
- return &IndexOptionsBuilder{}
-}
-
-// Background specifies a value for the background option.
-//
-// Deprecated: Use the IndexOptions.SetBackground function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Background(background bool) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"background", background})
- return iob
-}
-
-// ExpireAfterSeconds specifies a value for the expireAfterSeconds option.
-//
-// Deprecated: Use the IndexOptions.SetExpireAfterSeconds function in mongo/options instead.
-func (iob *IndexOptionsBuilder) ExpireAfterSeconds(expireAfterSeconds int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"expireAfterSeconds", expireAfterSeconds})
- return iob
-}
-
-// Name specifies a value for the name option.
-//
-// Deprecated: Use the IndexOptions.SetName function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Name(name string) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"name", name})
- return iob
-}
-
-// Sparse specifies a value for the sparse option.
-//
-// Deprecated: Use the IndexOptions.SetSparse function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Sparse(sparse bool) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"sparse", sparse})
- return iob
-}
-
-// StorageEngine specifies a value for the storageEngine option.
-//
-// Deprecated: Use the IndexOptions.SetStorageEngine function in mongo/options instead.
-func (iob *IndexOptionsBuilder) StorageEngine(storageEngine interface{}) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"storageEngine", storageEngine})
- return iob
-}
-
-// Unique specifies a value for the unique option.
-//
-// Deprecated: Use the IndexOptions.SetUnique function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Unique(unique bool) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"unique", unique})
- return iob
-}
-
-// Version specifies a value for the version option.
-//
-// Deprecated: Use the IndexOptions.SetVersion function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Version(version int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"v", version})
- return iob
-}
-
-// DefaultLanguage specifies a value for the default_language option.
-//
-// Deprecated: Use the IndexOptions.SetDefaultLanguage function in mongo/options instead.
-func (iob *IndexOptionsBuilder) DefaultLanguage(defaultLanguage string) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"default_language", defaultLanguage})
- return iob
-}
-
-// LanguageOverride specifies a value for the language_override option.
-//
-// Deprecated: Use the IndexOptions.SetLanguageOverride function in mongo/options instead.
-func (iob *IndexOptionsBuilder) LanguageOverride(languageOverride string) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"language_override", languageOverride})
- return iob
-}
-
-// TextVersion specifies a value for the textIndexVersion option.
-//
-// Deprecated: Use the IndexOptions.SetTextVersion function in mongo/options instead.
-func (iob *IndexOptionsBuilder) TextVersion(textVersion int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"textIndexVersion", textVersion})
- return iob
-}
-
-// Weights specifies a value for the weights option.
-//
-// Deprecated: Use the IndexOptions.SetWeights function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Weights(weights interface{}) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"weights", weights})
- return iob
-}
-
-// SphereVersion specifies a value for the 2dsphereIndexVersion option.
-//
-// Deprecated: Use the IndexOptions.SetSphereVersion function in mongo/options instead.
-func (iob *IndexOptionsBuilder) SphereVersion(sphereVersion int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"2dsphereIndexVersion", sphereVersion})
- return iob
-}
-
-// Bits specifies a value for the bits option.
-//
-// Deprecated: Use the IndexOptions.SetBits function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Bits(bits int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"bits", bits})
- return iob
-}
-
-// Max specifies a value for the max option.
-//
-// Deprecated: Use the IndexOptions.SetMax function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Max(max float64) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"max", max})
- return iob
-}
-
-// Min specifies a value for the min option.
-//
-// Deprecated: Use the IndexOptions.SetMin function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Min(min float64) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"min", min})
- return iob
-}
-
-// BucketSize specifies a value for the bucketSize option.
-//
-// Deprecated: Use the IndexOptions.SetBucketSize function in mongo/options instead.
-func (iob *IndexOptionsBuilder) BucketSize(bucketSize int32) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"bucketSize", bucketSize})
- return iob
-}
-
-// PartialFilterExpression specifies a value for the partialFilterExpression option.
-//
-// Deprecated: Use the IndexOptions.SetPartialFilterExpression function in mongo/options instead.
-func (iob *IndexOptionsBuilder) PartialFilterExpression(partialFilterExpression interface{}) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"partialFilterExpression", partialFilterExpression})
- return iob
-}
-
-// Collation specifies a value for the collation option.
-//
-// Deprecated: Use the IndexOptions.SetCollation function in mongo/options instead.
-func (iob *IndexOptionsBuilder) Collation(collation interface{}) *IndexOptionsBuilder {
- iob.document = append(iob.document, bson.E{"collation", collation})
- return iob
-}
-
-// Build finishes constructing an the builder.
-//
-// Deprecated: Use the IndexOptions type in the mongo/options package instead.
-func (iob *IndexOptionsBuilder) Build() bson.D {
- return iob.document
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_enabled.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_enabled.go
deleted file mode 100644
index 588e9ad6d..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_enabled.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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
-
-//go:build cse
-// +build cse
-
-package mtest
-
-// IsCSFLEEnabled returns true if driver is built with Client Side Field Level Encryption support.
-// Client Side Field Level Encryption support is enabled with the cse build tag.
-func IsCSFLEEnabled() bool {
- return true
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_not_enabled.go
deleted file mode 100644
index 289cf5ce6..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/csfle_not_enabled.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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
-
-//go:build !cse
-// +build !cse
-
-package mtest
-
-// IsCSFLEEnabled returns true if driver is built with Client Side Field Level Encryption support.
-// Client Side Field Level Encryption support is enabled with the cse build tag.
-func IsCSFLEEnabled() bool {
- return false
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/deployment_helpers.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/deployment_helpers.go
deleted file mode 100644
index 299fae567..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/deployment_helpers.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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 mtest
-
-import (
- "go.mongodb.org/mongo-driver/bson"
-)
-
-// BatchIdentifier specifies the keyword to identify the batch in a cursor response.
-type BatchIdentifier string
-
-// These constants specify valid values for BatchIdentifier.
-const (
- FirstBatch BatchIdentifier = "firstBatch"
- NextBatch BatchIdentifier = "nextBatch"
-)
-
-// CommandError is a representation of a command error from the server.
-type CommandError struct {
- Code int32
- Message string
- Name string
- Labels []string
-}
-
-// WriteError is a representation of a write error from the server.
-type WriteError struct {
- Index int
- Code int
- Message string
-}
-
-// WriteConcernError is a representation of a write concern error from the server.
-type WriteConcernError struct {
- Name string `bson:"codeName"`
- Code int `bson:"code"`
- Message string `bson:"errmsg"`
- Details bson.Raw `bson:"errInfo"`
-}
-
-// CreateCursorResponse creates a response for a cursor command.
-func CreateCursorResponse(cursorID int64, ns string, identifier BatchIdentifier, batch ...bson.D) bson.D {
- batchArr := bson.A{}
- for _, doc := range batch {
- batchArr = append(batchArr, doc)
- }
-
- return bson.D{
- {"ok", 1},
- {"cursor", bson.D{
- {"id", cursorID},
- {"ns", ns},
- {string(identifier), batchArr},
- }},
- }
-}
-
-// CreateCommandErrorResponse creates a response with a command error.
-func CreateCommandErrorResponse(ce CommandError) bson.D {
- res := bson.D{
- {"ok", 0},
- {"code", ce.Code},
- {"errmsg", ce.Message},
- {"codeName", ce.Name},
- }
- if len(ce.Labels) > 0 {
- var labelsArr bson.A
- for _, label := range ce.Labels {
- labelsArr = append(labelsArr, label)
- }
- res = append(res, bson.E{Key: "errorLabels", Value: labelsArr})
- }
- return res
-}
-
-// CreateWriteErrorsResponse creates a response with one or more write errors.
-func CreateWriteErrorsResponse(writeErrorrs ...WriteError) bson.D {
- arr := make(bson.A, len(writeErrorrs))
- for idx, we := range writeErrorrs {
- arr[idx] = bson.D{
- {"index", we.Index},
- {"code", we.Code},
- {"errmsg", we.Message},
- }
- }
-
- return bson.D{
- {"ok", 1},
- {"writeErrors", arr},
- }
-}
-
-// CreateWriteConcernErrorResponse creates a response with a write concern error.
-func CreateWriteConcernErrorResponse(wce WriteConcernError) bson.D {
- wceDoc := bson.D{
- {"code", wce.Code},
- {"codeName", wce.Name},
- {"errmsg", wce.Message},
- }
- if len(wce.Details) > 0 {
- wceDoc = append(wceDoc, bson.E{Key: "errInfo", Value: wce.Details})
- }
-
- return bson.D{
- {"ok", 1},
- {"writeConcernError", wceDoc},
- }
-}
-
-// CreateSuccessResponse creates a response for a successful operation with the given elements.
-func CreateSuccessResponse(elems ...bson.E) bson.D {
- res := bson.D{
- {"ok", 1},
- }
- return append(res, elems...)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/doc.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/doc.go
deleted file mode 100644
index 9d4ae6f32..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/doc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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 mtest is unstable and there is no backward compatibility guarantee.
-// It is experimental and subject to change.
-package mtest
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/global_state.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/global_state.go
deleted file mode 100644
index adb262203..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/global_state.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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 mtest
-
-import (
- "context"
- "fmt"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
-)
-
-// AuthEnabled returns whether or not the cluster requires auth.
-func AuthEnabled() bool {
- return testContext.authEnabled
-}
-
-// SSLEnabled returns whether or not the cluster requires SSL.
-func SSLEnabled() bool {
- return testContext.sslEnabled
-}
-
-// ClusterTopologyKind returns the topology kind of the cluster under test.
-func ClusterTopologyKind() TopologyKind {
- return testContext.topoKind
-}
-
-// ClusterURI returns the connection string for the cluster.
-func ClusterURI() string {
- return testContext.connString.Original
-}
-
-// Serverless returns whether the test is running against a serverless instance.
-func Serverless() bool {
- return testContext.serverless
-}
-
-// SingleMongosLoadBalancerURI returns the URI for a load balancer fronting a single mongos. This will only be set
-// if the cluster is load balanced.
-func SingleMongosLoadBalancerURI() string {
- return testContext.singleMongosLoadBalancerURI
-}
-
-// MultiMongosLoadBalancerURI returns the URI for a load balancer fronting multiple mongoses. This will only be set
-// if the cluster is load balanced.
-func MultiMongosLoadBalancerURI() string {
- return testContext.multiMongosLoadBalancerURI
-}
-
-// ClusterConnString returns the parsed ConnString for the cluster.
-func ClusterConnString() *connstring.ConnString {
- return testContext.connString
-}
-
-// GlobalClient returns a Client connected to the cluster configured with read concern majority, write concern majority,
-// and read preference primary.
-func GlobalClient() *mongo.Client {
- return testContext.client
-}
-
-// GlobalTopology returns a Topology that's connected to the cluster.
-func GlobalTopology() *topology.Topology {
- return testContext.topo
-}
-
-// ServerVersion returns the server version of the cluster. This assumes that all nodes in the cluster have the same
-// version.
-func ServerVersion() string {
- return testContext.serverVersion
-}
-
-// SetFailPoint configures the provided fail point on the cluster under test using the provided Client.
-func SetFailPoint(fp FailPoint, client *mongo.Client) error {
- admin := client.Database("admin")
- if err := admin.RunCommand(context.Background(), fp).Err(); err != nil {
- return fmt.Errorf("error creating fail point: %w", err)
- }
- return nil
-}
-
-// SetRawFailPoint configures the fail point represented by the fp parameter on the cluster under test using the
-// provided Client
-func SetRawFailPoint(fp bson.Raw, client *mongo.Client) error {
- admin := client.Database("admin")
- if err := admin.RunCommand(context.Background(), fp).Err(); err != nil {
- return fmt.Errorf("error creating fail point: %w", err)
- }
- return nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/mongotest.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/mongotest.go
deleted file mode 100644
index 41292e67a..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/mongotest.go
+++ /dev/null
@@ -1,914 +0,0 @@
-// 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 mtest
-
-import (
- "context"
- "errors"
- "fmt"
- "strings"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/assert"
- "go.mongodb.org/mongo-driver/internal/csfle"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
-)
-
-var (
- // MajorityWc is the majority write concern.
- MajorityWc = writeconcern.New(writeconcern.WMajority())
- // PrimaryRp is the primary read preference.
- PrimaryRp = readpref.Primary()
- // SecondaryRp is the secondary read preference.
- SecondaryRp = readpref.Secondary()
- // LocalRc is the local read concern
- LocalRc = readconcern.Local()
- // MajorityRc is the majority read concern
- MajorityRc = readconcern.Majority()
-)
-
-const (
- namespaceExistsErrCode int32 = 48
-)
-
-// FailPoint is a representation of a server fail point.
-// See https://github.com/mongodb/specifications/tree/HEAD/source/transactions/tests#server-fail-point
-// for more information regarding fail points.
-type FailPoint struct {
- ConfigureFailPoint string `bson:"configureFailPoint"`
- // Mode should be a string, FailPointMode, or map[string]interface{}
- Mode interface{} `bson:"mode"`
- Data FailPointData `bson:"data"`
-}
-
-// FailPointMode is a representation of the Failpoint.Mode field.
-type FailPointMode struct {
- Times int32 `bson:"times"`
- Skip int32 `bson:"skip"`
-}
-
-// FailPointData is a representation of the FailPoint.Data field.
-type FailPointData struct {
- FailCommands []string `bson:"failCommands,omitempty"`
- CloseConnection bool `bson:"closeConnection,omitempty"`
- ErrorCode int32 `bson:"errorCode,omitempty"`
- FailBeforeCommitExceptionCode int32 `bson:"failBeforeCommitExceptionCode,omitempty"`
- ErrorLabels *[]string `bson:"errorLabels,omitempty"`
- WriteConcernError *WriteConcernErrorData `bson:"writeConcernError,omitempty"`
- BlockConnection bool `bson:"blockConnection,omitempty"`
- BlockTimeMS int32 `bson:"blockTimeMS,omitempty"`
- AppName string `bson:"appName,omitempty"`
-}
-
-// WriteConcernErrorData is a representation of the FailPoint.Data.WriteConcern field.
-type WriteConcernErrorData struct {
- Code int32 `bson:"code"`
- Name string `bson:"codeName"`
- Errmsg string `bson:"errmsg"`
- ErrorLabels *[]string `bson:"errorLabels,omitempty"`
- ErrInfo bson.Raw `bson:"errInfo,omitempty"`
-}
-
-// T is a wrapper around testing.T.
-type T struct {
- // connsCheckedOut is the net number of connections checked out during test execution.
- // It must be accessed using the atomic package and should be at the beginning of the struct.
- // - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG
- // - suggested layout: https://go101.org/article/memory-layout.html
- connsCheckedOut int64
-
- *testing.T
-
- // members for only this T instance
- createClient *bool
- createCollection *bool
- runOn []RunOnBlock
- mockDeployment *mockDeployment // nil if the test is not being run against a mock
- mockResponses []bson.D
- createdColls []*Collection // collections created in this test
- proxyDialer *proxyDialer
- dbName, collName string
- failPointNames []string
- minServerVersion string
- maxServerVersion string
- validTopologies []TopologyKind
- auth *bool
- enterprise *bool
- dataLake *bool
- ssl *bool
- collCreateOpts *options.CreateCollectionOptions
- requireAPIVersion *bool
-
- // options copied to sub-tests
- clientType ClientType
- clientOpts *options.ClientOptions
- collOpts *options.CollectionOptions
- shareClient *bool
-
- baseOpts *Options // used to create subtests
-
- // command monitoring channels
- monitorLock sync.Mutex
- started []*event.CommandStartedEvent
- succeeded []*event.CommandSucceededEvent
- failed []*event.CommandFailedEvent
-
- Client *mongo.Client
- DB *mongo.Database
- Coll *mongo.Collection
-}
-
-func newT(wrapped *testing.T, opts ...*Options) *T {
- t := &T{
- T: wrapped,
- }
- for _, opt := range opts {
- for _, optFn := range opt.optFuncs {
- optFn(t)
- }
- }
-
- if err := t.verifyConstraints(); err != nil {
- t.Skipf("skipping due to environmental constraints: %v", err)
- }
-
- if t.collName == "" {
- t.collName = t.Name()
- }
- if t.dbName == "" {
- t.dbName = TestDb
- }
- t.collName = sanitizeCollectionName(t.dbName, t.collName)
-
- // create a set of base options for sub-tests
- t.baseOpts = NewOptions().ClientOptions(t.clientOpts).CollectionOptions(t.collOpts).ClientType(t.clientType)
- if t.shareClient != nil {
- t.baseOpts.ShareClient(*t.shareClient)
- }
-
- return t
-}
-
-// New creates a new T instance with the given options. If the current environment does not satisfy constraints
-// specified in the options, the test will be skipped automatically.
-func New(wrapped *testing.T, opts ...*Options) *T {
- // All tests that use mtest.New() are expected to be integration tests, so skip them when the
- // -short flag is included in the "go test" command.
- if testing.Short() {
- wrapped.Skip("skipping mtest integration test in short mode")
- }
-
- t := newT(wrapped, opts...)
-
- // only create a client if it needs to be shared in sub-tests
- // otherwise, a new client will be created for each subtest
- if t.shareClient != nil && *t.shareClient {
- t.createTestClient()
- }
-
- wrapped.Cleanup(t.cleanup)
-
- return t
-}
-
-// cleanup cleans up any resources associated with a T. It is intended to be
-// called by [testing.T.Cleanup].
-func (t *T) cleanup() {
- if t.Client == nil {
- return
- }
-
- // only clear collections and fail points if the test is not running against a mock
- if t.clientType != Mock {
- t.ClearCollections()
- t.ClearFailPoints()
- }
-
- // always disconnect the client regardless of clientType because Client.Disconnect will work against
- // all deployments
- _ = t.Client.Disconnect(context.Background())
-}
-
-// Run creates a new T instance for a sub-test and runs the given callback. It also creates a new collection using the
-// given name which is available to the callback through the T.Coll variable and is dropped after the callback
-// returns.
-func (t *T) Run(name string, callback func(mt *T)) {
- t.RunOpts(name, NewOptions(), callback)
-}
-
-// RunOpts creates a new T instance for a sub-test with the given options. If the current environment does not satisfy
-// constraints specified in the options, the new sub-test will be skipped automatically. If the test is not skipped,
-// the callback will be run with the new T instance. RunOpts creates a new collection with the given name which is
-// available to the callback through the T.Coll variable and is dropped after the callback returns.
-func (t *T) RunOpts(name string, opts *Options, callback func(mt *T)) {
- t.T.Run(name, func(wrapped *testing.T) {
- sub := newT(wrapped, t.baseOpts, opts)
-
- // add any mock responses for this test
- if sub.clientType == Mock && len(sub.mockResponses) > 0 {
- sub.AddMockResponses(sub.mockResponses...)
- }
-
- // for shareClient, inherit the client from the parent
- if sub.shareClient != nil && *sub.shareClient && sub.clientType == t.clientType {
- sub.Client = t.Client
- }
- // only create a client if not already set
- if sub.Client == nil {
- if sub.createClient == nil || *sub.createClient {
- sub.createTestClient()
- }
- }
- // create a collection for this test
- if sub.Client != nil {
- sub.createTestCollection()
- }
-
- // defer dropping all collections if the test is using a client
- defer func() {
- if sub.Client == nil {
- return
- }
-
- // store number of sessions and connections checked out here but assert that they're equal to 0 after
- // cleaning up test resources to make sure resources are always cleared
- sessions := sub.Client.NumberSessionsInProgress()
- conns := sub.NumberConnectionsCheckedOut()
-
- if sub.clientType != Mock {
- sub.ClearFailPoints()
- sub.ClearCollections()
- }
- // only disconnect client if it's not being shared
- if sub.shareClient == nil || !*sub.shareClient {
- _ = sub.Client.Disconnect(context.Background())
- }
- assert.Equal(sub, 0, sessions, "%v sessions checked out", sessions)
- assert.Equal(sub, 0, conns, "%v connections checked out", conns)
- }()
-
- // clear any events that may have happened during setup and run the test
- sub.ClearEvents()
- callback(sub)
- })
-}
-
-// AddMockResponses adds responses to be returned by the mock deployment. This should only be used if T is being run
-// against a mock deployment.
-func (t *T) AddMockResponses(responses ...bson.D) {
- t.mockDeployment.addResponses(responses...)
-}
-
-// ClearMockResponses clears all responses in the mock deployment.
-func (t *T) ClearMockResponses() {
- t.mockDeployment.clearResponses()
-}
-
-// GetStartedEvent returns the most recent CommandStartedEvent, or nil if one is not present.
-// This can only be called once per event.
-func (t *T) GetStartedEvent() *event.CommandStartedEvent {
- // TODO(GODRIVER-2075): GetStartedEvent documents that it returns the most recent event, but actually returns the first
- // TODO event. Update either the documentation or implementation.
- if len(t.started) == 0 {
- return nil
- }
- e := t.started[0]
- t.started = t.started[1:]
- return e
-}
-
-// GetSucceededEvent returns the most recent CommandSucceededEvent, or nil if one is not present.
-// This can only be called once per event.
-func (t *T) GetSucceededEvent() *event.CommandSucceededEvent {
- // TODO(GODRIVER-2075): GetSucceededEvent documents that it returns the most recent event, but actually returns the
- // TODO first event. Update either the documentation or implementation.
- if len(t.succeeded) == 0 {
- return nil
- }
- e := t.succeeded[0]
- t.succeeded = t.succeeded[1:]
- return e
-}
-
-// GetFailedEvent returns the most recent CommandFailedEvent, or nil if one is not present.
-// This can only be called once per event.
-func (t *T) GetFailedEvent() *event.CommandFailedEvent {
- // TODO(GODRIVER-2075): GetFailedEvent documents that it returns the most recent event, but actually returns the first
- // TODO event. Update either the documentation or implementation.
- if len(t.failed) == 0 {
- return nil
- }
- e := t.failed[0]
- t.failed = t.failed[1:]
- return e
-}
-
-// GetAllStartedEvents returns a slice of all CommandStartedEvent instances for this test. This can be called multiple
-// times.
-func (t *T) GetAllStartedEvents() []*event.CommandStartedEvent {
- return t.started
-}
-
-// GetAllSucceededEvents returns a slice of all CommandSucceededEvent instances for this test. This can be called multiple
-// times.
-func (t *T) GetAllSucceededEvents() []*event.CommandSucceededEvent {
- return t.succeeded
-}
-
-// GetAllFailedEvents returns a slice of all CommandFailedEvent instances for this test. This can be called multiple
-// times.
-func (t *T) GetAllFailedEvents() []*event.CommandFailedEvent {
- return t.failed
-}
-
-// FilterStartedEvents filters the existing CommandStartedEvent instances for this test using the provided filter
-// callback. An event will be retained if the filter returns true. The list of filtered events will be used to overwrite
-// the list of events for this test and will therefore change the output of t.GetAllStartedEvents().
-func (t *T) FilterStartedEvents(filter func(*event.CommandStartedEvent) bool) {
- var newEvents []*event.CommandStartedEvent
- for _, evt := range t.started {
- if filter(evt) {
- newEvents = append(newEvents, evt)
- }
- }
- t.started = newEvents
-}
-
-// FilterSucceededEvents filters the existing CommandSucceededEvent instances for this test using the provided filter
-// callback. An event will be retained if the filter returns true. The list of filtered events will be used to overwrite
-// the list of events for this test and will therefore change the output of t.GetAllSucceededEvents().
-func (t *T) FilterSucceededEvents(filter func(*event.CommandSucceededEvent) bool) {
- var newEvents []*event.CommandSucceededEvent
- for _, evt := range t.succeeded {
- if filter(evt) {
- newEvents = append(newEvents, evt)
- }
- }
- t.succeeded = newEvents
-}
-
-// FilterFailedEvents filters the existing CommandFailedEVent instances for this test using the provided filter
-// callback. An event will be retained if the filter returns true. The list of filtered events will be used to overwrite
-// the list of events for this test and will therefore change the output of t.GetAllFailedEvents().
-func (t *T) FilterFailedEvents(filter func(*event.CommandFailedEvent) bool) {
- var newEvents []*event.CommandFailedEvent
- for _, evt := range t.failed {
- if filter(evt) {
- newEvents = append(newEvents, evt)
- }
- }
- t.failed = newEvents
-}
-
-// GetProxiedMessages returns the messages proxied to the server by the test. If the client type is not Proxy, this
-// returns nil.
-func (t *T) GetProxiedMessages() []*ProxyMessage {
- if t.proxyDialer == nil {
- return nil
- }
- return t.proxyDialer.Messages()
-}
-
-// NumberConnectionsCheckedOut returns the number of connections checked out from the test Client.
-func (t *T) NumberConnectionsCheckedOut() int {
- return int(atomic.LoadInt64(&t.connsCheckedOut))
-}
-
-// ClearEvents clears the existing command monitoring events.
-func (t *T) ClearEvents() {
- t.started = t.started[:0]
- t.succeeded = t.succeeded[:0]
- t.failed = t.failed[:0]
-}
-
-// ResetClient resets the existing client with the given options. If opts is nil, the existing options will be used.
-// If t.Coll is not-nil, it will be reset to use the new client. Should only be called if the existing client is
-// not nil. This will Disconnect the existing client but will not drop existing collections. To do so, ClearCollections
-// must be called before calling ResetClient.
-func (t *T) ResetClient(opts *options.ClientOptions) {
- if opts != nil {
- t.clientOpts = opts
- }
-
- _ = t.Client.Disconnect(context.Background())
- t.createTestClient()
- t.DB = t.Client.Database(t.dbName)
- t.Coll = t.DB.Collection(t.collName, t.collOpts)
-
- for _, coll := range t.createdColls {
- // If the collection was created using a different Client, it doesn't need to be reset.
- if coll.hasDifferentClient {
- continue
- }
-
- // If the namespace is the same as t.Coll, we can use t.Coll.
- if coll.created.Name() == t.collName && coll.created.Database().Name() == t.dbName {
- coll.created = t.Coll
- continue
- }
-
- // Otherwise, reset the collection to use the new Client.
- coll.created = t.Client.Database(coll.DB).Collection(coll.Name, coll.Opts)
- }
-}
-
-// Collection is used to configure a new collection created during a test.
-type Collection struct {
- Name string
- DB string // defaults to mt.DB.Name() if not specified
- Client *mongo.Client // defaults to mt.Client if not specified
- Opts *options.CollectionOptions
- CreateOpts *options.CreateCollectionOptions
- ViewOn string
- ViewPipeline interface{}
- hasDifferentClient bool
- created *mongo.Collection // the actual collection that was created
-}
-
-// CreateCollection creates a new collection with the given configuration. The collection will be dropped after the test
-// finishes running. If createOnServer is true, the function ensures that the collection has been created server-side
-// by running the create command. The create command will appear in command monitoring channels.
-func (t *T) CreateCollection(coll Collection, createOnServer bool) *mongo.Collection {
- if coll.DB == "" {
- coll.DB = t.DB.Name()
- }
- if coll.Client == nil {
- coll.Client = t.Client
- }
- coll.hasDifferentClient = coll.Client != t.Client
-
- db := coll.Client.Database(coll.DB)
-
- if coll.CreateOpts != nil && coll.CreateOpts.EncryptedFields != nil {
- // An encrypted collection consists of a data collection and three state collections.
- // Aborted test runs may leave these collections.
- // Drop all four collections to avoid a quiet failure to create all collections.
- DropEncryptedCollection(t, db.Collection(coll.Name), coll.CreateOpts.EncryptedFields)
- }
-
- if createOnServer && t.clientType != Mock {
- var err error
- if coll.ViewOn != "" {
- err = db.CreateView(context.Background(), coll.Name, coll.ViewOn, coll.ViewPipeline)
- } else {
- err = db.CreateCollection(context.Background(), coll.Name, coll.CreateOpts)
- }
-
- // ignore ErrUnacknowledgedWrite. Client may be configured with unacknowledged write concern.
- if err != nil && !errors.Is(err, driver.ErrUnacknowledgedWrite) {
- // ignore NamespaceExists errors for idempotency
-
- var cmdErr mongo.CommandError
- if !errors.As(err, &cmdErr) || cmdErr.Code != namespaceExistsErrCode {
- t.Fatalf("error creating collection or view: %v on server: %v", coll.Name, err)
- }
- }
- }
-
- coll.created = db.Collection(coll.Name, coll.Opts)
- t.createdColls = append(t.createdColls, &coll)
- return coll.created
-}
-
-// DropEncryptedCollection drops a collection with EncryptedFields.
-// The EncryptedFields option is not supported in Collection.Drop(). See GODRIVER-2413.
-func DropEncryptedCollection(t *T, coll *mongo.Collection, encryptedFields interface{}) {
- t.Helper()
-
- var efBSON bsoncore.Document
- efBSON, err := bson.Marshal(encryptedFields)
- assert.Nil(t, err, "error in Marshal: %v", err)
-
- // Drop the two encryption-related, associated collections: `escCollection` and `ecocCollection`.
- // Drop ESCCollection.
- escCollection, err := csfle.GetEncryptedStateCollectionName(efBSON, coll.Name(), csfle.EncryptedStateCollection)
- assert.Nil(t, err, "error in getEncryptedStateCollectionName: %v", err)
- err = coll.Database().Collection(escCollection).Drop(context.Background())
- assert.Nil(t, err, "error in Drop: %v", err)
-
- // Drop ECOCCollection.
- ecocCollection, err := csfle.GetEncryptedStateCollectionName(efBSON, coll.Name(), csfle.EncryptedCompactionCollection)
- assert.Nil(t, err, "error in getEncryptedStateCollectionName: %v", err)
- err = coll.Database().Collection(ecocCollection).Drop(context.Background())
- assert.Nil(t, err, "error in Drop: %v", err)
-
- // Drop the data collection.
- err = coll.Drop(context.Background())
- assert.Nil(t, err, "error in Drop: %v", err)
-}
-
-// ClearCollections drops all collections previously created by this test.
-func (t *T) ClearCollections() {
- // Collections should not be dropped when testing against Atlas Data Lake because the data is pre-inserted.
- if !testContext.dataLake {
- for _, coll := range t.createdColls {
- if coll.CreateOpts != nil && coll.CreateOpts.EncryptedFields != nil {
- DropEncryptedCollection(t, coll.created, coll.CreateOpts.EncryptedFields)
- }
-
- err := coll.created.Drop(context.Background())
- if errors.Is(err, mongo.ErrUnacknowledgedWrite) || errors.Is(err, driver.ErrUnacknowledgedWrite) {
- // It's possible that a collection could have an unacknowledged write concern, which
- // could prevent it from being dropped for sharded clusters. We can resolve this by
- // re-instantiating the collection with a majority write concern before dropping.
- collname := coll.created.Name()
- wcm := writeconcern.New(writeconcern.WMajority(), writeconcern.WTimeout(1*time.Second))
- wccoll := t.DB.Collection(collname, options.Collection().SetWriteConcern(wcm))
- _ = wccoll.Drop(context.Background())
-
- }
- }
- }
- t.createdColls = t.createdColls[:0]
-}
-
-// SetFailPoint sets a fail point for the client associated with T. Commands to create the failpoint will appear
-// in command monitoring channels. The fail point will automatically be disabled after this test has run.
-func (t *T) SetFailPoint(fp FailPoint) {
- // ensure mode fields are int32
- if modeMap, ok := fp.Mode.(map[string]interface{}); ok {
- var key string
- var err error
-
- if times, ok := modeMap["times"]; ok {
- key = "times"
- modeMap["times"], err = t.interfaceToInt32(times)
- }
- if skip, ok := modeMap["skip"]; ok {
- key = "skip"
- modeMap["skip"], err = t.interfaceToInt32(skip)
- }
-
- if err != nil {
- t.Fatalf("error converting %s to int32: %v", key, err)
- }
- }
-
- if err := SetFailPoint(fp, t.Client); err != nil {
- t.Fatal(err)
- }
- t.failPointNames = append(t.failPointNames, fp.ConfigureFailPoint)
-}
-
-// SetFailPointFromDocument sets the fail point represented by the given document for the client associated with T. This
-// method assumes that the given document is in the form {configureFailPoint: , ...}. Commands to create
-// the failpoint will appear in command monitoring channels. The fail point will be automatically disabled after this
-// test has run.
-func (t *T) SetFailPointFromDocument(fp bson.Raw) {
- if err := SetRawFailPoint(fp, t.Client); err != nil {
- t.Fatal(err)
- }
-
- name := fp.Index(0).Value().StringValue()
- t.failPointNames = append(t.failPointNames, name)
-}
-
-// TrackFailPoint adds the given fail point to the list of fail points to be disabled when the current test finishes.
-// This function does not create a fail point on the server.
-func (t *T) TrackFailPoint(fpName string) {
- t.failPointNames = append(t.failPointNames, fpName)
-}
-
-// ClearFailPoints disables all previously set failpoints for this test.
-func (t *T) ClearFailPoints() {
- db := t.Client.Database("admin")
- for _, fp := range t.failPointNames {
- cmd := bson.D{
- {"configureFailPoint", fp},
- {"mode", "off"},
- }
- err := db.RunCommand(context.Background(), cmd).Err()
- if err != nil {
- t.Fatalf("error clearing fail point %s: %v", fp, err)
- }
- }
- t.failPointNames = t.failPointNames[:0]
-}
-
-// CloneDatabase modifies the default database for this test to match the given options.
-func (t *T) CloneDatabase(opts *options.DatabaseOptions) {
- t.DB = t.Client.Database(t.dbName, opts)
-}
-
-// CloneCollection modifies the default collection for this test to match the given options.
-func (t *T) CloneCollection(opts *options.CollectionOptions) {
- var err error
- t.Coll, err = t.Coll.Clone(opts)
- assert.Nil(t, err, "error cloning collection: %v", err)
-}
-
-func sanitizeCollectionName(db string, coll string) string {
- // Collections can't have "$" in their names, so we substitute it with "%".
- coll = strings.ReplaceAll(coll, "$", "%")
-
- // Namespaces can only have 120 bytes max.
- if len(db+"."+coll) >= 120 {
- // coll len must be <= remaining
- remaining := 120 - (len(db) + 1) // +1 for "."
- coll = coll[len(coll)-remaining:]
- }
- return coll
-}
-
-func (t *T) createTestClient() {
- clientOpts := t.clientOpts
- if clientOpts == nil {
- // default opts
- clientOpts = options.Client().SetWriteConcern(MajorityWc).SetReadPreference(PrimaryRp)
- }
- // set ServerAPIOptions to latest version if required
- if clientOpts.Deployment == nil && t.clientType != Mock && clientOpts.ServerAPIOptions == nil && testContext.requireAPIVersion {
- clientOpts.SetServerAPIOptions(options.ServerAPI(driver.TestServerAPIVersion))
- }
-
- // Setup command monitor
- var customMonitor = clientOpts.Monitor
- clientOpts.SetMonitor(&event.CommandMonitor{
- Started: func(ctx context.Context, cse *event.CommandStartedEvent) {
- if customMonitor != nil && customMonitor.Started != nil {
- customMonitor.Started(ctx, cse)
- }
- t.monitorLock.Lock()
- defer t.monitorLock.Unlock()
- t.started = append(t.started, cse)
- },
- Succeeded: func(ctx context.Context, cse *event.CommandSucceededEvent) {
- if customMonitor != nil && customMonitor.Succeeded != nil {
- customMonitor.Succeeded(ctx, cse)
- }
- t.monitorLock.Lock()
- defer t.monitorLock.Unlock()
- t.succeeded = append(t.succeeded, cse)
- },
- Failed: func(ctx context.Context, cfe *event.CommandFailedEvent) {
- if customMonitor != nil && customMonitor.Failed != nil {
- customMonitor.Failed(ctx, cfe)
- }
- t.monitorLock.Lock()
- defer t.monitorLock.Unlock()
- t.failed = append(t.failed, cfe)
- },
- })
- // only specify connection pool monitor if no deployment is given
- if clientOpts.Deployment == nil {
- previousPoolMonitor := clientOpts.PoolMonitor
-
- clientOpts.SetPoolMonitor(&event.PoolMonitor{
- Event: func(evt *event.PoolEvent) {
- if previousPoolMonitor != nil {
- previousPoolMonitor.Event(evt)
- }
-
- switch evt.Type {
- case event.GetSucceeded:
- atomic.AddInt64(&t.connsCheckedOut, 1)
- case event.ConnectionReturned:
- atomic.AddInt64(&t.connsCheckedOut, -1)
- }
- },
- })
- }
-
- var err error
- switch t.clientType {
- case Pinned:
- // pin to first mongos
- pinnedHostList := []string{testContext.connString.Hosts[0]}
- uriOpts := options.Client().ApplyURI(testContext.connString.Original).SetHosts(pinnedHostList)
- t.Client, err = mongo.NewClient(uriOpts, clientOpts)
- case Mock:
- // clear pool monitor to avoid configuration error
- clientOpts.PoolMonitor = nil
- t.mockDeployment = newMockDeployment()
- clientOpts.Deployment = t.mockDeployment
- t.Client, err = mongo.NewClient(clientOpts)
- case Proxy:
- t.proxyDialer = newProxyDialer()
- clientOpts.SetDialer(t.proxyDialer)
-
- // After setting the Dialer, fall-through to the Default case to apply the correct URI
- fallthrough
- case Default:
- // Use a different set of options to specify the URI because clientOpts may already have a URI or host seedlist
- // specified.
- var uriOpts *options.ClientOptions
- if clientOpts.Deployment == nil {
- // Only specify URI if the deployment is not set to avoid setting topology/server options along with the
- // deployment.
- uriOpts = options.Client().ApplyURI(testContext.connString.Original)
- }
-
- // Pass in uriOpts first so clientOpts wins if there are any conflicting settings.
- t.Client, err = mongo.NewClient(uriOpts, clientOpts)
- }
- if err != nil {
- t.Fatalf("error creating client: %v", err)
- }
- if err := t.Client.Connect(context.Background()); err != nil {
- t.Fatalf("error connecting client: %v", err)
- }
-}
-
-func (t *T) createTestCollection() {
- t.DB = t.Client.Database(t.dbName)
- t.createdColls = t.createdColls[:0]
-
- // Collections should not be explicitly created when testing against Atlas Data Lake because they already exist in
- // the server with pre-seeded data.
- createOnServer := (t.createCollection == nil || *t.createCollection) && !testContext.dataLake
- t.Coll = t.CreateCollection(Collection{
- Name: t.collName,
- CreateOpts: t.collCreateOpts,
- Opts: t.collOpts,
- }, createOnServer)
-}
-
-// verifyVersionConstraints returns an error if the cluster's server version is not in the range [min, max]. Server
-// versions will only be checked if they are non-empty.
-func verifyVersionConstraints(min, max string) error {
- if min != "" && CompareServerVersions(testContext.serverVersion, min) < 0 {
- return fmt.Errorf("server version %q is lower than min required version %q", testContext.serverVersion, min)
- }
- if max != "" && CompareServerVersions(testContext.serverVersion, max) > 0 {
- return fmt.Errorf("server version %q is higher than max version %q", testContext.serverVersion, max)
- }
- return nil
-}
-
-// verifyTopologyConstraints returns an error if the cluster's topology kind does not match one of the provided
-// kinds. If the topologies slice is empty, nil is returned without any additional checks.
-func verifyTopologyConstraints(topologies []TopologyKind) error {
- if len(topologies) == 0 {
- return nil
- }
-
- for _, topo := range topologies {
- // For ShardedReplicaSet, we won't get an exact match because testContext.topoKind will be Sharded so we do an
- // additional comparison with the testContext.shardedReplicaSet field.
- if topo == testContext.topoKind || (topo == ShardedReplicaSet && testContext.shardedReplicaSet) {
- return nil
- }
- }
- return fmt.Errorf("topology kind %q does not match any of the required kinds %q", testContext.topoKind, topologies)
-}
-
-func verifyServerParametersConstraints(serverParameters map[string]bson.RawValue) error {
- for param, expected := range serverParameters {
- actual, err := testContext.serverParameters.LookupErr(param)
- if err != nil {
- return fmt.Errorf("server does not support parameter %q", param)
- }
- if !expected.Equal(actual) {
- return fmt.Errorf("mismatched values for server parameter %q; expected %s, got %s", param, expected, actual)
- }
- }
- return nil
-}
-
-func verifyAuthConstraint(expected *bool) error {
- if expected != nil && *expected != testContext.authEnabled {
- return fmt.Errorf("test requires auth value: %v, cluster auth value: %v", *expected, testContext.authEnabled)
- }
- return nil
-}
-
-func verifyServerlessConstraint(expected string) error {
- switch expected {
- case "require":
- if !testContext.serverless {
- return fmt.Errorf("test requires serverless")
- }
- case "forbid":
- if testContext.serverless {
- return fmt.Errorf("test forbids serverless")
- }
- case "allow", "":
- default:
- return fmt.Errorf("invalid value for serverless: %s", expected)
- }
- return nil
-}
-
-// verifyRunOnBlockConstraint returns an error if the current environment does not match the provided RunOnBlock.
-func verifyRunOnBlockConstraint(rob RunOnBlock) error {
- if err := verifyVersionConstraints(rob.MinServerVersion, rob.MaxServerVersion); err != nil {
- return err
- }
- if err := verifyTopologyConstraints(rob.Topology); err != nil {
- return err
- }
-
- // Tests in the unified test format have runOn.auth to indicate whether the
- // test should be run against an auth-enabled configuration. SDAM integration
- // spec tests have runOn.authEnabled to indicate the same thing. Use whichever
- // is set for verifyAuthConstraint().
- auth := rob.Auth
- if rob.AuthEnabled != nil {
- if auth != nil {
- return fmt.Errorf("runOnBlock cannot specify both auth and authEnabled")
- }
- auth = rob.AuthEnabled
- }
- if err := verifyAuthConstraint(auth); err != nil {
- return err
- }
-
- if err := verifyServerlessConstraint(rob.Serverless); err != nil {
- return err
- }
- if err := verifyServerParametersConstraints(rob.ServerParameters); err != nil {
- return err
- }
-
- if rob.CSFLE != nil {
- if *rob.CSFLE && !IsCSFLEEnabled() {
- return fmt.Errorf("runOnBlock requires CSFLE to be enabled. Build with the cse tag to enable")
- } else if !*rob.CSFLE && IsCSFLEEnabled() {
- return fmt.Errorf("runOnBlock requires CSFLE to be disabled. Build without the cse tag to disable")
- }
- if *rob.CSFLE {
- if err := verifyVersionConstraints("4.2", ""); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-// verifyConstraints returns an error if the current environment does not match the constraints specified for the test.
-func (t *T) verifyConstraints() error {
- // Check constraints not specified as runOn blocks
- if err := verifyVersionConstraints(t.minServerVersion, t.maxServerVersion); err != nil {
- return err
- }
- if err := verifyTopologyConstraints(t.validTopologies); err != nil {
- return err
- }
- if err := verifyAuthConstraint(t.auth); err != nil {
- return err
- }
- if t.ssl != nil && *t.ssl != testContext.sslEnabled {
- return fmt.Errorf("test requires ssl value: %v, cluster ssl value: %v", *t.ssl, testContext.sslEnabled)
- }
- if t.enterprise != nil && *t.enterprise != testContext.enterpriseServer {
- return fmt.Errorf("test requires enterprise value: %v, cluster enterprise value: %v", *t.enterprise,
- testContext.enterpriseServer)
- }
- if t.dataLake != nil && *t.dataLake != testContext.dataLake {
- return fmt.Errorf("test requires cluster to be data lake: %v, cluster is data lake: %v", *t.dataLake,
- testContext.dataLake)
- }
- if t.requireAPIVersion != nil && *t.requireAPIVersion != testContext.requireAPIVersion {
- return fmt.Errorf("test requires RequireAPIVersion value: %v, local RequireAPIVersion value: %v", *t.requireAPIVersion,
- testContext.requireAPIVersion)
- }
-
- // Check runOn blocks. The test can be executed if there are no blocks or at least block matches the current test
- // setup.
- if len(t.runOn) == 0 {
- return nil
- }
-
- // Stop once we find a RunOnBlock that matches the current environment. Record all errors as we go because if we
- // don't find any matching blocks, we want to report the comparison errors for each block.
- runOnErrors := make([]error, 0, len(t.runOn))
- for _, runOn := range t.runOn {
- err := verifyRunOnBlockConstraint(runOn)
- if err == nil {
- return nil
- }
-
- runOnErrors = append(runOnErrors, err)
- }
- return fmt.Errorf("no matching RunOnBlock; comparison errors: %v", runOnErrors)
-}
-
-func (t *T) interfaceToInt32(i interface{}) (int32, error) {
- switch conv := i.(type) {
- case int:
- return int32(conv), nil
- case int32:
- return conv, nil
- case int64:
- return int32(conv), nil
- case float64:
- return int32(conv), nil
- }
-
- return 0, fmt.Errorf("type %T cannot be converted to int32", i)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/opmsg_deployment.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/opmsg_deployment.go
deleted file mode 100644
index 2ddc23c41..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/opmsg_deployment.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// 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 mtest
-
-import (
- "context"
- "errors"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
-)
-
-const (
- serverAddress = address.Address("127.0.0.1:27017")
- maxDocumentSize uint32 = 16777216
- maxMessageSize uint32 = 48000000
- maxBatchCount uint32 = 100000
-)
-
-var (
- sessionTimeoutMinutes uint32 = 30
- sessionTimeoutMinutesInt64 = int64(sessionTimeoutMinutes)
-
- // MockDescription is the server description used for the mock deployment. Each mocked connection returns this
- // value from its Description method.
- MockDescription = description.Server{
- CanonicalAddr: serverAddress,
- MaxDocumentSize: maxDocumentSize,
- MaxMessageSize: maxMessageSize,
- MaxBatchCount: maxBatchCount,
- // TODO(GODRIVER-2885): This can be removed once legacy
- // SessionTimeoutMinutes is removed.
- SessionTimeoutMinutes: sessionTimeoutMinutes,
- SessionTimeoutMinutesPtr: &sessionTimeoutMinutesInt64,
- Kind: description.RSPrimary,
- WireVersion: &description.VersionRange{
- Max: topology.SupportedWireVersions.Max,
- },
- }
-)
-
-// connection implements the driver.Connection interface and responds to wire messages with pre-configured responses.
-type connection struct {
- responses []bson.D // responses to send when ReadWireMessage is called
-}
-
-var _ driver.Connection = &connection{}
-
-// WriteWireMessage is a no-op.
-func (c *connection) WriteWireMessage(context.Context, []byte) error {
- return nil
-}
-
-func (c *connection) OIDCTokenGenID() uint64 {
- return 0
-}
-
-func (c *connection) SetOIDCTokenGenID(uint64) {
-}
-
-// ReadWireMessage returns the next response in the connection's list of responses.
-func (c *connection) ReadWireMessage(_ context.Context) ([]byte, error) {
- var dst []byte
- if len(c.responses) == 0 {
- return dst, errors.New("no responses remaining")
- }
- nextRes := c.responses[0]
- c.responses = c.responses[1:]
-
- var wmindex int32
- wmindex, dst = wiremessage.AppendHeaderStart(dst, wiremessage.NextRequestID(), 0, wiremessage.OpMsg)
- dst = wiremessage.AppendMsgFlags(dst, 0)
- dst = wiremessage.AppendMsgSectionType(dst, wiremessage.SingleDocument)
- resBytes, _ := bson.Marshal(nextRes)
- dst = append(dst, resBytes...)
- dst = bsoncore.UpdateLength(dst, wmindex, int32(len(dst[wmindex:])))
- return dst, nil
-}
-
-// Description returns a fixed server description for the connection.
-func (c *connection) Description() description.Server {
- return MockDescription
-}
-
-// Close is a no-op operation.
-func (*connection) Close() error {
- return nil
-}
-
-// ID returns a fixed identifier for the connection.
-func (*connection) ID() string {
- return ""
-}
-
-// DriverConnectionID returns a fixed identifier for the driver pool connection.
-// TODO(GODRIVER-2824): replace return type with int64.
-func (*connection) DriverConnectionID() uint64 {
- return 0
-}
-
-// ServerConnectionID returns a fixed identifier for the server connection.
-func (*connection) ServerConnectionID() *int64 {
- serverConnectionID := int64(42)
- return &serverConnectionID
-}
-
-// Address returns a fixed address for the connection.
-func (*connection) Address() address.Address {
- return serverAddress
-}
-
-// Stale returns if the connection is stale.
-func (*connection) Stale() bool {
- return false
-}
-
-// mockDeployment wraps a connection and implements the driver.Deployment interface.
-type mockDeployment struct {
- conn *connection
- updates chan description.Topology
-}
-
-var _ driver.Deployment = &mockDeployment{}
-var _ driver.Server = &mockDeployment{}
-var _ driver.Connector = &mockDeployment{}
-var _ driver.Disconnector = &mockDeployment{}
-var _ driver.Subscriber = &mockDeployment{}
-
-// SelectServer implements the Deployment interface. This method does not use the
-// description.SelectedServer provided and instead returns itself. The Connections returned from the
-// Connection method have a no-op Close method.
-func (md *mockDeployment) SelectServer(context.Context, description.ServerSelector) (driver.Server, error) {
- return md, nil
-}
-
-// Kind implements the Deployment interface. It always returns description.Single.
-func (md *mockDeployment) Kind() description.TopologyKind {
- return description.Single
-}
-
-// Connection implements the driver.Server interface.
-func (md *mockDeployment) Connection(context.Context) (driver.Connection, error) {
- return md.conn, nil
-}
-
-// RTTMonitor implements the driver.Server interface.
-func (md *mockDeployment) RTTMonitor() driver.RTTMonitor {
- return &csot.ZeroRTTMonitor{}
-}
-
-// Connect is a no-op method which implements the driver.Connector interface.
-func (md *mockDeployment) Connect() error {
- return nil
-}
-
-// Disconnect is a no-op method which implements the driver.Disconnector interface {
-func (md *mockDeployment) Disconnect(context.Context) error {
- close(md.updates)
- return nil
-}
-
-// Subscribe returns a subscription from which new topology descriptions can be retrieved.
-// Subscribe implements the driver.Subscriber interface.
-func (md *mockDeployment) Subscribe() (*driver.Subscription, error) {
- if md.updates == nil {
- md.updates = make(chan description.Topology, 1)
-
- md.updates <- description.Topology{
- SessionTimeoutMinutesPtr: &sessionTimeoutMinutesInt64,
-
- // TODO(GODRIVER-2885): This can be removed once legacy
- // SessionTimeoutMinutes is removed.
- SessionTimeoutMinutes: sessionTimeoutMinutes,
- }
- }
-
- return &driver.Subscription{
- Updates: md.updates,
- }, nil
-}
-
-// Unsubscribe is a no-op method which implements the driver.Subscriber interface.
-func (md *mockDeployment) Unsubscribe(*driver.Subscription) error {
- return nil
-}
-
-// addResponses adds responses to this mock deployment.
-func (md *mockDeployment) addResponses(responses ...bson.D) {
- md.conn.responses = append(md.conn.responses, responses...)
-}
-
-// clearResponses clears all remaining responses in this mock deployment.
-func (md *mockDeployment) clearResponses() {
- md.conn.responses = md.conn.responses[:0]
-}
-
-// newMockDeployment returns a mock driver.Deployment that responds with OP_MSG wire messages.
-func newMockDeployment(responses ...bson.D) *mockDeployment {
- return &mockDeployment{
- conn: &connection{
- responses: responses,
- },
- }
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/options.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/options.go
deleted file mode 100644
index 0f103f7cd..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/options.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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 mtest
-
-import (
- "errors"
- "fmt"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo/options"
-)
-
-// TopologyKind describes the topology that a test is run on.
-type TopologyKind string
-
-// These constants specify valid values for TopologyKind
-const (
- ReplicaSet TopologyKind = "replicaset"
- Sharded TopologyKind = "sharded"
- Single TopologyKind = "single"
- LoadBalanced TopologyKind = "load-balanced"
- // ShardedReplicaSet is a special case of sharded that requires each shard to be a replica set rather than a
- // standalone server.
- ShardedReplicaSet TopologyKind = "sharded-replicaset"
-)
-
-// ClientType specifies the type of Client that should be created for a test.
-type ClientType int
-
-// These constants specify valid values for ClientType
-const (
- // Default specifies a client to the connection string in the MONGODB_URI env variable with command monitoring
- // enabled.
- Default ClientType = iota
- // Pinned specifies a client that is pinned to a single mongos in a sharded cluster.
- Pinned
- // Mock specifies a client that communicates with a mock deployment.
- Mock
- // Proxy specifies a client that proxies messages to the server and also stores parsed copies. The proxied
- // messages can be retrieved via T.GetProxiedMessages or T.GetRawProxiedMessages.
- Proxy
-)
-
-var (
- falseBool = false
-)
-
-// RunOnBlock describes a constraint for a test.
-type RunOnBlock struct {
- MinServerVersion string `bson:"minServerVersion"`
- MaxServerVersion string `bson:"maxServerVersion"`
- Topology []TopologyKind `bson:"topology"`
- Serverless string `bson:"serverless"`
- ServerParameters map[string]bson.RawValue `bson:"serverParameters"`
- Auth *bool `bson:"auth"`
- AuthEnabled *bool `bson:"authEnabled"`
- CSFLE *bool `bson:"csfle"`
-}
-
-// UnmarshalBSON implements custom BSON unmarshalling behavior for RunOnBlock because some test formats use the
-// "topology" key while the unified test format uses "topologies".
-func (r *RunOnBlock) UnmarshalBSON(data []byte) error {
- var temp struct {
- MinServerVersion string `bson:"minServerVersion"`
- MaxServerVersion string `bson:"maxServerVersion"`
- Topology []TopologyKind `bson:"topology"`
- Topologies []TopologyKind `bson:"topologies"`
- Serverless string `bson:"serverless"`
- ServerParameters map[string]bson.RawValue `bson:"serverParameters"`
- Auth *bool `bson:"auth"`
- AuthEnabled *bool `bson:"authEnabled"`
- CSFLE *bool `bson:"csfle"`
- Extra map[string]interface{} `bson:",inline"`
- }
- if err := bson.Unmarshal(data, &temp); err != nil {
- return fmt.Errorf("error unmarshalling to temporary RunOnBlock object: %w", err)
- }
- if len(temp.Extra) > 0 {
- return fmt.Errorf("unrecognized fields for RunOnBlock: %v", temp.Extra)
- }
-
- r.MinServerVersion = temp.MinServerVersion
- r.MaxServerVersion = temp.MaxServerVersion
- r.Serverless = temp.Serverless
- r.ServerParameters = temp.ServerParameters
- r.Auth = temp.Auth
- r.AuthEnabled = temp.AuthEnabled
- r.CSFLE = temp.CSFLE
-
- if temp.Topology != nil {
- r.Topology = temp.Topology
- }
- if temp.Topologies != nil {
- if r.Topology != nil {
- return errors.New("both 'topology' and 'topologies' keys cannot be specified for a RunOnBlock")
- }
-
- r.Topology = temp.Topologies
- }
- return nil
-}
-
-// optionFunc is a function type that configures a T instance.
-type optionFunc func(*T)
-
-// Options is the type used to configure a new T instance.
-type Options struct {
- optFuncs []optionFunc
-}
-
-// NewOptions creates an empty Options instance.
-func NewOptions() *Options {
- return &Options{}
-}
-
-// CollectionCreateOptions sets the options to pass to Database.CreateCollection() when creating a collection for a test.
-func (op *Options) CollectionCreateOptions(opts *options.CreateCollectionOptions) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.collCreateOpts = opts
- })
- return op
-}
-
-// CollectionOptions sets the options to use when creating a collection for a test.
-func (op *Options) CollectionOptions(opts *options.CollectionOptions) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.collOpts = opts
- })
- return op
-}
-
-// ClientOptions sets the options to use when creating a client for a test.
-func (op *Options) ClientOptions(opts *options.ClientOptions) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.clientOpts = opts
- })
- return op
-}
-
-// CreateClient specifies whether or not a client should be created for a test. This should be set to false when running
-// a test that only runs other tests.
-func (op *Options) CreateClient(create bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.createClient = &create
- })
- return op
-}
-
-// CreateCollection specifies whether or not a collection should be created for a test. The default value is true.
-func (op *Options) CreateCollection(create bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.createCollection = &create
- })
- return op
-}
-
-// ShareClient specifies whether or not a test should pass its client down to sub-tests. This should be set when calling
-// New() if the inheriting behavior is desired. This option must not be used if the test accesses command monitoring
-// events.
-func (op *Options) ShareClient(share bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.shareClient = &share
- })
- return op
-}
-
-// CollectionName specifies the name for the collection for the test.
-func (op *Options) CollectionName(collName string) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.collName = collName
- })
- return op
-}
-
-// DatabaseName specifies the name of the database for the test.
-func (op *Options) DatabaseName(dbName string) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.dbName = dbName
- })
- return op
-}
-
-// ClientType specifies the type of client that should be created for a test. This option will be propagated to all
-// sub-tests. If the provided ClientType is Proxy, the SSL(false) option will be also be added because the internal
-// proxy dialer and connection types do not support SSL.
-func (op *Options) ClientType(ct ClientType) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.clientType = ct
-
- if ct == Proxy {
- t.ssl = &falseBool
- }
- })
- return op
-}
-
-// MockResponses specifies the responses returned by a mock deployment. This should only be used if the current test
-// is being run with MockDeployment(true). Responses can also be added after a sub-test has already been created.
-func (op *Options) MockResponses(responses ...bson.D) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.mockResponses = responses
- })
- return op
-}
-
-// RunOn specifies run-on blocks used to determine if a test should run. If a test's environment meets at least one of the
-// given constraints, it will be run. Otherwise, it will be skipped.
-func (op *Options) RunOn(blocks ...RunOnBlock) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.runOn = append(t.runOn, blocks...)
- })
- return op
-}
-
-// MinServerVersion specifies the minimum server version for the test.
-func (op *Options) MinServerVersion(version string) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.minServerVersion = version
- })
- return op
-}
-
-// MaxServerVersion specifies the maximum server version for the test.
-func (op *Options) MaxServerVersion(version string) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.maxServerVersion = version
- })
- return op
-}
-
-// Topologies specifies a list of topologies that the test can run on.
-func (op *Options) Topologies(topos ...TopologyKind) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.validTopologies = topos
- })
- return op
-}
-
-// Auth specifies whether or not auth should be enabled for this test to run. By default, a test will run regardless
-// of whether or not auth is enabled.
-func (op *Options) Auth(auth bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.auth = &auth
- })
- return op
-}
-
-// SSL specifies whether or not SSL should be enabled for this test to run. By default, a test will run regardless
-// of whether or not SSL is enabled.
-func (op *Options) SSL(ssl bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.ssl = &ssl
- })
- return op
-}
-
-// Enterprise specifies whether or not this test should only be run on enterprise server variants. Defaults to false.
-func (op *Options) Enterprise(ent bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.enterprise = &ent
- })
- return op
-}
-
-// AtlasDataLake specifies whether this test should only be run against Atlas Data Lake servers. Defaults to false.
-func (op *Options) AtlasDataLake(adl bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.dataLake = &adl
- })
- return op
-}
-
-// RequireAPIVersion specifies whether this test should only be run when REQUIRE_API_VERSION is true. Defaults to false.
-func (op *Options) RequireAPIVersion(rav bool) *Options {
- op.optFuncs = append(op.optFuncs, func(t *T) {
- t.requireAPIVersion = &rav
- })
- return op
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/proxy_dialer.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/proxy_dialer.go
deleted file mode 100644
index c8e9e6d45..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/proxy_dialer.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// 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 mtest
-
-import (
- "context"
- "errors"
- "fmt"
- "net"
- "sync"
- "time"
-
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
-
-// ProxyMessage represents a sent/received pair of parsed wire messages.
-type ProxyMessage struct {
- ServerAddress string
- CommandName string
- Sent *SentMessage
- Received *ReceivedMessage
-}
-
-// proxyDialer is a ContextDialer implementation that wraps a net.Dialer and records the messages sent and received
-// using connections created through it.
-type proxyDialer struct {
- *net.Dialer
- sync.Mutex
-
- messages []*ProxyMessage
- // sentMap temporarily stores the message sent to the server using the requestID so it can map requests to their
- // responses.
- sentMap sync.Map
- // addressTranslations maps dialed addresses to the remote addresses reported by the created connections if they
- // differ. This can happen if a connection is dialed to a host name, in which case the reported remote address will
- // be the resolved IP address.
- addressTranslations sync.Map
-}
-
-var _ options.ContextDialer = (*proxyDialer)(nil)
-
-func newProxyDialer() *proxyDialer {
- return &proxyDialer{
- Dialer: &net.Dialer{Timeout: 30 * time.Second},
- }
-}
-
-func newProxyErrorWithWireMsg(wm []byte, err error) error {
- return fmt.Errorf("proxy error for wiremessage %v: %w", wm, err)
-}
-
-// DialContext creates a new proxyConnection.
-func (p *proxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
- netConn, err := p.Dialer.DialContext(ctx, network, address)
- if err != nil {
- return netConn, err
- }
-
- // If the connection's remote address does not match the dialed address, store it in the translations map for
- // future look-up. Use the remote address as they key because that's what we'll have access to in the connection's
- // Read/Write functions.
- if remoteAddress := netConn.RemoteAddr().String(); remoteAddress != address {
- p.addressTranslations.Store(remoteAddress, address)
- }
-
- proxy := &proxyConn{
- Conn: netConn,
- dialer: p,
- }
- return proxy, nil
-}
-
-func (p *proxyDialer) storeSentMessage(wm []byte) error {
- p.Lock()
- defer p.Unlock()
-
- // Create a copy of the wire message so it can be parsed/stored and will not be affected if the wm slice is
- // changed by the driver.
- wmCopy := copyBytes(wm)
- parsed, err := parseSentMessage(wmCopy)
- if err != nil {
- return err
- }
- p.sentMap.Store(parsed.RequestID, parsed)
- return nil
-}
-
-func (p *proxyDialer) storeReceivedMessage(wm []byte, addr string) error {
- p.Lock()
- defer p.Unlock()
-
- serverAddress := addr
- if translated, ok := p.addressTranslations.Load(addr); ok {
- serverAddress = translated.(string)
- }
-
- // Create a copy of the wire message so it can be parsed/stored and will not be affected if the wm slice is
- // changed by the driver. Parse the incoming message and get the corresponding outgoing message.
- wmCopy := copyBytes(wm)
- parsed, err := parseReceivedMessage(wmCopy)
- if err != nil {
- return err
- }
- mapValue, ok := p.sentMap.Load(parsed.ResponseTo)
- if !ok {
- return errors.New("no sent message found")
- }
- sent := mapValue.(*SentMessage)
- p.sentMap.Delete(parsed.ResponseTo)
-
- // Store the parsed message pair.
- msgPair := &ProxyMessage{
- // The command name is always the first key in the command document.
- CommandName: sent.Command.Index(0).Key(),
- ServerAddress: serverAddress,
- Sent: sent,
- Received: parsed,
- }
- p.messages = append(p.messages, msgPair)
- return nil
-}
-
-// Messages returns a slice of proxied messages. This slice is a copy of the messages proxied so far and will not be
-// updated for messages proxied after this call.
-func (p *proxyDialer) Messages() []*ProxyMessage {
- p.Lock()
- defer p.Unlock()
-
- copiedMessages := make([]*ProxyMessage, len(p.messages))
- copy(copiedMessages, p.messages)
- return copiedMessages
-}
-
-// proxyConn is a net.Conn that wraps a network connection. All messages sent/received through a proxyConn are stored
-// in the associated proxyDialer and are forwarded over the wrapped connection. Errors encountered when parsing and
-// storing wire messages are wrapped to add context, while errors returned from the underlying network connection are
-// forwarded without wrapping.
-type proxyConn struct {
- net.Conn
- dialer *proxyDialer
-}
-
-// Write stores the given message in the proxyDialer associated with this connection and forwards the message to the
-// server.
-func (pc *proxyConn) Write(wm []byte) (n int, err error) {
- if err := pc.dialer.storeSentMessage(wm); err != nil {
- wrapped := fmt.Errorf("error storing sent message: %w", err)
- return 0, newProxyErrorWithWireMsg(wm, wrapped)
- }
-
- return pc.Conn.Write(wm)
-}
-
-// Read reads the message from the server into the given buffer and stores the read message in the proxyDialer
-// associated with this connection.
-func (pc *proxyConn) Read(buffer []byte) (int, error) {
- n, err := pc.Conn.Read(buffer)
- if err != nil {
- return n, err
- }
-
- // The driver reads wire messages in two phases: a four-byte read to get the length of the incoming wire message
- // and a (length-4) byte read to get the message itself. There's nothing to be stored during the initial four-byte
- // read because we can calculate the length from the rest of the message.
- if len(buffer) == 4 {
- return 4, nil
- }
-
- // The buffer contains the entire wire message except for the length bytes. Re-create the full message by appending
- // buffer to the end of a four-byte slice and using UpdateLength to set the length bytes.
- idx, wm := bsoncore.ReserveLength(nil)
- wm = append(wm, buffer...)
- wm = bsoncore.UpdateLength(wm, idx, int32(len(wm[idx:])))
-
- if err := pc.dialer.storeReceivedMessage(wm, pc.RemoteAddr().String()); err != nil {
- wrapped := fmt.Errorf("error storing received message: %w", err)
- return 0, newProxyErrorWithWireMsg(wm, wrapped)
- }
-
- return n, nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/received_message.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/received_message.go
deleted file mode 100644
index 2e2f95224..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/received_message.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// 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 mtest
-
-import (
- "errors"
- "fmt"
-
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
-)
-
-// ReceivedMessage represents a message received from the server.
-type ReceivedMessage struct {
- ResponseTo int32
- RawMessage wiremessage.WireMessage
- Response bsoncore.Document
-}
-
-type receivedMsgParseFn func([]byte) (*ReceivedMessage, error)
-
-func getReceivedMessageParser(opcode wiremessage.OpCode) (receivedMsgParseFn, bool) {
- switch opcode {
- case wiremessage.OpReply:
- return parseOpReply, true
- case wiremessage.OpMsg:
- return parseReceivedOpMsg, true
- case wiremessage.OpCompressed:
- return parseReceivedOpCompressed, true
- default:
- return nil, false
- }
-}
-
-func parseReceivedMessage(wm []byte) (*ReceivedMessage, error) {
- // Re-assign the wire message to "remaining" so "wm" continues to point to the entire message after parsing.
- _, _, responseTo, opcode, remaining, ok := wiremessage.ReadHeader(wm)
- if !ok {
- return nil, errors.New("failed to read wiremessage header")
- }
-
- parseFn, ok := getReceivedMessageParser(opcode)
- if !ok {
- return nil, fmt.Errorf("unknown opcode: %s", opcode)
- }
- received, err := parseFn(remaining)
- if err != nil {
- return nil, fmt.Errorf("error parsing wiremessage with opcode %s: %w", opcode, err)
- }
-
- received.ResponseTo = responseTo
- received.RawMessage = wm
- return received, nil
-}
-
-func parseOpReply(wm []byte) (*ReceivedMessage, error) {
- var ok bool
-
- if _, wm, ok = wiremessage.ReadReplyFlags(wm); !ok {
- return nil, errors.New("failed to read reply flags")
- }
- if _, wm, ok = wiremessage.ReadReplyCursorID(wm); !ok {
- return nil, errors.New("failed to read cursor ID")
- }
- if _, wm, ok = wiremessage.ReadReplyStartingFrom(wm); !ok {
- return nil, errors.New("failed to read starting from")
- }
- if _, wm, ok = wiremessage.ReadReplyNumberReturned(wm); !ok {
- return nil, errors.New("failed to read number returned")
- }
-
- var replyDocuments []bsoncore.Document
- replyDocuments, wm, ok = wiremessage.ReadReplyDocuments(wm)
- if !ok {
- return nil, errors.New("failed to read reply documents")
- }
- if len(replyDocuments) == 0 {
- return nil, errors.New("no documents in response")
- }
-
- rm := &ReceivedMessage{
- Response: replyDocuments[0],
- }
- return rm, nil
-}
-
-func parseReceivedOpMsg(wm []byte) (*ReceivedMessage, error) {
- var ok bool
- var err error
-
- if _, wm, ok = wiremessage.ReadMsgFlags(wm); !ok {
- return nil, errors.New("failed to read flags")
- }
-
- if wm, err = assertMsgSectionType(wm, wiremessage.SingleDocument); err != nil {
- return nil, fmt.Errorf("error verifying section type for response document: %w", err)
- }
-
- response, wm, ok := wiremessage.ReadMsgSectionSingleDocument(wm)
- if !ok {
- return nil, errors.New("failed to read response document")
- }
- rm := &ReceivedMessage{
- Response: response,
- }
- return rm, nil
-}
-
-func parseReceivedOpCompressed(wm []byte) (*ReceivedMessage, error) {
- originalOpcode, wm, err := parseOpCompressed(wm)
- if err != nil {
- return nil, err
- }
-
- parser, ok := getReceivedMessageParser(originalOpcode)
- if !ok {
- return nil, fmt.Errorf("unknown original opcode %v", originalOpcode)
- }
- return parser(wm)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/sent_message.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/sent_message.go
deleted file mode 100644
index 94eed1225..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/sent_message.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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 mtest
-
-import (
- "errors"
- "fmt"
-
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
-)
-
-// SentMessage represents a message sent by the driver to the server.
-type SentMessage struct {
- RequestID int32
- RawMessage wiremessage.WireMessage
- Command bsoncore.Document
- OpCode wiremessage.OpCode
-
- // The $readPreference document. This is separated into its own field even though it's included in the larger
- // command document in both OP_QUERY and OP_MSG because OP_QUERY separates the command into a $query sub-document
- // if there is a read preference. To unify OP_QUERY and OP_MSG, we pull this out into a separate field and set
- // the Command field to the $query sub-document.
- ReadPreference bsoncore.Document
-
- // The documents sent for an insert, update, or delete command. This is separated into its own field because it's
- // sent as part of the command document in OP_QUERY and as a document sequence outside the command document in
- // OP_MSG.
- DocumentSequence *bsoncore.DocumentSequence
-}
-
-type sentMsgParseFn func([]byte) (*SentMessage, error)
-
-func getSentMessageParser(opcode wiremessage.OpCode) (sentMsgParseFn, bool) {
- switch opcode {
- case wiremessage.OpQuery:
- return parseOpQuery, true
- case wiremessage.OpMsg:
- return parseSentOpMsg, true
- case wiremessage.OpCompressed:
- return parseSentOpCompressed, true
- default:
- return nil, false
- }
-}
-
-func parseOpQuery(wm []byte) (*SentMessage, error) {
- var ok bool
-
- if _, wm, ok = wiremessage.ReadQueryFlags(wm); !ok {
- return nil, errors.New("failed to read query flags")
- }
- if _, wm, ok = wiremessage.ReadQueryFullCollectionName(wm); !ok {
- return nil, errors.New("failed to read full collection name")
- }
- if _, wm, ok = wiremessage.ReadQueryNumberToSkip(wm); !ok {
- return nil, errors.New("failed to read number to skip")
- }
- if _, wm, ok = wiremessage.ReadQueryNumberToReturn(wm); !ok {
- return nil, errors.New("failed to read number to return")
- }
-
- query, wm, ok := wiremessage.ReadQueryQuery(wm)
- if !ok {
- return nil, errors.New("failed to read query")
- }
-
- // If there is no read preference document, the command document is query.
- // Otherwise, query is in the format {$query: , $readPreference: }.
- commandDoc := query
- var rpDoc bsoncore.Document
-
- dollarQueryVal, err := query.LookupErr("$query")
- if err == nil {
- commandDoc = dollarQueryVal.Document()
-
- rpVal, err := query.LookupErr("$readPreference")
- if err != nil {
- return nil, fmt.Errorf("query %s contains $query but not $readPreference fields", query)
- }
- rpDoc = rpVal.Document()
- }
-
- // For OP_QUERY, inserts, updates, and deletes are sent as a BSON array of documents inside the main command
- // document. Pull these sequences out into an ArrayStyle DocumentSequence.
- var docSequence *bsoncore.DocumentSequence
- cmdElems, _ := commandDoc.Elements()
- for _, elem := range cmdElems {
- switch elem.Key() {
- case "documents", "updates", "deletes":
- docSequence = &bsoncore.DocumentSequence{
- Style: bsoncore.ArrayStyle,
- Data: elem.Value().Array(),
- }
- }
- if docSequence != nil {
- // There can only be one of these arrays in a well-formed command, so we exit the loop once one is found.
- break
- }
- }
-
- sm := &SentMessage{
- Command: commandDoc,
- ReadPreference: rpDoc,
- DocumentSequence: docSequence,
- }
- return sm, nil
-}
-
-func parseSentMessage(wm []byte) (*SentMessage, error) {
- // Re-assign the wire message to "remaining" so "wm" continues to point to the entire message after parsing.
- _, requestID, _, opcode, remaining, ok := wiremessage.ReadHeader(wm)
- if !ok {
- return nil, errors.New("failed to read wiremessage header")
- }
-
- parseFn, ok := getSentMessageParser(opcode)
- if !ok {
- return nil, fmt.Errorf("unknown opcode: %v", opcode)
- }
- sent, err := parseFn(remaining)
- if err != nil {
- return nil, fmt.Errorf("error parsing wiremessage with opcode %s: %w", opcode, err)
- }
-
- sent.RequestID = requestID
- sent.RawMessage = wm
- sent.OpCode = opcode
- return sent, nil
-}
-
-func parseSentOpMsg(wm []byte) (*SentMessage, error) {
- var ok bool
- var err error
-
- if _, wm, ok = wiremessage.ReadMsgFlags(wm); !ok {
- return nil, errors.New("failed to read flags")
- }
-
- if wm, err = assertMsgSectionType(wm, wiremessage.SingleDocument); err != nil {
- return nil, fmt.Errorf("error verifying section type for command document: %w", err)
- }
-
- var commandDoc bsoncore.Document
- commandDoc, wm, ok = wiremessage.ReadMsgSectionSingleDocument(wm)
- if !ok {
- return nil, errors.New("failed to read command document")
- }
-
- var rpDoc bsoncore.Document
- if rpVal, err := commandDoc.LookupErr("$readPreference"); err == nil {
- rpDoc = rpVal.Document()
- }
-
- var docSequence *bsoncore.DocumentSequence
- if len(wm) != 0 {
- // If there are bytes remaining in the wire message, they must correspond to a DocumentSequence section.
- if wm, err = assertMsgSectionType(wm, wiremessage.DocumentSequence); err != nil {
- return nil, fmt.Errorf("error verifying section type for document sequence: %w", err)
- }
-
- var data []byte
- _, data, wm, ok = wiremessage.ReadMsgSectionRawDocumentSequence(wm)
- if !ok {
- return nil, errors.New("failed to read document sequence")
- }
-
- docSequence = &bsoncore.DocumentSequence{
- Style: bsoncore.SequenceStyle,
- Data: data,
- }
- }
-
- sm := &SentMessage{
- Command: commandDoc,
- ReadPreference: rpDoc,
- DocumentSequence: docSequence,
- }
- return sm, nil
-}
-
-func parseSentOpCompressed(wm []byte) (*SentMessage, error) {
- originalOpcode, wm, err := parseOpCompressed(wm)
- if err != nil {
- return nil, err
- }
-
- parser, ok := getSentMessageParser(originalOpcode)
- if !ok {
- return nil, fmt.Errorf("unknown original opcode %v", originalOpcode)
- }
- return parser(wm)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup.go
deleted file mode 100644
index cdd33219c..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup.go
+++ /dev/null
@@ -1,368 +0,0 @@
-// 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 mtest
-
-import (
- "context"
- "errors"
- "fmt"
- "math"
- "os"
- "strconv"
- "strings"
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/integtest"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
-)
-
-const (
- // TestDb specifies the name of default test database.
- TestDb = "test"
-)
-
-// testContext holds the global context for the integration tests. The testContext members should only be initialized
-// once during the global setup in TestMain. These variables should only be accessed indirectly through MongoTest
-// instances.
-var testContext struct {
- connString *connstring.ConnString
- topo *topology.Topology
- topoKind TopologyKind
- // shardedReplicaSet will be true if we're connected to a sharded cluster and each shard is backed by a replica set.
- // We track this as a separate boolean rather than setting topoKind to ShardedReplicaSet because a general
- // "Sharded" constraint in a test should match both Sharded and ShardedReplicaSet.
- shardedReplicaSet bool
- client *mongo.Client // client used for setup and teardown
- serverVersion string
- authEnabled bool
- sslEnabled bool
- enterpriseServer bool
- dataLake bool
- requireAPIVersion bool
- serverParameters bson.Raw
- singleMongosLoadBalancerURI string
- multiMongosLoadBalancerURI string
- serverless bool
-}
-
-func setupClient(opts *options.ClientOptions) (*mongo.Client, error) {
- wcMajority := writeconcern.New(writeconcern.WMajority())
- // set ServerAPIOptions to latest version if required
- if opts.ServerAPIOptions == nil && testContext.requireAPIVersion {
- opts.SetServerAPIOptions(options.ServerAPI(driver.TestServerAPIVersion))
- }
- // for sharded clusters, pin to one host. Due to how the cache is implemented on 4.0 and 4.2, behavior
- // can be inconsistent when multiple mongoses are used
- return mongo.Connect(context.Background(), opts.SetWriteConcern(wcMajority).SetHosts(opts.Hosts[:1]))
-}
-
-// Setup initializes the current testing context.
-// This function must only be called one time and must be called before any tests run.
-func Setup(setupOpts ...*SetupOptions) error {
- opts := MergeSetupOptions(setupOpts...)
-
- var uri string
- var err error
-
- switch {
- case opts.URI != nil:
- uri = *opts.URI
- default:
- var err error
- uri, err = integtest.MongoDBURI()
- if err != nil {
- return fmt.Errorf("error getting uri: %w", err)
- }
- }
-
- testContext.connString, err = connstring.ParseAndValidate(uri)
- if err != nil {
- return fmt.Errorf("error parsing and validating connstring: %w", err)
- }
-
- testContext.dataLake = os.Getenv("ATLAS_DATA_LAKE_INTEGRATION_TEST") == "true"
- testContext.requireAPIVersion = os.Getenv("REQUIRE_API_VERSION") == "true"
-
- clientOpts := options.Client().ApplyURI(uri)
- integtest.AddTestServerAPIVersion(clientOpts)
-
- cfg, err := topology.NewConfig(clientOpts, nil)
- if err != nil {
- return fmt.Errorf("error constructing topology config: %w", err)
- }
-
- testContext.topo, err = topology.New(cfg)
- if err != nil {
- return fmt.Errorf("error creating topology: %w", err)
- }
- if err = testContext.topo.Connect(); err != nil {
- return fmt.Errorf("error connecting topology: %w", err)
- }
-
- testContext.client, err = setupClient(options.Client().ApplyURI(uri))
- if err != nil {
- return fmt.Errorf("error connecting test client: %w", err)
- }
-
- pingCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
- if err := testContext.client.Ping(pingCtx, readpref.Primary()); err != nil {
- return fmt.Errorf("ping error: %w; make sure the deployment is running on URI %v", err,
- testContext.connString.Original)
- }
-
- if testContext.serverVersion, err = getServerVersion(); err != nil {
- return fmt.Errorf("error getting server version: %w", err)
- }
-
- switch testContext.topo.Kind() {
- case description.Single:
- testContext.topoKind = Single
- case description.ReplicaSet, description.ReplicaSetWithPrimary, description.ReplicaSetNoPrimary:
- testContext.topoKind = ReplicaSet
- case description.Sharded:
- testContext.topoKind = Sharded
- case description.LoadBalanced:
- testContext.topoKind = LoadBalanced
- default:
- return fmt.Errorf("could not detect topology kind; current topology: %s", testContext.topo.String())
- }
-
- // If we're connected to a sharded cluster, determine if the cluster is backed by replica sets.
- if testContext.topoKind == Sharded {
- // Run a find against config.shards and get each document in the collection.
- cursor, err := testContext.client.Database("config").Collection("shards").Find(context.Background(), bson.D{})
- if err != nil {
- return fmt.Errorf("error running find against config.shards: %w", err)
- }
- defer cursor.Close(context.Background())
-
- var shards []struct {
- Host string `bson:"host"`
- }
- if err := cursor.All(context.Background(), &shards); err != nil {
- return fmt.Errorf("error getting results find against config.shards: %w", err)
- }
-
- // Each document's host field will contain a single hostname if the shard is a standalone. If it's a replica
- // set, the host field will be in the format "replicaSetName/host1,host2,...". Therefore, we can determine that
- // the shard is a standalone if the "/" character isn't present.
- var foundStandalone bool
- for _, shard := range shards {
- if !strings.Contains(shard.Host, "/") {
- foundStandalone = true
- break
- }
- }
- if !foundStandalone {
- testContext.shardedReplicaSet = true
- }
- }
-
- // For non-serverless, load balanced clusters, retrieve the required LB URIs and add additional information (e.g. TLS options) to
- // them if necessary.
- testContext.serverless = os.Getenv("SERVERLESS") == "serverless"
- if !testContext.serverless && testContext.topoKind == LoadBalanced {
- singleMongosURI := os.Getenv("SINGLE_MONGOS_LB_URI")
- if singleMongosURI == "" {
- return errors.New("SINGLE_MONGOS_LB_URI must be set when running against load balanced clusters")
- }
- testContext.singleMongosLoadBalancerURI, err = addNecessaryParamsToURI(singleMongosURI)
- if err != nil {
- return fmt.Errorf("error getting single mongos load balancer uri: %w", err)
- }
-
- multiMongosURI := os.Getenv("MULTI_MONGOS_LB_URI")
- if multiMongosURI == "" {
- return errors.New("MULTI_MONGOS_LB_URI must be set when running against load balanced clusters")
- }
- testContext.multiMongosLoadBalancerURI, err = addNecessaryParamsToURI(multiMongosURI)
- if err != nil {
- return fmt.Errorf("error getting multi mongos load balancer uri: %w", err)
- }
- }
-
- testContext.authEnabled = os.Getenv("AUTH") == "auth"
- testContext.sslEnabled = os.Getenv("SSL") == "ssl"
- biRes, err := testContext.client.Database("admin").RunCommand(context.Background(), bson.D{{"buildInfo", 1}}).Raw()
- if err != nil {
- return fmt.Errorf("buildInfo error: %w", err)
- }
- modulesRaw, err := biRes.LookupErr("modules")
- if err == nil {
- // older server versions don't report "modules" field in buildInfo result
- modules, _ := modulesRaw.Array().Values()
- for _, module := range modules {
- if module.StringValue() == "enterprise" {
- testContext.enterpriseServer = true
- break
- }
- }
- }
-
- // Get server parameters if test is not running against ADL; ADL does not have "getParameter" command.
- if !testContext.dataLake {
- db := testContext.client.Database("admin")
- testContext.serverParameters, err = db.RunCommand(context.Background(), bson.D{{"getParameter", "*"}}).Raw()
- if err != nil {
- return fmt.Errorf("error getting serverParameters: %w", err)
- }
- }
- return nil
-}
-
-// Teardown cleans up resources initialized by Setup.
-// This function must be called once after all tests have finished running.
-func Teardown() error {
- // Dropping the test database causes an error against Atlas Data Lake.
- if !testContext.dataLake {
- if err := testContext.client.Database(TestDb).Drop(context.Background()); err != nil {
- return fmt.Errorf("error dropping test database: %w", err)
- }
- }
- if err := testContext.client.Disconnect(context.Background()); err != nil {
- return fmt.Errorf("error disconnecting test client: %w", err)
- }
- if err := testContext.topo.Disconnect(context.Background()); err != nil {
- return fmt.Errorf("error disconnecting test topology: %w", err)
- }
- return nil
-}
-
-func getServerVersion() (string, error) {
- var serverStatus bson.Raw
- err := testContext.client.Database(TestDb).RunCommand(
- context.Background(),
- bson.D{{"buildInfo", 1}},
- ).Decode(&serverStatus)
- if err != nil {
- return "", err
- }
-
- version, err := serverStatus.LookupErr("version")
- if err != nil {
- return "", errors.New("no version string in serverStatus response")
- }
-
- return version.StringValue(), nil
-}
-
-// addOptions appends connection string options to a URI.
-func addOptions(uri string, opts ...string) string {
- if !strings.ContainsRune(uri, '?') {
- if uri[len(uri)-1] != '/' {
- uri += "/"
- }
-
- uri += "?"
- } else {
- uri += "&"
- }
-
- for _, opt := range opts {
- uri += opt
- }
-
- return uri
-}
-
-// addTLSConfig checks for the environmental variable indicating that the tests are being run
-// on an SSL-enabled server, and if so, returns a new URI with the necessary configuration.
-func addTLSConfig(uri string) string {
- if os.Getenv("SSL") == "ssl" {
- uri = addOptions(uri, "ssl=", "true")
- }
- caFile := os.Getenv("MONGO_GO_DRIVER_CA_FILE")
- if len(caFile) == 0 {
- return uri
- }
-
- return addOptions(uri, "sslCertificateAuthorityFile=", caFile)
-}
-
-// addCompressors checks for the environment variable indicating that the tests are being run with compression
-// enabled. If so, it returns a new URI with the necessary configuration
-func addCompressors(uri string) string {
- comp := os.Getenv("MONGO_GO_DRIVER_COMPRESSOR")
- if len(comp) == 0 {
- return uri
- }
-
- return addOptions(uri, "compressors=", comp)
-}
-
-func addServerlessAuthCredentials(uri string) (string, error) {
- if os.Getenv("SERVERLESS") != "serverless" {
- return uri, nil
- }
- user := os.Getenv("SERVERLESS_ATLAS_USER")
- if user == "" {
- return "", fmt.Errorf("serverless expects SERVERLESS_ATLAS_USER to be set")
- }
- password := os.Getenv("SERVERLESS_ATLAS_PASSWORD")
- if password == "" {
- return "", fmt.Errorf("serverless expects SERVERLESS_ATLAS_PASSWORD to be set")
- }
-
- var scheme string
- // remove the scheme
- switch {
- case strings.HasPrefix(uri, "mongodb+srv://"):
- scheme = "mongodb+srv://"
- case strings.HasPrefix(uri, "mongodb://"):
- scheme = "mongodb://"
- default:
- return "", errors.New(`scheme must be "mongodb" or "mongodb+srv"`)
- }
-
- uri = scheme + user + ":" + password + "@" + uri[len(scheme):]
- return uri, nil
-}
-
-func addNecessaryParamsToURI(uri string) (string, error) {
- uri = addTLSConfig(uri)
- uri = addCompressors(uri)
- return addServerlessAuthCredentials(uri)
-}
-
-// CompareServerVersions compares two version number strings (i.e. positive integers separated by
-// periods). Comparisons are done to the lesser precision of the two versions. For example, 3.2 is
-// considered equal to 3.2.11, whereas 3.2.0 is considered less than 3.2.11.
-//
-// Returns a positive int if version1 is greater than version2, a negative int if version1 is less
-// than version2, and 0 if version1 is equal to version2.
-func CompareServerVersions(v1 string, v2 string) int {
- n1 := strings.Split(v1, ".")
- n2 := strings.Split(v2, ".")
-
- for i := 0; i < int(math.Min(float64(len(n1)), float64(len(n2)))); i++ {
- i1, err := strconv.Atoi(n1[i])
- if err != nil {
- return 1
- }
-
- i2, err := strconv.Atoi(n2[i])
- if err != nil {
- return -1
- }
-
- difference := i1 - i2
- if difference != 0 {
- return difference
- }
- }
-
- return 0
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup_options.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup_options.go
deleted file mode 100644
index bd403a731..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/setup_options.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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 mtest
-
-// SetupOptions is the type used to configure mtest setup
-type SetupOptions struct {
- // Specifies the URI to connect to. Defaults to URI based on the environment variables MONGODB_URI,
- // MONGO_GO_DRIVER_CA_FILE, and MONGO_GO_DRIVER_COMPRESSOR
- URI *string
-}
-
-// NewSetupOptions creates an empty SetupOptions struct
-func NewSetupOptions() *SetupOptions {
- return &SetupOptions{}
-}
-
-// SetURI sets the uri to connect to
-func (so *SetupOptions) SetURI(uri string) *SetupOptions {
- so.URI = &uri
- return so
-}
-
-// MergeSetupOptions combines the given *SetupOptions into a single *Options in a last one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeSetupOptions(opts ...*SetupOptions) *SetupOptions {
- op := NewSetupOptions()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.URI != nil {
- op.URI = opt.URI
- }
- }
- return op
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/wiremessage_helpers.go b/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/wiremessage_helpers.go
deleted file mode 100644
index 5fd2bc9fa..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/integration/mtest/wiremessage_helpers.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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 mtest
-
-import (
- "errors"
- "fmt"
-
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
-)
-
-func copyBytes(original []byte) []byte {
- newSlice := make([]byte, len(original))
- copy(newSlice, original)
- return newSlice
-}
-
-// assertMsgSectionType asserts that the next section type in the OP_MSG wire message is equal to the provided type.
-// It returns the remainder of the wire message and an error if the section type could not be read or was not equal
-// to the expected type.
-func assertMsgSectionType(wm []byte, expected wiremessage.SectionType) ([]byte, error) {
- var actual wiremessage.SectionType
- var ok bool
-
- actual, wm, ok = wiremessage.ReadMsgSectionType(wm)
- if !ok {
- return wm, errors.New("failed to read section type")
- }
- if expected != actual {
- return wm, fmt.Errorf("unexpected section type %v; expected %v", actual, expected)
- }
- return wm, nil
-}
-
-func parseOpCompressed(wm []byte) (wiremessage.OpCode, []byte, error) {
- // Store the original opcode to forward to another parser later.
- originalOpcode, wm, ok := wiremessage.ReadCompressedOriginalOpCode(wm)
- if !ok {
- return originalOpcode, nil, errors.New("failed to read original opcode")
- }
-
- uncompressedSize, wm, ok := wiremessage.ReadCompressedUncompressedSize(wm)
- if !ok {
- return originalOpcode, nil, errors.New("failed to read uncompressed size")
- }
-
- compressorID, compressedMsg, ok := wiremessage.ReadCompressedCompressorID(wm)
- if !ok {
- return originalOpcode, nil, errors.New("failed to read compressor ID")
- }
-
- opts := driver.CompressionOpts{
- Compressor: compressorID,
- UncompressedSize: uncompressedSize,
- }
- decompressed, err := driver.DecompressPayload(compressedMsg, opts)
- if err != nil {
- return originalOpcode, nil, fmt.Errorf("error decompressing payload: %w", err)
- }
-
- return originalOpcode, decompressed, nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go
deleted file mode 100644
index 20e1c7043..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// 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 (
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
-)
-
-// AggregateOptions represents options that can be used to configure an Aggregate operation.
-type AggregateOptions struct {
- // If true, the operation can write to temporary files in the _tmp subdirectory of the database directory path on
- // the server. The default value is false.
- AllowDiskUse *bool
-
- // The maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // The maximum amount of time that the server should wait for new documents to satisfy a tailable cursor query.
- // This option is only valid for MongoDB versions >= 3.2 and is ignored for previous server versions.
- MaxAwaitTime *time.Duration
-
- // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation.
- // The default is nil, which means that no comment will be included in the logs.
- Comment *string
-
- // The index to use for the aggregation. This should either be the index name as a string or the index specification
- // as a document. The hint does not apply to $lookup and $graphLookup aggregation stages. The driver will return an
- // error if the hint parameter is a multi-key map. The default value is nil, which means that no hint will be sent.
- Hint interface{}
-
- // Specifies parameters for the aggregate expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // Custom options to be added to aggregate expression. Key-value pairs of the BSON map should correlate with desired
- // option names and values. Values must be Marshalable. Custom options may conflict with non-custom options, and custom
- // options bypass client-side validation. Prefer using non-custom options where possible.
- Custom bson.M
-}
-
-// Aggregate creates a new AggregateOptions instance.
-func Aggregate() *AggregateOptions {
- return &AggregateOptions{}
-}
-
-// SetAllowDiskUse sets the value for the AllowDiskUse field.
-func (ao *AggregateOptions) SetAllowDiskUse(b bool) *AggregateOptions {
- ao.AllowDiskUse = &b
- return ao
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (ao *AggregateOptions) SetBatchSize(i int32) *AggregateOptions {
- ao.BatchSize = &i
- return ao
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (ao *AggregateOptions) SetBypassDocumentValidation(b bool) *AggregateOptions {
- ao.BypassDocumentValidation = &b
- return ao
-}
-
-// SetCollation sets the value for the Collation field.
-func (ao *AggregateOptions) SetCollation(c *Collation) *AggregateOptions {
- ao.Collation = c
- return ao
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (ao *AggregateOptions) SetMaxTime(d time.Duration) *AggregateOptions {
- ao.MaxTime = &d
- return ao
-}
-
-// SetMaxAwaitTime sets the value for the MaxAwaitTime field.
-func (ao *AggregateOptions) SetMaxAwaitTime(d time.Duration) *AggregateOptions {
- ao.MaxAwaitTime = &d
- return ao
-}
-
-// SetComment sets the value for the Comment field.
-func (ao *AggregateOptions) SetComment(s string) *AggregateOptions {
- ao.Comment = &s
- return ao
-}
-
-// SetHint sets the value for the Hint field.
-func (ao *AggregateOptions) SetHint(h interface{}) *AggregateOptions {
- ao.Hint = h
- return ao
-}
-
-// SetLet sets the value for the Let field.
-func (ao *AggregateOptions) SetLet(let interface{}) *AggregateOptions {
- ao.Let = let
- return ao
-}
-
-// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate
-// with desired option names and values. Values must be Marshalable. Custom options may conflict
-// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom
-// options where possible.
-func (ao *AggregateOptions) SetCustom(c bson.M) *AggregateOptions {
- ao.Custom = c
- return ao
-}
-
-// MergeAggregateOptions combines the given AggregateOptions instances into a single AggregateOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeAggregateOptions(opts ...*AggregateOptions) *AggregateOptions {
- aggOpts := Aggregate()
- for _, ao := range opts {
- if ao == nil {
- continue
- }
- if ao.AllowDiskUse != nil {
- aggOpts.AllowDiskUse = ao.AllowDiskUse
- }
- if ao.BatchSize != nil {
- aggOpts.BatchSize = ao.BatchSize
- }
- if ao.BypassDocumentValidation != nil {
- aggOpts.BypassDocumentValidation = ao.BypassDocumentValidation
- }
- if ao.Collation != nil {
- aggOpts.Collation = ao.Collation
- }
- if ao.MaxTime != nil {
- aggOpts.MaxTime = ao.MaxTime
- }
- if ao.MaxAwaitTime != nil {
- aggOpts.MaxAwaitTime = ao.MaxAwaitTime
- }
- if ao.Comment != nil {
- aggOpts.Comment = ao.Comment
- }
- if ao.Hint != nil {
- aggOpts.Hint = ao.Hint
- }
- if ao.Let != nil {
- aggOpts.Let = ao.Let
- }
- if ao.Custom != nil {
- aggOpts.Custom = ao.Custom
- }
- }
-
- return aggOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go
deleted file mode 100644
index 49d7a0f5a..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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
-
-// DefaultOrdered is the default value for the Ordered option in BulkWriteOptions.
-var DefaultOrdered = true
-
-// BulkWriteOptions represents options that can be used to configure a BulkWrite operation.
-type BulkWriteOptions struct {
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // If true, no writes will be executed after one fails. The default value is true.
- Ordered *bool
-
- // Specifies parameters for all update and delete commands in the BulkWrite. This option is only valid for MongoDB
- // versions >= 5.0. Older servers will report an error for using this option. This must be a document mapping
- // parameter names to values. Values must be constant or closed expressions that do not reference document fields.
- // Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// BulkWrite creates a new *BulkWriteOptions instance.
-func BulkWrite() *BulkWriteOptions {
- return &BulkWriteOptions{
- Ordered: &DefaultOrdered,
- }
-}
-
-// SetComment sets the value for the Comment field.
-func (b *BulkWriteOptions) SetComment(comment interface{}) *BulkWriteOptions {
- b.Comment = comment
- return b
-}
-
-// SetOrdered sets the value for the Ordered field.
-func (b *BulkWriteOptions) SetOrdered(ordered bool) *BulkWriteOptions {
- b.Ordered = &ordered
- return b
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (b *BulkWriteOptions) SetBypassDocumentValidation(bypass bool) *BulkWriteOptions {
- b.BypassDocumentValidation = &bypass
- return b
-}
-
-// SetLet sets the value for the Let field. Let specifies parameters for all update and delete commands in the BulkWrite.
-// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using this option.
-// This must be a document mapping parameter names to values. Values must be constant or closed expressions that do not
-// reference document fields. Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var").
-func (b *BulkWriteOptions) SetLet(let interface{}) *BulkWriteOptions {
- b.Let = &let
- return b
-}
-
-// MergeBulkWriteOptions combines the given BulkWriteOptions instances into a single BulkWriteOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeBulkWriteOptions(opts ...*BulkWriteOptions) *BulkWriteOptions {
- b := BulkWrite()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Comment != nil {
- b.Comment = opt.Comment
- }
- if opt.Ordered != nil {
- b.Ordered = opt.Ordered
- }
- if opt.BypassDocumentValidation != nil {
- b.BypassDocumentValidation = opt.BypassDocumentValidation
- }
- if opt.Let != nil {
- b.Let = opt.Let
- }
- if opt.BypassEmptyTsReplacement != nil {
- b.BypassEmptyTsReplacement = opt.BypassEmptyTsReplacement
- }
- }
-
- return b
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go
deleted file mode 100644
index 3d06a668e..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// 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 (
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-// ChangeStreamOptions represents options that can be used to configure a Watch operation.
-type ChangeStreamOptions struct {
- // The maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation.
- // The default is nil, which means that no comment will be included in the logs.
- Comment *string
-
- // Specifies how the updated document should be returned in change notifications for update operations. The default
- // is options.Default, which means that only partial update deltas will be included in the change notification.
- FullDocument *FullDocument
-
- // Specifies how the pre-update document should be returned in change notifications for update operations. The default
- // is options.Off, which means that the pre-update document will not be included in the change notification.
- FullDocumentBeforeChange *FullDocument
-
- // The maximum amount of time that the server should wait for new documents to satisfy a tailable cursor query.
- MaxAwaitTime *time.Duration
-
- // A document specifying the logical starting point for the change stream. Only changes corresponding to an oplog
- // entry immediately after the resume token will be returned. If this is specified, StartAtOperationTime and
- // StartAfter must not be set.
- ResumeAfter interface{}
-
- // ShowExpandedEvents specifies whether the server will return an expanded list of change stream events. Additional
- // events include: createIndexes, dropIndexes, modify, create, shardCollection, reshardCollection and
- // refineCollectionShardKey. This option is only valid for MongoDB versions >= 6.0.
- ShowExpandedEvents *bool
-
- // If specified, the change stream will only return changes that occurred at or after the given timestamp. This
- // option is only valid for MongoDB versions >= 4.0. If this is specified, ResumeAfter and StartAfter must not be
- // set.
- StartAtOperationTime *primitive.Timestamp
-
- // A document specifying the logical starting point for the change stream. This is similar to the ResumeAfter
- // option, but allows a resume token from an "invalidate" notification to be used. This allows a change stream on a
- // collection to be resumed after the collection has been dropped and recreated or renamed. Only changes
- // corresponding to an oplog entry immediately after the specified token will be returned. If this is specified,
- // ResumeAfter and StartAtOperationTime must not be set. This option is only valid for MongoDB versions >= 4.1.1.
- StartAfter interface{}
-
- // Custom options to be added to the initial aggregate for the change stream. Key-value pairs of the BSON map should
- // correlate with desired option names and values. Values must be Marshalable. Custom options may conflict with
- // non-custom options, and custom options bypass client-side validation. Prefer using non-custom options where possible.
- Custom bson.M
-
- // Custom options to be added to the $changeStream stage in the initial aggregate. Key-value pairs of the BSON map should
- // correlate with desired option names and values. Values must be Marshalable. Custom pipeline options bypass client-side
- // validation. Prefer using non-custom options where possible.
- CustomPipeline bson.M
-}
-
-// ChangeStream creates a new ChangeStreamOptions instance.
-func ChangeStream() *ChangeStreamOptions {
- cso := &ChangeStreamOptions{}
- return cso
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (cso *ChangeStreamOptions) SetBatchSize(i int32) *ChangeStreamOptions {
- cso.BatchSize = &i
- return cso
-}
-
-// SetCollation sets the value for the Collation field.
-func (cso *ChangeStreamOptions) SetCollation(c Collation) *ChangeStreamOptions {
- cso.Collation = &c
- return cso
-}
-
-// SetComment sets the value for the Comment field.
-func (cso *ChangeStreamOptions) SetComment(comment string) *ChangeStreamOptions {
- cso.Comment = &comment
- return cso
-}
-
-// SetFullDocument sets the value for the FullDocument field.
-func (cso *ChangeStreamOptions) SetFullDocument(fd FullDocument) *ChangeStreamOptions {
- cso.FullDocument = &fd
- return cso
-}
-
-// SetFullDocumentBeforeChange sets the value for the FullDocumentBeforeChange field.
-func (cso *ChangeStreamOptions) SetFullDocumentBeforeChange(fdbc FullDocument) *ChangeStreamOptions {
- cso.FullDocumentBeforeChange = &fdbc
- return cso
-}
-
-// SetMaxAwaitTime sets the value for the MaxAwaitTime field.
-func (cso *ChangeStreamOptions) SetMaxAwaitTime(d time.Duration) *ChangeStreamOptions {
- cso.MaxAwaitTime = &d
- return cso
-}
-
-// SetResumeAfter sets the value for the ResumeAfter field.
-func (cso *ChangeStreamOptions) SetResumeAfter(rt interface{}) *ChangeStreamOptions {
- cso.ResumeAfter = rt
- return cso
-}
-
-// SetShowExpandedEvents sets the value for the ShowExpandedEvents field.
-func (cso *ChangeStreamOptions) SetShowExpandedEvents(see bool) *ChangeStreamOptions {
- cso.ShowExpandedEvents = &see
- return cso
-}
-
-// SetStartAtOperationTime sets the value for the StartAtOperationTime field.
-func (cso *ChangeStreamOptions) SetStartAtOperationTime(t *primitive.Timestamp) *ChangeStreamOptions {
- cso.StartAtOperationTime = t
- return cso
-}
-
-// SetStartAfter sets the value for the StartAfter field.
-func (cso *ChangeStreamOptions) SetStartAfter(sa interface{}) *ChangeStreamOptions {
- cso.StartAfter = sa
- return cso
-}
-
-// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate
-// with desired option names and values. Values must be Marshalable. Custom options may conflict
-// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom
-// options where possible.
-func (cso *ChangeStreamOptions) SetCustom(c bson.M) *ChangeStreamOptions {
- cso.Custom = c
- return cso
-}
-
-// SetCustomPipeline sets the value for the CustomPipeline field. Key-value pairs of the BSON map
-// should correlate with desired option names and values. Values must be Marshalable. Custom pipeline
-// options bypass client-side validation. Prefer using non-custom options where possible.
-func (cso *ChangeStreamOptions) SetCustomPipeline(cp bson.M) *ChangeStreamOptions {
- cso.CustomPipeline = cp
- return cso
-}
-
-// MergeChangeStreamOptions combines the given ChangeStreamOptions instances into a single ChangeStreamOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeChangeStreamOptions(opts ...*ChangeStreamOptions) *ChangeStreamOptions {
- csOpts := ChangeStream()
- for _, cso := range opts {
- if cso == nil {
- continue
- }
- if cso.BatchSize != nil {
- csOpts.BatchSize = cso.BatchSize
- }
- if cso.Collation != nil {
- csOpts.Collation = cso.Collation
- }
- if cso.Comment != nil {
- csOpts.Comment = cso.Comment
- }
- if cso.FullDocument != nil {
- csOpts.FullDocument = cso.FullDocument
- }
- if cso.FullDocumentBeforeChange != nil {
- csOpts.FullDocumentBeforeChange = cso.FullDocumentBeforeChange
- }
- if cso.MaxAwaitTime != nil {
- csOpts.MaxAwaitTime = cso.MaxAwaitTime
- }
- if cso.ResumeAfter != nil {
- csOpts.ResumeAfter = cso.ResumeAfter
- }
- if cso.ShowExpandedEvents != nil {
- csOpts.ShowExpandedEvents = cso.ShowExpandedEvents
- }
- if cso.StartAtOperationTime != nil {
- csOpts.StartAtOperationTime = cso.StartAtOperationTime
- }
- if cso.StartAfter != nil {
- csOpts.StartAfter = cso.StartAfter
- }
- if cso.Custom != nil {
- csOpts.Custom = cso.Custom
- }
- if cso.CustomPipeline != nil {
- csOpts.CustomPipeline = cso.CustomPipeline
- }
- }
-
- return csOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/collectionoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/collectionoptions.go
deleted file mode 100644
index 7904dbd67..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/collectionoptions.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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 (
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
-)
-
-// CollectionOptions represents options that can be used to configure a Collection.
-type CollectionOptions struct {
- // ReadConcern is the read concern to use for operations executed on the Collection. The default value is nil, which means that
- // the read concern of the Database used to configure the Collection will be used.
- ReadConcern *readconcern.ReadConcern
-
- // WriteConcern is the write concern to use for operations executed on the Collection. The default value is nil, which means that
- // the write concern of the Database used to configure the Collection will be used.
- WriteConcern *writeconcern.WriteConcern
-
- // ReadPreference is the read preference to use for operations executed on the Collection. The default value is nil, which means that
- // the read preference of the Database used to configure the Collection will be used.
- ReadPreference *readpref.ReadPref
-
- // BSONOptions configures optional BSON marshaling and unmarshaling
- // behavior.
- BSONOptions *BSONOptions
-
- // Registry is the BSON registry to marshal and unmarshal documents for operations executed on the Collection. The default value
- // is nil, which means that the registry of the Database used to configure the Collection will be used.
- Registry *bsoncodec.Registry
-}
-
-// Collection creates a new CollectionOptions instance.
-func Collection() *CollectionOptions {
- return &CollectionOptions{}
-}
-
-// SetReadConcern sets the value for the ReadConcern field.
-func (c *CollectionOptions) SetReadConcern(rc *readconcern.ReadConcern) *CollectionOptions {
- c.ReadConcern = rc
- return c
-}
-
-// SetWriteConcern sets the value for the WriteConcern field.
-func (c *CollectionOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *CollectionOptions {
- c.WriteConcern = wc
- return c
-}
-
-// SetReadPreference sets the value for the ReadPreference field.
-func (c *CollectionOptions) SetReadPreference(rp *readpref.ReadPref) *CollectionOptions {
- c.ReadPreference = rp
- return c
-}
-
-// SetBSONOptions configures optional BSON marshaling and unmarshaling behavior.
-func (c *CollectionOptions) SetBSONOptions(opts *BSONOptions) *CollectionOptions {
- c.BSONOptions = opts
- return c
-}
-
-// SetRegistry sets the value for the Registry field.
-func (c *CollectionOptions) SetRegistry(r *bsoncodec.Registry) *CollectionOptions {
- c.Registry = r
- return c
-}
-
-// MergeCollectionOptions combines the given CollectionOptions instances into a single *CollectionOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeCollectionOptions(opts ...*CollectionOptions) *CollectionOptions {
- c := Collection()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ReadConcern != nil {
- c.ReadConcern = opt.ReadConcern
- }
- if opt.WriteConcern != nil {
- c.WriteConcern = opt.WriteConcern
- }
- if opt.ReadPreference != nil {
- c.ReadPreference = opt.ReadPreference
- }
- if opt.Registry != nil {
- c.Registry = opt.Registry
- }
- if opt.BSONOptions != nil {
- c.BSONOptions = opt.BSONOptions
- }
- }
-
- return c
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/countoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/countoptions.go
deleted file mode 100644
index bb765d950..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/countoptions.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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 "time"
-
-// CountOptions represents options that can be used to configure a CountDocuments operation.
-type CountOptions struct {
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // TODO(GODRIVER-2386): CountOptions executor uses aggregation under the hood, which means this type has to be
- // TODO a string for now. This can be replaced with `Comment interface{}` once 2386 is implemented.
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default is nil, which means that no comment will be included in the logs.
- Comment *string
-
- // The index to use for the aggregation. This should either be the index name as a string or the index specification
- // as a document. The driver will return an error if the hint parameter is a multi-key map. The default value is nil,
- // which means that no hint will be sent.
- Hint interface{}
-
- // The maximum number of documents to count. The default value is 0, which means that there is no limit and all
- // documents matching the filter will be counted.
- Limit *int64
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there is
- // no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used in
- // its place to control the amount of time that a single operation can run before returning an error. MaxTime is
- // ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // The number of documents to skip before counting. The default value is 0.
- Skip *int64
-}
-
-// Count creates a new CountOptions instance.
-func Count() *CountOptions {
- return &CountOptions{}
-}
-
-// SetCollation sets the value for the Collation field.
-func (co *CountOptions) SetCollation(c *Collation) *CountOptions {
- co.Collation = c
- return co
-}
-
-// SetComment sets the value for the Comment field.
-func (co *CountOptions) SetComment(c string) *CountOptions {
- co.Comment = &c
- return co
-}
-
-// SetHint sets the value for the Hint field.
-func (co *CountOptions) SetHint(h interface{}) *CountOptions {
- co.Hint = h
- return co
-}
-
-// SetLimit sets the value for the Limit field.
-func (co *CountOptions) SetLimit(i int64) *CountOptions {
- co.Limit = &i
- return co
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (co *CountOptions) SetMaxTime(d time.Duration) *CountOptions {
- co.MaxTime = &d
- return co
-}
-
-// SetSkip sets the value for the Skip field.
-func (co *CountOptions) SetSkip(i int64) *CountOptions {
- co.Skip = &i
- return co
-}
-
-// MergeCountOptions combines the given CountOptions instances into a single CountOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeCountOptions(opts ...*CountOptions) *CountOptions {
- countOpts := Count()
- for _, co := range opts {
- if co == nil {
- continue
- }
- if co.Collation != nil {
- countOpts.Collation = co.Collation
- }
- if co.Comment != nil {
- countOpts.Comment = co.Comment
- }
- if co.Hint != nil {
- countOpts.Hint = co.Hint
- }
- if co.Limit != nil {
- countOpts.Limit = co.Limit
- }
- if co.MaxTime != nil {
- countOpts.MaxTime = co.MaxTime
- }
- if co.Skip != nil {
- countOpts.Skip = co.Skip
- }
- }
-
- return countOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/createcollectionoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/createcollectionoptions.go
deleted file mode 100644
index d8ffaaf33..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/createcollectionoptions.go
+++ /dev/null
@@ -1,360 +0,0 @@
-// 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 "time"
-
-// DefaultIndexOptions represents the default options for a collection to apply on new indexes. This type can be used
-// when creating a new collection through the CreateCollectionOptions.SetDefaultIndexOptions method.
-type DefaultIndexOptions struct {
- // Specifies the storage engine to use for the index. The value must be a document in the form
- // {: }. The default value is nil, which means that the default storage engine
- // will be used.
- StorageEngine interface{}
-}
-
-// DefaultIndex creates a new DefaultIndexOptions instance.
-func DefaultIndex() *DefaultIndexOptions {
- return &DefaultIndexOptions{}
-}
-
-// SetStorageEngine sets the value for the StorageEngine field.
-func (d *DefaultIndexOptions) SetStorageEngine(storageEngine interface{}) *DefaultIndexOptions {
- d.StorageEngine = storageEngine
- return d
-}
-
-// TimeSeriesOptions specifies options on a time-series collection.
-type TimeSeriesOptions struct {
- // TimeField is the top-level field to be used for time. Inserted documents must have this field,
- // and the field must be of the BSON UTC datetime type (0x9).
- TimeField string
-
- // MetaField is the name of the top-level field describing the series. This field is used to group
- // related data and may be of any BSON type, except for array. This name may not be the same
- // as the TimeField or _id. This field is optional.
- MetaField *string
-
- // Granularity is the granularity of time-series data. Allowed granularity options are
- // "seconds", "minutes" and "hours". This field is optional.
- Granularity *string
-
- // BucketMaxSpan is the maximum range of time values for a bucket. The
- // time.Duration is rounded down to the nearest second and applied as
- // the command option: "bucketRoundingSeconds". This field is optional.
- BucketMaxSpan *time.Duration
-
- // BucketRounding is used to determine the minimum time boundary when
- // opening a new bucket by rounding the first timestamp down to the next
- // multiple of this value. The time.Duration is rounded down to the
- // nearest second and applied as the command option:
- // "bucketRoundingSeconds". This field is optional.
- BucketRounding *time.Duration
-}
-
-// TimeSeries creates a new TimeSeriesOptions instance.
-func TimeSeries() *TimeSeriesOptions {
- return &TimeSeriesOptions{}
-}
-
-// SetTimeField sets the value for the TimeField.
-func (tso *TimeSeriesOptions) SetTimeField(timeField string) *TimeSeriesOptions {
- tso.TimeField = timeField
- return tso
-}
-
-// SetMetaField sets the value for the MetaField.
-func (tso *TimeSeriesOptions) SetMetaField(metaField string) *TimeSeriesOptions {
- tso.MetaField = &metaField
- return tso
-}
-
-// SetGranularity sets the value for Granularity.
-func (tso *TimeSeriesOptions) SetGranularity(granularity string) *TimeSeriesOptions {
- tso.Granularity = &granularity
- return tso
-}
-
-// SetBucketMaxSpan sets the value for BucketMaxSpan.
-func (tso *TimeSeriesOptions) SetBucketMaxSpan(dur time.Duration) *TimeSeriesOptions {
- tso.BucketMaxSpan = &dur
-
- return tso
-}
-
-// SetBucketRounding sets the value for BucketRounding.
-func (tso *TimeSeriesOptions) SetBucketRounding(dur time.Duration) *TimeSeriesOptions {
- tso.BucketRounding = &dur
-
- return tso
-}
-
-// CreateCollectionOptions represents options that can be used to configure a CreateCollection operation.
-type CreateCollectionOptions struct {
- // Specifies if the collection is capped (see https://www.mongodb.com/docs/manual/core/capped-collections/). If true,
- // the SizeInBytes option must also be specified. The default value is false.
- Capped *bool
-
- // Specifies the default collation for the new collection. This option is only valid for MongoDB versions >= 3.4.
- // For previous server versions, the driver will return an error if this option is used. The default value is nil.
- Collation *Collation
-
- // Specifies how change streams opened against the collection can return pre- and post-images of updated
- // documents. The value must be a document in the form {: }. This option is only valid for
- // MongoDB versions >= 6.0. The default value is nil, which means that change streams opened against the collection
- // will not return pre- and post-images of updated documents in any way.
- ChangeStreamPreAndPostImages interface{}
-
- // Specifies a default configuration for indexes on the collection. This option is only valid for MongoDB versions
- // >= 3.4. The default value is nil, meaning indexes will be configured using server defaults.
- DefaultIndexOptions *DefaultIndexOptions
-
- // Specifies the maximum number of documents allowed in a capped collection. The limit specified by the SizeInBytes
- // option takes precedence over this option. If a capped collection reaches its size limit, old documents will be
- // removed, regardless of the number of documents in the collection. The default value is 0, meaning the maximum
- // number of documents is unbounded.
- MaxDocuments *int64
-
- // Specifies the maximum size in bytes for a capped collection. The default value is 0.
- SizeInBytes *int64
-
- // Specifies the storage engine to use for the index. The value must be a document in the form
- // {: }. The default value is nil, which means that the default storage engine
- // will be used.
- StorageEngine interface{}
-
- // Specifies what should happen if a document being inserted does not pass validation. Valid values are "error" and
- // "warn". See https://www.mongodb.com/docs/manual/core/schema-validation/#accept-or-reject-invalid-documents for more
- // information. This option is only valid for MongoDB versions >= 3.2. The default value is "error".
- ValidationAction *string
-
- // Specifies how strictly the server applies validation rules to existing documents in the collection during update
- // operations. Valid values are "off", "strict", and "moderate". See
- // https://www.mongodb.com/docs/manual/core/schema-validation/#existing-documents for more information. This option is
- // only valid for MongoDB versions >= 3.2. The default value is "strict".
- ValidationLevel *string
-
- // A document specifying validation rules for the collection. See
- // https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about schema validation. This option
- // is only valid for MongoDB versions >= 3.2. The default value is nil, meaning no validator will be used for the
- // collection.
- Validator interface{}
-
- // Value indicating after how many seconds old time-series data should be deleted. See
- // https://www.mongodb.com/docs/manual/reference/command/create/ for supported options, and
- // https://www.mongodb.com/docs/manual/core/timeseries-collections/ for more information on time-series
- // collections.
- //
- // This option is only valid for MongoDB versions >= 5.0
- ExpireAfterSeconds *int64
-
- // Options for specifying a time-series collection. See
- // https://www.mongodb.com/docs/manual/reference/command/create/ for supported options, and
- // https://www.mongodb.com/docs/manual/core/timeseries-collections/ for more information on time-series
- // collections.
- //
- // This option is only valid for MongoDB versions >= 5.0
- TimeSeriesOptions *TimeSeriesOptions
-
- // EncryptedFields configures encrypted fields.
- //
- // This option is only valid for MongoDB versions >= 6.0
- EncryptedFields interface{}
-
- // ClusteredIndex is used to create a collection with a clustered index.
- //
- // This option is only valid for MongoDB versions >= 5.3
- ClusteredIndex interface{}
-}
-
-// CreateCollection creates a new CreateCollectionOptions instance.
-func CreateCollection() *CreateCollectionOptions {
- return &CreateCollectionOptions{}
-}
-
-// SetCapped sets the value for the Capped field.
-func (c *CreateCollectionOptions) SetCapped(capped bool) *CreateCollectionOptions {
- c.Capped = &capped
- return c
-}
-
-// SetCollation sets the value for the Collation field.
-func (c *CreateCollectionOptions) SetCollation(collation *Collation) *CreateCollectionOptions {
- c.Collation = collation
- return c
-}
-
-// SetChangeStreamPreAndPostImages sets the value for the ChangeStreamPreAndPostImages field.
-func (c *CreateCollectionOptions) SetChangeStreamPreAndPostImages(csppi interface{}) *CreateCollectionOptions {
- c.ChangeStreamPreAndPostImages = &csppi
- return c
-}
-
-// SetDefaultIndexOptions sets the value for the DefaultIndexOptions field.
-func (c *CreateCollectionOptions) SetDefaultIndexOptions(opts *DefaultIndexOptions) *CreateCollectionOptions {
- c.DefaultIndexOptions = opts
- return c
-}
-
-// SetMaxDocuments sets the value for the MaxDocuments field.
-func (c *CreateCollectionOptions) SetMaxDocuments(max int64) *CreateCollectionOptions {
- c.MaxDocuments = &max
- return c
-}
-
-// SetSizeInBytes sets the value for the SizeInBytes field.
-func (c *CreateCollectionOptions) SetSizeInBytes(size int64) *CreateCollectionOptions {
- c.SizeInBytes = &size
- return c
-}
-
-// SetStorageEngine sets the value for the StorageEngine field.
-func (c *CreateCollectionOptions) SetStorageEngine(storageEngine interface{}) *CreateCollectionOptions {
- c.StorageEngine = &storageEngine
- return c
-}
-
-// SetValidationAction sets the value for the ValidationAction field.
-func (c *CreateCollectionOptions) SetValidationAction(action string) *CreateCollectionOptions {
- c.ValidationAction = &action
- return c
-}
-
-// SetValidationLevel sets the value for the ValidationLevel field.
-func (c *CreateCollectionOptions) SetValidationLevel(level string) *CreateCollectionOptions {
- c.ValidationLevel = &level
- return c
-}
-
-// SetValidator sets the value for the Validator field.
-func (c *CreateCollectionOptions) SetValidator(validator interface{}) *CreateCollectionOptions {
- c.Validator = validator
- return c
-}
-
-// SetExpireAfterSeconds sets the value for the ExpireAfterSeconds field.
-func (c *CreateCollectionOptions) SetExpireAfterSeconds(eas int64) *CreateCollectionOptions {
- c.ExpireAfterSeconds = &eas
- return c
-}
-
-// SetTimeSeriesOptions sets the options for time-series collections.
-func (c *CreateCollectionOptions) SetTimeSeriesOptions(timeSeriesOpts *TimeSeriesOptions) *CreateCollectionOptions {
- c.TimeSeriesOptions = timeSeriesOpts
- return c
-}
-
-// SetEncryptedFields sets the encrypted fields for encrypted collections.
-func (c *CreateCollectionOptions) SetEncryptedFields(encryptedFields interface{}) *CreateCollectionOptions {
- c.EncryptedFields = encryptedFields
- return c
-}
-
-// SetClusteredIndex sets the value for the ClusteredIndex field.
-func (c *CreateCollectionOptions) SetClusteredIndex(clusteredIndex interface{}) *CreateCollectionOptions {
- c.ClusteredIndex = clusteredIndex
- return c
-}
-
-// MergeCreateCollectionOptions combines the given CreateCollectionOptions instances into a single
-// CreateCollectionOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeCreateCollectionOptions(opts ...*CreateCollectionOptions) *CreateCollectionOptions {
- cc := CreateCollection()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.Capped != nil {
- cc.Capped = opt.Capped
- }
- if opt.Collation != nil {
- cc.Collation = opt.Collation
- }
- if opt.ChangeStreamPreAndPostImages != nil {
- cc.ChangeStreamPreAndPostImages = opt.ChangeStreamPreAndPostImages
- }
- if opt.DefaultIndexOptions != nil {
- cc.DefaultIndexOptions = opt.DefaultIndexOptions
- }
- if opt.MaxDocuments != nil {
- cc.MaxDocuments = opt.MaxDocuments
- }
- if opt.SizeInBytes != nil {
- cc.SizeInBytes = opt.SizeInBytes
- }
- if opt.StorageEngine != nil {
- cc.StorageEngine = opt.StorageEngine
- }
- if opt.ValidationAction != nil {
- cc.ValidationAction = opt.ValidationAction
- }
- if opt.ValidationLevel != nil {
- cc.ValidationLevel = opt.ValidationLevel
- }
- if opt.Validator != nil {
- cc.Validator = opt.Validator
- }
- if opt.ExpireAfterSeconds != nil {
- cc.ExpireAfterSeconds = opt.ExpireAfterSeconds
- }
- if opt.TimeSeriesOptions != nil {
- cc.TimeSeriesOptions = opt.TimeSeriesOptions
- }
- if opt.EncryptedFields != nil {
- cc.EncryptedFields = opt.EncryptedFields
- }
- if opt.ClusteredIndex != nil {
- cc.ClusteredIndex = opt.ClusteredIndex
- }
- }
-
- return cc
-}
-
-// CreateViewOptions represents options that can be used to configure a CreateView operation.
-type CreateViewOptions struct {
- // Specifies the default collation for the new collection. This option is only valid for MongoDB versions >= 3.4.
- // For previous server versions, the driver will return an error if this option is used. The default value is nil.
- Collation *Collation
-}
-
-// CreateView creates an new CreateViewOptions instance.
-func CreateView() *CreateViewOptions {
- return &CreateViewOptions{}
-}
-
-// SetCollation sets the value for the Collation field.
-func (c *CreateViewOptions) SetCollation(collation *Collation) *CreateViewOptions {
- c.Collation = collation
- return c
-}
-
-// MergeCreateViewOptions combines the given CreateViewOptions instances into a single CreateViewOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeCreateViewOptions(opts ...*CreateViewOptions) *CreateViewOptions {
- cv := CreateView()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.Collation != nil {
- cv.Collation = opt.Collation
- }
- }
-
- return cv
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/dboptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/dboptions.go
deleted file mode 100644
index 38ee13550..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/dboptions.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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 (
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
-)
-
-// DatabaseOptions represents options that can be used to configure a Database.
-type DatabaseOptions struct {
- // ReadConcern is the read concern to use for operations executed on the Database. The default value is nil, which means that
- // the read concern of the Client used to configure the Database will be used.
- ReadConcern *readconcern.ReadConcern
-
- // WriteConcern is the write concern to use for operations executed on the Database. The default value is nil, which means that the
- // write concern of the Client used to configure the Database will be used.
- WriteConcern *writeconcern.WriteConcern
-
- // ReadPreference is the read preference to use for operations executed on the Database. The default value is nil, which means that
- // the read preference of the Client used to configure the Database will be used.
- ReadPreference *readpref.ReadPref
-
- // BSONOptions configures optional BSON marshaling and unmarshaling
- // behavior.
- BSONOptions *BSONOptions
-
- // Registry is the BSON registry to marshal and unmarshal documents for operations executed on the Database. The default value
- // is nil, which means that the registry of the Client used to configure the Database will be used.
- Registry *bsoncodec.Registry
-}
-
-// Database creates a new DatabaseOptions instance.
-func Database() *DatabaseOptions {
- return &DatabaseOptions{}
-}
-
-// SetReadConcern sets the value for the ReadConcern field.
-func (d *DatabaseOptions) SetReadConcern(rc *readconcern.ReadConcern) *DatabaseOptions {
- d.ReadConcern = rc
- return d
-}
-
-// SetWriteConcern sets the value for the WriteConcern field.
-func (d *DatabaseOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *DatabaseOptions {
- d.WriteConcern = wc
- return d
-}
-
-// SetReadPreference sets the value for the ReadPreference field.
-func (d *DatabaseOptions) SetReadPreference(rp *readpref.ReadPref) *DatabaseOptions {
- d.ReadPreference = rp
- return d
-}
-
-// SetBSONOptions configures optional BSON marshaling and unmarshaling behavior.
-func (d *DatabaseOptions) SetBSONOptions(opts *BSONOptions) *DatabaseOptions {
- d.BSONOptions = opts
- return d
-}
-
-// SetRegistry sets the value for the Registry field.
-func (d *DatabaseOptions) SetRegistry(r *bsoncodec.Registry) *DatabaseOptions {
- d.Registry = r
- return d
-}
-
-// MergeDatabaseOptions combines the given DatabaseOptions instances into a single DatabaseOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeDatabaseOptions(opts ...*DatabaseOptions) *DatabaseOptions {
- d := Database()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ReadConcern != nil {
- d.ReadConcern = opt.ReadConcern
- }
- if opt.WriteConcern != nil {
- d.WriteConcern = opt.WriteConcern
- }
- if opt.ReadPreference != nil {
- d.ReadPreference = opt.ReadPreference
- }
- if opt.Registry != nil {
- d.Registry = opt.Registry
- }
- if opt.BSONOptions != nil {
- d.BSONOptions = opt.BSONOptions
- }
- }
-
- return d
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go
deleted file mode 100644
index 59aaef915..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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
-
-// DeleteOptions represents options that can be used to configure DeleteOne and DeleteMany operations.
-type DeleteOptions struct {
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.4 will return an error
- // if this option is specified. For server versions < 3.4, the driver will return a client-side error if this option
- // is specified. The driver will return an error if this option is specified during an unacknowledged write
- // operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil,
- // which means that no hint will be sent.
- Hint interface{}
-
- // Specifies parameters for the delete expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-}
-
-// Delete creates a new DeleteOptions instance.
-func Delete() *DeleteOptions {
- return &DeleteOptions{}
-}
-
-// SetCollation sets the value for the Collation field.
-func (do *DeleteOptions) SetCollation(c *Collation) *DeleteOptions {
- do.Collation = c
- return do
-}
-
-// SetComment sets the value for the Comment field.
-func (do *DeleteOptions) SetComment(comment interface{}) *DeleteOptions {
- do.Comment = comment
- return do
-}
-
-// SetHint sets the value for the Hint field.
-func (do *DeleteOptions) SetHint(hint interface{}) *DeleteOptions {
- do.Hint = hint
- return do
-}
-
-// SetLet sets the value for the Let field.
-func (do *DeleteOptions) SetLet(let interface{}) *DeleteOptions {
- do.Let = let
- return do
-}
-
-// MergeDeleteOptions combines the given DeleteOptions instances into a single DeleteOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeDeleteOptions(opts ...*DeleteOptions) *DeleteOptions {
- dOpts := Delete()
- for _, do := range opts {
- if do == nil {
- continue
- }
- if do.Collation != nil {
- dOpts.Collation = do.Collation
- }
- if do.Comment != nil {
- dOpts.Comment = do.Comment
- }
- if do.Hint != nil {
- dOpts.Hint = do.Hint
- }
- if do.Let != nil {
- dOpts.Let = do.Let
- }
- }
-
- return dOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/distinctoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/distinctoptions.go
deleted file mode 100644
index 819f2a9a8..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/distinctoptions.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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 "time"
-
-// DistinctOptions represents options that can be used to configure a Distinct operation.
-type DistinctOptions struct {
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be
- // used in its place to control the amount of time that a single operation can run before returning an error.
- // MaxTime is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-}
-
-// Distinct creates a new DistinctOptions instance.
-func Distinct() *DistinctOptions {
- return &DistinctOptions{}
-}
-
-// SetCollation sets the value for the Collation field.
-func (do *DistinctOptions) SetCollation(c *Collation) *DistinctOptions {
- do.Collation = c
- return do
-}
-
-// SetComment sets the value for the Comment field.
-func (do *DistinctOptions) SetComment(comment interface{}) *DistinctOptions {
- do.Comment = comment
- return do
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (do *DistinctOptions) SetMaxTime(d time.Duration) *DistinctOptions {
- do.MaxTime = &d
- return do
-}
-
-// MergeDistinctOptions combines the given DistinctOptions instances into a single DistinctOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeDistinctOptions(opts ...*DistinctOptions) *DistinctOptions {
- distinctOpts := Distinct()
- for _, do := range opts {
- if do == nil {
- continue
- }
- if do.Collation != nil {
- distinctOpts.Collation = do.Collation
- }
- if do.Comment != nil {
- distinctOpts.Comment = do.Comment
- }
- if do.MaxTime != nil {
- distinctOpts.MaxTime = do.MaxTime
- }
- }
-
- return distinctOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/encryptoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/encryptoptions.go
deleted file mode 100644
index 68278ba45..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/encryptoptions.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// 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 (
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-// These constants specify valid values for QueryType
-// QueryType is used for Queryable Encryption.
-const (
- QueryTypeEquality string = "equality"
-)
-
-// RangeOptions specifies index options for a Queryable Encryption field supporting "range" queries.
-type RangeOptions struct {
- Min *bson.RawValue
- Max *bson.RawValue
- Sparsity *int64
- TrimFactor *int32
- Precision *int32
-}
-
-// EncryptOptions represents options to explicitly encrypt a value.
-type EncryptOptions struct {
- KeyID *primitive.Binary
- KeyAltName *string
- Algorithm string
- QueryType string
- ContentionFactor *int64
- RangeOptions *RangeOptions
-}
-
-// Encrypt creates a new EncryptOptions instance.
-func Encrypt() *EncryptOptions {
- return &EncryptOptions{}
-}
-
-// SetKeyID specifies an _id of a data key. This should be a UUID (a primitive.Binary with subtype 4).
-func (e *EncryptOptions) SetKeyID(keyID primitive.Binary) *EncryptOptions {
- e.KeyID = &keyID
- return e
-}
-
-// SetKeyAltName identifies a key vault document by 'keyAltName'.
-func (e *EncryptOptions) SetKeyAltName(keyAltName string) *EncryptOptions {
- e.KeyAltName = &keyAltName
- return e
-}
-
-// SetAlgorithm specifies an algorithm to use for encryption. This should be one of the following:
-// - AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic
-// - AEAD_AES_256_CBC_HMAC_SHA_512-Random
-// - Indexed
-// - Unindexed
-// - Range
-// This is required.
-// Indexed and Unindexed are used for Queryable Encryption.
-func (e *EncryptOptions) SetAlgorithm(algorithm string) *EncryptOptions {
- e.Algorithm = algorithm
- return e
-}
-
-// SetQueryType specifies the intended query type. It is only valid to set if algorithm is "Indexed".
-// This should be one of the following:
-// - equality
-// QueryType is used for Queryable Encryption.
-func (e *EncryptOptions) SetQueryType(queryType string) *EncryptOptions {
- e.QueryType = queryType
- return e
-}
-
-// SetContentionFactor specifies the contention factor. It is only valid to set if algorithm is "Indexed".
-// ContentionFactor is used for Queryable Encryption.
-func (e *EncryptOptions) SetContentionFactor(contentionFactor int64) *EncryptOptions {
- e.ContentionFactor = &contentionFactor
- return e
-}
-
-// SetRangeOptions specifies the options to use for explicit encryption with range. It is only valid to set if algorithm is "Range".
-func (e *EncryptOptions) SetRangeOptions(ro RangeOptions) *EncryptOptions {
- e.RangeOptions = &ro
- return e
-}
-
-// SetMin sets the range index minimum value.
-func (ro *RangeOptions) SetMin(min bson.RawValue) *RangeOptions {
- ro.Min = &min
- return ro
-}
-
-// SetMax sets the range index maximum value.
-func (ro *RangeOptions) SetMax(max bson.RawValue) *RangeOptions {
- ro.Max = &max
- return ro
-}
-
-// SetSparsity sets the range index sparsity.
-func (ro *RangeOptions) SetSparsity(sparsity int64) *RangeOptions {
- ro.Sparsity = &sparsity
- return ro
-}
-
-// SetTrimFactor sets the range index trim factor.
-func (ro *RangeOptions) SetTrimFactor(trimFactor int32) *RangeOptions {
- ro.TrimFactor = &trimFactor
- return ro
-}
-
-// SetPrecision sets the range index precision.
-func (ro *RangeOptions) SetPrecision(precision int32) *RangeOptions {
- ro.Precision = &precision
- return ro
-}
-
-// MergeEncryptOptions combines the argued EncryptOptions in a last-one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeEncryptOptions(opts ...*EncryptOptions) *EncryptOptions {
- eo := Encrypt()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.KeyID != nil {
- eo.KeyID = opt.KeyID
- }
- if opt.KeyAltName != nil {
- eo.KeyAltName = opt.KeyAltName
- }
- if opt.Algorithm != "" {
- eo.Algorithm = opt.Algorithm
- }
- if opt.QueryType != "" {
- eo.QueryType = opt.QueryType
- }
- if opt.ContentionFactor != nil {
- eo.ContentionFactor = opt.ContentionFactor
- }
- if opt.RangeOptions != nil {
- eo.RangeOptions = opt.RangeOptions
- }
- }
-
- return eo
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/estimatedcountoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/estimatedcountoptions.go
deleted file mode 100644
index d088af9c9..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/estimatedcountoptions.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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 "time"
-
-// EstimatedDocumentCountOptions represents options that can be used to configure an EstimatedDocumentCount operation.
-type EstimatedDocumentCountOptions struct {
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-}
-
-// EstimatedDocumentCount creates a new EstimatedDocumentCountOptions instance.
-func EstimatedDocumentCount() *EstimatedDocumentCountOptions {
- return &EstimatedDocumentCountOptions{}
-}
-
-// SetComment sets the value for the Comment field.
-func (eco *EstimatedDocumentCountOptions) SetComment(comment interface{}) *EstimatedDocumentCountOptions {
- eco.Comment = comment
- return eco
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option
-// may be used in its place to control the amount of time that a single operation can run before
-// returning an error. MaxTime is ignored if Timeout is set on the client.
-func (eco *EstimatedDocumentCountOptions) SetMaxTime(d time.Duration) *EstimatedDocumentCountOptions {
- eco.MaxTime = &d
- return eco
-}
-
-// MergeEstimatedDocumentCountOptions combines the given EstimatedDocumentCountOptions instances into a single
-// EstimatedDocumentCountOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeEstimatedDocumentCountOptions(opts ...*EstimatedDocumentCountOptions) *EstimatedDocumentCountOptions {
- e := EstimatedDocumentCount()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Comment != nil {
- e.Comment = opt.Comment
- }
- if opt.MaxTime != nil {
- e.MaxTime = opt.MaxTime
- }
- }
-
- return e
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go
deleted file mode 100644
index 5795f95a4..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go
+++ /dev/null
@@ -1,1128 +0,0 @@
-// 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 (
- "time"
-)
-
-// FindOptions represents options that can be used to configure a Find operation.
-type FindOptions struct {
- // AllowDiskUse specifies whether the server can write temporary data to disk while executing the Find operation.
- // This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.2 will report an error if this option
- // is specified. For server versions < 3.2, the driver will return a client-side error if this option is specified.
- // The default value is false.
- AllowDiskUse *bool
-
- // AllowPartial results specifies whether the Find operation on a sharded cluster can return partial results if some
- // shards are down rather than returning an error. The default value is false.
- AllowPartialResults *bool
-
- // BatchSize is the maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // Collation specifies a collation to use for string comparisons during the operation. This option is only valid for
- // MongoDB versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation.
- // The default is nil, which means that no comment will be included in the logs.
- Comment *string
-
- // CursorType specifies the type of cursor that should be created for the operation. The default is NonTailable, which
- // means that the cursor will be closed by the server when the last batch of documents is retrieved.
- CursorType *CursorType
-
- // Hint is the index to use for the Find operation. This should either be the index name as a string or the index
- // specification as a document. The driver will return an error if the hint parameter is a multi-key map. The default
- // value is nil, which means that no hint will be sent.
- Hint interface{}
-
- // Limit is the maximum number of documents to return. The default value is 0, which means that all documents matching the
- // filter will be returned. A negative limit specifies that the resulting documents should be returned in a single
- // batch. The default value is 0.
- Limit *int64
-
- // Max is a document specifying the exclusive upper bound for a specific index. The default value is nil, which means that
- // there is no maximum value.
- Max interface{}
-
- // MaxAwaitTime is the maximum amount of time that the server should wait for new documents to satisfy a tailable cursor
- // query. This option is only valid for tailable await cursors (see the CursorType option for more information) and
- // MongoDB versions >= 3.2. For other cursor types or previous server versions, this option is ignored.
- MaxAwaitTime *time.Duration
-
- // MaxTime is the maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used in its
- // place to control the amount of time that a single operation can run before returning an error. MaxTime is ignored if
- // Timeout is set on the client.
- MaxTime *time.Duration
-
- // Min is a document specifying the inclusive lower bound for a specific index. The default value is 0, which means that
- // there is no minimum value.
- Min interface{}
-
- // NoCursorTimeout specifies whether the cursor created by the operation will not timeout after a period of inactivity.
- // The default value is false.
- NoCursorTimeout *bool
-
- // OplogReplay is for internal replication use only and should not be set.
- //
- // Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by the server if it is
- // set.
- OplogReplay *bool
-
- // Project is a document describing which fields will be included in the documents returned by the Find operation. The
- // default value is nil, which means all fields will be included.
- Projection interface{}
-
- // ReturnKey specifies whether the documents returned by the Find operation will only contain fields corresponding to the
- // index used. The default value is false.
- ReturnKey *bool
-
- // ShowRecordID specifies whether a $recordId field with a record identifier will be included in the documents returned by
- // the Find operation. The default value is false.
- ShowRecordID *bool
-
- // Skip is the number of documents to skip before adding documents to the result. The default value is 0.
- Skip *int64
-
- // Snapshot specifies whether the cursor will not return a document more than once because of an intervening write operation.
- // The default value is false.
- //
- // Deprecated: This option has been deprecated in MongoDB version 3.6 and removed in MongoDB version 4.0.
- Snapshot *bool
-
- // Sort is a document specifying the order in which documents should be returned. The driver will return an error if the
- // sort parameter is a multi-key map.
- Sort interface{}
-
- // Let specifies parameters for the find expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-}
-
-// Find creates a new FindOptions instance.
-func Find() *FindOptions {
- return &FindOptions{}
-}
-
-// SetAllowDiskUse sets the value for the AllowDiskUse field.
-func (f *FindOptions) SetAllowDiskUse(b bool) *FindOptions {
- f.AllowDiskUse = &b
- return f
-}
-
-// SetAllowPartialResults sets the value for the AllowPartialResults field.
-func (f *FindOptions) SetAllowPartialResults(b bool) *FindOptions {
- f.AllowPartialResults = &b
- return f
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (f *FindOptions) SetBatchSize(i int32) *FindOptions {
- f.BatchSize = &i
- return f
-}
-
-// SetCollation sets the value for the Collation field.
-func (f *FindOptions) SetCollation(collation *Collation) *FindOptions {
- f.Collation = collation
- return f
-}
-
-// SetComment sets the value for the Comment field.
-func (f *FindOptions) SetComment(comment string) *FindOptions {
- f.Comment = &comment
- return f
-}
-
-// SetCursorType sets the value for the CursorType field.
-func (f *FindOptions) SetCursorType(ct CursorType) *FindOptions {
- f.CursorType = &ct
- return f
-}
-
-// SetHint sets the value for the Hint field.
-func (f *FindOptions) SetHint(hint interface{}) *FindOptions {
- f.Hint = hint
- return f
-}
-
-// SetLet sets the value for the Let field.
-func (f *FindOptions) SetLet(let interface{}) *FindOptions {
- f.Let = let
- return f
-}
-
-// SetLimit sets the value for the Limit field.
-func (f *FindOptions) SetLimit(i int64) *FindOptions {
- f.Limit = &i
- return f
-}
-
-// SetMax sets the value for the Max field.
-func (f *FindOptions) SetMax(max interface{}) *FindOptions {
- f.Max = max
- return f
-}
-
-// SetMaxAwaitTime sets the value for the MaxAwaitTime field.
-func (f *FindOptions) SetMaxAwaitTime(d time.Duration) *FindOptions {
- f.MaxAwaitTime = &d
- return f
-}
-
-// SetMaxTime specifies the max time to allow the query to run.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used used in its place to control the amount of time that a single operation
-// can run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *FindOptions) SetMaxTime(d time.Duration) *FindOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetMin sets the value for the Min field.
-func (f *FindOptions) SetMin(min interface{}) *FindOptions {
- f.Min = min
- return f
-}
-
-// SetNoCursorTimeout sets the value for the NoCursorTimeout field.
-func (f *FindOptions) SetNoCursorTimeout(b bool) *FindOptions {
- f.NoCursorTimeout = &b
- return f
-}
-
-// SetOplogReplay sets the value for the OplogReplay field.
-//
-// Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by the server if it is set.
-func (f *FindOptions) SetOplogReplay(b bool) *FindOptions {
- f.OplogReplay = &b
- return f
-}
-
-// SetProjection sets the value for the Projection field.
-func (f *FindOptions) SetProjection(projection interface{}) *FindOptions {
- f.Projection = projection
- return f
-}
-
-// SetReturnKey sets the value for the ReturnKey field.
-func (f *FindOptions) SetReturnKey(b bool) *FindOptions {
- f.ReturnKey = &b
- return f
-}
-
-// SetShowRecordID sets the value for the ShowRecordID field.
-func (f *FindOptions) SetShowRecordID(b bool) *FindOptions {
- f.ShowRecordID = &b
- return f
-}
-
-// SetSkip sets the value for the Skip field.
-func (f *FindOptions) SetSkip(i int64) *FindOptions {
- f.Skip = &i
- return f
-}
-
-// SetSnapshot sets the value for the Snapshot field.
-//
-// Deprecated: This option has been deprecated in MongoDB version 3.6 and removed in MongoDB version 4.0.
-func (f *FindOptions) SetSnapshot(b bool) *FindOptions {
- f.Snapshot = &b
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *FindOptions) SetSort(sort interface{}) *FindOptions {
- f.Sort = sort
- return f
-}
-
-// MergeFindOptions combines the given FindOptions instances into a single FindOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeFindOptions(opts ...*FindOptions) *FindOptions {
- fo := Find()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.AllowDiskUse != nil {
- fo.AllowDiskUse = opt.AllowDiskUse
- }
- if opt.AllowPartialResults != nil {
- fo.AllowPartialResults = opt.AllowPartialResults
- }
- if opt.BatchSize != nil {
- fo.BatchSize = opt.BatchSize
- }
- if opt.Collation != nil {
- fo.Collation = opt.Collation
- }
- if opt.Comment != nil {
- fo.Comment = opt.Comment
- }
- if opt.CursorType != nil {
- fo.CursorType = opt.CursorType
- }
- if opt.Hint != nil {
- fo.Hint = opt.Hint
- }
- if opt.Let != nil {
- fo.Let = opt.Let
- }
- if opt.Limit != nil {
- fo.Limit = opt.Limit
- }
- if opt.Max != nil {
- fo.Max = opt.Max
- }
- if opt.MaxAwaitTime != nil {
- fo.MaxAwaitTime = opt.MaxAwaitTime
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.Min != nil {
- fo.Min = opt.Min
- }
- if opt.NoCursorTimeout != nil {
- fo.NoCursorTimeout = opt.NoCursorTimeout
- }
- if opt.OplogReplay != nil {
- fo.OplogReplay = opt.OplogReplay
- }
- if opt.Projection != nil {
- fo.Projection = opt.Projection
- }
- if opt.ReturnKey != nil {
- fo.ReturnKey = opt.ReturnKey
- }
- if opt.ShowRecordID != nil {
- fo.ShowRecordID = opt.ShowRecordID
- }
- if opt.Skip != nil {
- fo.Skip = opt.Skip
- }
- if opt.Snapshot != nil {
- fo.Snapshot = opt.Snapshot
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- }
-
- return fo
-}
-
-// FindOneOptions represents options that can be used to configure a FindOne operation.
-type FindOneOptions struct {
- // If true, an operation on a sharded cluster can return partial results if some shards are down rather than
- // returning an error. The default value is false.
- AllowPartialResults *bool
-
- // The maximum number of documents to be included in each batch returned by the server.
- //
- // Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
- BatchSize *int32
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation.
- // The default is nil, which means that no comment will be included in the logs.
- Comment *string
-
- // Specifies the type of cursor that should be created for the operation. The default is NonTailable, which means
- // that the cursor will be closed by the server when the last batch of documents is retrieved.
- //
- // Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
- CursorType *CursorType
-
- // The index to use for the aggregation. This should either be the index name as a string or the index specification
- // as a document. The driver will return an error if the hint parameter is a multi-key map. The default value is nil,
- // which means that no hint will be sent.
- Hint interface{}
-
- // A document specifying the exclusive upper bound for a specific index. The default value is nil, which means that
- // there is no maximum value.
- Max interface{}
-
- // The maximum amount of time that the server should wait for new documents to satisfy a tailable cursor query.
- // This option is only valid for tailable await cursors (see the CursorType option for more information) and
- // MongoDB versions >= 3.2. For other cursor types or previous server versions, this option is ignored.
- //
- // Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
- MaxAwaitTime *time.Duration
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // A document specifying the inclusive lower bound for a specific index. The default value is 0, which means that
- // there is no minimum value.
- Min interface{}
-
- // If true, the cursor created by the operation will not timeout after a period of inactivity. The default value
- // is false.
- //
- // Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
- NoCursorTimeout *bool
-
- // This option is for internal replication use only and should not be set.
- //
- // Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by the server if it is
- // set.
- OplogReplay *bool
-
- // A document describing which fields will be included in the document returned by the operation. The default value
- // is nil, which means all fields will be included.
- Projection interface{}
-
- // If true, the document returned by the operation will only contain fields corresponding to the index used. The
- // default value is false.
- ReturnKey *bool
-
- // If true, a $recordId field with a record identifier will be included in the document returned by the operation.
- // The default value is false.
- ShowRecordID *bool
-
- // The number of documents to skip before selecting the document to be returned. The default value is 0.
- Skip *int64
-
- // If true, the cursor will not return a document more than once because of an intervening write operation. The
- // default value is false.
- //
- // Deprecated: This option has been deprecated in MongoDB version 3.6 and removed in MongoDB version 4.0.
- Snapshot *bool
-
- // A document specifying the sort order to apply to the query. The first document in the sorted order will be
- // returned. The driver will return an error if the sort parameter is a multi-key map.
- Sort interface{}
-}
-
-// FindOne creates a new FindOneOptions instance.
-func FindOne() *FindOneOptions {
- return &FindOneOptions{}
-}
-
-// SetAllowPartialResults sets the value for the AllowPartialResults field.
-func (f *FindOneOptions) SetAllowPartialResults(b bool) *FindOneOptions {
- f.AllowPartialResults = &b
- return f
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-//
-// Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
-func (f *FindOneOptions) SetBatchSize(i int32) *FindOneOptions {
- f.BatchSize = &i
- return f
-}
-
-// SetCollation sets the value for the Collation field.
-func (f *FindOneOptions) SetCollation(collation *Collation) *FindOneOptions {
- f.Collation = collation
- return f
-}
-
-// SetComment sets the value for the Comment field.
-func (f *FindOneOptions) SetComment(comment string) *FindOneOptions {
- f.Comment = &comment
- return f
-}
-
-// SetCursorType sets the value for the CursorType field.
-//
-// Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
-func (f *FindOneOptions) SetCursorType(ct CursorType) *FindOneOptions {
- f.CursorType = &ct
- return f
-}
-
-// SetHint sets the value for the Hint field.
-func (f *FindOneOptions) SetHint(hint interface{}) *FindOneOptions {
- f.Hint = hint
- return f
-}
-
-// SetMax sets the value for the Max field.
-func (f *FindOneOptions) SetMax(max interface{}) *FindOneOptions {
- f.Max = max
- return f
-}
-
-// SetMaxAwaitTime sets the value for the MaxAwaitTime field.
-//
-// Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
-func (f *FindOneOptions) SetMaxAwaitTime(d time.Duration) *FindOneOptions {
- f.MaxAwaitTime = &d
- return f
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *FindOneOptions) SetMaxTime(d time.Duration) *FindOneOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetMin sets the value for the Min field.
-func (f *FindOneOptions) SetMin(min interface{}) *FindOneOptions {
- f.Min = min
- return f
-}
-
-// SetNoCursorTimeout sets the value for the NoCursorTimeout field.
-//
-// Deprecated: This option is not valid for a findOne operation, as no cursor is actually created.
-func (f *FindOneOptions) SetNoCursorTimeout(b bool) *FindOneOptions {
- f.NoCursorTimeout = &b
- return f
-}
-
-// SetOplogReplay sets the value for the OplogReplay field.
-//
-// Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by the server if it is
-// set.
-func (f *FindOneOptions) SetOplogReplay(b bool) *FindOneOptions {
- f.OplogReplay = &b
- return f
-}
-
-// SetProjection sets the value for the Projection field.
-func (f *FindOneOptions) SetProjection(projection interface{}) *FindOneOptions {
- f.Projection = projection
- return f
-}
-
-// SetReturnKey sets the value for the ReturnKey field.
-func (f *FindOneOptions) SetReturnKey(b bool) *FindOneOptions {
- f.ReturnKey = &b
- return f
-}
-
-// SetShowRecordID sets the value for the ShowRecordID field.
-func (f *FindOneOptions) SetShowRecordID(b bool) *FindOneOptions {
- f.ShowRecordID = &b
- return f
-}
-
-// SetSkip sets the value for the Skip field.
-func (f *FindOneOptions) SetSkip(i int64) *FindOneOptions {
- f.Skip = &i
- return f
-}
-
-// SetSnapshot sets the value for the Snapshot field.
-//
-// Deprecated: This option has been deprecated in MongoDB version 3.6 and removed in MongoDB version 4.0.
-func (f *FindOneOptions) SetSnapshot(b bool) *FindOneOptions {
- f.Snapshot = &b
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *FindOneOptions) SetSort(sort interface{}) *FindOneOptions {
- f.Sort = sort
- return f
-}
-
-// MergeFindOneOptions combines the given FindOneOptions instances into a single FindOneOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeFindOneOptions(opts ...*FindOneOptions) *FindOneOptions {
- fo := FindOne()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.AllowPartialResults != nil {
- fo.AllowPartialResults = opt.AllowPartialResults
- }
- if opt.BatchSize != nil {
- fo.BatchSize = opt.BatchSize
- }
- if opt.Collation != nil {
- fo.Collation = opt.Collation
- }
- if opt.Comment != nil {
- fo.Comment = opt.Comment
- }
- if opt.CursorType != nil {
- fo.CursorType = opt.CursorType
- }
- if opt.Hint != nil {
- fo.Hint = opt.Hint
- }
- if opt.Max != nil {
- fo.Max = opt.Max
- }
- if opt.MaxAwaitTime != nil {
- fo.MaxAwaitTime = opt.MaxAwaitTime
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.Min != nil {
- fo.Min = opt.Min
- }
- if opt.NoCursorTimeout != nil {
- fo.NoCursorTimeout = opt.NoCursorTimeout
- }
- if opt.OplogReplay != nil {
- fo.OplogReplay = opt.OplogReplay
- }
- if opt.Projection != nil {
- fo.Projection = opt.Projection
- }
- if opt.ReturnKey != nil {
- fo.ReturnKey = opt.ReturnKey
- }
- if opt.ShowRecordID != nil {
- fo.ShowRecordID = opt.ShowRecordID
- }
- if opt.Skip != nil {
- fo.Skip = opt.Skip
- }
- if opt.Snapshot != nil {
- fo.Snapshot = opt.Snapshot
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- }
-
- return fo
-}
-
-// FindOneAndReplaceOptions represents options that can be used to configure a FindOneAndReplace instance.
-type FindOneAndReplaceOptions struct {
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // A document describing which fields will be included in the document returned by the operation. The default value
- // is nil, which means all fields will be included.
- Projection interface{}
-
- // Specifies whether the original or replaced document should be returned by the operation. The default value is
- // Before, which means the original document will be returned from before the replacement is performed.
- ReturnDocument *ReturnDocument
-
- // A document specifying which document should be replaced if the filter used by the operation matches multiple
- // documents in the collection. If set, the first document in the sorted order will be replaced. The driver will
- // return an error if the sort parameter is a multi-key map. The default value is nil.
- Sort interface{}
-
- // If true, a new document will be inserted if the filter does not match any documents in the collection. The
- // default value is false.
- Upsert *bool
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an error if
- // this option is specified. For server versions < 4.2, the driver will return an error if this option is specified.
- // The driver will return an error if this option is used with during an unacknowledged write operation. The driver
- // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint
- // will be sent.
- Hint interface{}
-
- // Specifies parameters for the find one and replace expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// FindOneAndReplace creates a new FindOneAndReplaceOptions instance.
-func FindOneAndReplace() *FindOneAndReplaceOptions {
- return &FindOneAndReplaceOptions{}
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (f *FindOneAndReplaceOptions) SetBypassDocumentValidation(b bool) *FindOneAndReplaceOptions {
- f.BypassDocumentValidation = &b
- return f
-}
-
-// SetCollation sets the value for the Collation field.
-func (f *FindOneAndReplaceOptions) SetCollation(collation *Collation) *FindOneAndReplaceOptions {
- f.Collation = collation
- return f
-}
-
-// SetComment sets the value for the Comment field.
-func (f *FindOneAndReplaceOptions) SetComment(comment interface{}) *FindOneAndReplaceOptions {
- f.Comment = comment
- return f
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *FindOneAndReplaceOptions) SetMaxTime(d time.Duration) *FindOneAndReplaceOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetProjection sets the value for the Projection field.
-func (f *FindOneAndReplaceOptions) SetProjection(projection interface{}) *FindOneAndReplaceOptions {
- f.Projection = projection
- return f
-}
-
-// SetReturnDocument sets the value for the ReturnDocument field.
-func (f *FindOneAndReplaceOptions) SetReturnDocument(rd ReturnDocument) *FindOneAndReplaceOptions {
- f.ReturnDocument = &rd
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *FindOneAndReplaceOptions) SetSort(sort interface{}) *FindOneAndReplaceOptions {
- f.Sort = sort
- return f
-}
-
-// SetUpsert sets the value for the Upsert field.
-func (f *FindOneAndReplaceOptions) SetUpsert(b bool) *FindOneAndReplaceOptions {
- f.Upsert = &b
- return f
-}
-
-// SetHint sets the value for the Hint field.
-func (f *FindOneAndReplaceOptions) SetHint(hint interface{}) *FindOneAndReplaceOptions {
- f.Hint = hint
- return f
-}
-
-// SetLet sets the value for the Let field.
-func (f *FindOneAndReplaceOptions) SetLet(let interface{}) *FindOneAndReplaceOptions {
- f.Let = let
- return f
-}
-
-// MergeFindOneAndReplaceOptions combines the given FindOneAndReplaceOptions instances into a single
-// FindOneAndReplaceOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeFindOneAndReplaceOptions(opts ...*FindOneAndReplaceOptions) *FindOneAndReplaceOptions {
- fo := FindOneAndReplace()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.BypassDocumentValidation != nil {
- fo.BypassDocumentValidation = opt.BypassDocumentValidation
- }
- if opt.Collation != nil {
- fo.Collation = opt.Collation
- }
- if opt.Comment != nil {
- fo.Comment = opt.Comment
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.Projection != nil {
- fo.Projection = opt.Projection
- }
- if opt.ReturnDocument != nil {
- fo.ReturnDocument = opt.ReturnDocument
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- if opt.Upsert != nil {
- fo.Upsert = opt.Upsert
- }
- if opt.Hint != nil {
- fo.Hint = opt.Hint
- }
- if opt.Let != nil {
- fo.Let = opt.Let
- }
- if opt.BypassEmptyTsReplacement != nil {
- fo.BypassEmptyTsReplacement = opt.BypassEmptyTsReplacement
- }
- }
-
- return fo
-}
-
-// FindOneAndUpdateOptions represents options that can be used to configure a FindOneAndUpdate options.
-type FindOneAndUpdateOptions struct {
- // A set of filters specifying to which array elements an update should apply. This option is only valid for MongoDB
- // versions >= 3.6. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the update will apply to all array elements.
- ArrayFilters *ArrayFilters
-
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime is
- // ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // A document describing which fields will be included in the document returned by the operation. The default value
- // is nil, which means all fields will be included.
- Projection interface{}
-
- // Specifies whether the original or replaced document should be returned by the operation. The default value is
- // Before, which means the original document will be returned before the replacement is performed.
- ReturnDocument *ReturnDocument
-
- // A document specifying which document should be updated if the filter used by the operation matches multiple
- // documents in the collection. If set, the first document in the sorted order will be updated. The driver will
- // return an error if the sort parameter is a multi-key map. The default value is nil.
- Sort interface{}
-
- // If true, a new document will be inserted if the filter does not match any documents in the collection. The
- // default value is false.
- Upsert *bool
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an error if
- // this option is specified. For server versions < 4.2, the driver will return an error if this option is specified.
- // The driver will return an error if this option is used with during an unacknowledged write operation. The driver
- // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint
- // will be sent.
- Hint interface{}
-
- // Specifies parameters for the find one and update expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// FindOneAndUpdate creates a new FindOneAndUpdateOptions instance.
-func FindOneAndUpdate() *FindOneAndUpdateOptions {
- return &FindOneAndUpdateOptions{}
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (f *FindOneAndUpdateOptions) SetBypassDocumentValidation(b bool) *FindOneAndUpdateOptions {
- f.BypassDocumentValidation = &b
- return f
-}
-
-// SetArrayFilters sets the value for the ArrayFilters field.
-func (f *FindOneAndUpdateOptions) SetArrayFilters(filters ArrayFilters) *FindOneAndUpdateOptions {
- f.ArrayFilters = &filters
- return f
-}
-
-// SetCollation sets the value for the Collation field.
-func (f *FindOneAndUpdateOptions) SetCollation(collation *Collation) *FindOneAndUpdateOptions {
- f.Collation = collation
- return f
-}
-
-// SetComment sets the value for the Comment field.
-func (f *FindOneAndUpdateOptions) SetComment(comment interface{}) *FindOneAndUpdateOptions {
- f.Comment = comment
- return f
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *FindOneAndUpdateOptions) SetMaxTime(d time.Duration) *FindOneAndUpdateOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetProjection sets the value for the Projection field.
-func (f *FindOneAndUpdateOptions) SetProjection(projection interface{}) *FindOneAndUpdateOptions {
- f.Projection = projection
- return f
-}
-
-// SetReturnDocument sets the value for the ReturnDocument field.
-func (f *FindOneAndUpdateOptions) SetReturnDocument(rd ReturnDocument) *FindOneAndUpdateOptions {
- f.ReturnDocument = &rd
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *FindOneAndUpdateOptions) SetSort(sort interface{}) *FindOneAndUpdateOptions {
- f.Sort = sort
- return f
-}
-
-// SetUpsert sets the value for the Upsert field.
-func (f *FindOneAndUpdateOptions) SetUpsert(b bool) *FindOneAndUpdateOptions {
- f.Upsert = &b
- return f
-}
-
-// SetHint sets the value for the Hint field.
-func (f *FindOneAndUpdateOptions) SetHint(hint interface{}) *FindOneAndUpdateOptions {
- f.Hint = hint
- return f
-}
-
-// SetLet sets the value for the Let field.
-func (f *FindOneAndUpdateOptions) SetLet(let interface{}) *FindOneAndUpdateOptions {
- f.Let = let
- return f
-}
-
-// MergeFindOneAndUpdateOptions combines the given FindOneAndUpdateOptions instances into a single
-// FindOneAndUpdateOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeFindOneAndUpdateOptions(opts ...*FindOneAndUpdateOptions) *FindOneAndUpdateOptions {
- fo := FindOneAndUpdate()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ArrayFilters != nil {
- fo.ArrayFilters = opt.ArrayFilters
- }
- if opt.BypassDocumentValidation != nil {
- fo.BypassDocumentValidation = opt.BypassDocumentValidation
- }
- if opt.Collation != nil {
- fo.Collation = opt.Collation
- }
- if opt.Comment != nil {
- fo.Comment = opt.Comment
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.Projection != nil {
- fo.Projection = opt.Projection
- }
- if opt.ReturnDocument != nil {
- fo.ReturnDocument = opt.ReturnDocument
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- if opt.Upsert != nil {
- fo.Upsert = opt.Upsert
- }
- if opt.Hint != nil {
- fo.Hint = opt.Hint
- }
- if opt.Let != nil {
- fo.Let = opt.Let
- }
- if opt.BypassEmptyTsReplacement != nil {
- fo.BypassEmptyTsReplacement = opt.BypassEmptyTsReplacement
- }
- }
-
- return fo
-}
-
-// FindOneAndDeleteOptions represents options that can be used to configure a FindOneAndDelete operation.
-type FindOneAndDeleteOptions struct {
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // A document describing which fields will be included in the document returned by the operation. The default value
- // is nil, which means all fields will be included.
- Projection interface{}
-
- // A document specifying which document should be replaced if the filter used by the operation matches multiple
- // documents in the collection. If set, the first document in the sorted order will be selected for replacement.
- // The driver will return an error if the sort parameter is a multi-key map. The default value is nil.
- Sort interface{}
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an error if
- // this option is specified. For server versions < 4.2, the driver will return an error if this option is specified.
- // The driver will return an error if this option is used with during an unacknowledged write operation. The driver
- // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint
- // will be sent.
- Hint interface{}
-
- // Specifies parameters for the find one and delete expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-}
-
-// FindOneAndDelete creates a new FindOneAndDeleteOptions instance.
-func FindOneAndDelete() *FindOneAndDeleteOptions {
- return &FindOneAndDeleteOptions{}
-}
-
-// SetCollation sets the value for the Collation field.
-func (f *FindOneAndDeleteOptions) SetCollation(collation *Collation) *FindOneAndDeleteOptions {
- f.Collation = collation
- return f
-}
-
-// SetComment sets the value for the Comment field.
-func (f *FindOneAndDeleteOptions) SetComment(comment interface{}) *FindOneAndDeleteOptions {
- f.Comment = comment
- return f
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *FindOneAndDeleteOptions) SetMaxTime(d time.Duration) *FindOneAndDeleteOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetProjection sets the value for the Projection field.
-func (f *FindOneAndDeleteOptions) SetProjection(projection interface{}) *FindOneAndDeleteOptions {
- f.Projection = projection
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *FindOneAndDeleteOptions) SetSort(sort interface{}) *FindOneAndDeleteOptions {
- f.Sort = sort
- return f
-}
-
-// SetHint sets the value for the Hint field.
-func (f *FindOneAndDeleteOptions) SetHint(hint interface{}) *FindOneAndDeleteOptions {
- f.Hint = hint
- return f
-}
-
-// SetLet sets the value for the Let field.
-func (f *FindOneAndDeleteOptions) SetLet(let interface{}) *FindOneAndDeleteOptions {
- f.Let = let
- return f
-}
-
-// MergeFindOneAndDeleteOptions combines the given FindOneAndDeleteOptions instances into a single
-// FindOneAndDeleteOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeFindOneAndDeleteOptions(opts ...*FindOneAndDeleteOptions) *FindOneAndDeleteOptions {
- fo := FindOneAndDelete()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Collation != nil {
- fo.Collation = opt.Collation
- }
- if opt.Comment != nil {
- fo.Comment = opt.Comment
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.Projection != nil {
- fo.Projection = opt.Projection
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- if opt.Hint != nil {
- fo.Hint = opt.Hint
- }
- if opt.Let != nil {
- fo.Let = opt.Let
- }
- }
-
- return fo
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/gridfsoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/gridfsoptions.go
deleted file mode 100644
index c8d347f4e..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/gridfsoptions.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// 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 (
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
-)
-
-// DefaultName is the default name for a GridFS bucket.
-var DefaultName = "fs"
-
-// DefaultChunkSize is the default size of each file chunk in bytes (255 KiB).
-var DefaultChunkSize int32 = 255 * 1024
-
-// DefaultRevision is the default revision number for a download by name operation.
-var DefaultRevision int32 = -1
-
-// BucketOptions represents options that can be used to configure GridFS bucket.
-type BucketOptions struct {
- // The name of the bucket. The default value is "fs".
- Name *string
-
- // The number of bytes in each chunk in the bucket. The default value is 255 KiB.
- ChunkSizeBytes *int32
-
- // The write concern for the bucket. The default value is the write concern of the database from which the bucket
- // is created.
- WriteConcern *writeconcern.WriteConcern
-
- // The read concern for the bucket. The default value is the read concern of the database from which the bucket
- // is created.
- ReadConcern *readconcern.ReadConcern
-
- // The read preference for the bucket. The default value is the read preference of the database from which the
- // bucket is created.
- ReadPreference *readpref.ReadPref
-}
-
-// GridFSBucket creates a new BucketOptions instance.
-func GridFSBucket() *BucketOptions {
- return &BucketOptions{
- Name: &DefaultName,
- ChunkSizeBytes: &DefaultChunkSize,
- }
-}
-
-// SetName sets the value for the Name field.
-func (b *BucketOptions) SetName(name string) *BucketOptions {
- b.Name = &name
- return b
-}
-
-// SetChunkSizeBytes sets the value for the ChunkSize field.
-func (b *BucketOptions) SetChunkSizeBytes(i int32) *BucketOptions {
- b.ChunkSizeBytes = &i
- return b
-}
-
-// SetWriteConcern sets the value for the WriteConcern field.
-func (b *BucketOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *BucketOptions {
- b.WriteConcern = wc
- return b
-}
-
-// SetReadConcern sets the value for the ReadConcern field.
-func (b *BucketOptions) SetReadConcern(rc *readconcern.ReadConcern) *BucketOptions {
- b.ReadConcern = rc
- return b
-}
-
-// SetReadPreference sets the value for the ReadPreference field.
-func (b *BucketOptions) SetReadPreference(rp *readpref.ReadPref) *BucketOptions {
- b.ReadPreference = rp
- return b
-}
-
-// MergeBucketOptions combines the given BucketOptions instances into a single BucketOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeBucketOptions(opts ...*BucketOptions) *BucketOptions {
- b := GridFSBucket()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Name != nil {
- b.Name = opt.Name
- }
- if opt.ChunkSizeBytes != nil {
- b.ChunkSizeBytes = opt.ChunkSizeBytes
- }
- if opt.WriteConcern != nil {
- b.WriteConcern = opt.WriteConcern
- }
- if opt.ReadConcern != nil {
- b.ReadConcern = opt.ReadConcern
- }
- if opt.ReadPreference != nil {
- b.ReadPreference = opt.ReadPreference
- }
- }
-
- return b
-}
-
-// UploadOptions represents options that can be used to configure a GridFS upload operation.
-type UploadOptions struct {
- // The number of bytes in each chunk in the bucket. The default value is DefaultChunkSize (255 KiB).
- ChunkSizeBytes *int32
-
- // Additional application data that will be stored in the "metadata" field of the document in the files collection.
- // The default value is nil, which means that the document in the files collection will not contain a "metadata"
- // field.
- Metadata interface{}
-
- // The BSON registry to use for converting filters to BSON documents. The default value is bson.DefaultRegistry.
- Registry *bsoncodec.Registry
-}
-
-// GridFSUpload creates a new UploadOptions instance.
-func GridFSUpload() *UploadOptions {
- return &UploadOptions{Registry: bson.DefaultRegistry}
-}
-
-// SetChunkSizeBytes sets the value for the ChunkSize field.
-func (u *UploadOptions) SetChunkSizeBytes(i int32) *UploadOptions {
- u.ChunkSizeBytes = &i
- return u
-}
-
-// SetMetadata sets the value for the Metadata field.
-func (u *UploadOptions) SetMetadata(doc interface{}) *UploadOptions {
- u.Metadata = doc
- return u
-}
-
-// MergeUploadOptions combines the given UploadOptions instances into a single UploadOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeUploadOptions(opts ...*UploadOptions) *UploadOptions {
- u := GridFSUpload()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ChunkSizeBytes != nil {
- u.ChunkSizeBytes = opt.ChunkSizeBytes
- }
- if opt.Metadata != nil {
- u.Metadata = opt.Metadata
- }
- if opt.Registry != nil {
- u.Registry = opt.Registry
- }
- }
-
- return u
-}
-
-// NameOptions represents options that can be used to configure a GridFS DownloadByName operation.
-type NameOptions struct {
- // Specifies the revision of the file to retrieve. Revision numbers are defined as follows:
- //
- // * 0 = the original stored file
- // * 1 = the first revision
- // * 2 = the second revision
- // * etc..
- // * -2 = the second most recent revision
- // * -1 = the most recent revision.
- //
- // The default value is -1
- Revision *int32
-}
-
-// GridFSName creates a new NameOptions instance.
-func GridFSName() *NameOptions {
- return &NameOptions{}
-}
-
-// SetRevision sets the value for the Revision field.
-func (n *NameOptions) SetRevision(r int32) *NameOptions {
- n.Revision = &r
- return n
-}
-
-// MergeNameOptions combines the given NameOptions instances into a single *NameOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeNameOptions(opts ...*NameOptions) *NameOptions {
- n := GridFSName()
- n.Revision = &DefaultRevision
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Revision != nil {
- n.Revision = opt.Revision
- }
- }
-
- return n
-}
-
-// GridFSFindOptions represents options that can be used to configure a GridFS Find operation.
-type GridFSFindOptions struct {
- // If true, the server can write temporary data to disk while executing the find operation. The default value
- // is false. This option is only valid for MongoDB versions >= 4.4. For previous server versions, the server will
- // return an error if this option is used.
- AllowDiskUse *bool
-
- // The maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // The maximum number of documents to return. The default value is 0, which means that all documents matching the
- // filter will be returned. A negative limit specifies that the resulting documents should be returned in a single
- // batch. The default value is 0.
- Limit *int32
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-
- // If true, the cursor created by the operation will not timeout after a period of inactivity. The default value
- // is false.
- NoCursorTimeout *bool
-
- // The number of documents to skip before adding documents to the result. The default value is 0.
- Skip *int32
-
- // A document specifying the order in which documents should be returned. The driver will return an error if the
- // sort parameter is a multi-key map.
- Sort interface{}
-}
-
-// GridFSFind creates a new GridFSFindOptions instance.
-func GridFSFind() *GridFSFindOptions {
- return &GridFSFindOptions{}
-}
-
-// SetAllowDiskUse sets the value for the AllowDiskUse field.
-func (f *GridFSFindOptions) SetAllowDiskUse(b bool) *GridFSFindOptions {
- f.AllowDiskUse = &b
- return f
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (f *GridFSFindOptions) SetBatchSize(i int32) *GridFSFindOptions {
- f.BatchSize = &i
- return f
-}
-
-// SetLimit sets the value for the Limit field.
-func (f *GridFSFindOptions) SetLimit(i int32) *GridFSFindOptions {
- f.Limit = &i
- return f
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (f *GridFSFindOptions) SetMaxTime(d time.Duration) *GridFSFindOptions {
- f.MaxTime = &d
- return f
-}
-
-// SetNoCursorTimeout sets the value for the NoCursorTimeout field.
-func (f *GridFSFindOptions) SetNoCursorTimeout(b bool) *GridFSFindOptions {
- f.NoCursorTimeout = &b
- return f
-}
-
-// SetSkip sets the value for the Skip field.
-func (f *GridFSFindOptions) SetSkip(i int32) *GridFSFindOptions {
- f.Skip = &i
- return f
-}
-
-// SetSort sets the value for the Sort field.
-func (f *GridFSFindOptions) SetSort(sort interface{}) *GridFSFindOptions {
- f.Sort = sort
- return f
-}
-
-// MergeGridFSFindOptions combines the given GridFSFindOptions instances into a single GridFSFindOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeGridFSFindOptions(opts ...*GridFSFindOptions) *GridFSFindOptions {
- fo := GridFSFind()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.AllowDiskUse != nil {
- fo.AllowDiskUse = opt.AllowDiskUse
- }
- if opt.BatchSize != nil {
- fo.BatchSize = opt.BatchSize
- }
- if opt.Limit != nil {
- fo.Limit = opt.Limit
- }
- if opt.MaxTime != nil {
- fo.MaxTime = opt.MaxTime
- }
- if opt.NoCursorTimeout != nil {
- fo.NoCursorTimeout = opt.NoCursorTimeout
- }
- if opt.Skip != nil {
- fo.Skip = opt.Skip
- }
- if opt.Sort != nil {
- fo.Sort = opt.Sort
- }
- }
-
- return fo
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go
deleted file mode 100644
index ab7e2b3f6..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go
+++ /dev/null
@@ -1,494 +0,0 @@
-// 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 (
- "time"
-)
-
-// CreateIndexesOptions represents options that can be used to configure IndexView.CreateOne and IndexView.CreateMany
-// operations.
-type CreateIndexesOptions struct {
- // The number of data-bearing members of a replica set, including the primary, that must complete the index builds
- // successfully before the primary marks the indexes as ready. This should either be a string or int32 value. The
- // semantics of the values are as follows:
- //
- // 1. String: specifies a tag. All members with that tag must complete the build.
- // 2. int: the number of members that must complete the build.
- // 3. "majority": A special value to indicate that more than half the nodes must complete the build.
- // 4. "votingMembers": A special value to indicate that all voting data-bearing nodes must complete.
- //
- // This option is only available on MongoDB versions >= 4.4. A client-side error will be returned if the option
- // is specified for MongoDB versions <= 4.2. The default value is nil, meaning that the server-side default will be
- // used. See dochub.mongodb.org/core/index-commit-quorum for more information.
- CommitQuorum interface{}
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-}
-
-// CreateIndexes creates a new CreateIndexesOptions instance.
-func CreateIndexes() *CreateIndexesOptions {
- return &CreateIndexesOptions{}
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (c *CreateIndexesOptions) SetMaxTime(d time.Duration) *CreateIndexesOptions {
- c.MaxTime = &d
- return c
-}
-
-// SetCommitQuorumInt sets the value for the CommitQuorum field as an int32.
-func (c *CreateIndexesOptions) SetCommitQuorumInt(quorum int32) *CreateIndexesOptions {
- c.CommitQuorum = quorum
- return c
-}
-
-// SetCommitQuorumString sets the value for the CommitQuorum field as a string.
-func (c *CreateIndexesOptions) SetCommitQuorumString(quorum string) *CreateIndexesOptions {
- c.CommitQuorum = quorum
- return c
-}
-
-// SetCommitQuorumMajority sets the value for the CommitQuorum to special "majority" value.
-func (c *CreateIndexesOptions) SetCommitQuorumMajority() *CreateIndexesOptions {
- c.CommitQuorum = "majority"
- return c
-}
-
-// SetCommitQuorumVotingMembers sets the value for the CommitQuorum to special "votingMembers" value.
-func (c *CreateIndexesOptions) SetCommitQuorumVotingMembers() *CreateIndexesOptions {
- c.CommitQuorum = "votingMembers"
- return c
-}
-
-// MergeCreateIndexesOptions combines the given CreateIndexesOptions into a single CreateIndexesOptions in a last one
-// wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeCreateIndexesOptions(opts ...*CreateIndexesOptions) *CreateIndexesOptions {
- c := CreateIndexes()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.MaxTime != nil {
- c.MaxTime = opt.MaxTime
- }
- if opt.CommitQuorum != nil {
- c.CommitQuorum = opt.CommitQuorum
- }
- }
-
- return c
-}
-
-// DropIndexesOptions represents options that can be used to configure IndexView.DropOne and IndexView.DropAll
-// operations.
-type DropIndexesOptions struct {
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-}
-
-// DropIndexes creates a new DropIndexesOptions instance.
-func DropIndexes() *DropIndexesOptions {
- return &DropIndexesOptions{}
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (d *DropIndexesOptions) SetMaxTime(duration time.Duration) *DropIndexesOptions {
- d.MaxTime = &duration
- return d
-}
-
-// MergeDropIndexesOptions combines the given DropIndexesOptions into a single DropIndexesOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeDropIndexesOptions(opts ...*DropIndexesOptions) *DropIndexesOptions {
- c := DropIndexes()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.MaxTime != nil {
- c.MaxTime = opt.MaxTime
- }
- }
-
- return c
-}
-
-// ListIndexesOptions represents options that can be used to configure an IndexView.List operation.
-type ListIndexesOptions struct {
- // The maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // The maximum amount of time that the query can run on the server. The default value is nil, meaning that there
- // is no time limit for query execution.
- //
- // NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout option may be used
- // in its place to control the amount of time that a single operation can run before returning an error. MaxTime
- // is ignored if Timeout is set on the client.
- MaxTime *time.Duration
-}
-
-// ListIndexes creates a new ListIndexesOptions instance.
-func ListIndexes() *ListIndexesOptions {
- return &ListIndexesOptions{}
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (l *ListIndexesOptions) SetBatchSize(i int32) *ListIndexesOptions {
- l.BatchSize = &i
- return l
-}
-
-// SetMaxTime sets the value for the MaxTime field.
-//
-// NOTE(benjirewis): MaxTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can
-// run before returning an error. MaxTime is ignored if Timeout is set on the client.
-func (l *ListIndexesOptions) SetMaxTime(d time.Duration) *ListIndexesOptions {
- l.MaxTime = &d
- return l
-}
-
-// MergeListIndexesOptions combines the given ListIndexesOptions instances into a single *ListIndexesOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeListIndexesOptions(opts ...*ListIndexesOptions) *ListIndexesOptions {
- c := ListIndexes()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.BatchSize != nil {
- c.BatchSize = opt.BatchSize
- }
- if opt.MaxTime != nil {
- c.MaxTime = opt.MaxTime
- }
- }
-
- return c
-}
-
-// IndexOptions represents options that can be used to configure a new index created through the IndexView.CreateOne
-// or IndexView.CreateMany operations.
-type IndexOptions struct {
- // If true, the index will be built in the background on the server and will not block other tasks. The default
- // value is false.
- //
- // Deprecated: This option has been deprecated in MongoDB version 4.2.
- Background *bool
-
- // The length of time, in seconds, for documents to remain in the collection. The default value is 0, which means
- // that documents will remain in the collection until they're explicitly deleted or the collection is dropped.
- ExpireAfterSeconds *int32
-
- // The name of the index. The default value is "[field1]_[direction1]_[field2]_[direction2]...". For example, an
- // index with the specification {name: 1, age: -1} will be named "name_1_age_-1".
- Name *string
-
- // If true, the index will only reference documents that contain the fields specified in the index. The default is
- // false.
- Sparse *bool
-
- // Specifies the storage engine to use for the index. The value must be a document in the form
- // {: }. The default value is nil, which means that the default storage engine
- // will be used. This option is only applicable for MongoDB versions >= 3.0 and is ignored for previous server
- // versions.
- StorageEngine interface{}
-
- // If true, the collection will not accept insertion or update of documents where the index key value matches an
- // existing value in the index. The default is false.
- Unique *bool
-
- // The index version number, either 0 or 1.
- Version *int32
-
- // The language that determines the list of stop words and the rules for the stemmer and tokenizer. This option
- // is only applicable for text indexes and is ignored for other index types. The default value is "english".
- DefaultLanguage *string
-
- // The name of the field in the collection's documents that contains the override language for the document. This
- // option is only applicable for text indexes and is ignored for other index types. The default value is the value
- // of the DefaultLanguage option.
- LanguageOverride *string
-
- // The index version number for a text index. See https://www.mongodb.com/docs/manual/core/index-text/#text-versions for
- // information about different version numbers.
- TextVersion *int32
-
- // A document that contains field and weight pairs. The weight is an integer ranging from 1 to 99,999, inclusive,
- // indicating the significance of the field relative to the other indexed fields in terms of the score. This option
- // is only applicable for text indexes and is ignored for other index types. The default value is nil, which means
- // that every field will have a weight of 1.
- Weights interface{}
-
- // The index version number for a 2D sphere index. See https://www.mongodb.com/docs/manual/core/2dsphere/#dsphere-v2 for
- // information about different version numbers.
- SphereVersion *int32
-
- // The precision of the stored geohash value of the location data. This option only applies to 2D indexes and is
- // ignored for other index types. The value must be between 1 and 32, inclusive. The default value is 26.
- Bits *int32
-
- // The upper inclusive boundary for longitude and latitude values. This option is only applicable to 2D indexes and
- // is ignored for other index types. The default value is 180.0.
- Max *float64
-
- // The lower inclusive boundary for longitude and latitude values. This option is only applicable to 2D indexes and
- // is ignored for other index types. The default value is -180.0.
- Min *float64
-
- // The number of units within which to group location values. Location values that are within BucketSize units of
- // each other will be grouped in the same bucket. This option is only applicable to geoHaystack indexes and is
- // ignored for other index types. The value must be greater than 0.
- BucketSize *int32
-
- // A document that defines which collection documents the index should reference. This option is only valid for
- // MongoDB versions >= 3.2 and is ignored for previous server versions.
- PartialFilterExpression interface{}
-
- // The collation to use for string comparisons for the index. This option is only valid for MongoDB versions >= 3.4.
- // For previous server versions, the driver will return an error if this option is used.
- Collation *Collation
-
- // A document that defines the wildcard projection for the index.
- WildcardProjection interface{}
-
- // If true, the index will exist on the target collection but will not be used by the query planner when executing
- // operations. This option is only valid for MongoDB versions >= 4.4. The default value is false.
- Hidden *bool
-}
-
-// Index creates a new IndexOptions instance.
-func Index() *IndexOptions {
- return &IndexOptions{}
-}
-
-// SetBackground sets value for the Background field.
-//
-// Deprecated: This option has been deprecated in MongoDB version 4.2.
-func (i *IndexOptions) SetBackground(background bool) *IndexOptions {
- i.Background = &background
- return i
-}
-
-// SetExpireAfterSeconds sets value for the ExpireAfterSeconds field.
-func (i *IndexOptions) SetExpireAfterSeconds(seconds int32) *IndexOptions {
- i.ExpireAfterSeconds = &seconds
- return i
-}
-
-// SetName sets the value for the Name field.
-func (i *IndexOptions) SetName(name string) *IndexOptions {
- i.Name = &name
- return i
-}
-
-// SetSparse sets the value of the Sparse field.
-func (i *IndexOptions) SetSparse(sparse bool) *IndexOptions {
- i.Sparse = &sparse
- return i
-}
-
-// SetStorageEngine sets the value for the StorageEngine field.
-func (i *IndexOptions) SetStorageEngine(engine interface{}) *IndexOptions {
- i.StorageEngine = engine
- return i
-}
-
-// SetUnique sets the value for the Unique field.
-func (i *IndexOptions) SetUnique(unique bool) *IndexOptions {
- i.Unique = &unique
- return i
-}
-
-// SetVersion sets the value for the Version field.
-func (i *IndexOptions) SetVersion(version int32) *IndexOptions {
- i.Version = &version
- return i
-}
-
-// SetDefaultLanguage sets the value for the DefaultLanguage field.
-func (i *IndexOptions) SetDefaultLanguage(language string) *IndexOptions {
- i.DefaultLanguage = &language
- return i
-}
-
-// SetLanguageOverride sets the value of the LanguageOverride field.
-func (i *IndexOptions) SetLanguageOverride(override string) *IndexOptions {
- i.LanguageOverride = &override
- return i
-}
-
-// SetTextVersion sets the value for the TextVersion field.
-func (i *IndexOptions) SetTextVersion(version int32) *IndexOptions {
- i.TextVersion = &version
- return i
-}
-
-// SetWeights sets the value for the Weights field.
-func (i *IndexOptions) SetWeights(weights interface{}) *IndexOptions {
- i.Weights = weights
- return i
-}
-
-// SetSphereVersion sets the value for the SphereVersion field.
-func (i *IndexOptions) SetSphereVersion(version int32) *IndexOptions {
- i.SphereVersion = &version
- return i
-}
-
-// SetBits sets the value for the Bits field.
-func (i *IndexOptions) SetBits(bits int32) *IndexOptions {
- i.Bits = &bits
- return i
-}
-
-// SetMax sets the value for the Max field.
-func (i *IndexOptions) SetMax(max float64) *IndexOptions {
- i.Max = &max
- return i
-}
-
-// SetMin sets the value for the Min field.
-func (i *IndexOptions) SetMin(min float64) *IndexOptions {
- i.Min = &min
- return i
-}
-
-// SetBucketSize sets the value for the BucketSize field
-func (i *IndexOptions) SetBucketSize(bucketSize int32) *IndexOptions {
- i.BucketSize = &bucketSize
- return i
-}
-
-// SetPartialFilterExpression sets the value for the PartialFilterExpression field.
-func (i *IndexOptions) SetPartialFilterExpression(expression interface{}) *IndexOptions {
- i.PartialFilterExpression = expression
- return i
-}
-
-// SetCollation sets the value for the Collation field.
-func (i *IndexOptions) SetCollation(collation *Collation) *IndexOptions {
- i.Collation = collation
- return i
-}
-
-// SetWildcardProjection sets the value for the WildcardProjection field.
-func (i *IndexOptions) SetWildcardProjection(wildcardProjection interface{}) *IndexOptions {
- i.WildcardProjection = wildcardProjection
- return i
-}
-
-// SetHidden sets the value for the Hidden field.
-func (i *IndexOptions) SetHidden(hidden bool) *IndexOptions {
- i.Hidden = &hidden
- return i
-}
-
-// MergeIndexOptions combines the given IndexOptions into a single IndexOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeIndexOptions(opts ...*IndexOptions) *IndexOptions {
- i := Index()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.Background != nil {
- i.Background = opt.Background
- }
- if opt.ExpireAfterSeconds != nil {
- i.ExpireAfterSeconds = opt.ExpireAfterSeconds
- }
- if opt.Name != nil {
- i.Name = opt.Name
- }
- if opt.Sparse != nil {
- i.Sparse = opt.Sparse
- }
- if opt.StorageEngine != nil {
- i.StorageEngine = opt.StorageEngine
- }
- if opt.Unique != nil {
- i.Unique = opt.Unique
- }
- if opt.Version != nil {
- i.Version = opt.Version
- }
- if opt.DefaultLanguage != nil {
- i.DefaultLanguage = opt.DefaultLanguage
- }
- if opt.LanguageOverride != nil {
- i.LanguageOverride = opt.LanguageOverride
- }
- if opt.TextVersion != nil {
- i.TextVersion = opt.TextVersion
- }
- if opt.Weights != nil {
- i.Weights = opt.Weights
- }
- if opt.SphereVersion != nil {
- i.SphereVersion = opt.SphereVersion
- }
- if opt.Bits != nil {
- i.Bits = opt.Bits
- }
- if opt.Max != nil {
- i.Max = opt.Max
- }
- if opt.Min != nil {
- i.Min = opt.Min
- }
- if opt.BucketSize != nil {
- i.BucketSize = opt.BucketSize
- }
- if opt.PartialFilterExpression != nil {
- i.PartialFilterExpression = opt.PartialFilterExpression
- }
- if opt.Collation != nil {
- i.Collation = opt.Collation
- }
- if opt.WildcardProjection != nil {
- i.WildcardProjection = opt.WildcardProjection
- }
- if opt.Hidden != nil {
- i.Hidden = opt.Hidden
- }
- }
-
- return i
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/insertoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/insertoptions.go
deleted file mode 100644
index f84f799de..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/insertoptions.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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
-
-// InsertOneOptions represents options that can be used to configure an InsertOne operation.
-type InsertOneOptions struct {
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// InsertOne creates a new InsertOneOptions instance.
-func InsertOne() *InsertOneOptions {
- return &InsertOneOptions{}
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (ioo *InsertOneOptions) SetBypassDocumentValidation(b bool) *InsertOneOptions {
- ioo.BypassDocumentValidation = &b
- return ioo
-}
-
-// SetComment sets the value for the Comment field.
-func (ioo *InsertOneOptions) SetComment(comment interface{}) *InsertOneOptions {
- ioo.Comment = comment
- return ioo
-}
-
-// MergeInsertOneOptions combines the given InsertOneOptions instances into a single InsertOneOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeInsertOneOptions(opts ...*InsertOneOptions) *InsertOneOptions {
- ioOpts := InsertOne()
- for _, ioo := range opts {
- if ioo == nil {
- continue
- }
- if ioo.BypassDocumentValidation != nil {
- ioOpts.BypassDocumentValidation = ioo.BypassDocumentValidation
- }
- if ioo.Comment != nil {
- ioOpts.Comment = ioo.Comment
- }
- if ioo.BypassEmptyTsReplacement != nil {
- ioOpts.BypassEmptyTsReplacement = ioo.BypassEmptyTsReplacement
- }
- }
-
- return ioOpts
-}
-
-// InsertManyOptions represents options that can be used to configure an InsertMany operation.
-type InsertManyOptions struct {
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // If true, no writes will be executed after one fails. The default value is true.
- Ordered *bool
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// InsertMany creates a new InsertManyOptions instance.
-func InsertMany() *InsertManyOptions {
- return &InsertManyOptions{
- Ordered: &DefaultOrdered,
- }
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (imo *InsertManyOptions) SetBypassDocumentValidation(b bool) *InsertManyOptions {
- imo.BypassDocumentValidation = &b
- return imo
-}
-
-// SetComment sets the value for the Comment field.
-func (imo *InsertManyOptions) SetComment(comment interface{}) *InsertManyOptions {
- imo.Comment = comment
- return imo
-}
-
-// SetOrdered sets the value for the Ordered field.
-func (imo *InsertManyOptions) SetOrdered(b bool) *InsertManyOptions {
- imo.Ordered = &b
- return imo
-}
-
-// MergeInsertManyOptions combines the given InsertManyOptions instances into a single InsertManyOptions in a last one
-// wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeInsertManyOptions(opts ...*InsertManyOptions) *InsertManyOptions {
- imOpts := InsertMany()
- for _, imo := range opts {
- if imo == nil {
- continue
- }
- if imo.BypassDocumentValidation != nil {
- imOpts.BypassDocumentValidation = imo.BypassDocumentValidation
- }
- if imo.Comment != nil {
- imOpts.Comment = imo.Comment
- }
- if imo.Ordered != nil {
- imOpts.Ordered = imo.Ordered
- }
- if imo.BypassEmptyTsReplacement != nil {
- imOpts.BypassEmptyTsReplacement = imo.BypassEmptyTsReplacement
- }
- }
-
- return imOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go
deleted file mode 100644
index 69b8c997e..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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
-
-// ListCollectionsOptions represents options that can be used to configure a ListCollections operation.
-type ListCollectionsOptions struct {
- // If true, each collection document will only contain a field for the collection name. The default value is false.
- NameOnly *bool
-
- // The maximum number of documents to be included in each batch returned by the server.
- BatchSize *int32
-
- // If true, and NameOnly is true, limits the documents returned to only contain collections the user is authorized to use. The default value
- // is false. This option is only valid for MongoDB server versions >= 4.0. Server versions < 4.0 ignore this option.
- AuthorizedCollections *bool
-}
-
-// ListCollections creates a new ListCollectionsOptions instance.
-func ListCollections() *ListCollectionsOptions {
- return &ListCollectionsOptions{}
-}
-
-// SetNameOnly sets the value for the NameOnly field.
-func (lc *ListCollectionsOptions) SetNameOnly(b bool) *ListCollectionsOptions {
- lc.NameOnly = &b
- return lc
-}
-
-// SetBatchSize sets the value for the BatchSize field.
-func (lc *ListCollectionsOptions) SetBatchSize(size int32) *ListCollectionsOptions {
- lc.BatchSize = &size
- return lc
-}
-
-// SetAuthorizedCollections sets the value for the AuthorizedCollections field. This option is only valid for MongoDB server versions >= 4.0. Server
-// versions < 4.0 ignore this option.
-func (lc *ListCollectionsOptions) SetAuthorizedCollections(b bool) *ListCollectionsOptions {
- lc.AuthorizedCollections = &b
- return lc
-}
-
-// MergeListCollectionsOptions combines the given ListCollectionsOptions instances into a single *ListCollectionsOptions
-// in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeListCollectionsOptions(opts ...*ListCollectionsOptions) *ListCollectionsOptions {
- lc := ListCollections()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.NameOnly != nil {
- lc.NameOnly = opt.NameOnly
- }
- if opt.BatchSize != nil {
- lc.BatchSize = opt.BatchSize
- }
- if opt.AuthorizedCollections != nil {
- lc.AuthorizedCollections = opt.AuthorizedCollections
- }
- }
-
- return lc
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go
deleted file mode 100644
index fbd3df60d..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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
-
-// ListDatabasesOptions represents options that can be used to configure a ListDatabases operation.
-type ListDatabasesOptions struct {
- // If true, only the Name field of the returned DatabaseSpecification objects will be populated. The default value
- // is false.
- NameOnly *bool
-
- // If true, only the databases which the user is authorized to see will be returned. For more information about
- // the behavior of this option, see https://www.mongodb.com/docs/manual/reference/privilege-actions/#find. The default
- // value is true.
- AuthorizedDatabases *bool
-}
-
-// ListDatabases creates a new ListDatabasesOptions instance.
-func ListDatabases() *ListDatabasesOptions {
- return &ListDatabasesOptions{}
-}
-
-// SetNameOnly sets the value for the NameOnly field.
-func (ld *ListDatabasesOptions) SetNameOnly(b bool) *ListDatabasesOptions {
- ld.NameOnly = &b
- return ld
-}
-
-// SetAuthorizedDatabases sets the value for the AuthorizedDatabases field.
-func (ld *ListDatabasesOptions) SetAuthorizedDatabases(b bool) *ListDatabasesOptions {
- ld.AuthorizedDatabases = &b
- return ld
-}
-
-// MergeListDatabasesOptions combines the given ListDatabasesOptions instances into a single *ListDatabasesOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeListDatabasesOptions(opts ...*ListDatabasesOptions) *ListDatabasesOptions {
- ld := ListDatabases()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.NameOnly != nil {
- ld.NameOnly = opt.NameOnly
- }
- if opt.AuthorizedDatabases != nil {
- ld.AuthorizedDatabases = opt.AuthorizedDatabases
- }
- }
-
- return ld
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go
deleted file mode 100644
index 36088c2fc..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// 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.
-//
-// Deprecated: Marshaling a Collation to BSON will not be supported in Go Driver 2.0.
-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 modified document for replace and update change events
- // if the post-image for this event is available.
- WhenAvailable FullDocument = "whenAvailable"
-)
-
-// TODO(GODRIVER-2617): Once Registry is removed, ArrayFilters doesn't need to
-// TODO be a separate type. Remove the type and update all ArrayFilters fields
-// TODO to be type []interface{}.
-
-// 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 is the registry to use for converting filters. Defaults to bson.DefaultRegistry.
- //
- // Deprecated: Marshaling ArrayFilters to BSON will not be supported in Go Driver 2.0.
- Registry *bsoncodec.Registry
-
- Filters []interface{} // The filters to apply
-}
-
-// ToArray builds a []bson.Raw from the provided ArrayFilters.
-//
-// Deprecated: Marshaling ArrayFilters to BSON will not be supported in Go Driver 2.0.
-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.
-//
-// Deprecated: Marshaling ArrayFilters to BSON will not be supported in Go Driver 2.0.
-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.
-//
-// Deprecated: MarshalError is unused and will be removed in Go Driver 2.0.
-type MarshalError struct {
- Value interface{}
- Err error
-}
-
-// Error implements the error interface.
-//
-// Deprecated: MarshalError is unused and will be removed in Go Driver 2.0.
-func (me MarshalError) Error() string {
- return fmt.Sprintf("cannot transform type %s to a bson.Raw", reflect.TypeOf(me.Value))
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go
deleted file mode 100644
index ae3e78494..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// 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
-
-// ReplaceOptions represents options that can be used to configure a ReplaceOne operation.
-type ReplaceOptions struct {
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will return an error
- // if this option is specified. For server versions < 3.4, the driver will return a client-side error if this option
- // is specified. The driver will return an error if this option is specified during an unacknowledged write
- // operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil,
- // which means that no hint will be sent.
- Hint interface{}
-
- // If true, a new document will be inserted if the filter does not match any documents in the collection. The
- // default value is false.
- Upsert *bool
-
- // Specifies parameters for the aggregate expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// Replace creates a new ReplaceOptions instance.
-func Replace() *ReplaceOptions {
- return &ReplaceOptions{}
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (ro *ReplaceOptions) SetBypassDocumentValidation(b bool) *ReplaceOptions {
- ro.BypassDocumentValidation = &b
- return ro
-}
-
-// SetCollation sets the value for the Collation field.
-func (ro *ReplaceOptions) SetCollation(c *Collation) *ReplaceOptions {
- ro.Collation = c
- return ro
-}
-
-// SetComment sets the value for the Comment field.
-func (ro *ReplaceOptions) SetComment(comment interface{}) *ReplaceOptions {
- ro.Comment = comment
- return ro
-}
-
-// SetHint sets the value for the Hint field.
-func (ro *ReplaceOptions) SetHint(h interface{}) *ReplaceOptions {
- ro.Hint = h
- return ro
-}
-
-// SetUpsert sets the value for the Upsert field.
-func (ro *ReplaceOptions) SetUpsert(b bool) *ReplaceOptions {
- ro.Upsert = &b
- return ro
-}
-
-// SetLet sets the value for the Let field.
-func (ro *ReplaceOptions) SetLet(l interface{}) *ReplaceOptions {
- ro.Let = l
- return ro
-}
-
-// MergeReplaceOptions combines the given ReplaceOptions instances into a single ReplaceOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeReplaceOptions(opts ...*ReplaceOptions) *ReplaceOptions {
- rOpts := Replace()
- for _, ro := range opts {
- if ro == nil {
- continue
- }
- if ro.BypassDocumentValidation != nil {
- rOpts.BypassDocumentValidation = ro.BypassDocumentValidation
- }
- if ro.Collation != nil {
- rOpts.Collation = ro.Collation
- }
- if ro.Comment != nil {
- rOpts.Comment = ro.Comment
- }
- if ro.Hint != nil {
- rOpts.Hint = ro.Hint
- }
- if ro.Upsert != nil {
- rOpts.Upsert = ro.Upsert
- }
- if ro.Let != nil {
- rOpts.Let = ro.Let
- }
- if ro.BypassEmptyTsReplacement != nil {
- rOpts.BypassEmptyTsReplacement = ro.BypassEmptyTsReplacement
- }
- }
-
- return rOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/rewrapdatakeyoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/rewrapdatakeyoptions.go
deleted file mode 100644
index 22ba58604..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/rewrapdatakeyoptions.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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
-
-// RewrapManyDataKeyOptions represents all possible options used to decrypt and encrypt all matching data keys with a
-// possibly new masterKey.
-type RewrapManyDataKeyOptions struct {
- // Provider identifies the new KMS provider. If omitted, encrypting uses the current KMS provider.
- Provider *string
-
- // MasterKey identifies the new masterKey. If omitted, rewraps with the current masterKey.
- MasterKey interface{}
-}
-
-// RewrapManyDataKey creates a new RewrapManyDataKeyOptions instance.
-func RewrapManyDataKey() *RewrapManyDataKeyOptions {
- return new(RewrapManyDataKeyOptions)
-}
-
-// SetProvider sets the value for the Provider field.
-func (rmdko *RewrapManyDataKeyOptions) SetProvider(provider string) *RewrapManyDataKeyOptions {
- rmdko.Provider = &provider
- return rmdko
-}
-
-// SetMasterKey sets the value for the MasterKey field.
-func (rmdko *RewrapManyDataKeyOptions) SetMasterKey(masterKey interface{}) *RewrapManyDataKeyOptions {
- rmdko.MasterKey = masterKey
- return rmdko
-}
-
-// MergeRewrapManyDataKeyOptions combines the given RewrapManyDataKeyOptions instances into a single
-// RewrapManyDataKeyOptions in a last one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeRewrapManyDataKeyOptions(opts ...*RewrapManyDataKeyOptions) *RewrapManyDataKeyOptions {
- rmdkOpts := RewrapManyDataKey()
- for _, rmdko := range opts {
- if rmdko == nil {
- continue
- }
- if provider := rmdko.Provider; provider != nil {
- rmdkOpts.Provider = provider
- }
- if masterKey := rmdko.MasterKey; masterKey != nil {
- rmdkOpts.MasterKey = masterKey
- }
- }
- return rmdkOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/runcmdoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/runcmdoptions.go
deleted file mode 100644
index b0cdec32c..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/runcmdoptions.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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 (
- "go.mongodb.org/mongo-driver/mongo/readpref"
-)
-
-// RunCmdOptions represents options that can be used to configure a RunCommand operation.
-type RunCmdOptions struct {
- // The read preference to use for the operation. The default value is nil, which means that the primary read
- // preference will be used.
- ReadPreference *readpref.ReadPref
-}
-
-// RunCmd creates a new RunCmdOptions instance.
-func RunCmd() *RunCmdOptions {
- return &RunCmdOptions{}
-}
-
-// SetReadPreference sets value for the ReadPreference field.
-func (rc *RunCmdOptions) SetReadPreference(rp *readpref.ReadPref) *RunCmdOptions {
- rc.ReadPreference = rp
- return rc
-}
-
-// MergeRunCmdOptions combines the given RunCmdOptions instances into one *RunCmdOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeRunCmdOptions(opts ...*RunCmdOptions) *RunCmdOptions {
- rc := RunCmd()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ReadPreference != nil {
- rc.ReadPreference = opt.ReadPreference
- }
- }
-
- return rc
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/searchindexoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/searchindexoptions.go
deleted file mode 100644
index 8cb8a08b7..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/searchindexoptions.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2023-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
-
-// SearchIndexesOptions represents options that can be used to configure a SearchIndexView.
-type SearchIndexesOptions struct {
- Name *string
- Type *string
-}
-
-// SearchIndexes creates a new SearchIndexesOptions instance.
-func SearchIndexes() *SearchIndexesOptions {
- return &SearchIndexesOptions{}
-}
-
-// SetName sets the value for the Name field.
-func (sio *SearchIndexesOptions) SetName(name string) *SearchIndexesOptions {
- sio.Name = &name
- return sio
-}
-
-// SetType sets the value for the Type field.
-func (sio *SearchIndexesOptions) SetType(typ string) *SearchIndexesOptions {
- sio.Type = &typ
- return sio
-}
-
-// CreateSearchIndexesOptions represents options that can be used to configure a SearchIndexView.CreateOne or
-// SearchIndexView.CreateMany operation.
-type CreateSearchIndexesOptions struct {
-}
-
-// ListSearchIndexesOptions represents options that can be used to configure a SearchIndexView.List operation.
-type ListSearchIndexesOptions struct {
- AggregateOpts *AggregateOptions
-}
-
-// DropSearchIndexOptions represents options that can be used to configure a SearchIndexView.DropOne operation.
-type DropSearchIndexOptions struct {
-}
-
-// UpdateSearchIndexOptions represents options that can be used to configure a SearchIndexView.UpdateOne operation.
-type UpdateSearchIndexOptions struct {
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/sessionoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/sessionoptions.go
deleted file mode 100644
index e1eab098b..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/sessionoptions.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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 (
- "time"
-
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
-)
-
-// DefaultCausalConsistency is the default value for the CausalConsistency option.
-var DefaultCausalConsistency = true
-
-// SessionOptions represents options that can be used to configure a Session.
-type SessionOptions struct {
- // If true, causal consistency will be enabled for the session. This option cannot be set to true if Snapshot is
- // set to true. The default value is true unless Snapshot is set to true. See
- // https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#sessions for more information.
- CausalConsistency *bool
-
- // The default read concern for transactions started in the session. The default value is nil, which means that
- // the read concern of the client used to start the session will be used.
- DefaultReadConcern *readconcern.ReadConcern
-
- // The default read preference for transactions started in the session. The default value is nil, which means that
- // the read preference of the client used to start the session will be used.
- DefaultReadPreference *readpref.ReadPref
-
- // The default write concern for transactions started in the session. The default value is nil, which means that
- // the write concern of the client used to start the session will be used.
- DefaultWriteConcern *writeconcern.WriteConcern
-
- // The default maximum amount of time that a CommitTransaction operation executed in the session can run on the
- // server. The default value is nil, which means that that there is no time limit for execution.
- //
- // NOTE(benjirewis): DefaultMaxCommitTime will be deprecated in a future release. The more general Timeout option
- // may be used in its place to control the amount of time that a single operation can run before returning an
- // error. DefaultMaxCommitTime is ignored if Timeout is set on the client.
- DefaultMaxCommitTime *time.Duration
-
- // If true, all read operations performed with this session will be read from the same snapshot. This option cannot
- // be set to true if CausalConsistency is set to true. Transactions and write operations are not allowed on
- // snapshot sessions and will error. The default value is false.
- Snapshot *bool
-}
-
-// Session creates a new SessionOptions instance.
-func Session() *SessionOptions {
- return &SessionOptions{}
-}
-
-// SetCausalConsistency sets the value for the CausalConsistency field.
-func (s *SessionOptions) SetCausalConsistency(b bool) *SessionOptions {
- s.CausalConsistency = &b
- return s
-}
-
-// SetDefaultReadConcern sets the value for the DefaultReadConcern field.
-func (s *SessionOptions) SetDefaultReadConcern(rc *readconcern.ReadConcern) *SessionOptions {
- s.DefaultReadConcern = rc
- return s
-}
-
-// SetDefaultReadPreference sets the value for the DefaultReadPreference field.
-func (s *SessionOptions) SetDefaultReadPreference(rp *readpref.ReadPref) *SessionOptions {
- s.DefaultReadPreference = rp
- return s
-}
-
-// SetDefaultWriteConcern sets the value for the DefaultWriteConcern field.
-func (s *SessionOptions) SetDefaultWriteConcern(wc *writeconcern.WriteConcern) *SessionOptions {
- s.DefaultWriteConcern = wc
- return s
-}
-
-// SetDefaultMaxCommitTime sets the value for the DefaultMaxCommitTime field.
-//
-// NOTE(benjirewis): DefaultMaxCommitTime will be deprecated in a future release. The more
-// general Timeout option may be used in its place to control the amount of time that a
-// single operation can run before returning an error. DefaultMaxCommitTime is ignored if
-// Timeout is set on the client.
-func (s *SessionOptions) SetDefaultMaxCommitTime(mct *time.Duration) *SessionOptions {
- s.DefaultMaxCommitTime = mct
- return s
-}
-
-// SetSnapshot sets the value for the Snapshot field.
-func (s *SessionOptions) SetSnapshot(b bool) *SessionOptions {
- s.Snapshot = &b
- return s
-}
-
-// MergeSessionOptions combines the given SessionOptions instances into a single SessionOptions in a last-one-wins
-// fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeSessionOptions(opts ...*SessionOptions) *SessionOptions {
- s := Session()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.CausalConsistency != nil {
- s.CausalConsistency = opt.CausalConsistency
- }
- if opt.DefaultReadConcern != nil {
- s.DefaultReadConcern = opt.DefaultReadConcern
- }
- if opt.DefaultReadPreference != nil {
- s.DefaultReadPreference = opt.DefaultReadPreference
- }
- if opt.DefaultWriteConcern != nil {
- s.DefaultWriteConcern = opt.DefaultWriteConcern
- }
- if opt.DefaultMaxCommitTime != nil {
- s.DefaultMaxCommitTime = opt.DefaultMaxCommitTime
- }
- if opt.Snapshot != nil {
- s.Snapshot = opt.Snapshot
- }
- }
- if s.CausalConsistency == nil && (s.Snapshot == nil || !*s.Snapshot) {
- s.CausalConsistency = &DefaultCausalConsistency
- }
-
- return s
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/transactionoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/transactionoptions.go
deleted file mode 100644
index 9270cd20d..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/transactionoptions.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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 (
- "time"
-
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
-)
-
-// TransactionOptions represents options that can be used to configure a transaction.
-type TransactionOptions struct {
- // The read concern for operations in the transaction. The default value is nil, which means that the default
- // read concern of the session used to start the transaction will be used.
- ReadConcern *readconcern.ReadConcern
-
- // The read preference for operations in the transaction. The default value is nil, which means that the default
- // read preference of the session used to start the transaction will be used.
- ReadPreference *readpref.ReadPref
-
- // The write concern for operations in the transaction. The default value is nil, which means that the default
- // write concern of the session used to start the transaction will be used.
- WriteConcern *writeconcern.WriteConcern
-
- // The default maximum amount of time that a CommitTransaction operation executed in the session can run on the
- // server. The default value is nil, meaning that there is no time limit for execution.
-
- // The maximum amount of time that a CommitTransaction operation can executed in the transaction can run on the
- // server. The default value is nil, which means that the default maximum commit time of the session used to
- // start the transaction will be used.
- //
- // NOTE(benjirewis): MaxCommitTime will be deprecated in a future release. The more general Timeout option may
- // be used in its place to control the amount of time that a single operation can run before returning an error.
- // MaxCommitTime is ignored if Timeout is set on the client.
- MaxCommitTime *time.Duration
-}
-
-// Transaction creates a new TransactionOptions instance.
-func Transaction() *TransactionOptions {
- return &TransactionOptions{}
-}
-
-// SetReadConcern sets the value for the ReadConcern field.
-func (t *TransactionOptions) SetReadConcern(rc *readconcern.ReadConcern) *TransactionOptions {
- t.ReadConcern = rc
- return t
-}
-
-// SetReadPreference sets the value for the ReadPreference field.
-func (t *TransactionOptions) SetReadPreference(rp *readpref.ReadPref) *TransactionOptions {
- t.ReadPreference = rp
- return t
-}
-
-// SetWriteConcern sets the value for the WriteConcern field.
-func (t *TransactionOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *TransactionOptions {
- t.WriteConcern = wc
- return t
-}
-
-// SetMaxCommitTime sets the value for the MaxCommitTime field.
-//
-// NOTE(benjirewis): MaxCommitTime will be deprecated in a future release. The more general Timeout
-// option may be used in its place to control the amount of time that a single operation can run before
-// returning an error. MaxCommitTime is ignored if Timeout is set on the client.
-func (t *TransactionOptions) SetMaxCommitTime(mct *time.Duration) *TransactionOptions {
- t.MaxCommitTime = mct
- return t
-}
-
-// MergeTransactionOptions combines the given TransactionOptions instances into a single TransactionOptions in a
-// last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeTransactionOptions(opts ...*TransactionOptions) *TransactionOptions {
- t := Transaction()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- if opt.ReadConcern != nil {
- t.ReadConcern = opt.ReadConcern
- }
- if opt.ReadPreference != nil {
- t.ReadPreference = opt.ReadPreference
- }
- if opt.WriteConcern != nil {
- t.WriteConcern = opt.WriteConcern
- }
- if opt.MaxCommitTime != nil {
- t.MaxCommitTime = opt.MaxCommitTime
- }
- }
-
- return t
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go
deleted file mode 100644
index 9f22ca904..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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
-
-// UpdateOptions represents options that can be used to configure UpdateOne and UpdateMany operations.
-type UpdateOptions struct {
- // A set of filters specifying to which array elements an update should apply. This option is only valid for MongoDB
- // versions >= 3.6. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the update will apply to all array elements.
- ArrayFilters *ArrayFilters
-
- // If true, writes executed as part of the operation will opt out of document-level validation on the server. This
- // option is valid for MongoDB versions >= 3.2 and is ignored for previous server versions. The default value is
- // false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
- // validation.
- BypassDocumentValidation *bool
-
- // Specifies a collation to use for string comparisons during the operation. This option is only valid for MongoDB
- // versions >= 3.4. For previous server versions, the driver will return an error if this option is used. The
- // default value is nil, which means the default collation of the collection will be used.
- Collation *Collation
-
- // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
- // the operation. The default value is nil, which means that no comment will be included in the logs.
- Comment interface{}
-
- // The index to use for the operation. This should either be the index name as a string or the index specification
- // as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will return an error
- // if this option is specified. For server versions < 3.4, the driver will return a client-side error if this option
- // is specified. The driver will return an error if this option is specified during an unacknowledged write
- // operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil,
- // which means that no hint will be sent.
- Hint interface{}
-
- // If true, a new document will be inserted if the filter does not match any documents in the collection. The
- // default value is false.
- Upsert *bool
-
- // Specifies parameters for the update expression. This option is only valid for MongoDB versions >= 5.0. Older
- // servers will report an error for using this option. This must be a document mapping parameter names to values.
- // Values must be constant or closed expressions that do not reference document fields. Parameters can then be
- // accessed as variables in an aggregate expression context (e.g. "$$var").
- Let interface{}
-
- // If true, the server accepts empty Timestamp as a literal rather than replacing it with the current time.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- BypassEmptyTsReplacement *bool
-}
-
-// Update creates a new UpdateOptions instance.
-func Update() *UpdateOptions {
- return &UpdateOptions{}
-}
-
-// SetArrayFilters sets the value for the ArrayFilters field.
-func (uo *UpdateOptions) SetArrayFilters(af ArrayFilters) *UpdateOptions {
- uo.ArrayFilters = &af
- return uo
-}
-
-// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field.
-func (uo *UpdateOptions) SetBypassDocumentValidation(b bool) *UpdateOptions {
- uo.BypassDocumentValidation = &b
- return uo
-}
-
-// SetCollation sets the value for the Collation field.
-func (uo *UpdateOptions) SetCollation(c *Collation) *UpdateOptions {
- uo.Collation = c
- return uo
-}
-
-// SetComment sets the value for the Comment field.
-func (uo *UpdateOptions) SetComment(comment interface{}) *UpdateOptions {
- uo.Comment = comment
- return uo
-}
-
-// SetHint sets the value for the Hint field.
-func (uo *UpdateOptions) SetHint(h interface{}) *UpdateOptions {
- uo.Hint = h
- return uo
-}
-
-// SetUpsert sets the value for the Upsert field.
-func (uo *UpdateOptions) SetUpsert(b bool) *UpdateOptions {
- uo.Upsert = &b
- return uo
-}
-
-// SetLet sets the value for the Let field.
-func (uo *UpdateOptions) SetLet(l interface{}) *UpdateOptions {
- uo.Let = l
- return uo
-}
-
-// MergeUpdateOptions combines the given UpdateOptions instances into a single UpdateOptions in a last-one-wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeUpdateOptions(opts ...*UpdateOptions) *UpdateOptions {
- uOpts := Update()
- for _, uo := range opts {
- if uo == nil {
- continue
- }
- if uo.ArrayFilters != nil {
- uOpts.ArrayFilters = uo.ArrayFilters
- }
- if uo.BypassDocumentValidation != nil {
- uOpts.BypassDocumentValidation = uo.BypassDocumentValidation
- }
- if uo.Collation != nil {
- uOpts.Collation = uo.Collation
- }
- if uo.Comment != nil {
- uOpts.Comment = uo.Comment
- }
- if uo.Hint != nil {
- uOpts.Hint = uo.Hint
- }
- if uo.Upsert != nil {
- uOpts.Upsert = uo.Upsert
- }
- if uo.Let != nil {
- uOpts.Let = uo.Let
- }
- if uo.BypassEmptyTsReplacement != nil {
- uOpts.BypassEmptyTsReplacement = uo.BypassEmptyTsReplacement
- }
- }
-
- return uOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/results.go b/vendor/go.mongodb.org/mongo-driver/mongo/results.go
deleted file mode 100644
index 2dbaf2af6..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/results.go
+++ /dev/null
@@ -1,286 +0,0 @@
-// 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 mongo
-
-import (
- "fmt"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
-)
-
-// BulkWriteResult is the result type returned by a BulkWrite operation.
-type BulkWriteResult struct {
- // The number of documents inserted.
- InsertedCount int64
-
- // The number of documents matched by filters in update and replace operations.
- MatchedCount int64
-
- // The number of documents modified by update and replace operations.
- ModifiedCount int64
-
- // The number of documents deleted.
- DeletedCount int64
-
- // The number of documents upserted by update and replace operations.
- UpsertedCount int64
-
- // A map of operation index to the _id of each upserted document.
- UpsertedIDs map[int64]interface{}
-}
-
-// InsertOneResult is the result type returned by an InsertOne operation.
-type InsertOneResult struct {
- // The _id of the inserted document. A value generated by the driver will be of type primitive.ObjectID.
- InsertedID interface{}
-}
-
-// InsertManyResult is a result type returned by an InsertMany operation.
-type InsertManyResult struct {
- // The _id values of the inserted documents. Values generated by the driver will be of type primitive.ObjectID.
- InsertedIDs []interface{}
-}
-
-// TODO(GODRIVER-2367): Remove the BSON struct tags on DeleteResult.
-
-// DeleteResult is the result type returned by DeleteOne and DeleteMany operations.
-type DeleteResult struct {
- DeletedCount int64 `bson:"n"` // The number of documents deleted.
-}
-
-// RewrapManyDataKeyResult is the result of the bulk write operation used to update the key vault collection with
-// rewrapped data keys.
-type RewrapManyDataKeyResult struct {
- *BulkWriteResult
-}
-
-// ListDatabasesResult is a result of a ListDatabases operation.
-type ListDatabasesResult struct {
- // A slice containing one DatabaseSpecification for each database matched by the operation's filter.
- Databases []DatabaseSpecification
-
- // The total size of the database files of the returned databases in bytes.
- // This will be the sum of the SizeOnDisk field for each specification in Databases.
- TotalSize int64
-}
-
-func newListDatabasesResultFromOperation(res operation.ListDatabasesResult) ListDatabasesResult {
- var ldr ListDatabasesResult
- ldr.Databases = make([]DatabaseSpecification, 0, len(res.Databases))
- for _, spec := range res.Databases {
- ldr.Databases = append(
- ldr.Databases,
- DatabaseSpecification{Name: spec.Name, SizeOnDisk: spec.SizeOnDisk, Empty: spec.Empty},
- )
- }
- ldr.TotalSize = res.TotalSize
- return ldr
-}
-
-// DatabaseSpecification contains information for a database. This type is returned as part of ListDatabasesResult.
-type DatabaseSpecification struct {
- Name string // The name of the database.
- SizeOnDisk int64 // The total size of the database files on disk in bytes.
- Empty bool // Specifies whether or not the database is empty.
-}
-
-// UpdateResult is the result type returned from UpdateOne, UpdateMany, and ReplaceOne operations.
-type UpdateResult struct {
- MatchedCount int64 // The number of documents matched by the filter.
- ModifiedCount int64 // The number of documents modified by the operation.
- UpsertedCount int64 // The number of documents upserted by the operation.
- UpsertedID interface{} // The _id field of the upserted document, or nil if no upsert was done.
-}
-
-// UnmarshalBSON implements the bson.Unmarshaler interface.
-//
-// Deprecated: Unmarshalling an UpdateResult directly from BSON is not supported and may produce
-// different results compared to running Update* operations directly.
-func (result *UpdateResult) UnmarshalBSON(b []byte) error {
- // TODO(GODRIVER-2367): Remove the ability to unmarshal BSON directly to an UpdateResult.
- elems, err := bson.Raw(b).Elements()
- if err != nil {
- return err
- }
-
- for _, elem := range elems {
- switch elem.Key() {
- case "n":
- switch elem.Value().Type {
- case bson.TypeInt32:
- result.MatchedCount = int64(elem.Value().Int32())
- case bson.TypeInt64:
- result.MatchedCount = elem.Value().Int64()
- default:
- return fmt.Errorf("Received invalid type for n, should be Int32 or Int64, received %s", elem.Value().Type)
- }
- case "nModified":
- switch elem.Value().Type {
- case bson.TypeInt32:
- result.ModifiedCount = int64(elem.Value().Int32())
- case bson.TypeInt64:
- result.ModifiedCount = elem.Value().Int64()
- default:
- return fmt.Errorf("Received invalid type for nModified, should be Int32 or Int64, received %s", elem.Value().Type)
- }
- case "upserted":
- switch elem.Value().Type {
- case bson.TypeArray:
- e, err := elem.Value().Array().IndexErr(0)
- if err != nil {
- break
- }
- if e.Value().Type != bson.TypeEmbeddedDocument {
- break
- }
- var d struct {
- ID interface{} `bson:"_id"`
- }
- err = bson.Unmarshal(e.Value().Document(), &d)
- if err != nil {
- return err
- }
- result.UpsertedID = d.ID
- default:
- return fmt.Errorf("Received invalid type for upserted, should be Array, received %s", elem.Value().Type)
- }
- }
- }
-
- return nil
-}
-
-// IndexSpecification represents an index in a database. This type is returned by the IndexView.ListSpecifications
-// function and is also used in the CollectionSpecification type.
-type IndexSpecification struct {
- // The index name.
- Name string
-
- // The namespace for the index. This is a string in the format "databaseName.collectionName".
- Namespace string
-
- // The keys specification document for the index.
- KeysDocument bson.Raw
-
- // The index version.
- Version int32
-
- // The length of time, in seconds, for documents to remain in the collection. The default value is 0, which means
- // that documents will remain in the collection until they're explicitly deleted or the collection is dropped.
- ExpireAfterSeconds *int32
-
- // If true, the index will only reference documents that contain the fields specified in the index. The default is
- // false.
- Sparse *bool
-
- // If true, the collection will not accept insertion or update of documents where the index key value matches an
- // existing value in the index. The default is false.
- Unique *bool
-
- // The clustered index.
- Clustered *bool
-}
-
-var _ bson.Unmarshaler = (*IndexSpecification)(nil)
-
-type unmarshalIndexSpecification struct {
- Name string `bson:"name"`
- Namespace string `bson:"ns"`
- KeysDocument bson.Raw `bson:"key"`
- Version int32 `bson:"v"`
- ExpireAfterSeconds *int32 `bson:"expireAfterSeconds"`
- Sparse *bool `bson:"sparse"`
- Unique *bool `bson:"unique"`
- Clustered *bool `bson:"clustered"`
-}
-
-// UnmarshalBSON implements the bson.Unmarshaler interface.
-//
-// Deprecated: Unmarshaling an IndexSpecification from BSON will not be supported in Go Driver 2.0.
-func (i *IndexSpecification) UnmarshalBSON(data []byte) error {
- var temp unmarshalIndexSpecification
- if err := bson.Unmarshal(data, &temp); err != nil {
- return err
- }
-
- i.Name = temp.Name
- i.Namespace = temp.Namespace
- i.KeysDocument = temp.KeysDocument
- i.Version = temp.Version
- i.ExpireAfterSeconds = temp.ExpireAfterSeconds
- i.Sparse = temp.Sparse
- i.Unique = temp.Unique
- i.Clustered = temp.Clustered
- return nil
-}
-
-// CollectionSpecification represents a collection in a database. This type is returned by the
-// Database.ListCollectionSpecifications function.
-type CollectionSpecification struct {
- // The collection name.
- Name string
-
- // The type of the collection. This will either be "collection" or "view".
- Type string
-
- // Whether or not the collection is readOnly. This will be false for MongoDB versions < 3.4.
- ReadOnly bool
-
- // The collection UUID. This field will be nil for MongoDB versions < 3.6. For versions 3.6 and higher, this will
- // be a primitive.Binary with Subtype 4.
- UUID *primitive.Binary
-
- // A document containing the options used to construct the collection.
- Options bson.Raw
-
- // An IndexSpecification instance with details about the collection's _id index. This will be nil if the NameOnly
- // option is used and for MongoDB versions < 3.4.
- IDIndex *IndexSpecification
-}
-
-var _ bson.Unmarshaler = (*CollectionSpecification)(nil)
-
-// unmarshalCollectionSpecification is used to unmarshal BSON bytes from a listCollections command into a
-// CollectionSpecification.
-type unmarshalCollectionSpecification struct {
- Name string `bson:"name"`
- Type string `bson:"type"`
- Info *struct {
- ReadOnly bool `bson:"readOnly"`
- UUID *primitive.Binary `bson:"uuid"`
- } `bson:"info"`
- Options bson.Raw `bson:"options"`
- IDIndex *IndexSpecification `bson:"idIndex"`
-}
-
-// UnmarshalBSON implements the bson.Unmarshaler interface.
-//
-// Deprecated: Unmarshaling a CollectionSpecification from BSON will not be supported in Go Driver
-// 2.0.
-func (cs *CollectionSpecification) UnmarshalBSON(data []byte) error {
- var temp unmarshalCollectionSpecification
- if err := bson.Unmarshal(data, &temp); err != nil {
- return err
- }
-
- cs.Name = temp.Name
- cs.Type = temp.Type
- if cs.Type == "" {
- // The "type" field is only present on 3.4+ because views were introduced in 3.4, so we implicitly set the
- // value to "collection" if it's empty.
- cs.Type = "collection"
- }
- if temp.Info != nil {
- cs.ReadOnly = temp.Info.ReadOnly
- cs.UUID = temp.Info.UUID
- }
- cs.Options = temp.Options
- cs.IDIndex = temp.IDIndex
- return nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/session.go b/vendor/go.mongodb.org/mongo-driver/mongo/session.go
deleted file mode 100644
index 77be4ab6d..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/session.go
+++ /dev/null
@@ -1,390 +0,0 @@
-// 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 mongo
-
-import (
- "context"
- "errors"
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
-)
-
-// ErrWrongClient is returned when a user attempts to pass in a session created by a different client than
-// the method call is using.
-var ErrWrongClient = errors.New("session was not created by this client")
-
-var withTransactionTimeout = 120 * time.Second
-
-// SessionContext combines the context.Context and mongo.Session interfaces. It should be used as the Context arguments
-// to operations that should be executed in a session.
-//
-// Implementations of SessionContext are not safe for concurrent use by multiple goroutines.
-//
-// There are two ways to create a SessionContext and use it in a session/transaction. The first is to use one of the
-// callback-based functions such as WithSession and UseSession. These functions create a SessionContext and pass it to
-// the provided callback. The other is to use NewSessionContext to explicitly create a SessionContext.
-type SessionContext interface {
- context.Context
- Session
-}
-
-type sessionContext struct {
- context.Context
- Session
-}
-
-type sessionKey struct {
-}
-
-// NewSessionContext creates a new SessionContext associated with the given Context and Session parameters.
-func NewSessionContext(ctx context.Context, sess Session) SessionContext {
- return &sessionContext{
- Context: context.WithValue(ctx, sessionKey{}, sess),
- Session: sess,
- }
-}
-
-// SessionFromContext extracts the mongo.Session object stored in a Context. This can be used on a SessionContext that
-// was created implicitly through one of the callback-based session APIs or explicitly by calling NewSessionContext. If
-// there is no Session stored in the provided Context, nil is returned.
-func SessionFromContext(ctx context.Context) Session {
- val := ctx.Value(sessionKey{})
- if val == nil {
- return nil
- }
-
- sess, ok := val.(Session)
- if !ok {
- return nil
- }
-
- return sess
-}
-
-// Session is an interface that represents a MongoDB logical session. Sessions can be used to enable causal consistency
-// for a group of operations or to execute operations in an ACID transaction. A new Session can be created from a Client
-// instance. A Session created from a Client must only be used to execute operations using that Client or a Database or
-// Collection created from that Client. Custom implementations of this interface should not be used in production. For
-// more information about sessions, and their use cases, see
-// https://www.mongodb.com/docs/manual/reference/server-sessions/,
-// https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#causal-consistency, and
-// https://www.mongodb.com/docs/manual/core/transactions/.
-//
-// Implementations of Session are not safe for concurrent use by multiple goroutines.
-type Session interface {
- // StartTransaction starts a new transaction, configured with the given options, on this
- // session. This method returns an error if there is already a transaction in-progress for this
- // session.
- StartTransaction(...*options.TransactionOptions) error
-
- // AbortTransaction aborts the active transaction for this session. This method returns an error
- // if there is no active transaction for this session or if the transaction has been committed
- // or aborted.
- AbortTransaction(context.Context) error
-
- // CommitTransaction commits the active transaction for this session. This method returns an
- // error if there is no active transaction for this session or if the transaction has been
- // aborted.
- CommitTransaction(context.Context) error
-
- // WithTransaction starts a transaction on this session and runs the fn callback. Errors with
- // the TransientTransactionError and UnknownTransactionCommitResult labels are retried for up to
- // 120 seconds. Inside the callback, the SessionContext must be used as the Context parameter
- // for any operations that should be part of the transaction. If the ctx parameter already has a
- // Session attached to it, it will be replaced by this session. The fn callback may be run
- // multiple times during WithTransaction due to retry attempts, so it must be idempotent.
- // Non-retryable operation errors or any operation errors that occur after the timeout expires
- // will be returned without retrying. If the callback fails, the driver will call
- // AbortTransaction. Because this method must succeed to ensure that server-side resources are
- // properly cleaned up, context deadlines and cancellations will not be respected during this
- // call. For a usage example, see the Client.StartSession method documentation.
- WithTransaction(ctx context.Context, fn func(ctx SessionContext) (interface{}, error),
- opts ...*options.TransactionOptions) (interface{}, error)
-
- // EndSession aborts any existing transactions and close the session.
- EndSession(context.Context)
-
- // ClusterTime returns the current cluster time document associated with the session.
- ClusterTime() bson.Raw
-
- // OperationTime returns the current operation time document associated with the session.
- OperationTime() *primitive.Timestamp
-
- // Client the Client associated with the session.
- Client() *Client
-
- // ID returns the current ID document associated with the session. The ID document is in the
- // form {"id": }.
- ID() bson.Raw
-
- // AdvanceClusterTime advances the cluster time for a session. This method returns an error if
- // the session has ended.
- AdvanceClusterTime(bson.Raw) error
-
- // AdvanceOperationTime advances the operation time for a session. This method returns an error
- // if the session has ended.
- AdvanceOperationTime(*primitive.Timestamp) error
-
- session()
-}
-
-// XSession is an unstable interface for internal use only.
-//
-// Deprecated: This interface is unstable because it provides access to a session.Client object, which exists in the
-// "x" package. It should not be used by applications and may be changed or removed in any release.
-type XSession interface {
- ClientSession() *session.Client
-}
-
-// sessionImpl represents a set of sequential operations executed by an application that are related in some way.
-type sessionImpl struct {
- clientSession *session.Client
- client *Client
- deployment driver.Deployment
- didCommitAfterStart bool // true if commit was called after start with no other operations
-}
-
-var _ Session = &sessionImpl{}
-var _ XSession = &sessionImpl{}
-
-// ClientSession implements the XSession interface.
-func (s *sessionImpl) ClientSession() *session.Client {
- return s.clientSession
-}
-
-// ID implements the Session interface.
-func (s *sessionImpl) ID() bson.Raw {
- return bson.Raw(s.clientSession.SessionID)
-}
-
-// EndSession implements the Session interface.
-func (s *sessionImpl) EndSession(ctx context.Context) {
- if s.clientSession.TransactionInProgress() {
- // ignore all errors aborting during an end session
- _ = s.AbortTransaction(ctx)
- }
- s.clientSession.EndSession()
-}
-
-// WithTransaction implements the Session interface.
-func (s *sessionImpl) WithTransaction(ctx context.Context, fn func(ctx SessionContext) (interface{}, error),
- opts ...*options.TransactionOptions) (interface{}, error) {
- timeout := time.NewTimer(withTransactionTimeout)
- defer timeout.Stop()
- var err error
- for {
- err = s.StartTransaction(opts...)
- if err != nil {
- return nil, err
- }
-
- res, err := fn(NewSessionContext(ctx, s))
- if err != nil {
- if s.clientSession.TransactionRunning() {
- // Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and
- // cancellations, but forwards Value requests to the original one.
- _ = s.AbortTransaction(newBackgroundContext(ctx))
- }
-
- select {
- case <-timeout.C:
- return nil, err
- default:
- }
-
- if errorHasLabel(err, driver.TransientTransactionError) {
- continue
- }
- return res, err
- }
-
- // Check if callback intentionally aborted and, if so, return immediately
- // with no error.
- err = s.clientSession.CheckAbortTransaction()
- if err != nil {
- return res, nil
- }
-
- // If context has errored, run AbortTransaction and return, as the CommitLoop
- // has no chance of succeeding.
- //
- // Aborting after a failed CommitTransaction is dangerous. Failed transaction
- // commits may unpin the session server-side, and subsequent transaction aborts
- // may run on a new mongos which could end up with commit and abort being executed
- // simultaneously.
- if ctx.Err() != nil {
- // Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and
- // cancellations, but forwards Value requests to the original one.
- _ = s.AbortTransaction(newBackgroundContext(ctx))
- return nil, ctx.Err()
- }
-
- CommitLoop:
- for {
- err = s.CommitTransaction(newBackgroundContext(ctx))
- // End when error is nil, as transaction has been committed.
- if err == nil {
- return res, nil
- }
-
- select {
- case <-timeout.C:
- return res, err
- default:
- }
-
- if cerr, ok := err.(CommandError); ok {
- if cerr.HasErrorLabel(driver.UnknownTransactionCommitResult) && !cerr.IsMaxTimeMSExpiredError() {
- continue
- }
- if cerr.HasErrorLabel(driver.TransientTransactionError) {
- break CommitLoop
- }
- }
- return res, err
- }
- }
-}
-
-// StartTransaction implements the Session interface.
-func (s *sessionImpl) StartTransaction(opts ...*options.TransactionOptions) error {
- err := s.clientSession.CheckStartTransaction()
- if err != nil {
- return err
- }
-
- s.didCommitAfterStart = false
-
- topts := options.MergeTransactionOptions(opts...)
- coreOpts := &session.TransactionOptions{
- ReadConcern: topts.ReadConcern,
- ReadPreference: topts.ReadPreference,
- WriteConcern: topts.WriteConcern,
- MaxCommitTime: topts.MaxCommitTime,
- }
-
- return s.clientSession.StartTransaction(coreOpts)
-}
-
-// AbortTransaction implements the Session interface.
-func (s *sessionImpl) AbortTransaction(ctx context.Context) error {
- err := s.clientSession.CheckAbortTransaction()
- if err != nil {
- return err
- }
-
- // Do not run the abort command if the transaction is in starting state
- if s.clientSession.TransactionStarting() || s.didCommitAfterStart {
- return s.clientSession.AbortTransaction()
- }
-
- selector := makePinnedSelector(s.clientSession, description.WriteSelector())
-
- s.clientSession.Aborting = true
- _ = operation.NewAbortTransaction().Session(s.clientSession).ClusterClock(s.client.clock).Database("admin").
- Deployment(s.deployment).WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector).
- Retry(driver.RetryOncePerCommand).CommandMonitor(s.client.monitor).
- RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)).ServerAPI(s.client.serverAPI).
- Authenticator(s.client.authenticator).Execute(ctx)
-
- s.clientSession.Aborting = false
- _ = s.clientSession.AbortTransaction()
-
- return nil
-}
-
-// CommitTransaction implements the Session interface.
-func (s *sessionImpl) CommitTransaction(ctx context.Context) error {
- err := s.clientSession.CheckCommitTransaction()
- if err != nil {
- return err
- }
-
- // Do not run the commit command if the transaction is in started state
- if s.clientSession.TransactionStarting() || s.didCommitAfterStart {
- s.didCommitAfterStart = true
- return s.clientSession.CommitTransaction()
- }
-
- if s.clientSession.TransactionCommitted() {
- s.clientSession.RetryingCommit = true
- }
-
- selector := makePinnedSelector(s.clientSession, description.WriteSelector())
-
- s.clientSession.Committing = true
- op := operation.NewCommitTransaction().
- Session(s.clientSession).ClusterClock(s.client.clock).Database("admin").Deployment(s.deployment).
- WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector).Retry(driver.RetryOncePerCommand).
- CommandMonitor(s.client.monitor).RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)).
- ServerAPI(s.client.serverAPI).MaxTime(s.clientSession.CurrentMct).Authenticator(s.client.authenticator)
-
- err = op.Execute(ctx)
- // Return error without updating transaction state if it is a timeout, as the transaction has not
- // actually been committed.
- if IsTimeout(err) {
- return replaceErrors(err)
- }
- s.clientSession.Committing = false
- commitErr := s.clientSession.CommitTransaction()
-
- // We set the write concern to majority for subsequent calls to CommitTransaction.
- s.clientSession.UpdateCommitTransactionWriteConcern()
-
- if err != nil {
- return replaceErrors(err)
- }
- return commitErr
-}
-
-// ClusterTime implements the Session interface.
-func (s *sessionImpl) ClusterTime() bson.Raw {
- return s.clientSession.ClusterTime
-}
-
-// AdvanceClusterTime implements the Session interface.
-func (s *sessionImpl) AdvanceClusterTime(d bson.Raw) error {
- return s.clientSession.AdvanceClusterTime(d)
-}
-
-// OperationTime implements the Session interface.
-func (s *sessionImpl) OperationTime() *primitive.Timestamp {
- return s.clientSession.OperationTime
-}
-
-// AdvanceOperationTime implements the Session interface.
-func (s *sessionImpl) AdvanceOperationTime(ts *primitive.Timestamp) error {
- return s.clientSession.AdvanceOperationTime(ts)
-}
-
-// Client implements the Session interface.
-func (s *sessionImpl) Client() *Client {
- return s.client
-}
-
-// session implements the Session interface.
-func (*sessionImpl) session() {
-}
-
-// sessionFromContext checks for a sessionImpl in the argued context and returns the session if it
-// exists
-func sessionFromContext(ctx context.Context) *session.Client {
- s := ctx.Value(sessionKey{})
- if ses, ok := s.(*sessionImpl); ses != nil && ok {
- return ses.clientSession
- }
-
- return nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/writeconcern/writeconcern.go b/vendor/go.mongodb.org/mongo-driver/mongo/writeconcern/writeconcern.go
deleted file mode 100644
index 7a73d8d72..000000000
--- a/vendor/go.mongodb.org/mongo-driver/mongo/writeconcern/writeconcern.go
+++ /dev/null
@@ -1,439 +0,0 @@
-// 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 writeconcern defines write concerns for MongoDB operations.
-//
-// For more information about MongoDB write concerns, see
-// https://www.mongodb.com/docs/manual/reference/write-concern/
-package writeconcern // import "go.mongodb.org/mongo-driver/mongo/writeconcern"
-
-import (
- "errors"
- "fmt"
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
-
-const majority = "majority"
-
-// ErrInconsistent indicates that an inconsistent write concern was specified.
-//
-// Deprecated: ErrInconsistent will be removed in Go Driver 2.0.
-var ErrInconsistent = errors.New("a write concern cannot have both w=0 and j=true")
-
-// ErrEmptyWriteConcern indicates that a write concern has no fields set.
-//
-// Deprecated: ErrEmptyWriteConcern will be removed in Go Driver 2.0.
-var ErrEmptyWriteConcern = errors.New("a write concern must have at least one field set")
-
-// ErrNegativeW indicates that a negative integer `w` field was specified.
-//
-// Deprecated: ErrNegativeW will be removed in Go Driver 2.0.
-var ErrNegativeW = errors.New("write concern `w` field cannot be a negative number")
-
-// ErrNegativeWTimeout indicates that a negative WTimeout was specified.
-//
-// Deprecated: ErrNegativeWTimeout will be removed in Go Driver 2.0.
-var ErrNegativeWTimeout = errors.New("write concern `wtimeout` field cannot be negative")
-
-// A WriteConcern defines a MongoDB write concern, which describes the level of acknowledgment
-// requested from MongoDB for write operations to a standalone mongod, to replica sets, or to
-// sharded clusters.
-//
-// For more information about MongoDB write concerns, see
-// https://www.mongodb.com/docs/manual/reference/write-concern/
-type WriteConcern struct {
- // W requests acknowledgment that the write operation has propagated to a
- // specified number of mongod instances or to mongod instances with
- // specified tags. It sets the "w" option in a MongoDB write concern.
- //
- // W values must be a string or an int.
- //
- // Common values are:
- // - "majority": requests acknowledgment that write operations have been
- // durably committed to the calculated majority of the data-bearing
- // voting members.
- // - 1: requests acknowledgment that write operations have been written
- // to 1 node.
- // - 0: requests no acknowledgment of write operations
- //
- // For more information about the "w" option, see
- // https://www.mongodb.com/docs/manual/reference/write-concern/#w-option
- W interface{}
-
- // Journal requests acknowledgment from MongoDB that the write operation has
- // been written to the on-disk journal. It sets the "j" option in a MongoDB
- // write concern.
- //
- // For more information about the "j" option, see
- // https://www.mongodb.com/docs/manual/reference/write-concern/#j-option
- Journal *bool
-
- // WTimeout specifies a time limit for the write concern. It sets the
- // "wtimeout" option in a MongoDB write concern.
- //
- // It is only applicable for "w" values greater than 1. Using a WTimeout and
- // setting Timeout on the Client at the same time will result in undefined
- // behavior.
- //
- // For more information about the "wtimeout" option, see
- // https://www.mongodb.com/docs/manual/reference/write-concern/#wtimeout
- WTimeout time.Duration
-}
-
-// Unacknowledged returns a WriteConcern that requests no acknowledgment of
-// write operations.
-//
-// For more information about write concern "w: 0", see
-// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-number-
-func Unacknowledged() *WriteConcern {
- return &WriteConcern{W: 0}
-}
-
-// W1 returns a WriteConcern that requests acknowledgment that write operations
-// have been written to memory on one node (e.g. the standalone mongod or the
-// primary in a replica set).
-//
-// For more information about write concern "w: 1", see
-// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-number-
-func W1() *WriteConcern {
- return &WriteConcern{W: 1}
-}
-
-// Journaled returns a WriteConcern that requests acknowledgment that write
-// operations have been written to the on-disk journal on MongoDB.
-//
-// The database's default value for "w" determines how many nodes must write to
-// their on-disk journal before the write operation is acknowledged.
-//
-// For more information about write concern "j: true", see
-// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-ournal
-func Journaled() *WriteConcern {
- journal := true
- return &WriteConcern{Journal: &journal}
-}
-
-// Majority returns a WriteConcern that requests acknowledgment that write
-// operations have been durably committed to the calculated majority of the
-// data-bearing voting members.
-//
-// Write concern "w: majority" typically requires write operations to be written
-// to the on-disk journal before they are acknowledged, unless journaling is
-// disabled on MongoDB or the "writeConcernMajorityJournalDefault" replica set
-// configuration is set to false.
-//
-// For more information about write concern "w: majority", see
-// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-majority-
-func Majority() *WriteConcern {
- return &WriteConcern{W: majority}
-}
-
-// Custom returns a WriteConcern that requests acknowledgment that write
-// operations have propagated to tagged members that satisfy the custom write
-// concern defined in "settings.getLastErrorModes".
-//
-// For more information about custom write concern names, see
-// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-custom-write-concern-name-
-func Custom(tag string) *WriteConcern {
- return &WriteConcern{W: tag}
-}
-
-// Option is an option to provide when creating a WriteConcern.
-//
-// Deprecated: Use the WriteConcern convenience functions or define a struct literal instead.
-// For example:
-//
-// writeconcern.Majority()
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: 2,
-// Journal: &journal,
-// }
-type Option func(concern *WriteConcern)
-
-// New constructs a new WriteConcern.
-//
-// Deprecated: Use the WriteConcern convenience functions or define a struct literal instead.
-// For example:
-//
-// writeconcern.Majority()
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: 2,
-// Journal: &journal,
-// }
-func New(options ...Option) *WriteConcern {
- concern := &WriteConcern{}
-
- for _, option := range options {
- option(concern)
- }
-
- return concern
-}
-
-// W requests acknowledgement that write operations propagate to the specified number of mongod
-// instances.
-//
-// Deprecated: Use the Unacknowledged or W1 functions or define a struct literal instead.
-// For example:
-//
-// writeconcern.Unacknowledged()
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: 2,
-// Journal: &journal,
-// }
-func W(w int) Option {
- return func(concern *WriteConcern) {
- concern.W = w
- }
-}
-
-// WMajority requests acknowledgement that write operations propagate to the majority of mongod
-// instances.
-//
-// Deprecated: Use [Majority] instead.
-func WMajority() Option {
- return func(concern *WriteConcern) {
- concern.W = majority
- }
-}
-
-// WTagSet requests acknowledgement that write operations propagate to the specified mongod
-// instance.
-//
-// Deprecated: Use [Custom] instead.
-func WTagSet(tag string) Option {
- return func(concern *WriteConcern) {
- concern.W = tag
- }
-}
-
-// J requests acknowledgement from MongoDB that write operations are written to
-// the journal.
-//
-// Deprecated: Use the Journaled function or define a struct literal instead.
-// For example:
-//
-// writeconcern.Journaled()
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: 2,
-// Journal: &journal,
-// }
-func J(j bool) Option {
- return func(concern *WriteConcern) {
- // To maintain backward compatible behavior (now that the J field is a
- // bool pointer), only set a value for J if the input is true. If the
- // input is false, do not set a value, which omits "j" from the
- // marshaled write concern.
- if j {
- concern.Journal = &j
- }
- }
-}
-
-// WTimeout specifies a time limit for the write concern.
-//
-// It is only applicable for "w" values greater than 1. Using a WTimeout and setting Timeout on the
-// Client at the same time will result in undefined behavior.
-//
-// Deprecated: Use the WriteConcern convenience functions or define a struct literal instead.
-// For example:
-//
-// wc := writeconcern.W1()
-// wc.WTimeout = 30 * time.Second
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: "majority",
-// WTimeout: 30 * time.Second,
-// }
-func WTimeout(d time.Duration) Option {
- return func(concern *WriteConcern) {
- concern.WTimeout = d
- }
-}
-
-// MarshalBSONValue implements the bson.ValueMarshaler interface.
-//
-// Deprecated: Marshaling a WriteConcern to BSON will not be supported in Go
-// Driver 2.0.
-func (wc *WriteConcern) MarshalBSONValue() (bsontype.Type, []byte, error) {
- if wc == nil {
- return 0, nil, ErrEmptyWriteConcern
- }
-
- var elems []byte
- if wc.W != nil {
- // Only support string or int values for W. That aligns with the
- // documentation and the behavior of other functions, like Acknowledged.
- switch w := wc.W.(type) {
- case int:
- if w < 0 {
- return 0, nil, ErrNegativeW
- }
-
- // If Journal=true and W=0, return an error because that write
- // concern is ambiguous.
- if wc.Journal != nil && *wc.Journal && w == 0 {
- return 0, nil, ErrInconsistent
- }
-
- elems = bsoncore.AppendInt32Element(elems, "w", int32(w))
- case string:
- elems = bsoncore.AppendStringElement(elems, "w", w)
- default:
- return 0,
- nil,
- fmt.Errorf("WriteConcern.W must be a string or int, but is a %T", wc.W)
- }
- }
-
- if wc.Journal != nil {
- elems = bsoncore.AppendBooleanElement(elems, "j", *wc.Journal)
- }
-
- if wc.WTimeout < 0 {
- return 0, nil, ErrNegativeWTimeout
- }
-
- if wc.WTimeout != 0 {
- elems = bsoncore.AppendInt64Element(elems, "wtimeout", int64(wc.WTimeout/time.Millisecond))
- }
-
- if len(elems) == 0 {
- return 0, nil, ErrEmptyWriteConcern
- }
- return bson.TypeEmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
-}
-
-// AcknowledgedValue returns true if a BSON RawValue for a write concern represents an acknowledged write concern.
-// The element's value must be a document representing a write concern.
-//
-// Deprecated: AcknowledgedValue will not be supported in Go Driver 2.0.
-func AcknowledgedValue(rawv bson.RawValue) bool {
- doc, ok := bsoncore.Value{Type: rawv.Type, Data: rawv.Value}.DocumentOK()
- if !ok {
- return false
- }
-
- val, err := doc.LookupErr("w")
- if err != nil {
- // key w not found --> acknowledged
- return true
- }
-
- i32, ok := val.Int32OK()
- if !ok {
- return false
- }
- return i32 != 0
-}
-
-// Acknowledged indicates whether or not a write with the given write concern will be acknowledged.
-func (wc *WriteConcern) Acknowledged() bool {
- // Only {w: 0} or {w: 0, j: false} are an unacknowledged write concerns. All other values are
- // acknowledged.
- return wc == nil || wc.W != 0 || (wc.Journal != nil && *wc.Journal)
-}
-
-// IsValid returns true if the WriteConcern is valid.
-func (wc *WriteConcern) IsValid() bool {
- if wc == nil {
- return true
- }
-
- switch w := wc.W.(type) {
- case int:
- // A write concern with {w: int} must have a non-negative value and
- // cannot have the combination {w: 0, j: true}.
- return w >= 0 && (w > 0 || wc.Journal == nil || !*wc.Journal)
- case string, nil:
- // A write concern with {w: string} or no w specified is always valid.
- return true
- default:
- // A write concern with an unsupported w type is not valid.
- return false
- }
-}
-
-// GetW returns the write concern w level.
-//
-// Deprecated: Use the WriteConcern.W field instead.
-func (wc *WriteConcern) GetW() interface{} {
- return wc.W
-}
-
-// GetJ returns the write concern journaling level.
-//
-// Deprecated: Use the WriteConcern.Journal field instead.
-func (wc *WriteConcern) GetJ() bool {
- // Treat a nil Journal as false. That maintains backward compatibility with the existing
- // behavior of GetJ where unset is false. If users want the real value of Journal, they can
- // access the Journal field.
- return wc.Journal != nil && *wc.Journal
-}
-
-// GetWTimeout returns the write concern timeout.
-//
-// Deprecated: Use the WriteConcern.WTimeout field instead.
-func (wc *WriteConcern) GetWTimeout() time.Duration {
- return wc.WTimeout
-}
-
-// WithOptions returns a copy of this WriteConcern with the options set.
-//
-// Deprecated: Use the WriteConcern convenience functions or define a struct literal instead.
-// For example:
-//
-// writeconcern.Majority()
-//
-// or
-//
-// journal := true
-// &writeconcern.WriteConcern{
-// W: 2,
-// Journal: &journal,
-// }
-func (wc *WriteConcern) WithOptions(options ...Option) *WriteConcern {
- if wc == nil {
- return New(options...)
- }
- newWC := &WriteConcern{}
- *newWC = *wc
-
- for _, option := range options {
- option(newWC)
- }
-
- return newWC
-}
-
-// AckWrite returns true if a write concern represents an acknowledged write
-//
-// Deprecated: Use [WriteConcern.Acknowledged] instead.
-func AckWrite(wc *WriteConcern) bool {
- return wc == nil || wc.Acknowledged()
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/LICENSE b/vendor/go.mongodb.org/mongo-driver/v2/LICENSE
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/LICENSE
rename to vendor/go.mongodb.org/mongo-driver/v2/LICENSE
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go
similarity index 51%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go
index 652aa48b8..5714b0e81 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go
@@ -4,52 +4,43 @@
// 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 bsoncodec
+package bson
import (
+ "fmt"
"reflect"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
-// ArrayCodec is the Codec used for bsoncore.Array values.
-//
-// Deprecated: ArrayCodec will not be directly accessible in Go Driver 2.0.
-type ArrayCodec struct{}
-
-var defaultArrayCodec = NewArrayCodec()
-
-// NewArrayCodec returns an ArrayCodec.
-//
-// Deprecated: NewArrayCodec will not be available in Go Driver 2.0. See
-// [ArrayCodec] for more details.
-func NewArrayCodec() *ArrayCodec {
- return &ArrayCodec{}
-}
+// arrayCodec is the Codec used for bsoncore.Array values.
+type arrayCodec struct{}
// EncodeValue is the ValueEncoder for bsoncore.Array values.
-func (ac *ArrayCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (ac *arrayCodec) EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != tCoreArray {
return ValueEncoderError{Name: "CoreArrayEncodeValue", Types: []reflect.Type{tCoreArray}, Received: val}
}
arr := val.Interface().(bsoncore.Array)
- return bsonrw.Copier{}.CopyArrayFromBytes(vw, arr)
+ return copyArrayFromBytes(vw, arr)
}
// DecodeValue is the ValueDecoder for bsoncore.Array values.
-func (ac *ArrayCodec) DecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (ac *arrayCodec) DecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Type() != tCoreArray {
return ValueDecoderError{Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, Received: val}
}
+ if vrType := vr.Type(); vrType != TypeArray {
+ return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
+ }
if val.IsNil() {
val.Set(reflect.MakeSlice(val.Type(), 0, 0))
}
val.SetLen(0)
- arr, err := bsonrw.Copier{}.AppendArrayBytes(val.Interface().(bsoncore.Array), vr)
+ arr, err := appendArrayBytes(val.Interface().(bsoncore.Array), vr)
val.Set(reflect.ValueOf(arr))
return err
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go
new file mode 100644
index 000000000..c0eeca24e
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go
@@ -0,0 +1,203 @@
+// 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 bson
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+var emptyValue = reflect.Value{}
+
+// ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be
+// encoded by the ValueEncoder.
+type ValueEncoderError struct {
+ Name string
+ Types []reflect.Type
+ Kinds []reflect.Kind
+ Received reflect.Value
+}
+
+func (vee ValueEncoderError) Error() string {
+ typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds))
+ for _, t := range vee.Types {
+ typeKinds = append(typeKinds, t.String())
+ }
+ for _, k := range vee.Kinds {
+ if k == reflect.Map {
+ typeKinds = append(typeKinds, "map[string]*")
+ continue
+ }
+ typeKinds = append(typeKinds, k.String())
+ }
+ received := vee.Received.Kind().String()
+ if vee.Received.IsValid() {
+ received = vee.Received.Type().String()
+ }
+ return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received)
+}
+
+// ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be
+// decoded by the ValueDecoder.
+type ValueDecoderError struct {
+ Name string
+ Types []reflect.Type
+ Kinds []reflect.Kind
+ Received reflect.Value
+}
+
+func (vde ValueDecoderError) Error() string {
+ typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds))
+ for _, t := range vde.Types {
+ typeKinds = append(typeKinds, t.String())
+ }
+ for _, k := range vde.Kinds {
+ if k == reflect.Map {
+ typeKinds = append(typeKinds, "map[string]*")
+ continue
+ }
+ typeKinds = append(typeKinds, k.String())
+ }
+ received := vde.Received.Kind().String()
+ if vde.Received.IsValid() {
+ received = vde.Received.Type().String()
+ }
+ if !vde.Received.CanSet() {
+ received = "unsettable " + received
+ }
+ return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received)
+}
+
+// EncodeContext is the contextual information required for a Codec to encode a
+// value.
+type EncodeContext struct {
+ *Registry
+
+ // minSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64,
+ // uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits)
+ // that can represent the integer value.
+ minSize bool
+
+ errorOnInlineDuplicates bool
+ stringifyMapKeysWithFmt bool
+ nilMapAsEmpty bool
+ nilSliceAsEmpty bool
+ nilByteSliceAsEmpty bool
+ omitZeroStruct bool
+ omitEmpty bool
+ useJSONStructTags bool
+}
+
+// DecodeContext is the contextual information required for a Codec to decode a
+// value.
+type DecodeContext struct {
+ *Registry
+
+ // truncate, if true, instructs decoders to to truncate the fractional part of BSON "double"
+ // values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, int64,
+ // uint, uint8, uint16, uint32, or uint64) struct field. The truncation logic does not apply to
+ // BSON "decimal128" values.
+ truncate bool
+
+ // defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the
+ // usage for this field is restricted to data typed as "any" or "map[string]any". If DocumentType is
+ // set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an
+ // error.
+ defaultDocumentType reflect.Type
+
+ binaryAsSlice bool
+
+ // a false value results in a decoding error.
+ objectIDAsHexString bool
+
+ useJSONStructTags bool
+ useLocalTimeZone bool
+ zeroMaps bool
+ zeroStructs bool
+}
+
+// ValueEncoder is the interface implemented by types that can encode a provided Go type to BSON.
+// The value to encode is provided as a reflect.Value and a bson.ValueWriter is used within the
+// EncodeValue method to actually create the BSON representation. For convenience, ValueEncoderFunc
+// is provided to allow use of a function with the correct signature as a ValueEncoder. An
+// EncodeContext instance is provided to allow implementations to lookup further ValueEncoders and
+// to provide configuration information.
+type ValueEncoder interface {
+ EncodeValue(EncodeContext, ValueWriter, reflect.Value) error
+}
+
+// ValueEncoderFunc is an adapter function that allows a function with the correct signature to be
+// used as a ValueEncoder.
+type ValueEncoderFunc func(EncodeContext, ValueWriter, reflect.Value) error
+
+// EncodeValue implements the ValueEncoder interface.
+func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ return fn(ec, vw, val)
+}
+
+// ValueDecoder is the interface implemented by types that can decode BSON to a provided Go type.
+// Implementations should ensure that the value they receive is settable. Similar to ValueEncoderFunc,
+// ValueDecoderFunc is provided to allow the use of a function with the correct signature as a
+// ValueDecoder. A DecodeContext instance is provided and serves similar functionality to the
+// EncodeContext.
+type ValueDecoder interface {
+ DecodeValue(DecodeContext, ValueReader, reflect.Value) error
+}
+
+// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be
+// used as a ValueDecoder.
+type ValueDecoderFunc func(DecodeContext, ValueReader, reflect.Value) error
+
+// DecodeValue implements the ValueDecoder interface.
+func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ return fn(dc, vr, val)
+}
+
+// typeDecoder is the interface implemented by types that can handle the decoding of a value given its type.
+type typeDecoder interface {
+ decodeType(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error)
+}
+
+// typeDecoderFunc is an adapter function that allows a function with the correct signature to be used as a typeDecoder.
+type typeDecoderFunc func(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error)
+
+func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ return fn(dc, vr, t)
+}
+
+// decodeAdapter allows two functions with the correct signatures to be used as both a ValueDecoder and typeDecoder.
+type decodeAdapter struct {
+ ValueDecoderFunc
+ typeDecoderFunc
+}
+
+var (
+ _ ValueDecoder = decodeAdapter{}
+ _ typeDecoder = decodeAdapter{}
+)
+
+func decodeTypeOrValueWithInfo(vd ValueDecoder, dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if td, _ := vd.(typeDecoder); td != nil {
+ val, err := td.decodeType(dc, vr, t)
+ if err == nil && val.Type() != t {
+ // This conversion step is necessary for slices and maps. If a user declares variables like:
+ //
+ // type myBool bool
+ // var m map[string]myBool
+ //
+ // and tries to decode BSON bytes into the map, the decoding will fail if this conversion is not present
+ // because we'll try to assign a value of type bool to one of type myBool.
+ val = val.Convert(t)
+ }
+ return val, err
+ }
+
+ val := reflect.New(t).Elem()
+ err := vd.DecodeValue(dc, vr, val)
+ return val, err
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go
new file mode 100644
index 000000000..eb4781c71
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go
@@ -0,0 +1,128 @@
+// Copyright (C) MongoDB, Inc. 2025-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 bson
+
+import (
+ "bytes"
+ "io"
+)
+
+// bufferedByteSrc implements the low-level byteSrc interface by reading
+// directly from an in-memory byte slice. It provides efficient, zero-copy
+// access for parsing BSON when the entire document is buffered in memory.
+type bufferedByteSrc struct {
+ buf []byte // entire BSON document
+ offset int64 // Current read index into buf
+}
+
+var _ byteSrc = (*bufferedByteSrc)(nil)
+
+// Read reads up to len(p) bytes from the in-memory buffer, advancing the offset
+// by the number of bytes read.
+func (b *bufferedByteSrc) readExact(p []byte) (int, error) {
+ if b.offset >= int64(len(b.buf)) {
+ return 0, io.EOF
+ }
+ n := copy(p, b.buf[b.offset:])
+ b.offset += int64(n)
+ return n, nil
+}
+
+// ReadByte returns the single byte at buf[offset] and advances offset by 1.
+func (b *bufferedByteSrc) ReadByte() (byte, error) {
+ if b.offset >= int64(len(b.buf)) {
+ return 0, io.EOF
+ }
+ b.offset++
+ return b.buf[b.offset-1], nil
+}
+
+// peek returns buf[offset:offset+n] without advancing offset.
+func (b *bufferedByteSrc) peek(n int) ([]byte, error) {
+ // Ensure we don't read past the end of the buffer.
+ if int64(n)+b.offset > int64(len(b.buf)) {
+ return b.buf[b.offset:], io.EOF
+ }
+
+ // Return the next n bytes without advancing the offset
+ return b.buf[b.offset : b.offset+int64(n)], nil
+}
+
+// discard advances offset by n bytes, returning the number of bytes discarded.
+func (b *bufferedByteSrc) discard(n int) (int, error) {
+ // Ensure we don't read past the end of the buffer.
+ if int64(n)+b.offset > int64(len(b.buf)) {
+ // If we have exceeded the buffer length, discard only up to the end.
+ left := len(b.buf) - int(b.offset)
+ b.offset = int64(len(b.buf))
+
+ return left, io.EOF
+ }
+
+ // Advance the read position
+ b.offset += int64(n)
+ return n, nil
+}
+
+// readSlice reads buf[offset:] for the first occurrence of delim, returning
+// buf[offset:idx+1], and advances offset past it; errors if delim not found.
+func (b *bufferedByteSrc) readSlice(delim byte) ([]byte, error) {
+ // Ensure we don't read past the end of the buffer.
+ if b.offset >= int64(len(b.buf)) {
+ return nil, io.EOF
+ }
+
+ // Look for the delimiter in the remaining bytes
+ rem := b.buf[b.offset:]
+ idx := bytes.IndexByte(rem, delim)
+ if idx < 0 {
+ return nil, io.EOF
+ }
+
+ // Build the result slice up through the delimiter.
+ result := rem[:idx+1]
+
+ // Advance the offset past the delimiter.
+ b.offset += int64(idx + 1)
+
+ return result, nil
+}
+
+// pos returns the current read position in the buffer.
+func (b *bufferedByteSrc) pos() int64 {
+ return b.offset
+}
+
+// regexLength will return the total byte length of a BSON regex value.
+func (b *bufferedByteSrc) regexLength() (int32, error) {
+ rem := b.buf[b.offset:]
+
+ // Find end of the first C-string (pattern).
+ i := bytes.IndexByte(rem, 0x00)
+ if i < 0 {
+ return 0, io.EOF
+ }
+
+ // Find end of second C-string (options).
+ j := bytes.IndexByte(rem[i+1:], 0x00)
+ if j < 0 {
+ return 0, io.EOF
+ }
+
+ // Total length = first C-string length (pattern) + second C-string length
+ // (options) + 2 null terminators
+ return int32(i + j + 2), nil
+}
+
+func (*bufferedByteSrc) streamable() bool {
+ return false
+}
+
+func (b *bufferedByteSrc) reset() {
+ b.buf = nil
+ b.offset = 0
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go
new file mode 100644
index 000000000..bd44cf9a8
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go
@@ -0,0 +1,97 @@
+// 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 bson
+
+import (
+ "fmt"
+ "reflect"
+)
+
+// byteSliceCodec is the Codec used for []byte values.
+type byteSliceCodec struct {
+ // encodeNilAsEmpty causes EncodeValue to marshal nil Go byte slices as empty BSON binary values
+ // instead of BSON null.
+ encodeNilAsEmpty bool
+}
+
+// Assert that byteSliceCodec satisfies the typeDecoder interface, which allows it to be
+// used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+// collection.
+var _ typeDecoder = &byteSliceCodec{}
+
+// EncodeValue is the ValueEncoder for []byte.
+func (bsc *byteSliceCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tByteSlice {
+ return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
+ }
+ if val.IsNil() && !bsc.encodeNilAsEmpty && !ec.nilByteSliceAsEmpty {
+ return vw.WriteNull()
+ }
+ return vw.WriteBinary(val.Interface().([]byte))
+}
+
+func (bsc *byteSliceCodec) decodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tByteSlice {
+ return emptyValue, ValueDecoderError{
+ Name: "ByteSliceDecodeValue",
+ Types: []reflect.Type{tByteSlice},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var data []byte
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeString:
+ str, err := vr.ReadString()
+ if err != nil {
+ return emptyValue, err
+ }
+ data = []byte(str)
+ case TypeSymbol:
+ sym, err := vr.ReadSymbol()
+ if err != nil {
+ return emptyValue, err
+ }
+ data = []byte(sym)
+ case TypeBinary:
+ var subtype byte
+ data, subtype, err = vr.ReadBinary()
+ if err != nil {
+ return emptyValue, err
+ }
+ if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld {
+ return emptyValue, decodeBinaryError{subtype: subtype, typeName: "[]byte"}
+ }
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a []byte", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(data), nil
+}
+
+// DecodeValue is the ValueDecoder for []byte.
+func (bsc *byteSliceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tByteSlice {
+ return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
+ }
+
+ elem, err := bsc.decodeType(dc, vr, tByteSlice)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go
similarity index 94%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go
index 844b50299..ee8275719 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go
@@ -4,7 +4,7 @@
// 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 bsoncodec
+package bson
import (
"reflect"
@@ -22,8 +22,10 @@ func init() {
}
// statically assert array size
-var _ = (kindEncoderCache{}).entries[reflect.UnsafePointer]
-var _ = (kindDecoderCache{}).entries[reflect.UnsafePointer]
+var (
+ _ = (kindEncoderCache{}).entries[reflect.UnsafePointer]
+ _ = (kindDecoderCache{}).entries[reflect.UnsafePointer]
+)
type typeEncoderCache struct {
cache sync.Map // map[reflect.Type]ValueEncoder
@@ -49,7 +51,7 @@ func (c *typeEncoderCache) LoadOrStore(rt reflect.Type, enc ValueEncoder) ValueE
func (c *typeEncoderCache) Clone() *typeEncoderCache {
cc := new(typeEncoderCache)
- c.cache.Range(func(k, v interface{}) bool {
+ c.cache.Range(func(k, v any) bool {
if k != nil && v != nil {
cc.cache.Store(k, v)
}
@@ -82,7 +84,7 @@ func (c *typeDecoderCache) LoadOrStore(rt reflect.Type, dec ValueDecoder) ValueD
func (c *typeDecoderCache) Clone() *typeDecoderCache {
cc := new(typeDecoderCache)
- c.cache.Range(func(k, v interface{}) bool {
+ c.cache.Range(func(k, v any) bool {
if k != nil && v != nil {
cc.cache.Store(k, v)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go
similarity index 77%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go
index cb8180f25..fed4d1f8d 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go
@@ -4,12 +4,10 @@
// 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 bsoncodec
+package bson
import (
"reflect"
-
- "go.mongodb.org/mongo-driver/bson/bsonrw"
)
// condAddrEncoder is the encoder used when a pointer to the encoding value has an encoder.
@@ -18,7 +16,7 @@ type condAddrEncoder struct {
elseEnc ValueEncoder
}
-var _ ValueEncoder = (*condAddrEncoder)(nil)
+var _ ValueEncoder = &condAddrEncoder{}
// newCondAddrEncoder returns an condAddrEncoder.
func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder {
@@ -27,14 +25,14 @@ func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder {
}
// EncodeValue is the ValueEncoderFunc for a value that may be addressable.
-func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
if val.CanAddr() {
return cae.canAddrEnc.EncodeValue(ec, vw, val)
}
if cae.elseEnc != nil {
return cae.elseEnc.EncodeValue(ec, vw, val)
}
- return ErrNoEncoder{Type: val.Type()}
+ return errNoEncoder{Type: val.Type()}
}
// condAddrDecoder is the decoder used when a pointer to the value has a decoder.
@@ -43,7 +41,7 @@ type condAddrDecoder struct {
elseDec ValueDecoder
}
-var _ ValueDecoder = (*condAddrDecoder)(nil)
+var _ ValueDecoder = &condAddrDecoder{}
// newCondAddrDecoder returns an CondAddrDecoder.
func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder {
@@ -52,12 +50,12 @@ func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder {
}
// DecodeValue is the ValueDecoderFunc for a value that may be addressable.
-func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if val.CanAddr() {
return cad.canAddrDec.DecodeValue(dc, vr, val)
}
if cad.elseDec != nil {
return cad.elseDec.DecodeValue(dc, vr, val)
}
- return ErrNoDecoder{Type: val.Type()}
+ return errNoDecoder{Type: val.Type()}
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go
new file mode 100644
index 000000000..c9a37c756
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go
@@ -0,0 +1,433 @@
+// 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 bson
+
+import (
+ "errors"
+ "fmt"
+ "io"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+// copyDocument handles copying one document from the src to the dst.
+func copyDocument(dst ValueWriter, src ValueReader) error {
+ dr, err := src.ReadDocument()
+ if err != nil {
+ return err
+ }
+
+ dw, err := dst.WriteDocument()
+ if err != nil {
+ return err
+ }
+
+ return copyDocumentCore(dw, dr)
+}
+
+// copyArrayFromBytes copies the values from a BSON array represented as a
+// []byte to a ValueWriter.
+func copyArrayFromBytes(dst ValueWriter, src []byte) error {
+ aw, err := dst.WriteArray()
+ if err != nil {
+ return err
+ }
+
+ err = copyBytesToArrayWriter(aw, src)
+ if err != nil {
+ return err
+ }
+
+ return aw.WriteArrayEnd()
+}
+
+// copyDocumentFromBytes copies the values from a BSON document represented as a
+// []byte to a ValueWriter.
+func copyDocumentFromBytes(dst ValueWriter, src []byte) error {
+ dw, err := dst.WriteDocument()
+ if err != nil {
+ return err
+ }
+
+ err = copyBytesToDocumentWriter(dw, src)
+ if err != nil {
+ return err
+ }
+
+ return dw.WriteDocumentEnd()
+}
+
+type writeElementFn func(key string) (ValueWriter, error)
+
+// copyBytesToArrayWriter copies the values from a BSON Array represented as a []byte to an
+// ArrayWriter.
+func copyBytesToArrayWriter(dst ArrayWriter, src []byte) error {
+ wef := func(_ string) (ValueWriter, error) {
+ return dst.WriteArrayElement()
+ }
+
+ return copyBytesToValueWriter(src, wef)
+}
+
+// copyBytesToDocumentWriter copies the values from a BSON document represented as a []byte to a
+// DocumentWriter.
+func copyBytesToDocumentWriter(dst DocumentWriter, src []byte) error {
+ wef := func(key string) (ValueWriter, error) {
+ return dst.WriteDocumentElement(key)
+ }
+
+ return copyBytesToValueWriter(src, wef)
+}
+
+func copyBytesToValueWriter(src []byte, wef writeElementFn) error {
+ // TODO(skriptble): Create errors types here. Anything that is a tag should be a property.
+ length, rem, ok := bsoncore.ReadLength(src)
+ if !ok {
+ return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src))
+ }
+ if len(src) < int(length) {
+ return fmt.Errorf("length read exceeds number of bytes available. length=%d bytes=%d", len(src), length)
+ }
+ rem = rem[:length-4]
+
+ var t bsoncore.Type
+ var key string
+ var val bsoncore.Value
+ for {
+ t, rem, ok = bsoncore.ReadType(rem)
+ if !ok {
+ return io.EOF
+ }
+ if t == bsoncore.Type(0) {
+ if len(rem) != 0 {
+ return fmt.Errorf("document end byte found before end of document. remaining bytes=%v", rem)
+ }
+ break
+ }
+
+ key, rem, ok = bsoncore.ReadKey(rem)
+ if !ok {
+ return fmt.Errorf("invalid key found. remaining bytes=%v", rem)
+ }
+
+ // write as either array element or document element using writeElementFn
+ vw, err := wef(key)
+ if err != nil {
+ return err
+ }
+
+ val, rem, ok = bsoncore.ReadValue(rem, t)
+ if !ok {
+ return fmt.Errorf("not enough bytes available to read type. bytes=%d type=%s", len(rem), t)
+ }
+ err = copyValueFromBytes(vw, Type(t), val.Data)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// copyDocumentToBytes copies an entire document from the ValueReader and
+// returns it as bytes.
+func copyDocumentToBytes(src ValueReader) ([]byte, error) {
+ return appendDocumentBytes(nil, src)
+}
+
+// appendDocumentBytes functions the same as CopyDocumentToBytes, but will
+// append the result to dst.
+func appendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) {
+ if br, ok := src.(bytesReader); ok {
+ _, dst, err := br.readValueBytes(dst)
+ return dst, err
+ }
+
+ vw := vwPool.Get().(*valueWriter)
+ defer putValueWriter(vw)
+
+ vw.reset(dst)
+
+ err := copyDocument(vw, src)
+ dst = vw.buf
+ return dst, err
+}
+
+// appendArrayBytes copies an array from the ValueReader to dst.
+func appendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
+ if br, ok := src.(bytesReader); ok {
+ _, dst, err := br.readValueBytes(dst)
+ return dst, err
+ }
+
+ vw := vwPool.Get().(*valueWriter)
+ defer putValueWriter(vw)
+
+ vw.reset(dst)
+
+ err := copyArray(vw, src)
+ dst = vw.buf
+ return dst, err
+}
+
+// copyValueFromBytes will write the value represtend by t and src to dst.
+func copyValueFromBytes(dst ValueWriter, t Type, src []byte) error {
+ if wvb, ok := dst.(bytesWriter); ok {
+ return wvb.writeValueBytes(t, src)
+ }
+
+ vr := newBufferedDocumentReader(src)
+ vr.advanceFrame()
+
+ vr.stack[vr.frame].mode = mElement
+ vr.stack[vr.frame].vType = t
+
+ return copyValue(dst, vr)
+}
+
+// copyValueToBytes copies a value from src and returns it as a Type and a
+// []byte.
+func copyValueToBytes(src ValueReader) (Type, []byte, error) {
+ if br, ok := src.(bytesReader); ok {
+ return br.readValueBytes(nil)
+ }
+
+ vw := vwPool.Get().(*valueWriter)
+ defer putValueWriter(vw)
+
+ vw.reset(nil)
+ vw.push(mElement)
+
+ err := copyValue(vw, src)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ return Type(vw.buf[0]), vw.buf[2:], nil
+}
+
+// copyValue will copy a single value from src to dst.
+func copyValue(dst ValueWriter, src ValueReader) error {
+ var err error
+ switch src.Type() {
+ case TypeDouble:
+ var f64 float64
+ f64, err = src.ReadDouble()
+ if err != nil {
+ break
+ }
+ err = dst.WriteDouble(f64)
+ case TypeString:
+ var str string
+ str, err = src.ReadString()
+ if err != nil {
+ return err
+ }
+ err = dst.WriteString(str)
+ case TypeEmbeddedDocument:
+ err = copyDocument(dst, src)
+ case TypeArray:
+ err = copyArray(dst, src)
+ case TypeBinary:
+ var data []byte
+ var subtype byte
+ data, subtype, err = src.ReadBinary()
+ if err != nil {
+ break
+ }
+ err = dst.WriteBinaryWithSubtype(data, subtype)
+ case TypeUndefined:
+ err = src.ReadUndefined()
+ if err != nil {
+ break
+ }
+ err = dst.WriteUndefined()
+ case TypeObjectID:
+ var oid ObjectID
+ oid, err = src.ReadObjectID()
+ if err != nil {
+ break
+ }
+ err = dst.WriteObjectID(oid)
+ case TypeBoolean:
+ var b bool
+ b, err = src.ReadBoolean()
+ if err != nil {
+ break
+ }
+ err = dst.WriteBoolean(b)
+ case TypeDateTime:
+ var dt int64
+ dt, err = src.ReadDateTime()
+ if err != nil {
+ break
+ }
+ err = dst.WriteDateTime(dt)
+ case TypeNull:
+ err = src.ReadNull()
+ if err != nil {
+ break
+ }
+ err = dst.WriteNull()
+ case TypeRegex:
+ var pattern, options string
+ pattern, options, err = src.ReadRegex()
+ if err != nil {
+ break
+ }
+ err = dst.WriteRegex(pattern, options)
+ case TypeDBPointer:
+ var ns string
+ var pointer ObjectID
+ ns, pointer, err = src.ReadDBPointer()
+ if err != nil {
+ break
+ }
+ err = dst.WriteDBPointer(ns, pointer)
+ case TypeJavaScript:
+ var js string
+ js, err = src.ReadJavascript()
+ if err != nil {
+ break
+ }
+ err = dst.WriteJavascript(js)
+ case TypeSymbol:
+ var symbol string
+ symbol, err = src.ReadSymbol()
+ if err != nil {
+ break
+ }
+ err = dst.WriteSymbol(symbol)
+ case TypeCodeWithScope:
+ var code string
+ var srcScope DocumentReader
+ code, srcScope, err = src.ReadCodeWithScope()
+ if err != nil {
+ break
+ }
+
+ var dstScope DocumentWriter
+ dstScope, err = dst.WriteCodeWithScope(code)
+ if err != nil {
+ break
+ }
+ err = copyDocumentCore(dstScope, srcScope)
+ case TypeInt32:
+ var i32 int32
+ i32, err = src.ReadInt32()
+ if err != nil {
+ break
+ }
+ err = dst.WriteInt32(i32)
+ case TypeTimestamp:
+ var t, i uint32
+ t, i, err = src.ReadTimestamp()
+ if err != nil {
+ break
+ }
+ err = dst.WriteTimestamp(t, i)
+ case TypeInt64:
+ var i64 int64
+ i64, err = src.ReadInt64()
+ if err != nil {
+ break
+ }
+ err = dst.WriteInt64(i64)
+ case TypeDecimal128:
+ var d128 Decimal128
+ d128, err = src.ReadDecimal128()
+ if err != nil {
+ break
+ }
+ err = dst.WriteDecimal128(d128)
+ case TypeMinKey:
+ err = src.ReadMinKey()
+ if err != nil {
+ break
+ }
+ err = dst.WriteMinKey()
+ case TypeMaxKey:
+ err = src.ReadMaxKey()
+ if err != nil {
+ break
+ }
+ err = dst.WriteMaxKey()
+ default:
+ err = fmt.Errorf("cannot copy unknown BSON type %s", src.Type())
+ }
+
+ return err
+}
+
+func copyArray(dst ValueWriter, src ValueReader) error {
+ ar, err := src.ReadArray()
+ if err != nil {
+ return err
+ }
+
+ aw, err := dst.WriteArray()
+ if err != nil {
+ return err
+ }
+
+ for {
+ vr, err := ar.ReadValue()
+ if errors.Is(err, ErrEOA) {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ vw, err := aw.WriteArrayElement()
+ if err != nil {
+ return err
+ }
+
+ err = copyValue(vw, vr)
+ if err != nil {
+ return err
+ }
+ }
+
+ return aw.WriteArrayEnd()
+}
+
+func copyDocumentCore(dw DocumentWriter, dr DocumentReader) error {
+ for {
+ key, vr, err := dr.ReadElement()
+ if errors.Is(err, ErrEOD) {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ vw, err := dw.WriteDocumentElement(key)
+ if err != nil {
+ return err
+ }
+
+ err = copyValue(vw, vr)
+ if err != nil {
+ return err
+ }
+ }
+
+ return dw.WriteDocumentEnd()
+}
+
+// bytesReader is the interface used to read BSON bytes from a valueReader.
+//
+// The bytes of the value will be appended to dst.
+type bytesReader interface {
+ readValueBytes(dst []byte) (Type, []byte, error)
+}
+
+// bytesWriter is the interface used to write BSON bytes to a valueWriter.
+type bytesWriter interface {
+ writeValueBytes(t Type, b []byte) error
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go
similarity index 75%
rename from vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go
index db8be74d8..f75d70cc3 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go
@@ -7,7 +7,7 @@
// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer
// See THIRD-PARTY-NOTICES for original license terms.
-package primitive
+package bson
import (
"encoding/json"
@@ -17,6 +17,8 @@ import (
"regexp"
"strconv"
"strings"
+
+ "go.mongodb.org/mongo-driver/v2/internal/decimal128"
)
// These constants are the maximum and minimum values for the exponent field in a decimal128 value.
@@ -50,85 +52,7 @@ func (d Decimal128) GetBytes() (uint64, uint64) {
// String returns a string representation of the decimal value.
func (d Decimal128) String() string {
- var posSign int // positive sign
- var exp int // exponent
- var high, low uint64 // significand high/low
-
- if d.h>>63&1 == 0 {
- posSign = 1
- }
-
- switch d.h >> 58 & (1<<5 - 1) {
- case 0x1F:
- return "NaN"
- case 0x1E:
- return "-Infinity"[posSign:]
- }
-
- low = d.l
- if d.h>>61&3 == 3 {
- // Bits: 1*sign 2*ignored 14*exponent 111*significand.
- // Implicit 0b100 prefix in significand.
- exp = int(d.h >> 47 & (1<<14 - 1))
- // Spec says all of these values are out of range.
- high, low = 0, 0
- } else {
- // Bits: 1*sign 14*exponent 113*significand
- exp = int(d.h >> 49 & (1<<14 - 1))
- high = d.h & (1<<49 - 1)
- }
- exp += MinDecimal128Exp
-
- // Would be handled by the logic below, but that's trivial and common.
- if high == 0 && low == 0 && exp == 0 {
- return "-0"[posSign:]
- }
-
- var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero.
- var last = len(repr)
- var i = len(repr)
- var dot = len(repr) + exp
- var rem uint32
-Loop:
- for d9 := 0; d9 < 5; d9++ {
- high, low, rem = divmod(high, low, 1e9)
- for d1 := 0; d1 < 9; d1++ {
- // Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc.
- if i < len(repr) && (dot == i || low == 0 && high == 0 && rem > 0 && rem < 10 && (dot < i-6 || exp > 0)) {
- exp += len(repr) - i
- i--
- repr[i] = '.'
- last = i - 1
- dot = len(repr) // Unmark.
- }
- c := '0' + byte(rem%10)
- rem /= 10
- i--
- repr[i] = c
- // Handle "0E+3", "1E+3", etc.
- if low == 0 && high == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || exp > 0) {
- last = i
- break Loop
- }
- if c != '0' {
- last = i
- }
- // Break early. Works without it, but why.
- if dot > i && low == 0 && high == 0 && rem == 0 {
- break Loop
- }
- }
- }
- repr[last-1] = '-'
- last--
-
- if exp > 0 {
- return string(repr[last+posSign:]) + "E+" + strconv.Itoa(exp)
- }
- if exp < 0 {
- return string(repr[last+posSign:]) + "E" + strconv.Itoa(exp)
- }
- return string(repr[last+posSign:])
+ return decimal128.String(d.h, d.l)
}
// BigInt returns significand as big.Int and exponent, bi * 10 ^ exp.
@@ -210,7 +134,7 @@ func (d Decimal128) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}
-// UnmarshalJSON creates a primitive.Decimal128 from a JSON string, an extended JSON $numberDecimal value, or the string
+// UnmarshalJSON creates a Decimal128 from a JSON string, an extended JSON $numberDecimal value, or the string
// "null". If b is a JSON string or extended JSON value, d will have the value of that string, and if b is "null", d will
// be unchanged.
func (d *Decimal128) UnmarshalJSON(b []byte) error {
@@ -221,7 +145,7 @@ func (d *Decimal128) UnmarshalJSON(b []byte) error {
return nil
}
- var res interface{}
+ var res any
err := json.Unmarshal(b, &res)
if err != nil {
return err
@@ -230,7 +154,7 @@ func (d *Decimal128) UnmarshalJSON(b []byte) error {
// Extended JSON
if !ok {
- m, ok := res.(map[string]interface{})
+ m, ok := res.(map[string]any)
if !ok {
return errors.New("not an extended JSON Decimal128: expected document")
}
@@ -248,26 +172,11 @@ func (d *Decimal128) UnmarshalJSON(b []byte) error {
return err
}
-func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) {
- div64 := uint64(div)
- a := h >> 32
- aq := a / div64
- ar := a % div64
- b := ar<<32 + h&(1<<32-1)
- bq := b / div64
- br := b % div64
- c := br<<32 + l>>32
- cq := c / div64
- cr := c % div64
- d := cr<<32 + l&(1<<32-1)
- dq := d / div64
- dr := d % div64
- return (aq<<32 | bq), (cq<<32 | dq), uint32(dr)
-}
-
-var dNaN = Decimal128{0x1F << 58, 0}
-var dPosInf = Decimal128{0x1E << 58, 0}
-var dNegInf = Decimal128{0x3E << 58, 0}
+var (
+ dNaN = Decimal128{0x1F << 58, 0}
+ dPosInf = Decimal128{0x1E << 58, 0}
+ dNegInf = Decimal128{0x3E << 58, 0}
+)
func dErr(s string) (Decimal128, error) {
return dNaN, fmt.Errorf("cannot parse %q as a decimal128", s)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/decoder.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go
similarity index 52%
rename from vendor/go.mongodb.org/mongo-driver/bson/decoder.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go
index eac74cd39..6e849a88e 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/decoder.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go
@@ -11,9 +11,6 @@ import (
"fmt"
"reflect"
"sync"
-
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
)
// ErrDecodeToNil is the error returned when trying to decode to a nil value
@@ -23,67 +20,34 @@ var ErrDecodeToNil = errors.New("cannot Decode to nil value")
// methods and is not consumable from outside of this package. The Decoders retrieved from this pool
// must have both Reset and SetRegistry called on them.
var decPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
return new(Decoder)
},
}
-// A Decoder reads and decodes BSON documents from a stream. It reads from a bsonrw.ValueReader as
+// A Decoder reads and decodes BSON documents from a stream. It reads from a ValueReader as
// the source of BSON data.
type Decoder struct {
- dc bsoncodec.DecodeContext
- vr bsonrw.ValueReader
-
- // We persist defaultDocumentM and defaultDocumentD on the Decoder to prevent overwriting from
- // (*Decoder).SetContext.
- defaultDocumentM bool
- defaultDocumentD bool
-
- binaryAsSlice bool
- useJSONStructTags bool
- useLocalTimeZone bool
- zeroMaps bool
- zeroStructs bool
+ dc DecodeContext
+ vr ValueReader
}
-// NewDecoder returns a new decoder that uses the DefaultRegistry to read from vr.
-func NewDecoder(vr bsonrw.ValueReader) (*Decoder, error) {
- if vr == nil {
- return nil, errors.New("cannot create a new Decoder with a nil ValueReader")
- }
-
+// NewDecoder returns a new decoder that reads from vr.
+func NewDecoder(vr ValueReader) *Decoder {
return &Decoder{
- dc: bsoncodec.DecodeContext{Registry: DefaultRegistry},
+ dc: DecodeContext{Registry: defaultRegistry},
vr: vr,
- }, nil
-}
-
-// NewDecoderWithContext returns a new decoder that uses DecodeContext dc to read from vr.
-//
-// Deprecated: Use [NewDecoder] and use the Decoder configuration methods set the desired unmarshal
-// behavior instead.
-func NewDecoderWithContext(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (*Decoder, error) {
- if dc.Registry == nil {
- dc.Registry = DefaultRegistry
}
- if vr == nil {
- return nil, errors.New("cannot create a new Decoder with a nil ValueReader")
- }
-
- return &Decoder{
- dc: dc,
- vr: vr,
- }, nil
}
// Decode reads the next BSON document from the stream and decodes it into the
// value pointed to by val.
//
// See [Unmarshal] for details about BSON unmarshaling behavior.
-func (d *Decoder) Decode(val interface{}) error {
+func (d *Decoder) Decode(val any) error {
if unmarshaler, ok := val.(Unmarshaler); ok {
// TODO(skriptble): Reuse a []byte here and use the AppendDocumentBytes method.
- buf, err := bsonrw.Copier{}.CopyDocumentToBytes(d.vr)
+ buf, err := copyDocumentToBytes(d.vr)
if err != nil {
return err
}
@@ -109,100 +73,71 @@ func (d *Decoder) Decode(val interface{}) error {
return err
}
- if d.defaultDocumentM {
- d.dc.DefaultDocumentM()
- }
- if d.defaultDocumentD {
- d.dc.DefaultDocumentD()
- }
- if d.binaryAsSlice {
- d.dc.BinaryAsSlice()
- }
- if d.useJSONStructTags {
- d.dc.UseJSONStructTags()
- }
- if d.useLocalTimeZone {
- d.dc.UseLocalTimeZone()
- }
- if d.zeroMaps {
- d.dc.ZeroMaps()
- }
- if d.zeroStructs {
- d.dc.ZeroStructs()
- }
-
return decoder.DecodeValue(d.dc, d.vr, rval)
}
// Reset will reset the state of the decoder, using the same *DecodeContext used in
// the original construction but using vr for reading.
-func (d *Decoder) Reset(vr bsonrw.ValueReader) error {
- // TODO:(GODRIVER-2719): Remove error return value.
+func (d *Decoder) Reset(vr ValueReader) {
d.vr = vr
- return nil
}
// SetRegistry replaces the current registry of the decoder with r.
-func (d *Decoder) SetRegistry(r *bsoncodec.Registry) error {
- // TODO:(GODRIVER-2719): Remove error return value.
+func (d *Decoder) SetRegistry(r *Registry) {
d.dc.Registry = r
- return nil
}
-// SetContext replaces the current registry of the decoder with dc.
-//
-// Deprecated: Use the Decoder configuration methods to set the desired unmarshal behavior instead.
-func (d *Decoder) SetContext(dc bsoncodec.DecodeContext) error {
- // TODO:(GODRIVER-2719): Remove error return value.
- d.dc = dc
- return nil
-}
-
-// DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This
-// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
+// DefaultDocumentM causes the Decoder to always unmarshal documents into the bson.M type. This
+// behavior is restricted to data typed as "any" or "map[string]any".
func (d *Decoder) DefaultDocumentM() {
- d.defaultDocumentM = true
+ d.dc.defaultDocumentType = reflect.TypeOf(M{})
}
-// DefaultDocumentD causes the Decoder to always unmarshal documents into the primitive.D type. This
-// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
-func (d *Decoder) DefaultDocumentD() {
- d.defaultDocumentD = true
+// DefaultDocumentMap causes the Decoder to always unmarshal documents into the
+// map[string]any type. This behavior is restricted to data typed as "any" or
+// "map[string]any".
+func (d *Decoder) DefaultDocumentMap() {
+ d.dc.defaultDocumentType = reflect.TypeOf(map[string]any{})
}
// AllowTruncatingDoubles causes the Decoder to truncate the fractional part of BSON "double" values
// when attempting to unmarshal them into a Go integer (int, int8, int16, int32, or int64) struct
// field. The truncation logic does not apply to BSON "decimal128" values.
func (d *Decoder) AllowTruncatingDoubles() {
- d.dc.Truncate = true
+ d.dc.truncate = true
}
// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or
-// "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
+// "Old" BSON binary subtype as a Go byte slice instead of a bson.Binary.
func (d *Decoder) BinaryAsSlice() {
- d.binaryAsSlice = true
+ d.dc.binaryAsSlice = true
+}
+
+// ObjectIDAsHexString causes the Decoder to decode object IDs to their hex representation.
+func (d *Decoder) ObjectIDAsHexString() {
+ d.dc.objectIDAsHexString = true
}
// UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson"
// struct tag is not specified.
func (d *Decoder) UseJSONStructTags() {
- d.useJSONStructTags = true
+ d.dc.useJSONStructTags = true
}
// UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead
// of the UTC timezone.
func (d *Decoder) UseLocalTimeZone() {
- d.useLocalTimeZone = true
+ d.dc.useLocalTimeZone = true
}
// ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value
// passed to Decode before unmarshaling BSON documents into them.
func (d *Decoder) ZeroMaps() {
- d.zeroMaps = true
+ d.dc.zeroMaps = true
}
// ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination
// value passed to Decode before unmarshaling BSON documents into them.
func (d *Decoder) ZeroStructs() {
- d.zeroStructs = true
+ d.dc.zeroStructs = true
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go
new file mode 100644
index 000000000..1dc598dde
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go
@@ -0,0 +1,1523 @@
+// 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 bson
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math"
+ "net/url"
+ "reflect"
+ "strconv"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+var errCannotTruncate = errors.New("float64 can only be truncated to a lower precision type when truncation is enabled")
+
+type decodeBinaryError struct {
+ subtype byte
+ typeName string
+}
+
+func (d decodeBinaryError) Error() string {
+ return fmt.Sprintf("only binary values with subtype 0x00 or 0x02 can be decoded into %s, but got subtype %v", d.typeName, d.subtype)
+}
+
+// registerDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with
+// the provided RegistryBuilder.
+//
+// There is no support for decoding map[string]any because there is no decoder for
+// any, so users must either register this decoder themselves or use the
+// EmptyInterfaceDecoder available in the bson package.
+func registerDefaultDecoders(reg *Registry) {
+ intDecoder := decodeAdapter{intDecodeValue, intDecodeType}
+ floatDecoder := decodeAdapter{floatDecodeValue, floatDecodeType}
+ uintCodec := &uintCodec{}
+
+ reg.RegisterTypeDecoder(tD, ValueDecoderFunc(dDecodeValue))
+ reg.RegisterTypeDecoder(tBinary, decodeAdapter{binaryDecodeValue, binaryDecodeType})
+ reg.RegisterTypeDecoder(tVector, decodeAdapter{vectorDecodeValue, vectorDecodeType})
+ reg.RegisterTypeDecoder(tUndefined, decodeAdapter{undefinedDecodeValue, undefinedDecodeType})
+ reg.RegisterTypeDecoder(tDateTime, decodeAdapter{dateTimeDecodeValue, dateTimeDecodeType})
+ reg.RegisterTypeDecoder(tNull, decodeAdapter{nullDecodeValue, nullDecodeType})
+ reg.RegisterTypeDecoder(tRegex, decodeAdapter{regexDecodeValue, regexDecodeType})
+ reg.RegisterTypeDecoder(tDBPointer, decodeAdapter{dbPointerDecodeValue, dbPointerDecodeType})
+ reg.RegisterTypeDecoder(tTimestamp, decodeAdapter{timestampDecodeValue, timestampDecodeType})
+ reg.RegisterTypeDecoder(tMinKey, decodeAdapter{minKeyDecodeValue, minKeyDecodeType})
+ reg.RegisterTypeDecoder(tMaxKey, decodeAdapter{maxKeyDecodeValue, maxKeyDecodeType})
+ reg.RegisterTypeDecoder(tJavaScript, decodeAdapter{javaScriptDecodeValue, javaScriptDecodeType})
+ reg.RegisterTypeDecoder(tSymbol, decodeAdapter{symbolDecodeValue, symbolDecodeType})
+ reg.RegisterTypeDecoder(tByteSlice, &byteSliceCodec{})
+ reg.RegisterTypeDecoder(tTime, &timeCodec{})
+ reg.RegisterTypeDecoder(tEmpty, &emptyInterfaceCodec{})
+ reg.RegisterTypeDecoder(tCoreArray, &arrayCodec{})
+ reg.RegisterTypeDecoder(tOID, decodeAdapter{objectIDDecodeValue, objectIDDecodeType})
+ reg.RegisterTypeDecoder(tDecimal, decodeAdapter{decimal128DecodeValue, decimal128DecodeType})
+ reg.RegisterTypeDecoder(tJSONNumber, decodeAdapter{jsonNumberDecodeValue, jsonNumberDecodeType})
+ reg.RegisterTypeDecoder(tURL, decodeAdapter{urlDecodeValue, urlDecodeType})
+ reg.RegisterTypeDecoder(tCoreDocument, ValueDecoderFunc(coreDocumentDecodeValue))
+ reg.RegisterTypeDecoder(tCodeWithScope, decodeAdapter{codeWithScopeDecodeValue, codeWithScopeDecodeType})
+ reg.RegisterKindDecoder(reflect.Bool, decodeAdapter{booleanDecodeValue, booleanDecodeType})
+ reg.RegisterKindDecoder(reflect.Int, intDecoder)
+ reg.RegisterKindDecoder(reflect.Int8, intDecoder)
+ reg.RegisterKindDecoder(reflect.Int16, intDecoder)
+ reg.RegisterKindDecoder(reflect.Int32, intDecoder)
+ reg.RegisterKindDecoder(reflect.Int64, intDecoder)
+ reg.RegisterKindDecoder(reflect.Uint, uintCodec)
+ reg.RegisterKindDecoder(reflect.Uint8, uintCodec)
+ reg.RegisterKindDecoder(reflect.Uint16, uintCodec)
+ reg.RegisterKindDecoder(reflect.Uint32, uintCodec)
+ reg.RegisterKindDecoder(reflect.Uint64, uintCodec)
+ reg.RegisterKindDecoder(reflect.Float32, floatDecoder)
+ reg.RegisterKindDecoder(reflect.Float64, floatDecoder)
+ reg.RegisterKindDecoder(reflect.Array, ValueDecoderFunc(arrayDecodeValue))
+ reg.RegisterKindDecoder(reflect.Map, &mapCodec{})
+ reg.RegisterKindDecoder(reflect.Slice, &sliceCodec{})
+ reg.RegisterKindDecoder(reflect.String, &stringCodec{})
+ reg.RegisterKindDecoder(reflect.Struct, newStructCodec(nil))
+ reg.RegisterKindDecoder(reflect.Ptr, &pointerCodec{})
+ reg.RegisterTypeMapEntry(TypeDouble, tFloat64)
+ reg.RegisterTypeMapEntry(TypeString, tString)
+ reg.RegisterTypeMapEntry(TypeArray, tA)
+ reg.RegisterTypeMapEntry(TypeBinary, tBinary)
+ reg.RegisterTypeMapEntry(TypeUndefined, tUndefined)
+ reg.RegisterTypeMapEntry(TypeObjectID, tOID)
+ reg.RegisterTypeMapEntry(TypeBoolean, tBool)
+ reg.RegisterTypeMapEntry(TypeDateTime, tDateTime)
+ reg.RegisterTypeMapEntry(TypeRegex, tRegex)
+ reg.RegisterTypeMapEntry(TypeDBPointer, tDBPointer)
+ reg.RegisterTypeMapEntry(TypeJavaScript, tJavaScript)
+ reg.RegisterTypeMapEntry(TypeSymbol, tSymbol)
+ reg.RegisterTypeMapEntry(TypeCodeWithScope, tCodeWithScope)
+ reg.RegisterTypeMapEntry(TypeInt32, tInt32)
+ reg.RegisterTypeMapEntry(TypeInt64, tInt64)
+ reg.RegisterTypeMapEntry(TypeTimestamp, tTimestamp)
+ reg.RegisterTypeMapEntry(TypeDecimal128, tDecimal)
+ reg.RegisterTypeMapEntry(TypeMinKey, tMinKey)
+ reg.RegisterTypeMapEntry(TypeMaxKey, tMaxKey)
+ reg.RegisterTypeMapEntry(Type(0), tD)
+ reg.RegisterTypeMapEntry(TypeEmbeddedDocument, tD)
+ reg.RegisterInterfaceDecoder(tValueUnmarshaler, ValueDecoderFunc(valueUnmarshalerDecodeValue))
+ reg.RegisterInterfaceDecoder(tUnmarshaler, ValueDecoderFunc(unmarshalerDecodeValue))
+}
+
+// dDecodeValue is the ValueDecoderFunc for D instances.
+func dDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || !val.CanSet() || val.Type() != tD {
+ return ValueDecoderError{Name: "DDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
+ }
+
+ switch vrType := vr.Type(); vrType {
+ case Type(0), TypeEmbeddedDocument:
+ break
+ case TypeNull:
+ val.Set(reflect.Zero(val.Type()))
+ return vr.ReadNull()
+ default:
+ return fmt.Errorf("cannot decode %v into a D", vrType)
+ }
+
+ dr, err := vr.ReadDocument()
+ if err != nil {
+ return err
+ }
+
+ decoder, err := dc.LookupDecoder(tEmpty)
+ if err != nil {
+ return err
+ }
+
+ // Use the elements in the provided value if it's non nil. Otherwise, allocate a new D instance.
+ var elems D
+ if !val.IsNil() {
+ val.SetLen(0)
+ elems = val.Interface().(D)
+ } else {
+ elems = make(D, 0)
+ }
+
+ for {
+ key, elemVr, err := dr.ReadElement()
+ if errors.Is(err, ErrEOD) {
+ break
+ } else if err != nil {
+ return err
+ }
+
+ var v any
+ err = decoder.DecodeValue(dc, elemVr, reflect.ValueOf(&v).Elem())
+ if err != nil {
+ return err
+ }
+
+ elems = append(elems, E{Key: key, Value: v})
+ }
+
+ val.Set(reflect.ValueOf(elems))
+ return nil
+}
+
+func booleanDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t.Kind() != reflect.Bool {
+ return emptyValue, ValueDecoderError{
+ Name: "BooleanDecodeValue",
+ Kinds: []reflect.Kind{reflect.Bool},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var b bool
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeInt32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return emptyValue, err
+ }
+ b = (i32 != 0)
+ case TypeInt64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return emptyValue, err
+ }
+ b = (i64 != 0)
+ case TypeDouble:
+ f64, err := vr.ReadDouble()
+ if err != nil {
+ return emptyValue, err
+ }
+ b = (f64 != 0)
+ case TypeBoolean:
+ b, err = vr.ReadBoolean()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a boolean", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(b), nil
+}
+
+// booleanDecodeValue is the ValueDecoderFunc for bool types.
+func booleanDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool {
+ return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
+ }
+
+ elem, err := booleanDecodeType(dctx, vr, val.Type())
+ if err != nil {
+ return err
+ }
+
+ val.SetBool(elem.Bool())
+ return nil
+}
+
+func intDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ var i64 int64
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeInt32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return emptyValue, err
+ }
+ i64 = int64(i32)
+ case TypeInt64:
+ i64, err = vr.ReadInt64()
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeDouble:
+ f64, err := vr.ReadDouble()
+ if err != nil {
+ return emptyValue, err
+ }
+ if !dc.truncate && math.Floor(f64) != f64 {
+ return emptyValue, errCannotTruncate
+ }
+ if f64 > float64(math.MaxInt64) {
+ return emptyValue, fmt.Errorf("%g overflows int64", f64)
+ }
+ i64 = int64(f64)
+ case TypeBoolean:
+ b, err := vr.ReadBoolean()
+ if err != nil {
+ return emptyValue, err
+ }
+ if b {
+ i64 = 1
+ }
+ case TypeNull:
+ if err = vr.ReadNull(); err != nil {
+ return emptyValue, err
+ }
+ case TypeUndefined:
+ if err = vr.ReadUndefined(); err != nil {
+ return emptyValue, err
+ }
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into an integer type", vrType)
+ }
+
+ switch t.Kind() {
+ case reflect.Int8:
+ if i64 < math.MinInt8 || i64 > math.MaxInt8 {
+ return emptyValue, fmt.Errorf("%d overflows int8", i64)
+ }
+
+ return reflect.ValueOf(int8(i64)), nil
+ case reflect.Int16:
+ if i64 < math.MinInt16 || i64 > math.MaxInt16 {
+ return emptyValue, fmt.Errorf("%d overflows int16", i64)
+ }
+
+ return reflect.ValueOf(int16(i64)), nil
+ case reflect.Int32:
+ if i64 < math.MinInt32 || i64 > math.MaxInt32 {
+ return emptyValue, fmt.Errorf("%d overflows int32", i64)
+ }
+
+ return reflect.ValueOf(int32(i64)), nil
+ case reflect.Int64:
+ return reflect.ValueOf(i64), nil
+ case reflect.Int:
+ if i64 > math.MaxInt { // Can we fit this inside of an int
+ return emptyValue, fmt.Errorf("%d overflows int", i64)
+ }
+
+ return reflect.ValueOf(int(i64)), nil
+ default:
+ return emptyValue, ValueDecoderError{
+ Name: "IntDecodeValue",
+ Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
+ Received: reflect.Zero(t),
+ }
+ }
+}
+
+// intDecodeValue is the ValueDecoderFunc for int types.
+func intDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() {
+ return ValueDecoderError{
+ Name: "IntDecodeValue",
+ Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
+ Received: val,
+ }
+ }
+
+ elem, err := intDecodeType(dc, vr, val.Type())
+ if err != nil {
+ return err
+ }
+
+ val.SetInt(elem.Int())
+ return nil
+}
+
+func floatDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ var f float64
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeInt32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return emptyValue, err
+ }
+ f = float64(i32)
+ case TypeInt64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return emptyValue, err
+ }
+ f = float64(i64)
+ case TypeDouble:
+ f, err = vr.ReadDouble()
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeBoolean:
+ b, err := vr.ReadBoolean()
+ if err != nil {
+ return emptyValue, err
+ }
+ if b {
+ f = 1
+ }
+ case TypeNull:
+ if err = vr.ReadNull(); err != nil {
+ return emptyValue, err
+ }
+ case TypeUndefined:
+ if err = vr.ReadUndefined(); err != nil {
+ return emptyValue, err
+ }
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a float32 or float64 type", vrType)
+ }
+
+ switch t.Kind() {
+ case reflect.Float32:
+ if !dc.truncate && float64(float32(f)) != f {
+ return emptyValue, errCannotTruncate
+ }
+
+ return reflect.ValueOf(float32(f)), nil
+ case reflect.Float64:
+ return reflect.ValueOf(f), nil
+ default:
+ return emptyValue, ValueDecoderError{
+ Name: "FloatDecodeValue",
+ Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
+ Received: reflect.Zero(t),
+ }
+ }
+}
+
+// floatDecodeValue is the ValueDecoderFunc for float types.
+func floatDecodeValue(ec DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() {
+ return ValueDecoderError{
+ Name: "FloatDecodeValue",
+ Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
+ Received: val,
+ }
+ }
+
+ elem, err := floatDecodeType(ec, vr, val.Type())
+ if err != nil {
+ return err
+ }
+
+ val.SetFloat(elem.Float())
+ return nil
+}
+
+func javaScriptDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tJavaScript {
+ return emptyValue, ValueDecoderError{
+ Name: "JavaScriptDecodeValue",
+ Types: []reflect.Type{tJavaScript},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var js string
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeJavaScript:
+ js, err = vr.ReadJavascript()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a JavaScript", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(JavaScript(js)), nil
+}
+
+// javaScriptDecodeValue is the ValueDecoderFunc for the JavaScript type.
+func javaScriptDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tJavaScript {
+ return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
+ }
+
+ elem, err := javaScriptDecodeType(dctx, vr, tJavaScript)
+ if err != nil {
+ return err
+ }
+
+ val.SetString(elem.String())
+ return nil
+}
+
+func symbolDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tSymbol {
+ return emptyValue, ValueDecoderError{
+ Name: "SymbolDecodeValue",
+ Types: []reflect.Type{tSymbol},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var symbol string
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeString:
+ symbol, err = vr.ReadString()
+ case TypeSymbol:
+ symbol, err = vr.ReadSymbol()
+ case TypeBinary:
+ data, subtype, err := vr.ReadBinary()
+ if err != nil {
+ return emptyValue, err
+ }
+
+ if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld {
+ return emptyValue, decodeBinaryError{subtype: subtype, typeName: "Symbol"}
+ }
+ symbol = string(data)
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a Symbol", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(Symbol(symbol)), nil
+}
+
+// symbolDecodeValue is the ValueDecoderFunc for the Symbol type.
+func symbolDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tSymbol {
+ return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val}
+ }
+
+ elem, err := symbolDecodeType(dctx, vr, tSymbol)
+ if err != nil {
+ return err
+ }
+
+ val.SetString(elem.String())
+ return nil
+}
+
+func binaryDecode(vr ValueReader) (Binary, error) {
+ var b Binary
+
+ var data []byte
+ var subtype byte
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeBinary:
+ data, subtype, err = vr.ReadBinary()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return b, fmt.Errorf("cannot decode %v into a Binary", vrType)
+ }
+ if err != nil {
+ return b, err
+ }
+ b.Subtype = subtype
+ b.Data = data
+
+ return b, nil
+}
+
+func binaryDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tBinary {
+ return emptyValue, ValueDecoderError{
+ Name: "BinaryDecodeValue",
+ Types: []reflect.Type{tBinary},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ b, err := binaryDecode(vr)
+ if err != nil {
+ return emptyValue, err
+ }
+ return reflect.ValueOf(b), nil
+}
+
+// binaryDecodeValue is the ValueDecoderFunc for Binary.
+func binaryDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tBinary {
+ return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val}
+ }
+
+ elem, err := binaryDecodeType(dc, vr, tBinary)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func vectorDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tVector {
+ return emptyValue, ValueDecoderError{
+ Name: "VectorDecodeValue",
+ Types: []reflect.Type{tVector},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ b, err := binaryDecode(vr)
+ if err != nil {
+ return emptyValue, err
+ }
+
+ v, err := NewVectorFromBinary(b)
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(v), nil
+}
+
+// vectorDecodeValue is the ValueDecoderFunc for Vector.
+func vectorDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ t := val.Type()
+ if !val.CanSet() || t != tVector {
+ return ValueDecoderError{
+ Name: "VectorDecodeValue",
+ Types: []reflect.Type{tVector},
+ Received: val,
+ }
+ }
+
+ elem, err := vectorDecodeType(dctx, vr, t)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func undefinedDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tUndefined {
+ return emptyValue, ValueDecoderError{
+ Name: "UndefinedDecodeValue",
+ Types: []reflect.Type{tUndefined},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ case TypeNull:
+ err = vr.ReadNull()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into an Undefined", vr.Type())
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(Undefined{}), nil
+}
+
+// undefinedDecodeValue is the ValueDecoderFunc for Undefined.
+func undefinedDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tUndefined {
+ return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val}
+ }
+
+ elem, err := undefinedDecodeType(dc, vr, tUndefined)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+// Accept both 12-byte string and pretty-printed 24-byte hex string formats.
+func objectIDDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tOID {
+ return emptyValue, ValueDecoderError{
+ Name: "ObjectIDDecodeValue",
+ Types: []reflect.Type{tOID},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var oid ObjectID
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeObjectID:
+ oid, err = vr.ReadObjectID()
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeString:
+ str, err := vr.ReadString()
+ if err != nil {
+ return emptyValue, err
+ }
+ if oid, err = ObjectIDFromHex(str); err == nil {
+ break
+ }
+ if len(str) != 12 {
+ return emptyValue, fmt.Errorf("an ObjectID string must be exactly 12 bytes long (got %v)", len(str))
+ }
+ byteArr := []byte(str)
+ copy(oid[:], byteArr)
+ case TypeNull:
+ if err = vr.ReadNull(); err != nil {
+ return emptyValue, err
+ }
+ case TypeUndefined:
+ if err = vr.ReadUndefined(); err != nil {
+ return emptyValue, err
+ }
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into an ObjectID", vrType)
+ }
+
+ return reflect.ValueOf(oid), nil
+}
+
+// objectIDDecodeValue is the ValueDecoderFunc for ObjectID.
+func objectIDDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tOID {
+ return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val}
+ }
+
+ elem, err := objectIDDecodeType(dc, vr, tOID)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func dateTimeDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tDateTime {
+ return emptyValue, ValueDecoderError{
+ Name: "DateTimeDecodeValue",
+ Types: []reflect.Type{tDateTime},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var dt int64
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeDateTime:
+ dt, err = vr.ReadDateTime()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a DateTime", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(DateTime(dt)), nil
+}
+
+// dateTimeDecodeValue is the ValueDecoderFunc for DateTime.
+func dateTimeDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tDateTime {
+ return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val}
+ }
+
+ elem, err := dateTimeDecodeType(dc, vr, tDateTime)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func nullDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tNull {
+ return emptyValue, ValueDecoderError{
+ Name: "NullDecodeValue",
+ Types: []reflect.Type{tNull},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ case TypeNull:
+ err = vr.ReadNull()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a Null", vr.Type())
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(Null{}), nil
+}
+
+// nullDecodeValue is the ValueDecoderFunc for Null.
+func nullDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tNull {
+ return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val}
+ }
+
+ elem, err := nullDecodeType(dc, vr, tNull)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func regexDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tRegex {
+ return emptyValue, ValueDecoderError{
+ Name: "RegexDecodeValue",
+ Types: []reflect.Type{tRegex},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var pattern, options string
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeRegex:
+ pattern, options, err = vr.ReadRegex()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a Regex", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(Regex{Pattern: pattern, Options: options}), nil
+}
+
+// regexDecodeValue is the ValueDecoderFunc for Regex.
+func regexDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tRegex {
+ return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val}
+ }
+
+ elem, err := regexDecodeType(dc, vr, tRegex)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func dbPointerDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tDBPointer {
+ return emptyValue, ValueDecoderError{
+ Name: "DBPointerDecodeValue",
+ Types: []reflect.Type{tDBPointer},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var ns string
+ var pointer ObjectID
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeDBPointer:
+ ns, pointer, err = vr.ReadDBPointer()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a DBPointer", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(DBPointer{DB: ns, Pointer: pointer}), nil
+}
+
+// dbPointerDecodeValue is the ValueDecoderFunc for DBPointer.
+func dbPointerDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tDBPointer {
+ return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
+ }
+
+ elem, err := dbPointerDecodeType(dc, vr, tDBPointer)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func timestampDecodeType(_ DecodeContext, vr ValueReader, reflectType reflect.Type) (reflect.Value, error) {
+ if reflectType != tTimestamp {
+ return emptyValue, ValueDecoderError{
+ Name: "TimestampDecodeValue",
+ Types: []reflect.Type{tTimestamp},
+ Received: reflect.Zero(reflectType),
+ }
+ }
+
+ var t, incr uint32
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeTimestamp:
+ t, incr, err = vr.ReadTimestamp()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a Timestamp", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(Timestamp{T: t, I: incr}), nil
+}
+
+// timestampDecodeValue is the ValueDecoderFunc for Timestamp.
+func timestampDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tTimestamp {
+ return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
+ }
+
+ elem, err := timestampDecodeType(dc, vr, tTimestamp)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func minKeyDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tMinKey {
+ return emptyValue, ValueDecoderError{
+ Name: "MinKeyDecodeValue",
+ Types: []reflect.Type{tMinKey},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeMinKey:
+ err = vr.ReadMinKey()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a MinKey", vr.Type())
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(MinKey{}), nil
+}
+
+// minKeyDecodeValue is the ValueDecoderFunc for MinKey.
+func minKeyDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tMinKey {
+ return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val}
+ }
+
+ elem, err := minKeyDecodeType(dc, vr, tMinKey)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func maxKeyDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tMaxKey {
+ return emptyValue, ValueDecoderError{
+ Name: "MaxKeyDecodeValue",
+ Types: []reflect.Type{tMaxKey},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeMaxKey:
+ err = vr.ReadMaxKey()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a MaxKey", vr.Type())
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(MaxKey{}), nil
+}
+
+// maxKeyDecodeValue is the ValueDecoderFunc for MaxKey.
+func maxKeyDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tMaxKey {
+ return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
+ }
+
+ elem, err := maxKeyDecodeType(dc, vr, tMaxKey)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func decimal128DecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tDecimal {
+ return emptyValue, ValueDecoderError{
+ Name: "Decimal128DecodeValue",
+ Types: []reflect.Type{tDecimal},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var d128 Decimal128
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeDecimal128:
+ d128, err = vr.ReadDecimal128()
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a Decimal128", vr.Type())
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(d128), nil
+}
+
+// decimal128DecodeValue is the ValueDecoderFunc for Decimal128.
+func decimal128DecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tDecimal {
+ return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val}
+ }
+
+ elem, err := decimal128DecodeType(dctx, vr, tDecimal)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func jsonNumberDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tJSONNumber {
+ return emptyValue, ValueDecoderError{
+ Name: "JSONNumberDecodeValue",
+ Types: []reflect.Type{tJSONNumber},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var jsonNum json.Number
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeDouble:
+ f64, err := vr.ReadDouble()
+ if err != nil {
+ return emptyValue, err
+ }
+ jsonNum = json.Number(strconv.FormatFloat(f64, 'f', -1, 64))
+ case TypeInt32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return emptyValue, err
+ }
+ jsonNum = json.Number(strconv.FormatInt(int64(i32), 10))
+ case TypeInt64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return emptyValue, err
+ }
+ jsonNum = json.Number(strconv.FormatInt(i64, 10))
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a json.Number", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(jsonNum), nil
+}
+
+// jsonNumberDecodeValue is the ValueDecoderFunc for json.Number.
+func jsonNumberDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tJSONNumber {
+ return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
+ }
+
+ elem, err := jsonNumberDecodeType(dc, vr, tJSONNumber)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func urlDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tURL {
+ return emptyValue, ValueDecoderError{
+ Name: "URLDecodeValue",
+ Types: []reflect.Type{tURL},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ urlPtr := &url.URL{}
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeString:
+ var str string // Declare str here to avoid shadowing err during the ReadString call.
+ str, err = vr.ReadString()
+ if err != nil {
+ return emptyValue, err
+ }
+
+ urlPtr, err = url.Parse(str)
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a *url.URL", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(urlPtr).Elem(), nil
+}
+
+// urlDecodeValue is the ValueDecoderFunc for url.URL.
+func urlDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tURL {
+ return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val}
+ }
+
+ elem, err := urlDecodeType(dc, vr, tURL)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+// arrayDecodeValue is the ValueDecoderFunc for array types.
+func arrayDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || val.Kind() != reflect.Array {
+ return ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
+ }
+
+ switch vrType := vr.Type(); vrType {
+ case TypeArray:
+ case Type(0), TypeEmbeddedDocument:
+ if val.Type().Elem() != tE {
+ return fmt.Errorf("cannot decode document into %s", val.Type())
+ }
+ case TypeBinary:
+ if val.Type().Elem() != tByte {
+ return fmt.Errorf("ArrayDecodeValue can only be used to decode binary into a byte array, got %v", vrType)
+ }
+ data, subtype, err := vr.ReadBinary()
+ if err != nil {
+ return err
+ }
+ if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld {
+ return fmt.Errorf("ArrayDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", TypeBinary, subtype)
+ }
+
+ if len(data) > val.Len() {
+ return fmt.Errorf("more elements returned in array than can fit inside %s", val.Type())
+ }
+
+ for idx, elem := range data {
+ val.Index(idx).Set(reflect.ValueOf(elem))
+ }
+ return nil
+ case TypeNull:
+ val.Set(reflect.Zero(val.Type()))
+ return vr.ReadNull()
+ case TypeUndefined:
+ val.Set(reflect.Zero(val.Type()))
+ return vr.ReadUndefined()
+ default:
+ return fmt.Errorf("cannot decode %v into an array", vrType)
+ }
+
+ var elemsFunc func(DecodeContext, ValueReader, reflect.Value) ([]reflect.Value, error)
+ switch val.Type().Elem() {
+ case tE:
+ elemsFunc = decodeD
+ default:
+ elemsFunc = decodeDefault
+ }
+
+ elems, err := elemsFunc(dc, vr, val)
+ if err != nil {
+ return err
+ }
+
+ if len(elems) > val.Len() {
+ return fmt.Errorf("more elements returned in array than can fit inside %s, got %v elements", val.Type(), len(elems))
+ }
+
+ for idx, elem := range elems {
+ val.Index(idx).Set(elem)
+ }
+
+ return nil
+}
+
+// valueUnmarshalerDecodeValue is the ValueDecoderFunc for ValueUnmarshaler implementations.
+func valueUnmarshalerDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || (!val.Type().Implements(tValueUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tValueUnmarshaler)) {
+ return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
+ }
+
+ // If BSON value is null and the go value is a pointer, then don't call
+ // UnmarshalBSONValue. Even if the Go pointer is already initialized (i.e.,
+ // non-nil), encountering null in BSON will result in the pointer being
+ // directly set to nil here. Since the pointer is being replaced with nil,
+ // there is no opportunity (or reason) for the custom UnmarshalBSONValue logic
+ // to be called.
+ if vr.Type() == TypeNull && val.Kind() == reflect.Ptr {
+ val.Set(reflect.Zero(val.Type()))
+
+ return vr.ReadNull()
+ }
+
+ if val.Kind() == reflect.Ptr && val.IsNil() {
+ if !val.CanSet() {
+ return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
+ }
+ val.Set(reflect.New(val.Type().Elem()))
+ }
+
+ if !val.Type().Implements(tValueUnmarshaler) {
+ if !val.CanAddr() {
+ return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
+ }
+ val = val.Addr() // If the type doesn't implement the interface, a pointer to it must.
+ }
+
+ t, src, err := copyValueToBytes(vr)
+ if err != nil {
+ return err
+ }
+
+ m, ok := val.Interface().(ValueUnmarshaler)
+ if !ok {
+ // NB: this error should be unreachable due to the above checks
+ return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
+ }
+ return m.UnmarshalBSONValue(byte(t), src)
+}
+
+// unmarshalerDecodeValue is the ValueDecoderFunc for Unmarshaler implementations.
+func unmarshalerDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || (!val.Type().Implements(tUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tUnmarshaler)) {
+ return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
+ }
+
+ if val.Kind() == reflect.Ptr && val.IsNil() {
+ if !val.CanSet() {
+ return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
+ }
+ val.Set(reflect.New(val.Type().Elem()))
+ }
+
+ _, src, err := copyValueToBytes(vr)
+ if err != nil {
+ return err
+ }
+
+ // If the target Go value is a pointer and the BSON field value is empty, set the value to the
+ // zero value of the pointer (nil) and don't call UnmarshalBSON. UnmarshalBSON has no way to
+ // change the pointer value from within the function (only the value at the pointer address),
+ // so it can't set the pointer to "nil" itself. Since the most common Go value for an empty BSON
+ // field value is "nil", we set "nil" here and don't call UnmarshalBSON. This behavior matches
+ // the behavior of the Go "encoding/json" unmarshaler when the target Go value is a pointer and
+ // the JSON field value is "null".
+ if val.Kind() == reflect.Ptr && len(src) == 0 {
+ val.Set(reflect.Zero(val.Type()))
+ return nil
+ }
+
+ if !val.Type().Implements(tUnmarshaler) {
+ if !val.CanAddr() {
+ return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
+ }
+ val = val.Addr() // If the type doesn't implement the interface, a pointer to it must.
+ }
+
+ m, ok := val.Interface().(Unmarshaler)
+ if !ok {
+ // NB: this error should be unreachable due to the above checks
+ return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
+ }
+ return m.UnmarshalBSON(src)
+}
+
+// coreDocumentDecodeValue is the ValueDecoderFunc for bsoncore.Document.
+func coreDocumentDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tCoreDocument {
+ return ValueDecoderError{Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
+ }
+ vrType := vr.Type()
+ isDocument := vrType == Type(0) || vrType == TypeEmbeddedDocument || vrType == TypeArray
+ if !isDocument {
+ return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
+ }
+
+ if val.IsNil() {
+ val.Set(reflect.MakeSlice(val.Type(), 0, 0))
+ }
+
+ val.SetLen(0)
+
+ cdoc, err := appendDocumentBytes(val.Interface().(bsoncore.Document), vr)
+ val.Set(reflect.ValueOf(cdoc))
+ return err
+}
+
+func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]reflect.Value, error) {
+ elems := make([]reflect.Value, 0)
+
+ ar, err := vr.ReadArray()
+ if err != nil {
+ return nil, err
+ }
+
+ eType := val.Type().Elem()
+
+ isInterfaceSlice := eType.Kind() == reflect.Interface && val.Len() > 0
+
+ // If this is not an interface slice with pre-populated elements, we can look up
+ // the decoder for eType once.
+ var vDecoder ValueDecoder
+ if !isInterfaceSlice {
+ vDecoder, err = dc.LookupDecoder(eType)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ idx := 0
+ for {
+ vr, err := ar.ReadValue()
+ if errors.Is(err, ErrEOA) {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ var elem reflect.Value
+ if isInterfaceSlice && idx < val.Len() {
+ // Decode into an existing any slot.
+
+ elem = val.Index(idx).Elem()
+ switch {
+ case elem.Kind() != reflect.Ptr || elem.IsNil():
+ valueDecoder, err := dc.LookupDecoder(elem.Type())
+ if err != nil {
+ return nil, err
+ }
+
+ // If an element is allocated and unsettable, it must be overwritten.
+ if !elem.CanSet() {
+ elem = reflect.New(elem.Type()).Elem()
+ }
+
+ err = valueDecoder.DecodeValue(dc, vr, elem)
+ if err != nil {
+ return nil, newDecodeError(strconv.Itoa(idx), err)
+ }
+ case vr.Type() == TypeNull:
+ if err = vr.ReadNull(); err != nil {
+ return nil, err
+ }
+ elem = reflect.Zero(val.Index(idx).Type())
+ default:
+ e := elem.Elem()
+ valueDecoder, err := dc.LookupDecoder(e.Type())
+ if err != nil {
+ return nil, err
+ }
+ err = valueDecoder.DecodeValue(dc, vr, e)
+ if err != nil {
+ return nil, newDecodeError(strconv.Itoa(idx), err)
+ }
+ }
+ } else {
+ // For non-interface slices, or if we've exhausted the pre-populated
+ // slots, we create a fresh value.
+
+ if vDecoder == nil {
+ vDecoder, err = dc.LookupDecoder(eType)
+ if err != nil {
+ return nil, err
+ }
+ }
+ elem, err = decodeTypeOrValueWithInfo(vDecoder, dc, vr, eType)
+ if err != nil {
+ return nil, newDecodeError(strconv.Itoa(idx), err)
+ }
+ }
+
+ elems = append(elems, elem)
+ idx++
+ }
+
+ return elems, nil
+}
+
+func codeWithScopeDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tCodeWithScope {
+ return emptyValue, ValueDecoderError{
+ Name: "CodeWithScopeDecodeValue",
+ Types: []reflect.Type{tCodeWithScope},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var cws CodeWithScope
+ var err error
+ switch vrType := vr.Type(); vrType {
+ case TypeCodeWithScope:
+ code, dr, err := vr.ReadCodeWithScope()
+ if err != nil {
+ return emptyValue, err
+ }
+
+ scope := reflect.New(tD).Elem()
+ elems, err := decodeElemsFromDocumentReader(dc, dr)
+ if err != nil {
+ return emptyValue, err
+ }
+
+ scope.Set(reflect.MakeSlice(tD, 0, len(elems)))
+ scope.Set(reflect.Append(scope, elems...))
+
+ cws = CodeWithScope{
+ Code: JavaScript(code),
+ Scope: scope.Interface().(D),
+ }
+ case TypeNull:
+ err = vr.ReadNull()
+ case TypeUndefined:
+ err = vr.ReadUndefined()
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a CodeWithScope", vrType)
+ }
+ if err != nil {
+ return emptyValue, err
+ }
+
+ return reflect.ValueOf(cws), nil
+}
+
+// codeWithScopeDecodeValue is the ValueDecoderFunc for CodeWithScope.
+func codeWithScopeDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tCodeWithScope {
+ return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
+ }
+
+ elem, err := codeWithScopeDecodeType(dc, vr, tCodeWithScope)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+func decodeD(dc DecodeContext, vr ValueReader, _ reflect.Value) ([]reflect.Value, error) {
+ switch vr.Type() {
+ case Type(0), TypeEmbeddedDocument:
+ default:
+ return nil, fmt.Errorf("cannot decode %v into a D", vr.Type())
+ }
+
+ dr, err := vr.ReadDocument()
+ if err != nil {
+ return nil, err
+ }
+
+ return decodeElemsFromDocumentReader(dc, dr)
+}
+
+func decodeElemsFromDocumentReader(dc DecodeContext, dr DocumentReader) ([]reflect.Value, error) {
+ decoder, err := dc.LookupDecoder(tEmpty)
+ if err != nil {
+ return nil, err
+ }
+
+ elems := make([]reflect.Value, 0)
+ for {
+ key, vr, err := dr.ReadElement()
+ if errors.Is(err, ErrEOD) {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ val := reflect.New(tEmpty).Elem()
+ err = decoder.DecodeValue(dc, vr, val)
+ if err != nil {
+ return nil, newDecodeError(key, err)
+ }
+
+ elems = append(elems, reflect.ValueOf(E{Key: key, Value: val.Interface()}))
+ }
+
+ return elems, nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go
new file mode 100644
index 000000000..f5d15bc30
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go
@@ -0,0 +1,518 @@
+// 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 bson
+
+import (
+ "encoding/json"
+ "errors"
+ "math"
+ "net/url"
+ "reflect"
+ "sync"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+var bvwPool = sync.Pool{
+ New: func() any {
+ return new(valueWriter)
+ },
+}
+
+var errInvalidValue = errors.New("cannot encode invalid element")
+
+var sliceWriterPool = sync.Pool{
+ New: func() any {
+ sw := make(sliceWriter, 0)
+ return &sw
+ },
+}
+
+func encodeElement(ec EncodeContext, dw DocumentWriter, e E) error {
+ vw, err := dw.WriteDocumentElement(e.Key)
+ if err != nil {
+ return err
+ }
+
+ if e.Value == nil {
+ return vw.WriteNull()
+ }
+ encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value))
+ if err != nil {
+ return err
+ }
+
+ err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// registerDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
+// the provided RegistryBuilder.
+func registerDefaultEncoders(reg *Registry) {
+ mapEncoder := &mapCodec{}
+ uintCodec := &uintCodec{}
+
+ reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{})
+ reg.RegisterTypeEncoder(tTime, &timeCodec{})
+ reg.RegisterTypeEncoder(tEmpty, &emptyInterfaceCodec{})
+ reg.RegisterTypeEncoder(tCoreArray, &arrayCodec{})
+ reg.RegisterTypeEncoder(tOID, ValueEncoderFunc(objectIDEncodeValue))
+ reg.RegisterTypeEncoder(tDecimal, ValueEncoderFunc(decimal128EncodeValue))
+ reg.RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(jsonNumberEncodeValue))
+ reg.RegisterTypeEncoder(tURL, ValueEncoderFunc(urlEncodeValue))
+ reg.RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(javaScriptEncodeValue))
+ reg.RegisterTypeEncoder(tSymbol, ValueEncoderFunc(symbolEncodeValue))
+ reg.RegisterTypeEncoder(tBinary, ValueEncoderFunc(binaryEncodeValue))
+ reg.RegisterTypeEncoder(tVector, ValueEncoderFunc(vectorEncodeValue))
+ reg.RegisterTypeEncoder(tUndefined, ValueEncoderFunc(undefinedEncodeValue))
+ reg.RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dateTimeEncodeValue))
+ reg.RegisterTypeEncoder(tNull, ValueEncoderFunc(nullEncodeValue))
+ reg.RegisterTypeEncoder(tRegex, ValueEncoderFunc(regexEncodeValue))
+ reg.RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dbPointerEncodeValue))
+ reg.RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(timestampEncodeValue))
+ reg.RegisterTypeEncoder(tMinKey, ValueEncoderFunc(minKeyEncodeValue))
+ reg.RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(maxKeyEncodeValue))
+ reg.RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(coreDocumentEncodeValue))
+ reg.RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(codeWithScopeEncodeValue))
+ reg.RegisterKindEncoder(reflect.Bool, ValueEncoderFunc(booleanEncodeValue))
+ reg.RegisterKindEncoder(reflect.Int, ValueEncoderFunc(intEncodeValue))
+ reg.RegisterKindEncoder(reflect.Int8, ValueEncoderFunc(intEncodeValue))
+ reg.RegisterKindEncoder(reflect.Int16, ValueEncoderFunc(intEncodeValue))
+ reg.RegisterKindEncoder(reflect.Int32, ValueEncoderFunc(intEncodeValue))
+ reg.RegisterKindEncoder(reflect.Int64, ValueEncoderFunc(intEncodeValue))
+ reg.RegisterKindEncoder(reflect.Uint, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint8, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint16, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint32, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint64, uintCodec)
+ reg.RegisterKindEncoder(reflect.Float32, ValueEncoderFunc(floatEncodeValue))
+ reg.RegisterKindEncoder(reflect.Float64, ValueEncoderFunc(floatEncodeValue))
+ reg.RegisterKindEncoder(reflect.Array, ValueEncoderFunc(arrayEncodeValue))
+ reg.RegisterKindEncoder(reflect.Map, mapEncoder)
+ reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{})
+ reg.RegisterKindEncoder(reflect.String, &stringCodec{})
+ reg.RegisterKindEncoder(reflect.Struct, newStructCodec(mapEncoder))
+ reg.RegisterKindEncoder(reflect.Ptr, &pointerCodec{})
+ reg.RegisterInterfaceEncoder(tValueMarshaler, ValueEncoderFunc(valueMarshalerEncodeValue))
+ reg.RegisterInterfaceEncoder(tMarshaler, ValueEncoderFunc(marshalerEncodeValue))
+}
+
+// booleanEncodeValue is the ValueEncoderFunc for bool types.
+func booleanEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Kind() != reflect.Bool {
+ return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
+ }
+ return vw.WriteBoolean(val.Bool())
+}
+
+func fitsIn32Bits(i int64) bool {
+ return math.MinInt32 <= i && i <= math.MaxInt32
+}
+
+// intEncodeValue is the ValueEncoderFunc for int types.
+func intEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ switch val.Kind() {
+ case reflect.Int8, reflect.Int16, reflect.Int32:
+ return vw.WriteInt32(int32(val.Int()))
+ case reflect.Int:
+ i64 := val.Int()
+ if fitsIn32Bits(i64) {
+ return vw.WriteInt32(int32(i64))
+ }
+ return vw.WriteInt64(i64)
+ case reflect.Int64:
+ i64 := val.Int()
+ if ec.minSize && fitsIn32Bits(i64) {
+ return vw.WriteInt32(int32(i64))
+ }
+ return vw.WriteInt64(i64)
+ }
+
+ return ValueEncoderError{
+ Name: "IntEncodeValue",
+ Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
+ Received: val,
+ }
+}
+
+// floatEncodeValue is the ValueEncoderFunc for float types.
+func floatEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ switch val.Kind() {
+ case reflect.Float32, reflect.Float64:
+ return vw.WriteDouble(val.Float())
+ }
+
+ return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
+}
+
+// objectIDEncodeValue is the ValueEncoderFunc for ObjectID.
+func objectIDEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tOID {
+ return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
+ }
+ return vw.WriteObjectID(val.Interface().(ObjectID))
+}
+
+// decimal128EncodeValue is the ValueEncoderFunc for Decimal128.
+func decimal128EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tDecimal {
+ return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
+ }
+ return vw.WriteDecimal128(val.Interface().(Decimal128))
+}
+
+// jsonNumberEncodeValue is the ValueEncoderFunc for json.Number.
+func jsonNumberEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tJSONNumber {
+ return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
+ }
+ jsnum := val.Interface().(json.Number)
+
+ // Attempt int first, then float64
+ if i64, err := jsnum.Int64(); err == nil {
+ return intEncodeValue(ec, vw, reflect.ValueOf(i64))
+ }
+
+ f64, err := jsnum.Float64()
+ if err != nil {
+ return err
+ }
+
+ return floatEncodeValue(ec, vw, reflect.ValueOf(f64))
+}
+
+// urlEncodeValue is the ValueEncoderFunc for url.URL.
+func urlEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tURL {
+ return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
+ }
+ u := val.Interface().(url.URL)
+ return vw.WriteString(u.String())
+}
+
+// arrayEncodeValue is the ValueEncoderFunc for array types.
+func arrayEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Kind() != reflect.Array {
+ return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
+ }
+
+ // If we have a []E we want to treat it as a document instead of as an array.
+ if val.Type().Elem() == tE {
+ dw, err := vw.WriteDocument()
+ if err != nil {
+ return err
+ }
+
+ for idx := 0; idx < val.Len(); idx++ {
+ e := val.Index(idx).Interface().(E)
+ err = encodeElement(ec, dw, e)
+ if err != nil {
+ return err
+ }
+ }
+
+ return dw.WriteDocumentEnd()
+ }
+
+ // If we have a []byte we want to treat it as a binary instead of as an array.
+ if val.Type().Elem() == tByte {
+ var byteSlice []byte
+ for idx := 0; idx < val.Len(); idx++ {
+ byteSlice = append(byteSlice, val.Index(idx).Interface().(byte))
+ }
+ return vw.WriteBinary(byteSlice)
+ }
+
+ aw, err := vw.WriteArray()
+ if err != nil {
+ return err
+ }
+
+ elemType := val.Type().Elem()
+ encoder, err := ec.LookupEncoder(elemType)
+ if err != nil && elemType.Kind() != reflect.Interface {
+ return err
+ }
+
+ for idx := 0; idx < val.Len(); idx++ {
+ currEncoder, currVal, lookupErr := lookupElementEncoder(ec, encoder, val.Index(idx))
+ if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
+ return lookupErr
+ }
+
+ vw, err := aw.WriteArrayElement()
+ if err != nil {
+ return err
+ }
+
+ if errors.Is(lookupErr, errInvalidValue) {
+ err = vw.WriteNull()
+ if err != nil {
+ return err
+ }
+ continue
+ }
+
+ err = currEncoder.EncodeValue(ec, vw, currVal)
+ if err != nil {
+ return err
+ }
+ }
+ return aw.WriteArrayEnd()
+}
+
+func lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) {
+ if origEncoder != nil || (currVal.Kind() != reflect.Interface) {
+ return origEncoder, currVal, nil
+ }
+ currVal = currVal.Elem()
+ if !currVal.IsValid() {
+ return nil, currVal, errInvalidValue
+ }
+ currEncoder, err := ec.LookupEncoder(currVal.Type())
+
+ return currEncoder, currVal, err
+}
+
+// valueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
+func valueMarshalerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ // Either val or a pointer to val must implement ValueMarshaler
+ switch {
+ case !val.IsValid():
+ return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
+ case val.Type().Implements(tValueMarshaler):
+ // If ValueMarshaler is implemented on a concrete type, make sure that val isn't a nil pointer
+ if isImplementationNil(val, tValueMarshaler) {
+ return vw.WriteNull()
+ }
+ case reflect.PtrTo(val.Type()).Implements(tValueMarshaler) && val.CanAddr():
+ val = val.Addr()
+ default:
+ return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
+ }
+
+ m, ok := val.Interface().(ValueMarshaler)
+ if !ok {
+ return vw.WriteNull()
+ }
+ t, data, err := m.MarshalBSONValue()
+ if err != nil {
+ return err
+ }
+ return copyValueFromBytes(vw, Type(t), data)
+}
+
+// marshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
+func marshalerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ // Either val or a pointer to val must implement Marshaler
+ switch {
+ case !val.IsValid():
+ return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
+ case val.Type().Implements(tMarshaler):
+ // If Marshaler is implemented on a concrete type, make sure that val isn't a nil pointer
+ if isImplementationNil(val, tMarshaler) {
+ return vw.WriteNull()
+ }
+ case reflect.PtrTo(val.Type()).Implements(tMarshaler) && val.CanAddr():
+ val = val.Addr()
+ default:
+ return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
+ }
+
+ m, ok := val.Interface().(Marshaler)
+ if !ok {
+ return vw.WriteNull()
+ }
+ data, err := m.MarshalBSON()
+ if err != nil {
+ return err
+ }
+ return copyValueFromBytes(vw, TypeEmbeddedDocument, data)
+}
+
+// javaScriptEncodeValue is the ValueEncoderFunc for the JavaScript type.
+func javaScriptEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tJavaScript {
+ return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
+ }
+
+ return vw.WriteJavascript(val.String())
+}
+
+// symbolEncodeValue is the ValueEncoderFunc for the Symbol type.
+func symbolEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tSymbol {
+ return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
+ }
+
+ return vw.WriteSymbol(val.String())
+}
+
+// binaryEncodeValue is the ValueEncoderFunc for Binary.
+func binaryEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tBinary {
+ return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
+ }
+ b := val.Interface().(Binary)
+
+ return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
+}
+
+// vectorEncodeValue is the ValueEncoderFunc for Vector.
+func vectorEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ t := val.Type()
+ if !val.IsValid() || t != tVector {
+ return ValueEncoderError{
+ Name: "VectorEncodeValue",
+ Types: []reflect.Type{tVector},
+ Received: val,
+ }
+ }
+ v := val.Interface().(Vector)
+ b := v.Binary()
+ return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
+}
+
+// undefinedEncodeValue is the ValueEncoderFunc for Undefined.
+func undefinedEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tUndefined {
+ return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
+ }
+
+ return vw.WriteUndefined()
+}
+
+// dateTimeEncodeValue is the ValueEncoderFunc for DateTime.
+func dateTimeEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tDateTime {
+ return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
+ }
+
+ return vw.WriteDateTime(val.Int())
+}
+
+// nullEncodeValue is the ValueEncoderFunc for Null.
+func nullEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tNull {
+ return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
+ }
+
+ return vw.WriteNull()
+}
+
+// regexEncodeValue is the ValueEncoderFunc for Regex.
+func regexEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tRegex {
+ return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
+ }
+
+ regex := val.Interface().(Regex)
+
+ return vw.WriteRegex(regex.Pattern, regex.Options)
+}
+
+// dbPointerEncodeValue is the ValueEncoderFunc for DBPointer.
+func dbPointerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tDBPointer {
+ return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
+ }
+
+ dbp := val.Interface().(DBPointer)
+
+ return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
+}
+
+// timestampEncodeValue is the ValueEncoderFunc for Timestamp.
+func timestampEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tTimestamp {
+ return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
+ }
+
+ ts := val.Interface().(Timestamp)
+
+ return vw.WriteTimestamp(ts.T, ts.I)
+}
+
+// minKeyEncodeValue is the ValueEncoderFunc for MinKey.
+func minKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tMinKey {
+ return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
+ }
+
+ return vw.WriteMinKey()
+}
+
+// maxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
+func maxKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tMaxKey {
+ return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
+ }
+
+ return vw.WriteMaxKey()
+}
+
+// coreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
+func coreDocumentEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tCoreDocument {
+ return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
+ }
+
+ cdoc := val.Interface().(bsoncore.Document)
+
+ return copyDocumentFromBytes(vw, cdoc)
+}
+
+// codeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
+func codeWithScopeEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tCodeWithScope {
+ return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
+ }
+
+ cws := val.Interface().(CodeWithScope)
+
+ dw, err := vw.WriteCodeWithScope(string(cws.Code))
+ if err != nil {
+ return err
+ }
+
+ sw := sliceWriterPool.Get().(*sliceWriter)
+ defer sliceWriterPool.Put(sw)
+ *sw = (*sw)[:0]
+
+ scopeVW := bvwPool.Get().(*valueWriter)
+ scopeVW.reset(scopeVW.buf[:0])
+ scopeVW.w = sw
+ defer bvwPool.Put(scopeVW)
+
+ encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
+ if err != nil {
+ return err
+ }
+
+ err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
+ if err != nil {
+ return err
+ }
+
+ err = copyBytesToDocumentWriter(dw, *sw)
+ if err != nil {
+ return err
+ }
+ return dw.WriteDocumentEnd()
+}
+
+// isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type
+func isImplementationNil(val reflect.Value, inter reflect.Type) bool {
+ vt := val.Type()
+ for vt.Kind() == reflect.Ptr {
+ vt = vt.Elem()
+ }
+ return vt.Implements(inter) && val.Kind() == reflect.Ptr && val.IsNil()
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go
similarity index 68%
rename from vendor/go.mongodb.org/mongo-driver/bson/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go
index fb075b478..b346f71f0 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go
@@ -4,30 +4,14 @@
// 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 bson is a library for reading, writing, and manipulating BSON. BSON is a binary serialization format used to
-// store documents and make remote procedure calls in MongoDB. The BSON specification is located at https://bsonspec.org.
-// The BSON library handles marshaling and unmarshaling of values through a configurable codec system. For a description
-// of the codec system and examples of registering custom codecs, see the bsoncodec package. For additional information
-// and usage examples, check out the [Work with BSON] page in the Go Driver docs site.
-//
-// # Raw BSON
-//
-// The Raw family of types is used to validate and retrieve elements from a slice of bytes. This
-// type is most useful when you want do lookups on BSON bytes without unmarshaling it into another
-// type.
-//
-// Example:
-//
-// var raw bson.Raw = ... // bytes from somewhere
-// err := raw.Validate()
-// if err != nil { return err }
-// val := raw.Lookup("foo")
-// i32, ok := val.Int32OK()
-// // do something with i32...
+// Package bson is a library for reading, writing, and manipulating BSON. BSON is a binary serialization
+// format used to store documents and make remote procedure calls in MongoDB. For more information about
+// the Go BSON library, including usage examples, check out the [Work with BSON] page in the Go Driver
+// docs site. For more information about BSON, see https://bsonspec.org.
//
// # Native Go Types
//
-// The D and M types defined in this package can be used to build representations of BSON using native Go types. D is a
+// The [D] and [M] types defined in this package can be used to build representations of BSON using native Go types. D is a
// slice and M is a map. For more information about the use cases for these types, see the documentation on the type
// definitions.
//
@@ -47,20 +31,20 @@
// 5. BSON boolean unmarshals to a bool.
// 6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M).
// 7. BSON array unmarshals to a bson.A.
-// 8. BSON ObjectId unmarshals to a primitive.ObjectID.
-// 9. BSON datetime unmarshals to a primitive.DateTime.
-// 10. BSON binary unmarshals to a primitive.Binary.
-// 11. BSON regular expression unmarshals to a primitive.Regex.
-// 12. BSON JavaScript unmarshals to a primitive.JavaScript.
-// 13. BSON code with scope unmarshals to a primitive.CodeWithScope.
-// 14. BSON timestamp unmarshals to an primitive.Timestamp.
-// 15. BSON 128-bit decimal unmarshals to an primitive.Decimal128.
-// 16. BSON min key unmarshals to an primitive.MinKey.
-// 17. BSON max key unmarshals to an primitive.MaxKey.
-// 18. BSON undefined unmarshals to a primitive.Undefined.
+// 8. BSON ObjectId unmarshals to a bson.ObjectID.
+// 9. BSON datetime unmarshals to a bson.DateTime.
+// 10. BSON binary unmarshals to a bson.Binary.
+// 11. BSON regular expression unmarshals to a bson.Regex.
+// 12. BSON JavaScript unmarshals to a bson.JavaScript.
+// 13. BSON code with scope unmarshals to a bson.CodeWithScope.
+// 14. BSON timestamp unmarshals to an bson.Timestamp.
+// 15. BSON 128-bit decimal unmarshals to an bson.Decimal128.
+// 16. BSON min key unmarshals to an bson.MinKey.
+// 17. BSON max key unmarshals to an bson.MaxKey.
+// 18. BSON undefined unmarshals to a bson.Undefined.
// 19. BSON null unmarshals to nil.
-// 20. BSON DBPointer unmarshals to a primitive.DBPointer.
-// 21. BSON symbol unmarshals to a primitive.Symbol.
+// 20. BSON DBPointer unmarshals to a bson.DBPointer.
+// 21. BSON symbol unmarshals to a bson.Symbol.
//
// The above mappings also apply when marshaling a D or M to BSON. Some other useful marshaling mappings are:
//
@@ -90,29 +74,19 @@
// 4. A pointer field is marshaled as the underlying type if the pointer is non-nil. If the pointer is nil, it is
// marshaled as a BSON null value.
//
-// 5. When unmarshaling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents
-// unmarshaled into an interface{} field will be unmarshaled as a D.
-//
-// The encoding of each struct field can be customized by the "bson" struct tag.
-//
-// This tag behavior is configurable, and different struct tag behavior can be configured by initializing a new
-// bsoncodec.StructCodec with the desired tag parser and registering that StructCodec onto the Registry. By default, JSON
-// tags are not honored, but that can be enabled by creating a StructCodec with JSONFallbackStructTagParser, like below:
-//
-// Example:
-//
-// structcodec, _ := bsoncodec.NewStructCodec(bsoncodec.JSONFallbackStructTagParser)
+// 5. When unmarshaling, a field of type any will follow the D/M type mappings listed above. BSON documents
+// unmarshaled into an any field will be unmarshaled as a D.
//
-// The bson tag gives the name of the field, possibly followed by a comma-separated list of options.
-// The name may be empty in order to specify options without overriding the default field name. The following options can
-// be used to configure behavior:
+// The encoding of each struct field can be customized by the "bson" struct tag. The "bson" tag gives the name of the
+// field, followed by a comma-separated list of options. The name may be omitted in order to specify options without
+// overriding the default field name. The following options can be used to configure behavior:
//
// 1. omitempty: If the "omitempty" struct tag is specified on a field, the field will not be marshaled if it is set to
// an "empty" value. Numbers, booleans, and strings are considered empty if their value is equal to the zero value for
// the type (i.e. 0 for numbers, false for booleans, and "" for strings). Slices, maps, and arrays are considered
// empty if they are of length zero. Interfaces and pointers are considered empty if their value is nil. By default,
-// structs are only considered empty if the struct type implements [bsoncodec.Zeroer] and the IsZero
-// method returns true. Struct types that do not implement [bsoncodec.Zeroer] are never considered empty and will be
+// structs are only considered empty if the struct type implements [Zeroer] and the "IsZero"
+// method returns true. Struct types that do not implement [Zeroer] are never considered empty and will be
// marshaled as embedded documents. NOTE: It is recommended that this tag be used for all slice and map fields.
//
// 2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of
@@ -127,16 +101,41 @@
// 4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when
// marshaling and "un-flattened" when unmarshaling. This means that all of the fields in that struct/map will be
// pulled up one level and will become top-level fields rather than being fields in a nested document. For example,
-// if a map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will
+// if a map field named "Map" with value map[string]any{"foo": "bar"} is inlined, the resulting document will
// be {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If
// there are duplicated fields in the resulting document when an inlined struct is marshaled, the inlined field will
// be overwritten. If there are duplicated fields in the resulting document when an inlined map is marshaled, an
// error will be returned. This tag can be used with fields that are pointers to structs. If an inlined pointer field
// is nil, it will not be marshaled. For fields that are not maps or structs, this tag is ignored.
//
-// # Marshaling and Unmarshaling
+// # Raw BSON
+//
+// The Raw family of types is used to validate and retrieve elements from a slice of bytes. This
+// type is most useful when you want do lookups on BSON bytes without unmarshaling it into another
+// type.
+//
+// Example:
+//
+// var raw bson.Raw = ... // bytes from somewhere
+// err := raw.Validate()
+// if err != nil { return err }
+// val := raw.Lookup("foo")
+// i32, ok := val.Int32OK()
+// // do something with i32...
+//
+// # Custom Registry
+//
+// The Go BSON library uses a [Registry] to define encoding and decoding behavior for different data types.
+// The default encoding and decoding behavior can be customized or extended by using a modified Registry.
+// The custom registry system is composed of two parts:
+//
+// 1) [ValueEncoder] and [ValueDecoder] that handle encoding and decoding Go values to and from BSON
+// representations.
+//
+// 2) A [Registry] that holds these ValueEncoders and ValueDecoders and provides methods for
+// retrieving them.
//
-// Manually marshaling and unmarshaling can be done with the Marshal and Unmarshal family of functions.
+// To use a custom Registry, use [Encoder.SetRegistry] or [Decoder.SetRegistry].
//
// [Work with BSON]: https://www.mongodb.com/docs/drivers/go/current/fundamentals/bson/
package bson
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go
new file mode 100644
index 000000000..ae1db53f9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go
@@ -0,0 +1,127 @@
+// 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 bson
+
+import (
+ "reflect"
+)
+
+// emptyInterfaceCodec is the Codec used for any values.
+type emptyInterfaceCodec struct {
+ // decodeBinaryAsSlice causes DecodeValue to unmarshal BSON binary field values that are the
+ // "Generic" or "Old" BSON binary subtype as a Go byte slice instead of a Binary.
+ decodeBinaryAsSlice bool
+}
+
+// Assert that emptyInterfaceCodec satisfies the typeDecoder interface, which allows it
+// to be used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+// collection.
+var _ typeDecoder = &emptyInterfaceCodec{}
+
+// EncodeValue is the ValueEncoderFunc for any.
+func (eic *emptyInterfaceCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tEmpty {
+ return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
+ }
+
+ if val.IsNil() {
+ return vw.WriteNull()
+ }
+ encoder, err := ec.LookupEncoder(val.Elem().Type())
+ if err != nil {
+ return err
+ }
+
+ return encoder.EncodeValue(ec, vw, val.Elem())
+}
+
+func (eic *emptyInterfaceCodec) getEmptyInterfaceDecodeType(dc DecodeContext, valueType Type) (reflect.Type, error) {
+ isDocument := valueType == Type(0) || valueType == TypeEmbeddedDocument
+ if isDocument {
+ if dc.defaultDocumentType != nil {
+ // If the bsontype is an embedded document and the DocumentType is set on the DecodeContext, then return
+ // that type.
+ return dc.defaultDocumentType, nil
+ }
+ }
+
+ rtype, err := dc.LookupTypeMapEntry(valueType)
+ if err == nil {
+ return rtype, nil
+ }
+
+ if isDocument {
+ // For documents, fallback to looking up a type map entry for Type(0) or TypeEmbeddedDocument,
+ // depending on the original valueType.
+ var lookupType Type
+ switch valueType {
+ case Type(0):
+ lookupType = TypeEmbeddedDocument
+ case TypeEmbeddedDocument:
+ lookupType = Type(0)
+ }
+
+ rtype, err = dc.LookupTypeMapEntry(lookupType)
+ if err == nil {
+ return rtype, nil
+ }
+ // fallback to bson.D
+ return tD, nil
+ }
+
+ return nil, err
+}
+
+func (eic *emptyInterfaceCodec) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tEmpty {
+ return emptyValue, ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.Zero(t)}
+ }
+
+ rtype, err := eic.getEmptyInterfaceDecodeType(dc, vr.Type())
+ if err != nil {
+ switch vr.Type() {
+ case TypeNull:
+ return reflect.Zero(t), vr.ReadNull()
+ default:
+ return emptyValue, err
+ }
+ }
+
+ decoder, err := dc.LookupDecoder(rtype)
+ if err != nil {
+ return emptyValue, err
+ }
+
+ elem, err := decodeTypeOrValueWithInfo(decoder, dc, vr, rtype)
+ if err != nil {
+ return emptyValue, err
+ }
+
+ if (eic.decodeBinaryAsSlice || dc.binaryAsSlice) && rtype == tBinary {
+ binElem := elem.Interface().(Binary)
+ if binElem.Subtype == TypeBinaryGeneric || binElem.Subtype == TypeBinaryBinaryOld {
+ elem = reflect.ValueOf(binElem.Data)
+ }
+ }
+
+ return elem, nil
+}
+
+// DecodeValue is the ValueDecoderFunc for any.
+func (eic *emptyInterfaceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tEmpty {
+ return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val}
+ }
+
+ elem, err := eic.decodeType(dc, vr, val.Type())
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/encoder.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go
similarity index 54%
rename from vendor/go.mongodb.org/mongo-driver/bson/encoder.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go
index 0be2a97fb..d27bb7b59 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/encoder.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go
@@ -7,81 +7,45 @@
package bson
import (
- "errors"
"reflect"
"sync"
-
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
)
// This pool is used to keep the allocations of Encoders down. This is only used for the Marshal*
// methods and is not consumable from outside of this package. The Encoders retrieved from this pool
// must have both Reset and SetRegistry called on them.
var encPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
return new(Encoder)
},
}
-// An Encoder writes a serialization format to an output stream. It writes to a bsonrw.ValueWriter
+// An Encoder writes a serialization format to an output stream. It writes to a ValueWriter
// as the destination of BSON data.
type Encoder struct {
- ec bsoncodec.EncodeContext
- vw bsonrw.ValueWriter
-
- errorOnInlineDuplicates bool
- intMinSize bool
- stringifyMapKeysWithFmt bool
- nilMapAsEmpty bool
- nilSliceAsEmpty bool
- nilByteSliceAsEmpty bool
- omitZeroStruct bool
- useJSONStructTags bool
+ ec EncodeContext
+ vw ValueWriter
}
-// NewEncoder returns a new encoder that uses the DefaultRegistry to write to vw.
-func NewEncoder(vw bsonrw.ValueWriter) (*Encoder, error) {
- // TODO:(GODRIVER-2719): Remove error return value.
- if vw == nil {
- return nil, errors.New("cannot create a new Encoder with a nil ValueWriter")
- }
-
+// NewEncoder returns a new encoder that writes to vw.
+func NewEncoder(vw ValueWriter) *Encoder {
return &Encoder{
- ec: bsoncodec.EncodeContext{Registry: DefaultRegistry},
+ ec: EncodeContext{Registry: defaultRegistry},
vw: vw,
- }, nil
-}
-
-// NewEncoderWithContext returns a new encoder that uses EncodeContext ec to write to vw.
-//
-// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
-// behavior instead.
-func NewEncoderWithContext(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter) (*Encoder, error) {
- if ec.Registry == nil {
- ec = bsoncodec.EncodeContext{Registry: DefaultRegistry}
}
- if vw == nil {
- return nil, errors.New("cannot create a new Encoder with a nil ValueWriter")
- }
-
- return &Encoder{
- ec: ec,
- vw: vw,
- }, nil
}
// Encode writes the BSON encoding of val to the stream.
//
// See [Marshal] for details about BSON marshaling behavior.
-func (e *Encoder) Encode(val interface{}) error {
+func (e *Encoder) Encode(val any) error {
if marshaler, ok := val.(Marshaler); ok {
// TODO(skriptble): Should we have a MarshalAppender interface so that we can have []byte reuse?
buf, err := marshaler.MarshalBSON()
if err != nil {
return err
}
- return bsonrw.Copier{}.CopyDocumentFromBytes(e.vw, buf)
+ return copyDocumentFromBytes(e.vw, buf)
}
encoder, err := e.ec.LookupEncoder(reflect.TypeOf(val))
@@ -89,111 +53,78 @@ func (e *Encoder) Encode(val interface{}) error {
return err
}
- // Copy the configurations applied to the Encoder over to the EncodeContext, which actually
- // communicates those configurations to the default ValueEncoders.
- if e.errorOnInlineDuplicates {
- e.ec.ErrorOnInlineDuplicates()
- }
- if e.intMinSize {
- e.ec.MinSize = true
- }
- if e.stringifyMapKeysWithFmt {
- e.ec.StringifyMapKeysWithFmt()
- }
- if e.nilMapAsEmpty {
- e.ec.NilMapAsEmpty()
- }
- if e.nilSliceAsEmpty {
- e.ec.NilSliceAsEmpty()
- }
- if e.nilByteSliceAsEmpty {
- e.ec.NilByteSliceAsEmpty()
- }
- if e.omitZeroStruct {
- e.ec.OmitZeroStruct()
- }
- if e.useJSONStructTags {
- e.ec.UseJSONStructTags()
- }
-
return encoder.EncodeValue(e.ec, e.vw, reflect.ValueOf(val))
}
// Reset will reset the state of the Encoder, using the same *EncodeContext used in
// the original construction but using vw.
-func (e *Encoder) Reset(vw bsonrw.ValueWriter) error {
- // TODO:(GODRIVER-2719): Remove error return value.
+func (e *Encoder) Reset(vw ValueWriter) {
e.vw = vw
- return nil
}
// SetRegistry replaces the current registry of the Encoder with r.
-func (e *Encoder) SetRegistry(r *bsoncodec.Registry) error {
- // TODO:(GODRIVER-2719): Remove error return value.
+func (e *Encoder) SetRegistry(r *Registry) {
e.ec.Registry = r
- return nil
-}
-
-// SetContext replaces the current EncodeContext of the encoder with ec.
-//
-// Deprecated: Use the Encoder configuration methods set the desired marshal behavior instead.
-func (e *Encoder) SetContext(ec bsoncodec.EncodeContext) error {
- // TODO:(GODRIVER-2719): Remove error return value.
- e.ec = ec
- return nil
}
// ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in
// the marshaled BSON when the "inline" struct tag option is set.
func (e *Encoder) ErrorOnInlineDuplicates() {
- e.errorOnInlineDuplicates = true
+ e.ec.errorOnInlineDuplicates = true
}
// IntMinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, uint,
// uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) that can
// represent the integer value.
func (e *Encoder) IntMinSize() {
- e.intMinSize = true
+ e.ec.minSize = true
}
// StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name
// strings using fmt.Sprint instead of the default string conversion logic.
func (e *Encoder) StringifyMapKeysWithFmt() {
- e.stringifyMapKeysWithFmt = true
+ e.ec.stringifyMapKeysWithFmt = true
}
// NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON
// null.
func (e *Encoder) NilMapAsEmpty() {
- e.nilMapAsEmpty = true
+ e.ec.nilMapAsEmpty = true
}
// NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON
// null.
func (e *Encoder) NilSliceAsEmpty() {
- e.nilSliceAsEmpty = true
+ e.ec.nilSliceAsEmpty = true
}
// NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values
// instead of BSON null.
func (e *Encoder) NilByteSliceAsEmpty() {
- e.nilByteSliceAsEmpty = true
+ e.ec.nilByteSliceAsEmpty = true
}
// TODO(GODRIVER-2820): Update the description to remove the note about only examining exported
// TODO struct fields once the logic is updated to also inspect private struct fields.
// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{})
-// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.
+// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set
+// or the OmitEmpty() method is called.
//
// Note that the Encoder only examines exported struct fields when determining if a struct is the
// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.
func (e *Encoder) OmitZeroStruct() {
- e.omitZeroStruct = true
+ e.ec.omitZeroStruct = true
+}
+
+// OmitEmpty causes the Encoder to omit empty values from the marshaled BSON as the "omitempty"
+// struct tag option is set.
+func (e *Encoder) OmitEmpty() {
+ e.ec.omitEmpty = true
}
// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson"
// struct tag is not specified.
func (e *Encoder) UseJSONStructTags() {
- e.useJSONStructTags = true
+ e.ec.useJSONStructTags = true
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go
similarity index 86%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go
index f0702d9d3..52cd7d855 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"encoding/base64"
@@ -13,8 +13,6 @@ import (
"fmt"
"io"
"strings"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
const maxNestingDepth = 200
@@ -47,8 +45,8 @@ const (
)
type extJSONValue struct {
- t bsontype.Type
- v interface{}
+ t Type
+ v any
}
type extJSONObject struct {
@@ -63,10 +61,10 @@ type extJSONParser struct {
k string
v *extJSONValue
- err error
- canonical bool
- depth int
- maxDepth int
+ err error
+ canonicalOnly bool
+ depth int
+ maxDepth int
emptyObject bool
relaxedUUID bool
@@ -76,19 +74,19 @@ type extJSONParser struct {
// parsing from the first character of the argued json input. It will not
// perform any read-ahead and will therefore not report any errors about
// malformed JSON at this point.
-func newExtJSONParser(r io.Reader, canonical bool) *extJSONParser {
+func newExtJSONParser(r io.Reader, canonicalOnly bool) *extJSONParser {
return &extJSONParser{
- js: &jsonScanner{r: r},
- s: jpsStartState,
- m: []jsonParseMode{},
- canonical: canonical,
- maxDepth: maxNestingDepth,
+ js: &jsonScanner{r: r},
+ s: jpsStartState,
+ m: []jsonParseMode{},
+ canonicalOnly: canonicalOnly,
+ maxDepth: maxNestingDepth,
}
}
// peekType examines the next value and returns its BSON Type
-func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
- var t bsontype.Type
+func (ejp *extJSONParser) peekType() (Type, error) {
+ var t Type
var err error
initialState := ejp.s
@@ -97,7 +95,7 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
case jpsSawValue:
t = ejp.v.t
case jpsSawBeginArray:
- t = bsontype.Array
+ t = TypeArray
case jpsInvalidState:
err = ejp.err
case jpsSawComma:
@@ -113,26 +111,26 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
ejp.advanceState()
switch ejp.s {
case jpsSawEndObject: // empty embedded document
- t = bsontype.EmbeddedDocument
+ t = TypeEmbeddedDocument
ejp.emptyObject = true
case jpsInvalidState:
err = ejp.err
case jpsSawKey:
if initialState == jpsStartState {
- return bsontype.EmbeddedDocument, nil
+ return TypeEmbeddedDocument, nil
}
t = wrapperKeyBSONType(ejp.k)
// if $uuid is encountered, parse as binary subtype 4
if ejp.k == "$uuid" {
ejp.relaxedUUID = true
- t = bsontype.Binary
+ t = TypeBinary
}
switch t {
- case bsontype.JavaScript:
+ case TypeJavaScript:
// just saw $code, need to check for $scope at same level
- _, err = ejp.readValue(bsontype.JavaScript)
+ _, err = ejp.readValue(TypeJavaScript)
if err != nil {
break
}
@@ -143,7 +141,7 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
ejp.advanceState()
if ejp.s == jpsSawKey && ejp.k == "$scope" {
- t = bsontype.CodeWithScope
+ t = TypeCodeWithScope
} else {
err = fmt.Errorf("invalid extended JSON: unexpected key %s in CodeWithScope object", ejp.k)
}
@@ -152,7 +150,7 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
default:
err = ErrInvalidJSON
}
- case bsontype.CodeWithScope:
+ case TypeCodeWithScope:
err = errors.New("invalid extended JSON: code with $scope must contain $code before $scope")
}
}
@@ -162,7 +160,7 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
}
// readKey parses the next key and its type and returns them
-func (ejp *extJSONParser) readKey() (string, bsontype.Type, error) {
+func (ejp *extJSONParser) readKey() (string, Type, error) {
if ejp.emptyObject {
ejp.emptyObject = false
return "", 0, ErrEOD
@@ -226,7 +224,7 @@ func (ejp *extJSONParser) readKey() (string, bsontype.Type, error) {
}
// readValue returns the value corresponding to the Type returned by peekType
-func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
+func (ejp *extJSONParser) readValue(t Type) (*extJSONValue, error) {
if ejp.s == jpsInvalidState {
return nil, ejp.err
}
@@ -234,19 +232,19 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
var v *extJSONValue
switch t {
- case bsontype.Null, bsontype.Boolean, bsontype.String:
+ case TypeNull, TypeBoolean, TypeString:
if ejp.s != jpsSawValue {
return nil, invalidRequestError(t.String())
}
v = ejp.v
- case bsontype.Int32, bsontype.Int64, bsontype.Double:
+ case TypeInt32, TypeInt64, TypeDouble:
// relaxed version allows these to be literal number values
if ejp.s == jpsSawValue {
v = ejp.v
break
}
fallthrough
- case bsontype.Decimal128, bsontype.Symbol, bsontype.ObjectID, bsontype.MinKey, bsontype.MaxKey, bsontype.Undefined:
+ case TypeDecimal128, TypeSymbol, TypeObjectID, TypeMinKey, TypeMaxKey, TypeUndefined:
switch ejp.s {
case jpsSawKey:
// read colon
@@ -271,7 +269,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
default:
return nil, invalidRequestError(t.String())
}
- case bsontype.Binary, bsontype.Regex, bsontype.Timestamp, bsontype.DBPointer:
+ case TypeBinary, TypeRegex, TypeTimestamp, TypeDBPointer:
if ejp.s != jpsSawKey {
return nil, invalidRequestError(t.String())
}
@@ -282,7 +280,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
}
ejp.advanceState()
- if t == bsontype.Binary && ejp.s == jpsSawValue {
+ if t == TypeBinary && ejp.s == jpsSawValue {
// convert relaxed $uuid format
if ejp.relaxedUUID {
defer func() { ejp.relaxedUUID = false }()
@@ -318,20 +316,20 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
ejp.advanceState()
if ejp.s != jpsSawEndObject {
- return nil, invalidJSONErrorForType("$uuid and value and then }", bsontype.Binary)
+ return nil, invalidJSONErrorForType("$uuid and value and then }", TypeBinary)
}
base64 := &extJSONValue{
- t: bsontype.String,
+ t: TypeString,
v: base64.StdEncoding.EncodeToString(bytes),
}
subType := &extJSONValue{
- t: bsontype.String,
+ t: TypeString,
v: "04",
}
v = &extJSONValue{
- t: bsontype.EmbeddedDocument,
+ t: TypeEmbeddedDocument,
v: &extJSONObject{
keys: []string{"base64", "subType"},
values: []*extJSONValue{base64, subType},
@@ -346,7 +344,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
ejp.advanceState()
if ejp.s != jpsSawComma {
- return nil, invalidJSONErrorForType(",", bsontype.Binary)
+ return nil, invalidJSONErrorForType(",", TypeBinary)
}
ejp.advanceState()
@@ -355,7 +353,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
return nil, err
}
if key != "$type" {
- return nil, invalidJSONErrorForType("$type", bsontype.Binary)
+ return nil, invalidJSONErrorForType("$type", TypeBinary)
}
subType, err := ejp.readValue(t)
@@ -365,11 +363,11 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
ejp.advanceState()
if ejp.s != jpsSawEndObject {
- return nil, invalidJSONErrorForType("2 key-value pairs and then }", bsontype.Binary)
+ return nil, invalidJSONErrorForType("2 key-value pairs and then }", TypeBinary)
}
v = &extJSONValue{
- t: bsontype.EmbeddedDocument,
+ t: TypeEmbeddedDocument,
v: &extJSONObject{
keys: []string{"base64", "subType"},
values: []*extJSONValue{base64, subType},
@@ -393,9 +391,9 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
return nil, invalidJSONErrorForType("2 key-value pairs and then }", t)
}
- v = &extJSONValue{t: bsontype.EmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}}
+ v = &extJSONValue{t: TypeEmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}}
- case bsontype.DateTime:
+ case TypeDateTime:
switch ejp.s {
case jpsSawValue:
v = ejp.v
@@ -413,14 +411,14 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
if err != nil {
return nil, err
}
- v = &extJSONValue{t: bsontype.EmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}}
+ v = &extJSONValue{t: TypeEmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}}
case jpsSawValue:
- if ejp.canonical {
+ if ejp.canonicalOnly {
return nil, invalidJSONError("{")
}
v = ejp.v
default:
- if ejp.canonical {
+ if ejp.canonicalOnly {
return nil, invalidJSONErrorForType("object", t)
}
return nil, invalidJSONErrorForType("ISO-8601 Internet Date/Time Format as described in RFC-3339", t)
@@ -433,7 +431,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
default:
return nil, invalidRequestError(t.String())
}
- case bsontype.JavaScript:
+ case TypeJavaScript:
switch ejp.s {
case jpsSawKey:
// read colon
@@ -456,7 +454,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
default:
return nil, invalidRequestError(t.String())
}
- case bsontype.CodeWithScope:
+ case TypeCodeWithScope:
if ejp.s == jpsSawKey && ejp.k == "$scope" {
v = ejp.v // this is the $code string from earlier
@@ -474,7 +472,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
} else {
return nil, invalidRequestError(t.String())
}
- case bsontype.EmbeddedDocument, bsontype.Array:
+ case TypeEmbeddedDocument, TypeArray:
return nil, invalidRequestError(t.String())
}
@@ -533,7 +531,6 @@ func (ejp *extJSONParser) advanceState() {
}
jt, err := ejp.js.nextToken()
-
if err != nil {
ejp.err = err
ejp.s = jpsInvalidState
@@ -703,14 +700,14 @@ func (ejp *extJSONParser) validateToken(jtt jsonTokenType) bool {
// ensureExtValueType returns true if the current value has the expected
// value type for single-key extended JSON types. For example,
// {"$numberInt": v} v must be TypeString
-func (ejp *extJSONParser) ensureExtValueType(t bsontype.Type) bool {
+func (ejp *extJSONParser) ensureExtValueType(t Type) bool {
switch t {
- case bsontype.MinKey, bsontype.MaxKey:
- return ejp.v.t == bsontype.Int32
- case bsontype.Undefined:
- return ejp.v.t == bsontype.Boolean
- case bsontype.Int32, bsontype.Int64, bsontype.Double, bsontype.Decimal128, bsontype.Symbol, bsontype.ObjectID:
- return ejp.v.t == bsontype.String
+ case TypeMinKey, TypeMaxKey:
+ return ejp.v.t == TypeInt32
+ case TypeUndefined:
+ return ejp.v.t == TypeBoolean
+ case TypeInt32, TypeInt64, TypeDouble, TypeDecimal128, TypeSymbol, TypeObjectID:
+ return ejp.v.t == TypeString
default:
return false
}
@@ -742,21 +739,21 @@ func (ejp *extJSONParser) peekMode() jsonParseMode {
}
func extendJSONToken(jt *jsonToken) *extJSONValue {
- var t bsontype.Type
+ var t Type
switch jt.t {
case jttInt32:
- t = bsontype.Int32
+ t = TypeInt32
case jttInt64:
- t = bsontype.Int64
+ t = TypeInt64
case jttDouble:
- t = bsontype.Double
+ t = TypeDouble
case jttString:
- t = bsontype.String
+ t = TypeString
case jttBool:
- t = bsontype.Boolean
+ t = TypeBoolean
case jttNull:
- t = bsontype.Null
+ t = TypeNull
default:
return nil
}
@@ -780,7 +777,7 @@ func invalidJSONError(expected string) error {
return fmt.Errorf("invalid JSON input; expected %s", expected)
}
-func invalidJSONErrorForType(expected string, t bsontype.Type) error {
+func invalidJSONErrorForType(expected string, t Type) error {
return fmt.Errorf("invalid JSON input; expected %s for %s", expected, t)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go
similarity index 62%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go
index 59ddfc448..339cdbbcb 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go
@@ -4,64 +4,17 @@
// 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 bsonrw
+package bson
import (
"errors"
"fmt"
"io"
- "sync"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
)
-// ExtJSONValueReaderPool is a pool for ValueReaders that read ExtJSON.
-//
-// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
-type ExtJSONValueReaderPool struct {
- pool sync.Pool
-}
-
-// NewExtJSONValueReaderPool instantiates a new ExtJSONValueReaderPool.
-//
-// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
-func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool {
- return &ExtJSONValueReaderPool{
- pool: sync.Pool{
- New: func() interface{} {
- return new(extJSONValueReader)
- },
- },
- }
-}
-
-// Get retrieves a ValueReader from the pool and uses src as the underlying ExtJSON.
-//
-// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
-func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReader, error) {
- vr := bvrp.pool.Get().(*extJSONValueReader)
- return vr.reset(r, canonical)
-}
-
-// Put inserts a ValueReader into the pool. If the ValueReader is not a ExtJSON ValueReader nothing
-// is inserted into the pool and ok will be false.
-//
-// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
-func (bvrp *ExtJSONValueReaderPool) Put(vr ValueReader) (ok bool) {
- bvr, ok := vr.(*extJSONValueReader)
- if !ok {
- return false
- }
-
- bvr, _ = bvr.reset(nil, false)
- bvrp.pool.Put(bvr)
- return true
-}
-
type ejvrState struct {
mode mode
- vType bsontype.Type
+ vType Type
depth int
}
@@ -73,31 +26,30 @@ type extJSONValueReader struct {
frame int
}
-// NewExtJSONValueReader creates a new ValueReader from a given io.Reader
-// It will interpret the JSON of r as canonical or relaxed according to the
-// given canonical flag
-func NewExtJSONValueReader(r io.Reader, canonical bool) (ValueReader, error) {
- return newExtJSONValueReader(r, canonical)
+// NewExtJSONValueReader returns a ValueReader that reads Extended JSON values
+// from r. If canonicalOnly is true, reading values from the ValueReader returns
+// an error if the Extended JSON was not marshaled in canonical mode.
+func NewExtJSONValueReader(r io.Reader, canonicalOnly bool) (ValueReader, error) {
+ return newExtJSONValueReader(r, canonicalOnly)
}
-func newExtJSONValueReader(r io.Reader, canonical bool) (*extJSONValueReader, error) {
+func newExtJSONValueReader(r io.Reader, canonicalOnly bool) (*extJSONValueReader, error) {
ejvr := new(extJSONValueReader)
- return ejvr.reset(r, canonical)
+ return ejvr.reset(r, canonicalOnly)
}
-func (ejvr *extJSONValueReader) reset(r io.Reader, canonical bool) (*extJSONValueReader, error) {
- p := newExtJSONParser(r, canonical)
+func (ejvr *extJSONValueReader) reset(r io.Reader, canonicalOnly bool) (*extJSONValueReader, error) {
+ p := newExtJSONParser(r, canonicalOnly)
typ, err := p.peekType()
-
if err != nil {
return nil, ErrInvalidJSON
}
var m mode
switch typ {
- case bsontype.EmbeddedDocument:
+ case TypeEmbeddedDocument:
m = mTopLevel
- case bsontype.Array:
+ case TypeArray:
m = mArray
default:
m = mValue
@@ -152,7 +104,7 @@ func (ejvr *extJSONValueReader) pushArray() {
ejvr.stack[ejvr.frame].mode = mArray
}
-func (ejvr *extJSONValueReader) push(m mode, t bsontype.Type) {
+func (ejvr *extJSONValueReader) push(m mode, t Type) {
ejvr.advanceFrame()
ejvr.stack[ejvr.frame].mode = m
@@ -213,11 +165,11 @@ func (ejvr *extJSONValueReader) invalidTransitionErr(destination mode, name stri
return te
}
-func (ejvr *extJSONValueReader) typeError(t bsontype.Type) error {
+func (ejvr *extJSONValueReader) typeError(t Type) error {
return fmt.Errorf("positioned on %s, but attempted to read %s", ejvr.stack[ejvr.frame].vType, t)
}
-func (ejvr *extJSONValueReader) ensureElementValue(t bsontype.Type, destination mode, callerName string, addModes ...mode) error {
+func (ejvr *extJSONValueReader) ensureElementValue(t Type, destination mode, callerName string, addModes ...mode) error {
switch ejvr.stack[ejvr.frame].mode {
case mElement, mValue:
if ejvr.stack[ejvr.frame].vType != t {
@@ -234,7 +186,7 @@ func (ejvr *extJSONValueReader) ensureElementValue(t bsontype.Type, destination
return nil
}
-func (ejvr *extJSONValueReader) Type() bsontype.Type {
+func (ejvr *extJSONValueReader) Type() Type {
return ejvr.stack[ejvr.frame].vType
}
@@ -249,7 +201,7 @@ func (ejvr *extJSONValueReader) Skip() error {
t := ejvr.stack[ejvr.frame].vType
switch t {
- case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope:
+ case TypeArray, TypeEmbeddedDocument, TypeCodeWithScope:
// read entire array, doc or CodeWithScope
ejvr.skipObject()
default:
@@ -268,7 +220,7 @@ func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) {
case mArray:
return ejvr, nil
default:
- if err := ejvr.ensureElementValue(bsontype.Array, mArray, "ReadArray", mTopLevel, mArray); err != nil {
+ if err := ejvr.ensureElementValue(TypeArray, mArray, "ReadArray", mTopLevel, mArray); err != nil {
return nil, err
}
}
@@ -279,11 +231,11 @@ func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) {
}
func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) {
- if err := ejvr.ensureElementValue(bsontype.Binary, 0, "ReadBinary"); err != nil {
+ if err := ejvr.ensureElementValue(TypeBinary, 0, "ReadBinary"); err != nil {
return nil, 0, err
}
- v, err := ejvr.p.readValue(bsontype.Binary)
+ v, err := ejvr.p.readValue(TypeBinary)
if err != nil {
return nil, 0, err
}
@@ -295,16 +247,16 @@ func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) {
}
func (ejvr *extJSONValueReader) ReadBoolean() (bool, error) {
- if err := ejvr.ensureElementValue(bsontype.Boolean, 0, "ReadBoolean"); err != nil {
+ if err := ejvr.ensureElementValue(TypeBoolean, 0, "ReadBoolean"); err != nil {
return false, err
}
- v, err := ejvr.p.readValue(bsontype.Boolean)
+ v, err := ejvr.p.readValue(TypeBoolean)
if err != nil {
return false, err
}
- if v.t != bsontype.Boolean {
+ if v.t != TypeBoolean {
return false, fmt.Errorf("expected type bool, but got type %s", v.t)
}
@@ -317,8 +269,8 @@ func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) {
case mTopLevel:
return ejvr, nil
case mElement, mValue:
- if ejvr.stack[ejvr.frame].vType != bsontype.EmbeddedDocument {
- return nil, ejvr.typeError(bsontype.EmbeddedDocument)
+ if ejvr.stack[ejvr.frame].vType != TypeEmbeddedDocument {
+ return nil, ejvr.typeError(TypeEmbeddedDocument)
}
ejvr.pushDocument()
@@ -329,11 +281,11 @@ func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) {
}
func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentReader, err error) {
- if err = ejvr.ensureElementValue(bsontype.CodeWithScope, 0, "ReadCodeWithScope"); err != nil {
+ if err = ejvr.ensureElementValue(TypeCodeWithScope, 0, "ReadCodeWithScope"); err != nil {
return "", nil, err
}
- v, err := ejvr.p.readValue(bsontype.CodeWithScope)
+ v, err := ejvr.p.readValue(TypeCodeWithScope)
if err != nil {
return "", nil, err
}
@@ -344,14 +296,14 @@ func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentRea
return code, ejvr, err
}
-func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid primitive.ObjectID, err error) {
- if err = ejvr.ensureElementValue(bsontype.DBPointer, 0, "ReadDBPointer"); err != nil {
- return "", primitive.NilObjectID, err
+func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid ObjectID, err error) {
+ if err = ejvr.ensureElementValue(TypeDBPointer, 0, "ReadDBPointer"); err != nil {
+ return "", NilObjectID, err
}
- v, err := ejvr.p.readValue(bsontype.DBPointer)
+ v, err := ejvr.p.readValue(TypeDBPointer)
if err != nil {
- return "", primitive.NilObjectID, err
+ return "", NilObjectID, err
}
ns, oid, err = v.parseDBPointer()
@@ -361,11 +313,11 @@ func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid primitive.Object
}
func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) {
- if err := ejvr.ensureElementValue(bsontype.DateTime, 0, "ReadDateTime"); err != nil {
+ if err := ejvr.ensureElementValue(TypeDateTime, 0, "ReadDateTime"); err != nil {
return 0, err
}
- v, err := ejvr.p.readValue(bsontype.DateTime)
+ v, err := ejvr.p.readValue(TypeDateTime)
if err != nil {
return 0, err
}
@@ -376,14 +328,14 @@ func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) {
return d, err
}
-func (ejvr *extJSONValueReader) ReadDecimal128() (primitive.Decimal128, error) {
- if err := ejvr.ensureElementValue(bsontype.Decimal128, 0, "ReadDecimal128"); err != nil {
- return primitive.Decimal128{}, err
+func (ejvr *extJSONValueReader) ReadDecimal128() (Decimal128, error) {
+ if err := ejvr.ensureElementValue(TypeDecimal128, 0, "ReadDecimal128"); err != nil {
+ return Decimal128{}, err
}
- v, err := ejvr.p.readValue(bsontype.Decimal128)
+ v, err := ejvr.p.readValue(TypeDecimal128)
if err != nil {
- return primitive.Decimal128{}, err
+ return Decimal128{}, err
}
d, err := v.parseDecimal128()
@@ -393,11 +345,11 @@ func (ejvr *extJSONValueReader) ReadDecimal128() (primitive.Decimal128, error) {
}
func (ejvr *extJSONValueReader) ReadDouble() (float64, error) {
- if err := ejvr.ensureElementValue(bsontype.Double, 0, "ReadDouble"); err != nil {
+ if err := ejvr.ensureElementValue(TypeDouble, 0, "ReadDouble"); err != nil {
return 0, err
}
- v, err := ejvr.p.readValue(bsontype.Double)
+ v, err := ejvr.p.readValue(TypeDouble)
if err != nil {
return 0, err
}
@@ -409,11 +361,11 @@ func (ejvr *extJSONValueReader) ReadDouble() (float64, error) {
}
func (ejvr *extJSONValueReader) ReadInt32() (int32, error) {
- if err := ejvr.ensureElementValue(bsontype.Int32, 0, "ReadInt32"); err != nil {
+ if err := ejvr.ensureElementValue(TypeInt32, 0, "ReadInt32"); err != nil {
return 0, err
}
- v, err := ejvr.p.readValue(bsontype.Int32)
+ v, err := ejvr.p.readValue(TypeInt32)
if err != nil {
return 0, err
}
@@ -425,11 +377,11 @@ func (ejvr *extJSONValueReader) ReadInt32() (int32, error) {
}
func (ejvr *extJSONValueReader) ReadInt64() (int64, error) {
- if err := ejvr.ensureElementValue(bsontype.Int64, 0, "ReadInt64"); err != nil {
+ if err := ejvr.ensureElementValue(TypeInt64, 0, "ReadInt64"); err != nil {
return 0, err
}
- v, err := ejvr.p.readValue(bsontype.Int64)
+ v, err := ejvr.p.readValue(TypeInt64)
if err != nil {
return 0, err
}
@@ -441,11 +393,11 @@ func (ejvr *extJSONValueReader) ReadInt64() (int64, error) {
}
func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) {
- if err = ejvr.ensureElementValue(bsontype.JavaScript, 0, "ReadJavascript"); err != nil {
+ if err = ejvr.ensureElementValue(TypeJavaScript, 0, "ReadJavascript"); err != nil {
return "", err
}
- v, err := ejvr.p.readValue(bsontype.JavaScript)
+ v, err := ejvr.p.readValue(TypeJavaScript)
if err != nil {
return "", err
}
@@ -457,11 +409,11 @@ func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) {
}
func (ejvr *extJSONValueReader) ReadMaxKey() error {
- if err := ejvr.ensureElementValue(bsontype.MaxKey, 0, "ReadMaxKey"); err != nil {
+ if err := ejvr.ensureElementValue(TypeMaxKey, 0, "ReadMaxKey"); err != nil {
return err
}
- v, err := ejvr.p.readValue(bsontype.MaxKey)
+ v, err := ejvr.p.readValue(TypeMaxKey)
if err != nil {
return err
}
@@ -473,11 +425,11 @@ func (ejvr *extJSONValueReader) ReadMaxKey() error {
}
func (ejvr *extJSONValueReader) ReadMinKey() error {
- if err := ejvr.ensureElementValue(bsontype.MinKey, 0, "ReadMinKey"); err != nil {
+ if err := ejvr.ensureElementValue(TypeMinKey, 0, "ReadMinKey"); err != nil {
return err
}
- v, err := ejvr.p.readValue(bsontype.MinKey)
+ v, err := ejvr.p.readValue(TypeMinKey)
if err != nil {
return err
}
@@ -489,16 +441,16 @@ func (ejvr *extJSONValueReader) ReadMinKey() error {
}
func (ejvr *extJSONValueReader) ReadNull() error {
- if err := ejvr.ensureElementValue(bsontype.Null, 0, "ReadNull"); err != nil {
+ if err := ejvr.ensureElementValue(TypeNull, 0, "ReadNull"); err != nil {
return err
}
- v, err := ejvr.p.readValue(bsontype.Null)
+ v, err := ejvr.p.readValue(TypeNull)
if err != nil {
return err
}
- if v.t != bsontype.Null {
+ if v.t != TypeNull {
return fmt.Errorf("expected type null but got type %s", v.t)
}
@@ -506,14 +458,14 @@ func (ejvr *extJSONValueReader) ReadNull() error {
return nil
}
-func (ejvr *extJSONValueReader) ReadObjectID() (primitive.ObjectID, error) {
- if err := ejvr.ensureElementValue(bsontype.ObjectID, 0, "ReadObjectID"); err != nil {
- return primitive.ObjectID{}, err
+func (ejvr *extJSONValueReader) ReadObjectID() (ObjectID, error) {
+ if err := ejvr.ensureElementValue(TypeObjectID, 0, "ReadObjectID"); err != nil {
+ return ObjectID{}, err
}
- v, err := ejvr.p.readValue(bsontype.ObjectID)
+ v, err := ejvr.p.readValue(TypeObjectID)
if err != nil {
- return primitive.ObjectID{}, err
+ return ObjectID{}, err
}
oid, err := v.parseObjectID()
@@ -523,11 +475,11 @@ func (ejvr *extJSONValueReader) ReadObjectID() (primitive.ObjectID, error) {
}
func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err error) {
- if err = ejvr.ensureElementValue(bsontype.Regex, 0, "ReadRegex"); err != nil {
+ if err = ejvr.ensureElementValue(TypeRegex, 0, "ReadRegex"); err != nil {
return "", "", err
}
- v, err := ejvr.p.readValue(bsontype.Regex)
+ v, err := ejvr.p.readValue(TypeRegex)
if err != nil {
return "", "", err
}
@@ -539,16 +491,16 @@ func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err
}
func (ejvr *extJSONValueReader) ReadString() (string, error) {
- if err := ejvr.ensureElementValue(bsontype.String, 0, "ReadString"); err != nil {
+ if err := ejvr.ensureElementValue(TypeString, 0, "ReadString"); err != nil {
return "", err
}
- v, err := ejvr.p.readValue(bsontype.String)
+ v, err := ejvr.p.readValue(TypeString)
if err != nil {
return "", err
}
- if v.t != bsontype.String {
+ if v.t != TypeString {
return "", fmt.Errorf("expected type string but got type %s", v.t)
}
@@ -557,11 +509,11 @@ func (ejvr *extJSONValueReader) ReadString() (string, error) {
}
func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) {
- if err = ejvr.ensureElementValue(bsontype.Symbol, 0, "ReadSymbol"); err != nil {
+ if err = ejvr.ensureElementValue(TypeSymbol, 0, "ReadSymbol"); err != nil {
return "", err
}
- v, err := ejvr.p.readValue(bsontype.Symbol)
+ v, err := ejvr.p.readValue(TypeSymbol)
if err != nil {
return "", err
}
@@ -573,11 +525,11 @@ func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) {
}
func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error) {
- if err = ejvr.ensureElementValue(bsontype.Timestamp, 0, "ReadTimestamp"); err != nil {
+ if err = ejvr.ensureElementValue(TypeTimestamp, 0, "ReadTimestamp"); err != nil {
return 0, 0, err
}
- v, err := ejvr.p.readValue(bsontype.Timestamp)
+ v, err := ejvr.p.readValue(TypeTimestamp)
if err != nil {
return 0, 0, err
}
@@ -589,11 +541,11 @@ func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error)
}
func (ejvr *extJSONValueReader) ReadUndefined() error {
- if err := ejvr.ensureElementValue(bsontype.Undefined, 0, "ReadUndefined"); err != nil {
+ if err := ejvr.ensureElementValue(TypeUndefined, 0, "ReadUndefined"); err != nil {
return err
}
- v, err := ejvr.p.readValue(bsontype.Undefined)
+ v, err := ejvr.p.readValue(TypeUndefined)
if err != nil {
return err
}
@@ -612,7 +564,6 @@ func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) {
}
name, t, err := ejvr.p.readKey()
-
if err != nil {
if errors.Is(err, ErrEOD) {
if ejvr.stack[ejvr.frame].mode == mCodeWithScope {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go
index ba39c9601..5384db225 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go
@@ -7,7 +7,7 @@
// Based on github.com/golang/go by The Go Authors
// See THIRD-PARTY-NOTICES for original license terms.
-package bsonrw
+package bson
import "unicode/utf8"
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_wrappers.go
similarity index 74%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_wrappers.go
index af6ae7b76..7e506b2f8 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_wrappers.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"encoding/base64"
@@ -13,52 +13,49 @@ import (
"math"
"strconv"
"time"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
)
-func wrapperKeyBSONType(key string) bsontype.Type {
+func wrapperKeyBSONType(key string) Type {
switch key {
case "$numberInt":
- return bsontype.Int32
+ return TypeInt32
case "$numberLong":
- return bsontype.Int64
+ return TypeInt64
case "$oid":
- return bsontype.ObjectID
+ return TypeObjectID
case "$symbol":
- return bsontype.Symbol
+ return TypeSymbol
case "$numberDouble":
- return bsontype.Double
+ return TypeDouble
case "$numberDecimal":
- return bsontype.Decimal128
+ return TypeDecimal128
case "$binary":
- return bsontype.Binary
+ return TypeBinary
case "$code":
- return bsontype.JavaScript
+ return TypeJavaScript
case "$scope":
- return bsontype.CodeWithScope
+ return TypeCodeWithScope
case "$timestamp":
- return bsontype.Timestamp
+ return TypeTimestamp
case "$regularExpression":
- return bsontype.Regex
+ return TypeRegex
case "$dbPointer":
- return bsontype.DBPointer
+ return TypeDBPointer
case "$date":
- return bsontype.DateTime
+ return TypeDateTime
case "$minKey":
- return bsontype.MinKey
+ return TypeMinKey
case "$maxKey":
- return bsontype.MaxKey
+ return TypeMaxKey
case "$undefined":
- return bsontype.Undefined
+ return TypeUndefined
}
- return bsontype.EmbeddedDocument
+ return TypeEmbeddedDocument
}
func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
- if ejv.t != bsontype.EmbeddedDocument {
+ if ejv.t != TypeEmbeddedDocument {
return nil, 0, fmt.Errorf("$binary value should be object, but instead is %s", ejv.t)
}
@@ -75,7 +72,7 @@ func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
return nil, 0, errors.New("duplicate base64 key in $binary")
}
- if val.t != bsontype.String {
+ if val.t != TypeString {
return nil, 0, fmt.Errorf("$binary base64 value should be string, but instead is %s", val.t)
}
@@ -91,7 +88,7 @@ func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
return nil, 0, errors.New("duplicate subType key in $binary")
}
- if val.t != bsontype.String {
+ if val.t != TypeString {
return nil, 0, fmt.Errorf("$binary subType value should be string, but instead is %s", val.t)
}
@@ -113,15 +110,14 @@ func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
if !stFound {
return nil, 0, errors.New("missing subType field in $binary object")
-
}
return b, subType, nil
}
-func (ejv *extJSONValue) parseDBPointer() (ns string, oid primitive.ObjectID, err error) {
- if ejv.t != bsontype.EmbeddedDocument {
- return "", primitive.NilObjectID, fmt.Errorf("$dbPointer value should be object, but instead is %s", ejv.t)
+func (ejv *extJSONValue) parseDBPointer() (ns string, oid ObjectID, err error) {
+ if ejv.t != TypeEmbeddedDocument {
+ return "", NilObjectID, fmt.Errorf("$dbPointer value should be object, but instead is %s", ejv.t)
}
dbpObj := ejv.v.(*extJSONObject)
@@ -134,32 +130,32 @@ func (ejv *extJSONValue) parseDBPointer() (ns string, oid primitive.ObjectID, er
switch key {
case "$ref":
if nsFound {
- return "", primitive.NilObjectID, errors.New("duplicate $ref key in $dbPointer")
+ return "", NilObjectID, errors.New("duplicate $ref key in $dbPointer")
}
- if val.t != bsontype.String {
- return "", primitive.NilObjectID, fmt.Errorf("$dbPointer $ref value should be string, but instead is %s", val.t)
+ if val.t != TypeString {
+ return "", NilObjectID, fmt.Errorf("$dbPointer $ref value should be string, but instead is %s", val.t)
}
ns = val.v.(string)
nsFound = true
case "$id":
if oidFound {
- return "", primitive.NilObjectID, errors.New("duplicate $id key in $dbPointer")
+ return "", NilObjectID, errors.New("duplicate $id key in $dbPointer")
}
- if val.t != bsontype.String {
- return "", primitive.NilObjectID, fmt.Errorf("$dbPointer $id value should be string, but instead is %s", val.t)
+ if val.t != TypeString {
+ return "", NilObjectID, fmt.Errorf("$dbPointer $id value should be string, but instead is %s", val.t)
}
- oid, err = primitive.ObjectIDFromHex(val.v.(string))
+ oid, err = ObjectIDFromHex(val.v.(string))
if err != nil {
- return "", primitive.NilObjectID, err
+ return "", NilObjectID, err
}
oidFound = true
default:
- return "", primitive.NilObjectID, fmt.Errorf("invalid key in $dbPointer object: %s", key)
+ return "", NilObjectID, fmt.Errorf("invalid key in $dbPointer object: %s", key)
}
}
@@ -178,19 +174,17 @@ const (
rfc3339Milli = "2006-01-02T15:04:05.999Z07:00"
)
-var (
- timeFormats = []string{rfc3339Milli, "2006-01-02T15:04:05.999Z0700"}
-)
+var timeFormats = []string{rfc3339Milli, "2006-01-02T15:04:05.999Z0700"}
func (ejv *extJSONValue) parseDateTime() (int64, error) {
switch ejv.t {
- case bsontype.Int32:
+ case TypeInt32:
return int64(ejv.v.(int32)), nil
- case bsontype.Int64:
+ case TypeInt64:
return ejv.v.(int64), nil
- case bsontype.String:
+ case TypeString:
return parseDatetimeString(ejv.v.(string))
- case bsontype.EmbeddedDocument:
+ case TypeEmbeddedDocument:
return parseDatetimeObject(ejv.v.(*extJSONObject))
default:
return 0, fmt.Errorf("$date value should be string or object, but instead is %s", ejv.t)
@@ -211,7 +205,7 @@ func parseDatetimeString(data string) (int64, error) {
return 0, fmt.Errorf("invalid $date value string: %s", data)
}
- return int64(primitive.NewDateTimeFromTime(t)), nil
+ return int64(NewDateTimeFromTime(t)), nil
}
func parseDatetimeObject(data *extJSONObject) (d int64, err error) {
@@ -226,7 +220,7 @@ func parseDatetimeObject(data *extJSONObject) (d int64, err error) {
return 0, errors.New("duplicate $numberLong key in $date")
}
- if val.t != bsontype.String {
+ if val.t != TypeString {
return 0, fmt.Errorf("$date $numberLong field should be string, but instead is %s", val.t)
}
@@ -247,25 +241,25 @@ func parseDatetimeObject(data *extJSONObject) (d int64, err error) {
return d, nil
}
-func (ejv *extJSONValue) parseDecimal128() (primitive.Decimal128, error) {
- if ejv.t != bsontype.String {
- return primitive.Decimal128{}, fmt.Errorf("$numberDecimal value should be string, but instead is %s", ejv.t)
+func (ejv *extJSONValue) parseDecimal128() (Decimal128, error) {
+ if ejv.t != TypeString {
+ return Decimal128{}, fmt.Errorf("$numberDecimal value should be string, but instead is %s", ejv.t)
}
- d, err := primitive.ParseDecimal128(ejv.v.(string))
+ d, err := ParseDecimal128(ejv.v.(string))
if err != nil {
- return primitive.Decimal128{}, fmt.Errorf("$invalid $numberDecimal string: %s", ejv.v.(string))
+ return Decimal128{}, fmt.Errorf("$invalid $numberDecimal string: %s", ejv.v.(string))
}
return d, nil
}
func (ejv *extJSONValue) parseDouble() (float64, error) {
- if ejv.t == bsontype.Double {
+ if ejv.t == TypeDouble {
return ejv.v.(float64), nil
}
- if ejv.t != bsontype.String {
+ if ejv.t != TypeString {
return 0, fmt.Errorf("$numberDouble value should be string, but instead is %s", ejv.t)
}
@@ -287,11 +281,11 @@ func (ejv *extJSONValue) parseDouble() (float64, error) {
}
func (ejv *extJSONValue) parseInt32() (int32, error) {
- if ejv.t == bsontype.Int32 {
+ if ejv.t == TypeInt32 {
return ejv.v.(int32), nil
}
- if ejv.t != bsontype.String {
+ if ejv.t != TypeString {
return 0, fmt.Errorf("$numberInt value should be string, but instead is %s", ejv.t)
}
@@ -308,11 +302,11 @@ func (ejv *extJSONValue) parseInt32() (int32, error) {
}
func (ejv *extJSONValue) parseInt64() (int64, error) {
- if ejv.t == bsontype.Int64 {
+ if ejv.t == TypeInt64 {
return ejv.v.(int64), nil
}
- if ejv.t != bsontype.String {
+ if ejv.t != TypeString {
return 0, fmt.Errorf("$numberLong value should be string, but instead is %s", ejv.t)
}
@@ -325,7 +319,7 @@ func (ejv *extJSONValue) parseInt64() (int64, error) {
}
func (ejv *extJSONValue) parseJavascript() (code string, err error) {
- if ejv.t != bsontype.String {
+ if ejv.t != TypeString {
return "", fmt.Errorf("$code value should be string, but instead is %s", ejv.t)
}
@@ -333,7 +327,7 @@ func (ejv *extJSONValue) parseJavascript() (code string, err error) {
}
func (ejv *extJSONValue) parseMinMaxKey(minmax string) error {
- if ejv.t != bsontype.Int32 {
+ if ejv.t != TypeInt32 {
return fmt.Errorf("$%sKey value should be int32, but instead is %s", minmax, ejv.t)
}
@@ -344,16 +338,16 @@ func (ejv *extJSONValue) parseMinMaxKey(minmax string) error {
return nil
}
-func (ejv *extJSONValue) parseObjectID() (primitive.ObjectID, error) {
- if ejv.t != bsontype.String {
- return primitive.NilObjectID, fmt.Errorf("$oid value should be string, but instead is %s", ejv.t)
+func (ejv *extJSONValue) parseObjectID() (ObjectID, error) {
+ if ejv.t != TypeString {
+ return NilObjectID, fmt.Errorf("$oid value should be string, but instead is %s", ejv.t)
}
- return primitive.ObjectIDFromHex(ejv.v.(string))
+ return ObjectIDFromHex(ejv.v.(string))
}
func (ejv *extJSONValue) parseRegex() (pattern, options string, err error) {
- if ejv.t != bsontype.EmbeddedDocument {
+ if ejv.t != TypeEmbeddedDocument {
return "", "", fmt.Errorf("$regularExpression value should be object, but instead is %s", ejv.t)
}
@@ -370,7 +364,7 @@ func (ejv *extJSONValue) parseRegex() (pattern, options string, err error) {
return "", "", errors.New("duplicate pattern key in $regularExpression")
}
- if val.t != bsontype.String {
+ if val.t != TypeString {
return "", "", fmt.Errorf("$regularExpression pattern value should be string, but instead is %s", val.t)
}
@@ -381,7 +375,7 @@ func (ejv *extJSONValue) parseRegex() (pattern, options string, err error) {
return "", "", errors.New("duplicate options key in $regularExpression")
}
- if val.t != bsontype.String {
+ if val.t != TypeString {
return "", "", fmt.Errorf("$regularExpression options value should be string, but instead is %s", val.t)
}
@@ -398,14 +392,13 @@ func (ejv *extJSONValue) parseRegex() (pattern, options string, err error) {
if !optFound {
return "", "", errors.New("missing options field in $regularExpression object")
-
}
return pattern, options, nil
}
func (ejv *extJSONValue) parseSymbol() (string, error) {
- if ejv.t != bsontype.String {
+ if ejv.t != TypeString {
return "", fmt.Errorf("$symbol value should be string, but instead is %s", ejv.t)
}
@@ -413,7 +406,7 @@ func (ejv *extJSONValue) parseSymbol() (string, error) {
}
func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
- if ejv.t != bsontype.EmbeddedDocument {
+ if ejv.t != TypeEmbeddedDocument {
return 0, 0, fmt.Errorf("$timestamp value should be object, but instead is %s", ejv.t)
}
@@ -423,7 +416,7 @@ func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
}
switch val.t {
- case bsontype.Int32:
+ case TypeInt32:
value := val.v.(int32)
if value < 0 {
@@ -431,7 +424,7 @@ func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
}
return uint32(value), nil
- case bsontype.Int64:
+ case TypeInt64:
value := val.v.(int64)
if value < 0 || value > int64(math.MaxUint32) {
return 0, fmt.Errorf("$timestamp %s number should be uint32: %d", key, value)
@@ -480,7 +473,7 @@ func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
}
func (ejv *extJSONValue) parseUndefined() error {
- if ejv.t != bsontype.Boolean {
+ if ejv.t != TypeBoolean {
return fmt.Errorf("undefined value should be boolean, but instead is %s", ejv.t)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_writer.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_writer.go
index 86a293570..2d43943fa 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_writer.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"bytes"
@@ -15,67 +15,10 @@ import (
"sort"
"strconv"
"strings"
- "sync"
"time"
"unicode/utf8"
-
- "go.mongodb.org/mongo-driver/bson/primitive"
)
-// ExtJSONValueWriterPool is a pool for ExtJSON ValueWriters.
-//
-// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
-type ExtJSONValueWriterPool struct {
- pool sync.Pool
-}
-
-// NewExtJSONValueWriterPool creates a new pool for ValueWriter instances that write to ExtJSON.
-//
-// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
-func NewExtJSONValueWriterPool() *ExtJSONValueWriterPool {
- return &ExtJSONValueWriterPool{
- pool: sync.Pool{
- New: func() interface{} {
- return new(extJSONValueWriter)
- },
- },
- }
-}
-
-// Get retrieves a ExtJSON ValueWriter from the pool and resets it to use w as the destination.
-//
-// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
-func (bvwp *ExtJSONValueWriterPool) Get(w io.Writer, canonical, escapeHTML bool) ValueWriter {
- vw := bvwp.pool.Get().(*extJSONValueWriter)
- if writer, ok := w.(*SliceWriter); ok {
- vw.reset(*writer, canonical, escapeHTML)
- vw.w = writer
- return vw
- }
- vw.buf = vw.buf[:0]
- vw.w = w
- return vw
-}
-
-// Put inserts a ValueWriter into the pool. If the ValueWriter is not a ExtJSON ValueWriter, nothing
-// happens and ok will be false.
-//
-// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
-func (bvwp *ExtJSONValueWriterPool) Put(vw ValueWriter) (ok bool) {
- bvw, ok := vw.(*extJSONValueWriter)
- if !ok {
- return false
- }
-
- if _, ok := bvw.w.(*SliceWriter); ok {
- bvw.buf = nil
- }
- bvw.w = nil
-
- bvwp.pool.Put(bvw)
- return true
-}
-
type ejvwState struct {
mode mode
}
@@ -92,15 +35,11 @@ type extJSONValueWriter struct {
}
// NewExtJSONValueWriter creates a ValueWriter that writes Extended JSON to w.
-func NewExtJSONValueWriter(w io.Writer, canonical, escapeHTML bool) (ValueWriter, error) {
- if w == nil {
- return nil, errNilWriter
- }
-
+func NewExtJSONValueWriter(w io.Writer, canonical, escapeHTML bool) ValueWriter {
// Enable newlines for all Extended JSON value writers created by NewExtJSONValueWriter. We
// expect these value writers to be used with an Encoder, which should add newlines after
// encoded Extended JSON documents.
- return newExtJSONWriter(w, canonical, escapeHTML, true), nil
+ return newExtJSONWriter(w, canonical, escapeHTML, true)
}
func newExtJSONWriter(w io.Writer, canonical, escapeHTML, newlines bool) *extJSONValueWriter {
@@ -270,7 +209,7 @@ func (ejvw *extJSONValueWriter) WriteCodeWithScope(code string) (DocumentWriter,
return ejvw, nil
}
-func (ejvw *extJSONValueWriter) WriteDBPointer(ns string, oid primitive.ObjectID) error {
+func (ejvw *extJSONValueWriter) WriteDBPointer(ns string, oid ObjectID) error {
if err := ejvw.ensureElementValue(mode(0), "WriteDBPointer"); err != nil {
return err
}
@@ -308,7 +247,7 @@ func (ejvw *extJSONValueWriter) WriteDateTime(dt int64) error {
return nil
}
-func (ejvw *extJSONValueWriter) WriteDecimal128(d primitive.Decimal128) error {
+func (ejvw *extJSONValueWriter) WriteDecimal128(d Decimal128) error {
if err := ejvw.ensureElementValue(mode(0), "WriteDecimal128"); err != nil {
return err
}
@@ -451,7 +390,7 @@ func (ejvw *extJSONValueWriter) WriteNull() error {
return nil
}
-func (ejvw *extJSONValueWriter) WriteObjectID(oid primitive.ObjectID) error {
+func (ejvw *extJSONValueWriter) WriteObjectID(oid ObjectID) error {
if err := ejvw.ensureElementValue(mode(0), "WriteObjectID"); err != nil {
return err
}
@@ -580,7 +519,7 @@ func (ejvw *extJSONValueWriter) WriteDocumentEnd() error {
case mTopLevel:
// If the value writer has newlines enabled, end top-level documents with a newline so that
// multiple documents encoded to the same writer are separated by newlines. That matches the
- // Go json.Encoder behavior and also works with bsonrw.NewExtJSONValueReader.
+ // Go json.Encoder behavior and also works with NewExtJSONValueReader.
if ejvw.newlines {
ejvw.buf = append(ejvw.buf, '\n')
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/json_scanner.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/json_scanner.go
index 978289191..61755b56f 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/json_scanner.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"bytes"
@@ -37,7 +37,7 @@ const (
type jsonToken struct {
t jsonTokenType
- v interface{}
+ v any
p int
}
@@ -100,7 +100,6 @@ func (js *jsonScanner) nextToken() (*jsonToken, error) {
func (js *jsonScanner) readNextByte() (byte, error) {
if js.pos >= len(js.buf) {
err := js.readIntoBuf()
-
if err != nil {
return 0, err
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/map_codec.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/map_codec.go
index d7e00ffa8..36d2f6ae2 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/map_codec.go
@@ -4,7 +4,7 @@
// 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 bsoncodec
+package bson
import (
"encoding"
@@ -12,51 +12,21 @@ import (
"fmt"
"reflect"
"strconv"
-
- "go.mongodb.org/mongo-driver/bson/bsonoptions"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
-var defaultMapCodec = NewMapCodec()
-
-// MapCodec is the Codec used for map values.
-//
-// Deprecated: MapCodec will not be directly configurable in Go Driver 2.0. To
-// configure the map encode and decode behavior, use the configuration methods
-// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
-// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the map encode and
-// decode behavior for a mongo.Client, use
-// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
-//
-// For example, to configure a mongo.Client to marshal nil Go maps as empty BSON
-// documents, use:
-//
-// opt := options.Client().SetBSONOptions(&options.BSONOptions{
-// NilMapAsEmpty: true,
-// })
-//
-// See the deprecation notice for each field in MapCodec for the corresponding
-// settings.
-type MapCodec struct {
+// mapCodec is the Codec used for map values.
+type mapCodec struct {
// DecodeZerosMap causes DecodeValue to delete any existing values from Go maps in the destination
// value passed to Decode before unmarshaling BSON documents into them.
- //
- // Deprecated: Use bson.Decoder.ZeroMaps or options.BSONOptions.ZeroMaps instead.
- DecodeZerosMap bool
+ decodeZerosMap bool
// EncodeNilAsEmpty causes EncodeValue to marshal nil Go maps as empty BSON documents instead of
// BSON null.
- //
- // Deprecated: Use bson.Encoder.NilMapAsEmpty or options.BSONOptions.NilMapAsEmpty instead.
- EncodeNilAsEmpty bool
+ encodeNilAsEmpty bool
// EncodeKeysWithStringer causes the Encoder to convert Go map keys to BSON document field name
// strings using fmt.Sprintf() instead of the default string conversion logic.
- //
- // Deprecated: Use bson.Encoder.StringifyMapKeysWithFmt or
- // options.BSONOptions.StringifyMapKeysWithFmt instead.
- EncodeKeysWithStringer bool
+ encodeKeysWithStringer bool
}
// KeyMarshaler is the interface implemented by an object that can marshal itself into a string key.
@@ -75,33 +45,13 @@ type KeyUnmarshaler interface {
UnmarshalKey(key string) error
}
-// NewMapCodec returns a MapCodec with options opts.
-//
-// Deprecated: NewMapCodec will not be available in Go Driver 2.0. See
-// [MapCodec] for more details.
-func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec {
- mapOpt := bsonoptions.MergeMapCodecOptions(opts...)
-
- codec := MapCodec{}
- if mapOpt.DecodeZerosMap != nil {
- codec.DecodeZerosMap = *mapOpt.DecodeZerosMap
- }
- if mapOpt.EncodeNilAsEmpty != nil {
- codec.EncodeNilAsEmpty = *mapOpt.EncodeNilAsEmpty
- }
- if mapOpt.EncodeKeysWithStringer != nil {
- codec.EncodeKeysWithStringer = *mapOpt.EncodeKeysWithStringer
- }
- return &codec
-}
-
// EncodeValue is the ValueEncoder for map[*]* types.
-func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (mc *mapCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Kind() != reflect.Map {
return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
}
- if val.IsNil() && !mc.EncodeNilAsEmpty && !ec.nilMapAsEmpty {
+ if val.IsNil() && !mc.encodeNilAsEmpty && !ec.nilMapAsEmpty {
// If we have a nil map but we can't WriteNull, that means we're probably trying to encode
// to a TopLevel document. We can't currently tell if this is what actually happened, but if
// there's a deeper underlying problem, the error will also be returned from WriteDocument,
@@ -118,14 +68,17 @@ func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val ref
return err
}
- return mc.mapEncodeValue(ec, dw, val, nil)
+ err = mc.encodeMapElements(ec, dw, val, nil)
+ if err != nil {
+ return err
+ }
+ return dw.WriteDocumentEnd()
}
-// mapEncodeValue handles encoding of the values of a map. The collisionFn returns
+// encodeMapElements handles encoding of the values of a map. The collisionFn returns
// true if the provided key exists, this is mainly used for inline maps in the
// struct codec.
-func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
-
+func (mc *mapCodec) encodeMapElements(ec EncodeContext, dw DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
elemType := val.Type().Elem()
encoder, err := ec.LookupEncoder(elemType)
if err != nil && elemType.Kind() != reflect.Interface {
@@ -143,7 +96,7 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v
return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
}
- currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.MapIndex(key))
+ currEncoder, currVal, lookupErr := lookupElementEncoder(ec, encoder, val.MapIndex(key))
if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
return lookupErr
}
@@ -167,21 +120,21 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v
}
}
- return dw.WriteDocumentEnd()
+ return nil
}
// DecodeValue is the ValueDecoder for map[string/decimal]* types.
-func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (mc *mapCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if val.Kind() != reflect.Map || (!val.CanSet() && val.IsNil()) {
return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
}
switch vrType := vr.Type(); vrType {
- case bsontype.Type(0), bsontype.EmbeddedDocument:
- case bsontype.Null:
+ case Type(0), TypeEmbeddedDocument:
+ case TypeNull:
val.Set(reflect.Zero(val.Type()))
return vr.ReadNull()
- case bsontype.Undefined:
+ case TypeUndefined:
val.Set(reflect.Zero(val.Type()))
return vr.ReadUndefined()
default:
@@ -197,7 +150,7 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref
val.Set(reflect.MakeMap(val.Type()))
}
- if val.Len() > 0 && (mc.DecodeZerosMap || dc.zeroMaps) {
+ if val.Len() > 0 && (mc.decodeZerosMap || dc.zeroMaps) {
clearMap(val)
}
@@ -206,17 +159,12 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref
if err != nil {
return err
}
- eTypeDecoder, _ := decoder.(typeDecoder)
-
- if eType == tEmpty {
- dc.Ancestor = val.Type()
- }
keyType := val.Type().Key()
for {
key, vr, err := dr.ReadElement()
- if errors.Is(err, bsonrw.ErrEOD) {
+ if errors.Is(err, ErrEOD) {
break
}
if err != nil {
@@ -228,7 +176,7 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref
return err
}
- elem, err := decodeTypeOrValueWithInfo(decoder, eTypeDecoder, dc, vr, eType, true)
+ elem, err := decodeTypeOrValueWithInfo(decoder, dc, vr, eType)
if err != nil {
return newDecodeError(key, err)
}
@@ -245,8 +193,8 @@ func clearMap(m reflect.Value) {
}
}
-func (mc *MapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (string, error) {
- if mc.EncodeKeysWithStringer || encodeKeysWithStringer {
+func (mc *mapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (string, error) {
+ if mc.encodeKeysWithStringer || encodeKeysWithStringer {
return fmt.Sprint(val), nil
}
@@ -288,15 +236,17 @@ func (mc *MapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (s
return "", fmt.Errorf("unsupported key type: %v", val.Type())
}
-var keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem()
-var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+var (
+ keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem()
+ textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+)
-func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) {
+func (mc *mapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) {
keyVal := reflect.ValueOf(key)
var err error
switch {
// First, if EncodeKeysWithStringer is not enabled, try to decode withKeyUnmarshaler
- case !mc.EncodeKeysWithStringer && reflect.PtrTo(keyType).Implements(keyUnmarshalerType):
+ case !mc.encodeKeysWithStringer && reflect.PtrTo(keyType).Implements(keyUnmarshalerType):
keyVal = reflect.New(keyType)
v := keyVal.Interface().(KeyUnmarshaler)
err = v.UnmarshalKey(key)
@@ -326,10 +276,10 @@ func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value,
}
keyVal = reflect.ValueOf(n).Convert(keyType)
case reflect.Float32, reflect.Float64:
- if mc.EncodeKeysWithStringer {
+ if mc.encodeKeysWithStringer {
parsed, err := strconv.ParseFloat(key, 64)
if err != nil {
- return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err)
+ return keyVal, fmt.Errorf("map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err)
}
keyVal = reflect.ValueOf(parsed)
break
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/marshal.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/marshal.go
new file mode 100644
index 000000000..71a28dab7
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/marshal.go
@@ -0,0 +1,191 @@
+// 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 bson
+
+import (
+ "bytes"
+ "encoding/json"
+ "sync"
+)
+
+const defaultDstCap = 256
+
+var extjPool = sync.Pool{
+ New: func() any {
+ return new(extJSONValueWriter)
+ },
+}
+
+// Marshaler is the interface implemented by types that can marshal themselves
+// into a valid BSON document.
+//
+// Implementations of Marshaler must return a full BSON document. To create
+// custom BSON marshaling behavior for individual values in a BSON document,
+// implement the ValueMarshaler interface instead.
+type Marshaler interface {
+ MarshalBSON() ([]byte, error)
+}
+
+// ValueMarshaler is the interface implemented by types that can marshal
+// themselves into a valid BSON value. The format of the returned bytes must
+// match the returned type.
+//
+// Implementations of ValueMarshaler must return an individual BSON value. To
+// create custom BSON marshaling behavior for an entire BSON document, implement
+// the Marshaler interface instead.
+type ValueMarshaler interface {
+ MarshalBSONValue() (typ byte, data []byte, err error)
+}
+
+// Pool of buffers for marshalling BSON.
+var bufPool = sync.Pool{
+ New: func() any {
+ return new(bytes.Buffer)
+ },
+}
+
+// Marshal returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed into a
+// document, MarshalValue should be used instead.
+//
+// Marshal will use the default registry created by NewRegistry to recursively
+// marshal val into a []byte. Marshal will inspect struct tags and alter the
+// marshaling process accordingly.
+func Marshal(val any) ([]byte, error) {
+ sw := bufPool.Get().(*bytes.Buffer)
+ defer func() {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum
+ // buffer to place back in the pool. We limit the size to 16MiB because
+ // that's the maximum wire message size supported by any current MongoDB
+ // server.
+ //
+ // Comment based on
+ // https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/fmt/print.go;l=147
+ //
+ // Recycle byte slices that are smaller than 16MiB and at least half
+ // occupied.
+ if sw.Cap() < 16*1024*1024 && sw.Cap()/2 < sw.Len() {
+ bufPool.Put(sw)
+ }
+ }()
+ sw.Reset()
+
+ vw := getDocumentWriter(sw)
+ defer putDocumentWriter(vw)
+
+ enc := encPool.Get().(*Encoder)
+ defer encPool.Put(enc)
+ enc.Reset(vw)
+ enc.SetRegistry(defaultRegistry)
+ err := enc.Encode(val)
+ if err != nil {
+ return nil, err
+ }
+ buf := append([]byte(nil), sw.Bytes()...)
+ return buf, nil
+}
+
+// MarshalValue returns the BSON encoding of val.
+//
+// MarshalValue will use bson.NewRegistry() to transform val into a BSON value. If val is a struct, this function will
+// inspect struct tags and alter the marshalling process accordingly.
+func MarshalValue(val any) (Type, []byte, error) {
+ sw := bufPool.Get().(*bytes.Buffer)
+ defer func() {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum
+ // buffer to place back in the pool. We limit the size to 16MiB because
+ // that's the maximum wire message size supported by any current MongoDB
+ // server.
+ //
+ // Comment based on
+ // https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/fmt/print.go;l=147
+ //
+ // Recycle byte slices that are smaller than 16MiB and at least half
+ // occupied.
+ if sw.Cap() < 16*1024*1024 && sw.Cap()/2 < sw.Len() {
+ bufPool.Put(sw)
+ }
+ }()
+ sw.Reset()
+ vwFlusher := newDocumentWriter(sw)
+ vw, err := vwFlusher.WriteDocumentElement("")
+ if err != nil {
+ return 0, nil, err
+ }
+
+ // get an Encoder and encode the value
+ enc := encPool.Get().(*Encoder)
+ defer encPool.Put(enc)
+ enc.Reset(vw)
+ enc.SetRegistry(defaultRegistry)
+ if err := enc.Encode(val); err != nil {
+ return 0, nil, err
+ }
+
+ // flush the bytes written because we cannot guarantee that a full document has been written
+ // after the flush, *sw will be in the format
+ // [value type, 0 (null byte to indicate end of empty element name), value bytes..]
+ if err := vwFlusher.Flush(); err != nil {
+ return 0, nil, err
+ }
+ typ := sw.Next(2)
+ clone := append([]byte{}, sw.Bytes()...) // Don't hand out a shared reference to byte buffer bytes
+ // and fully copy the data. The byte buffer is (potentially) reused
+ // and handing out only a reference to the bytes may lead to race-conditions with the buffer.
+ return Type(typ[0]), clone, nil
+}
+
+// MarshalExtJSON returns the extended JSON encoding of val.
+func MarshalExtJSON(val any, canonical, escapeHTML bool) ([]byte, error) {
+ sw := sliceWriter(make([]byte, 0, defaultDstCap))
+ ejvw := extjPool.Get().(*extJSONValueWriter)
+ ejvw.reset(sw, canonical, escapeHTML)
+ ejvw.w = &sw
+ defer func() {
+ ejvw.buf = nil
+ ejvw.w = nil
+ extjPool.Put(ejvw)
+ }()
+
+ enc := encPool.Get().(*Encoder)
+ defer encPool.Put(enc)
+
+ enc.Reset(ejvw)
+ enc.ec = EncodeContext{Registry: defaultRegistry}
+
+ err := enc.Encode(val)
+ if err != nil {
+ return nil, err
+ }
+
+ return sw, nil
+}
+
+// IndentExtJSON will prefix and indent the provided extended JSON src and append it to dst.
+func IndentExtJSON(dst *bytes.Buffer, src []byte, prefix, indent string) error {
+ return json.Indent(dst, src, prefix, indent)
+}
+
+// MarshalExtJSONIndent returns the extended JSON encoding of val with each line with prefixed
+// and indented.
+func MarshalExtJSONIndent(val any, canonical, escapeHTML bool, prefix, indent string) ([]byte, error) {
+ marshaled, err := MarshalExtJSON(val, canonical, escapeHTML)
+ if err != nil {
+ return nil, err
+ }
+
+ var buf bytes.Buffer
+ err = IndentExtJSON(&buf, marshaled, prefix, indent)
+ if err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/mgoregistry.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/mgoregistry.go
new file mode 100644
index 000000000..db0871525
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/mgoregistry.go
@@ -0,0 +1,209 @@
+// 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 bson
+
+import (
+ "errors"
+ "reflect"
+)
+
+var (
+ // ErrMgoSetZero may be returned from a SetBSON method to have the value set to its respective zero value.
+ ErrMgoSetZero = errors.New("set to zero")
+
+ tInt = reflect.TypeOf(int(0))
+ tM = reflect.TypeOf(M{})
+ tInterfaceSlice = reflect.TypeOf([]any{})
+ tGetter = reflect.TypeOf((*getter)(nil)).Elem()
+ tSetter = reflect.TypeOf((*setter)(nil)).Elem()
+)
+
+// NewMgoRegistry creates a new bson.Registry configured with the default encoders and decoders.
+func NewMgoRegistry() *Registry {
+ mapCodec := &mapCodec{
+ decodeZerosMap: true,
+ encodeNilAsEmpty: true,
+ encodeKeysWithStringer: true,
+ }
+ structCodec := &structCodec{
+ inlineMapEncoder: mapCodec,
+ decodeZeroStruct: true,
+ encodeOmitDefaultStruct: true,
+ allowUnexportedFields: true,
+ }
+ uintCodec := &uintCodec{encodeToMinSize: true}
+
+ reg := NewRegistry()
+ reg.RegisterTypeDecoder(tEmpty, &emptyInterfaceCodec{decodeBinaryAsSlice: true})
+ reg.RegisterKindDecoder(reflect.String, ValueDecoderFunc(mgoStringDecodeValue))
+ reg.RegisterKindDecoder(reflect.Struct, structCodec)
+ reg.RegisterKindDecoder(reflect.Map, mapCodec)
+ reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{encodeNilAsEmpty: true})
+ reg.RegisterKindEncoder(reflect.Struct, structCodec)
+ reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{encodeNilAsEmpty: true})
+ reg.RegisterKindEncoder(reflect.Map, mapCodec)
+ reg.RegisterKindEncoder(reflect.Uint, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint8, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint16, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint32, uintCodec)
+ reg.RegisterKindEncoder(reflect.Uint64, uintCodec)
+ reg.RegisterTypeMapEntry(TypeInt32, tInt)
+ reg.RegisterTypeMapEntry(TypeDateTime, tTime)
+ reg.RegisterTypeMapEntry(TypeArray, tInterfaceSlice)
+ reg.RegisterTypeMapEntry(Type(0), tM)
+ reg.RegisterTypeMapEntry(TypeEmbeddedDocument, tM)
+ reg.RegisterInterfaceEncoder(tGetter, ValueEncoderFunc(getterEncodeValue))
+ reg.RegisterInterfaceDecoder(tSetter, ValueDecoderFunc(setterDecodeValue))
+ return reg
+}
+
+// NewRespectNilValuesMgoRegistry creates a new bson.Registry configured to behave like mgo/bson
+// with RespectNilValues set to true.
+func NewRespectNilValuesMgoRegistry() *Registry {
+ mapCodec := &mapCodec{
+ decodeZerosMap: true,
+ }
+
+ reg := NewMgoRegistry()
+ reg.RegisterKindDecoder(reflect.Map, mapCodec)
+ reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{encodeNilAsEmpty: false})
+ reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{})
+ reg.RegisterKindEncoder(reflect.Map, mapCodec)
+ return reg
+}
+
+func mgoStringDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if val.Kind() != reflect.String {
+ return ValueDecoderError{
+ Name: "StringDecodeValue",
+ Kinds: []reflect.Kind{reflect.String},
+ Received: reflect.Zero(val.Type()),
+ }
+ }
+
+ if vr.Type() == TypeObjectID {
+ oid, err := vr.ReadObjectID()
+ if err != nil {
+ return err
+ }
+ if dc.objectIDAsHexString {
+ val.SetString(oid.Hex())
+ } else {
+ val.SetString(string(oid[:]))
+ }
+ return nil
+ }
+ return (&stringCodec{}).DecodeValue(dc, vr, val)
+}
+
+// setter interface: a value implementing the bson.Setter interface will receive the BSON
+// value via the SetBSON method during unmarshaling, and the object
+// itself will not be changed as usual.
+//
+// If setting the value works, the method should return nil or alternatively
+// ErrMgoSetZero to set the respective field to its zero value (nil for
+// pointer types). If SetBSON returns a non-nil error, the unmarshalling
+// procedure will stop and error out with the provided value.
+//
+// This interface is generally useful in pointer receivers, since the method
+// will want to change the receiver. A type field that implements the Setter
+// interface doesn't have to be a pointer, though.
+//
+// For example:
+//
+// type MyString string
+//
+// func (s *MyString) SetBSON(raw bson.RawValue) error {
+// return raw.Unmarshal(s)
+// }
+type setter interface {
+ SetBSON(raw RawValue) error
+}
+
+// getter interface: a value implementing the bson.Getter interface will have its GetBSON
+// method called when the given value has to be marshalled, and the result
+// of this method will be marshaled in place of the actual object.
+//
+// If GetBSON returns return a non-nil error, the marshalling procedure
+// will stop and error out with the provided value.
+type getter interface {
+ GetBSON() (any, error)
+}
+
+// setterDecodeValue is the ValueDecoderFunc for Setter types.
+func setterDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.IsValid() || (!val.Type().Implements(tSetter) && !reflect.PtrTo(val.Type()).Implements(tSetter)) {
+ return ValueDecoderError{Name: "SetterDecodeValue", Types: []reflect.Type{tSetter}, Received: val}
+ }
+
+ if val.Kind() == reflect.Ptr && val.IsNil() {
+ if !val.CanSet() {
+ return ValueDecoderError{Name: "SetterDecodeValue", Types: []reflect.Type{tSetter}, Received: val}
+ }
+ val.Set(reflect.New(val.Type().Elem()))
+ }
+
+ if !val.Type().Implements(tSetter) {
+ if !val.CanAddr() {
+ return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tSetter}, Received: val}
+ }
+ val = val.Addr() // If the type doesn't implement the interface, a pointer to it must.
+ }
+
+ t, src, err := copyValueToBytes(vr)
+ if err != nil {
+ return err
+ }
+
+ m, ok := val.Interface().(setter)
+ if !ok {
+ return ValueDecoderError{Name: "SetterDecodeValue", Types: []reflect.Type{tSetter}, Received: val}
+ }
+ if err := m.SetBSON(RawValue{Type: t, Value: src}); err != nil {
+ if !errors.Is(err, ErrMgoSetZero) {
+ return err
+ }
+ val.Set(reflect.Zero(val.Type()))
+ }
+ return nil
+}
+
+// getterEncodeValue is the ValueEncoderFunc for Getter types.
+func getterEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
+ // Either val or a pointer to val must implement Getter
+ switch {
+ case !val.IsValid():
+ return ValueEncoderError{Name: "GetterEncodeValue", Types: []reflect.Type{tGetter}, Received: val}
+ case val.Type().Implements(tGetter):
+ // If Getter is implemented on a concrete type, make sure that val isn't a nil pointer
+ if isImplementationNil(val, tGetter) {
+ return vw.WriteNull()
+ }
+ case reflect.PtrTo(val.Type()).Implements(tGetter) && val.CanAddr():
+ val = val.Addr()
+ default:
+ return ValueEncoderError{Name: "GetterEncodeValue", Types: []reflect.Type{tGetter}, Received: val}
+ }
+
+ m, ok := val.Interface().(getter)
+ if !ok {
+ return vw.WriteNull()
+ }
+ x, err := m.GetBSON()
+ if err != nil {
+ return err
+ }
+ if x == nil {
+ return vw.WriteNull()
+ }
+ vv := reflect.ValueOf(x)
+ encoder, err := ec.LookupEncoder(vv.Type())
+ if err != nil {
+ return err
+ }
+ return encoder.EncodeValue(ec, vw, vv)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/mode.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/mode.go
similarity index 71%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/mode.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/mode.go
index 617b5e221..a4563892a 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/mode.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/mode.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"fmt"
@@ -26,31 +26,6 @@ const (
func (m mode) String() string {
var str string
- switch m {
- case mTopLevel:
- str = "TopLevel"
- case mDocument:
- str = "DocumentMode"
- case mArray:
- str = "ArrayMode"
- case mValue:
- str = "ValueMode"
- case mElement:
- str = "ElementMode"
- case mCodeWithScope:
- str = "CodeWithScopeMode"
- case mSpacer:
- str = "CodeWithScopeSpacerFrame"
- default:
- str = "UnknownMode"
- }
-
- return str
-}
-
-func (m mode) TypeString() string {
- var str string
-
switch m {
case mTopLevel:
str = "TopLevel"
@@ -75,7 +50,6 @@ func (m mode) TypeString() string {
// TransitionError is an error returned when an invalid progressing a
// ValueReader or ValueWriter state machine occurs.
-// If read is false, the error is for writing
type TransitionError struct {
name string
parent mode
@@ -88,7 +62,7 @@ type TransitionError struct {
func (te TransitionError) Error() string {
errString := fmt.Sprintf("%s can only %s", te.name, te.action)
if te.destination != mode(0) {
- errString = fmt.Sprintf("%s a %s", errString, te.destination.TypeString())
+ errString = fmt.Sprintf("%s a %s", errString, te.destination)
}
errString = fmt.Sprintf("%s while positioned on a", errString)
for ind, m := range te.modes {
@@ -98,11 +72,11 @@ func (te TransitionError) Error() string {
if ind == len(te.modes)-1 && len(te.modes) > 1 {
errString = fmt.Sprintf("%s or", errString)
}
- errString = fmt.Sprintf("%s %s", errString, m.TypeString())
+ errString = fmt.Sprintf("%s %s", errString, m)
}
- errString = fmt.Sprintf("%s but is positioned on a %s", errString, te.current.TypeString())
+ errString = fmt.Sprintf("%s but is positioned on a %s", errString, te.current)
if te.parent != mode(0) {
- errString = fmt.Sprintf("%s with parent %s", errString, te.parent.TypeString())
+ errString = fmt.Sprintf("%s with parent %s", errString, te.parent)
}
return errString
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/objectid.go
similarity index 59%
rename from vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/objectid.go
index c130e3ff1..543278914 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/objectid.go
@@ -7,7 +7,7 @@
// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer
// See THIRD-PARTY-NOTICES for original license terms.
-package primitive
+package bson
import (
"crypto/rand"
@@ -31,11 +31,15 @@ type ObjectID [12]byte
// NilObjectID is the zero value for ObjectID.
var NilObjectID ObjectID
-var objectIDCounter = readRandomUint32()
-var processUnique = processUniqueBytes()
+var (
+ objectIDCounter = readRandomUint32()
+ processUnique = processUniqueBytes()
+)
-var _ encoding.TextMarshaler = ObjectID{}
-var _ encoding.TextUnmarshaler = &ObjectID{}
+var (
+ _ encoding.TextMarshaler = ObjectID{}
+ _ encoding.TextUnmarshaler = &ObjectID{}
+)
// NewObjectID generates a new ObjectID.
func NewObjectID() ObjectID {
@@ -67,7 +71,7 @@ func (id ObjectID) Hex() string {
}
func (id ObjectID) String() string {
- return fmt.Sprintf("ObjectID(%q)", id.Hex())
+ return `ObjectID("` + id.Hex() + `")`
}
// IsZero returns true if id is the empty ObjectID.
@@ -91,23 +95,33 @@ func ObjectIDFromHex(s string) (ObjectID, error) {
return oid, nil
}
-// IsValidObjectID returns true if the provided hex string represents a valid ObjectID and false if not.
-//
-// Deprecated: Use ObjectIDFromHex and check the error instead.
-func IsValidObjectID(s string) bool {
- _, err := ObjectIDFromHex(s)
- return err == nil
-}
-
// MarshalText returns the ObjectID as UTF-8-encoded text. Implementing this allows us to use ObjectID
// as a map key when marshalling JSON. See https://pkg.go.dev/encoding#TextMarshaler
func (id ObjectID) MarshalText() ([]byte, error) {
- return []byte(id.Hex()), nil
+ var buf [24]byte
+ hex.Encode(buf[:], id[:])
+ return buf[:], nil
}
-// UnmarshalText populates the byte slice with the ObjectID. Implementing this allows us to use ObjectID
-// as a map key when unmarshalling JSON. See https://pkg.go.dev/encoding#TextUnmarshaler
+// UnmarshalText populates the byte slice with the ObjectID. If the byte slice
+// is 24 bytes long, it will be populated with the hex representation of the
+// ObjectID. If the byte slice is 12 bytes long, it will be populated with the
+// BSON representation of the ObjectID. This method also accepts empty strings
+// and decodes them as NilObjectID.
+//
+// For any other inputs, an error will be returned.
+//
+// Implementing this allows us to use ObjectID as a map key when unmarshalling
+// JSON. See https://pkg.go.dev/encoding#TextUnmarshaler
func (id *ObjectID) UnmarshalText(b []byte) error {
+ // NB(charlie): The json package will use UnmarshalText instead of
+ // UnmarshalJSON if the value is a string.
+
+ // An empty string is not a valid ObjectID, but we treat it as a
+ // special value that decodes as NilObjectID.
+ if len(b) == 0 {
+ return nil
+ }
oid, err := ObjectIDFromHex(string(b))
if err != nil {
return err
@@ -118,65 +132,56 @@ func (id *ObjectID) UnmarshalText(b []byte) error {
// MarshalJSON returns the ObjectID as a string
func (id ObjectID) MarshalJSON() ([]byte, error) {
- return json.Marshal(id.Hex())
+ var buf [26]byte
+ buf[0] = '"'
+ hex.Encode(buf[1:25], id[:])
+ buf[25] = '"'
+ return buf[:], nil
}
-// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it
-// will be populated with the hex representation of the ObjectID. If the byte slice is twelve bytes
-// long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and
-// decodes them as NilObjectID. For any other inputs, an error will be returned.
+// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice
+// is 24 bytes long, it will be populated with the hex representation of the
+// ObjectID. If the byte slice is 12 bytes long, it will be populated with the
+// BSON representation of the ObjectID. This method also accepts empty strings
+// and decodes them as NilObjectID.
+//
+// As a special case UnmarshalJSON will decode a JSON object with key "$oid"
+// that stores a hex encoded ObjectID: {"$oid": "65b3f7edd9bfca00daa6e3b31"}.
+//
+// For any other inputs, an error will be returned.
func (id *ObjectID) UnmarshalJSON(b []byte) error {
- // Ignore "null" to keep parity with the standard library. Decoding a JSON null into a non-pointer ObjectID field
- // will leave the field unchanged. For pointer values, encoding/json will set the pointer to nil and will not
- // enter the UnmarshalJSON hook.
+ // Ignore "null" to keep parity with the standard library. Decoding a JSON
+ // null into a non-pointer ObjectID field will leave the field unchanged.
+ // For pointer values, encoding/json will set the pointer to nil and will
+ // not enter the UnmarshalJSON hook.
if string(b) == "null" {
return nil
}
- var err error
- switch len(b) {
- case 12:
+ // Handle string
+ if len(b) >= 2 && b[0] == '"' {
+ // TODO: fails because of error
+ return id.UnmarshalText(b[1 : len(b)-1])
+ }
+ if len(b) == 12 {
copy(id[:], b)
- default:
- // Extended JSON
- var res interface{}
- err := json.Unmarshal(b, &res)
- if err != nil {
- return err
- }
- str, ok := res.(string)
- if !ok {
- m, ok := res.(map[string]interface{})
- if !ok {
- return errors.New("not an extended JSON ObjectID")
- }
- oid, ok := m["$oid"]
- if !ok {
- return errors.New("not an extended JSON ObjectID")
- }
- str, ok = oid.(string)
- if !ok {
- return errors.New("not an extended JSON ObjectID")
- }
- }
-
- // An empty string is not a valid ObjectID, but we treat it as a special value that decodes as NilObjectID.
- if len(str) == 0 {
- copy(id[:], NilObjectID[:])
- return nil
- }
-
- if len(str) != 24 {
- return fmt.Errorf("cannot unmarshal into an ObjectID, the length must be 24 but it is %d", len(str))
- }
-
- _, err = hex.Decode(id[:], []byte(str))
- if err != nil {
- return err
- }
+ return nil
}
-
- return err
+ var v struct {
+ OID *string `json:"$oid"`
+ }
+ if err := json.Unmarshal(b, &v); err != nil {
+ return fmt.Errorf("failed to parse extended JSON ObjectID: %w", err)
+ }
+ if v.OID == nil {
+ return errors.New("not an extended JSON ObjectID")
+ }
+ i, err := ObjectIDFromHex(*v.OID)
+ if err != nil {
+ return err
+ }
+ *id = i
+ return nil
}
func processUniqueBytes() [5]byte {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/pointer_codec.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/pointer_codec.go
index ddfa4a33e..ff2e940ce 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/pointer_codec.go
@@ -4,46 +4,26 @@
// 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 bsoncodec
+package bson
import (
"reflect"
-
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
-var _ ValueEncoder = &PointerCodec{}
-var _ ValueDecoder = &PointerCodec{}
+var (
+ _ ValueEncoder = &pointerCodec{}
+ _ ValueDecoder = &pointerCodec{}
+)
-// PointerCodec is the Codec used for pointers.
-//
-// Deprecated: PointerCodec will not be directly accessible in Go Driver 2.0. To
-// override the default pointer encode and decode behavior, create a new registry
-// with [go.mongodb.org/mongo-driver/bson.NewRegistry] and register a new
-// encoder and decoder for pointers.
-//
-// For example,
-//
-// reg := bson.NewRegistry()
-// reg.RegisterKindEncoder(reflect.Ptr, myPointerEncoder)
-// reg.RegisterKindDecoder(reflect.Ptr, myPointerDecoder)
-type PointerCodec struct {
+// pointerCodec is the Codec used for pointers.
+type pointerCodec struct {
ecache typeEncoderCache
dcache typeDecoderCache
}
-// NewPointerCodec returns a PointerCodec that has been initialized.
-//
-// Deprecated: NewPointerCodec will not be available in Go Driver 2.0. See
-// [PointerCodec] for more details.
-func NewPointerCodec() *PointerCodec {
- return &PointerCodec{}
-}
-
// EncodeValue handles encoding a pointer by either encoding it to BSON Null if the pointer is nil
// or looking up an encoder for the type of value the pointer points to.
-func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (pc *pointerCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
if val.Kind() != reflect.Ptr {
if !val.IsValid() {
return vw.WriteNull()
@@ -58,7 +38,7 @@ func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
typ := val.Type()
if v, ok := pc.ecache.Load(typ); ok {
if v == nil {
- return ErrNoEncoder{Type: typ}
+ return errNoEncoder{Type: typ}
}
return v.EncodeValue(ec, vw, val.Elem())
}
@@ -73,17 +53,17 @@ func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
// DecodeValue handles decoding a pointer by looking up a decoder for the type it points to and
// using that to decode. If the BSON value is Null, this method will set the pointer to nil.
-func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (pc *pointerCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Kind() != reflect.Ptr {
return ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val}
}
typ := val.Type()
- if vr.Type() == bsontype.Null {
+ if vr.Type() == TypeNull {
val.Set(reflect.Zero(typ))
return vr.ReadNull()
}
- if vr.Type() == bsontype.Undefined {
+ if vr.Type() == TypeUndefined {
val.Set(reflect.Zero(typ))
return vr.ReadUndefined()
}
@@ -94,7 +74,7 @@ func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
if v, ok := pc.dcache.Load(typ); ok {
if v == nil {
- return ErrNoDecoder{Type: typ}
+ return errNoDecoder{Type: typ}
}
return v.DecodeValue(dc, vr, val.Elem())
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/primitive.go
similarity index 56%
rename from vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/primitive.go
index 65f4fbb94..beebb8956 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/primitive.go
@@ -3,18 +3,30 @@
// 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
+//
+// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer
+// See THIRD-PARTY-NOTICES for original license terms.
-// Package primitive contains types similar to Go primitives for BSON types that do not have direct
-// Go primitive representations.
-package primitive // import "go.mongodb.org/mongo-driver/bson/primitive"
+package bson
import (
"bytes"
"encoding/json"
"fmt"
+ "reflect"
"time"
)
+// Zeroer allows custom struct types to implement a report of zero
+// state. All struct types that don't implement Zeroer or where IsZero
+// returns false are considered to be not zero.
+type Zeroer interface {
+ IsZero() bool
+}
+
+// The following primitive types are similar to Go primitives for BSON types that
+// do not have direct Go primitive representations.
+
// Binary represents a BSON binary value.
type Binary struct {
Subtype byte
@@ -40,29 +52,28 @@ type Undefined struct{}
// DateTime represents the BSON datetime value.
type DateTime int64
-var _ json.Marshaler = DateTime(0)
-var _ json.Unmarshaler = (*DateTime)(nil)
+var (
+ _ json.Marshaler = DateTime(0)
+ _ json.Unmarshaler = (*DateTime)(nil)
+)
// MarshalJSON marshal to time type.
func (d DateTime) MarshalJSON() ([]byte, error) {
- return json.Marshal(d.Time().UTC())
+ return d.Time().UTC().MarshalJSON()
}
-// UnmarshalJSON creates a primitive.DateTime from a JSON string.
+// UnmarshalJSON creates a bson.DateTime from a JSON string.
func (d *DateTime) UnmarshalJSON(data []byte) error {
- // Ignore "null" to keep parity with the time.Time type and the standard library. Decoding "null" into a non-pointer
- // DateTime field will leave the field unchanged. For pointer values, the encoding/json will set the pointer to nil
- // and will not defer to the UnmarshalJSON hook.
+ // Ignore "null" so that we can distinguish between a "null" value and
+ // valid value that is the zero time (as reported by time.Time.IsZero).
if string(data) == "null" {
return nil
}
-
- var tempTime time.Time
- if err := json.Unmarshal(data, &tempTime); err != nil {
+ var t time.Time
+ if err := t.UnmarshalJSON(data); err != nil {
return err
}
-
- *d = NewDateTimeFromTime(tempTime)
+ *d = NewDateTimeFromTime(t)
return nil
}
@@ -128,7 +139,7 @@ type Symbol string
// CodeWithScope represents a BSON JavaScript code with scope value.
type CodeWithScope struct {
Code JavaScript
- Scope interface{}
+ Scope any
}
func (cws CodeWithScope) String() string {
@@ -174,14 +185,6 @@ func (tp Timestamp) Compare(tp2 Timestamp) int {
}
}
-// CompareTimestamp compares the time instant tp with tp2. If tp is before tp2, it returns -1; if tp is after
-// tp2, it returns +1; if they're the same, it returns 0.
-//
-// Deprecated: Use Timestamp.Compare instead.
-func CompareTimestamp(tp, tp2 Timestamp) int {
- return tp.Compare(tp2)
-}
-
// MinKey represents the BSON minkey value.
type MinKey struct{}
@@ -196,36 +199,183 @@ type MaxKey struct{}
// bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
type D []E
-// Map creates a map from the elements of the D.
-//
-// Deprecated: Converting directly from a D to an M will not be supported in Go Driver 2.0. Instead,
-// users should marshal the D to BSON using bson.Marshal and unmarshal it to M using bson.Unmarshal.
-func (d D) Map() M {
- m := make(M, len(d))
- for _, e := range d {
- m[e.Key] = e.Value
+func (d D) String() string {
+ b, err := MarshalExtJSON(d, true, false)
+ if err != nil {
+ return ""
+ }
+ return string(b)
+}
+
+// MarshalJSON encodes D into JSON.
+func (d D) MarshalJSON() ([]byte, error) {
+ if d == nil {
+ return json.Marshal(nil)
+ }
+ var err error
+ var buf bytes.Buffer
+ buf.Write([]byte("{"))
+ enc := json.NewEncoder(&buf)
+ for i, e := range d {
+ err = enc.Encode(e.Key)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write([]byte(":"))
+ err = enc.Encode(e.Value)
+ if err != nil {
+ return nil, err
+ }
+ if i < len(d)-1 {
+ buf.Write([]byte(","))
+ }
+ }
+ buf.Write([]byte("}"))
+ return json.RawMessage(buf.Bytes()).MarshalJSON()
+}
+
+// UnmarshalJSON decodes D from JSON.
+func (d *D) UnmarshalJSON(b []byte) error {
+ dec := json.NewDecoder(bytes.NewReader(b))
+ t, err := dec.Token()
+ if err != nil {
+ return err
+ }
+ if t == nil {
+ *d = nil
+ return nil
}
- return m
+ if v, ok := t.(json.Delim); !ok || v != '{' {
+ return &json.UnmarshalTypeError{
+ Value: tokenString(t),
+ Type: reflect.TypeOf(D(nil)),
+ Offset: dec.InputOffset(),
+ }
+ }
+ *d, err = jsonDecodeD(dec)
+ return err
}
// E represents a BSON element for a D. It is usually used inside a D.
type E struct {
Key string
- Value interface{}
+ Value any
}
// M is an unordered representation of a BSON document. This type should be used when the order of the elements does not
-// matter. This type is handled as a regular map[string]interface{} when encoding and decoding. Elements will be
+// matter. This type is handled as a regular map[string]any when encoding and decoding. Elements will be
// serialized in an undefined, random order. If the order of the elements matters, a D should be used instead.
//
// Example usage:
//
// bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
-type M map[string]interface{}
+type M map[string]any
+
+func (m M) String() string {
+ b, err := MarshalExtJSON(m, true, false)
+ if err != nil {
+ return ""
+ }
+ return string(b)
+}
// An A is an ordered representation of a BSON array.
//
// Example usage:
//
// bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
-type A []interface{}
+type A []any
+
+func jsonDecodeD(dec *json.Decoder) (D, error) {
+ res := D{}
+ for {
+ var e E
+
+ t, err := dec.Token()
+ if err != nil {
+ return nil, err
+ }
+ key, ok := t.(string)
+ if !ok {
+ break
+ }
+ e.Key = key
+
+ t, err = dec.Token()
+ if err != nil {
+ return nil, err
+ }
+ switch v := t.(type) {
+ case json.Delim:
+ switch v {
+ case '[':
+ e.Value, err = jsonDecodeSlice(dec)
+ if err != nil {
+ return nil, err
+ }
+ case '{':
+ e.Value, err = jsonDecodeD(dec)
+ if err != nil {
+ return nil, err
+ }
+ }
+ default:
+ e.Value = t
+ }
+
+ res = append(res, e)
+ }
+ return res, nil
+}
+
+func jsonDecodeSlice(dec *json.Decoder) ([]any, error) {
+ var res []any
+ done := false
+ for !done {
+ t, err := dec.Token()
+ if err != nil {
+ return nil, err
+ }
+ switch v := t.(type) {
+ case json.Delim:
+ switch v {
+ case '[':
+ a, err := jsonDecodeSlice(dec)
+ if err != nil {
+ return nil, err
+ }
+ res = append(res, a)
+ case '{':
+ d, err := jsonDecodeD(dec)
+ if err != nil {
+ return nil, err
+ }
+ res = append(res, d)
+ default:
+ done = true
+ }
+ default:
+ res = append(res, t)
+ }
+ }
+ return res, nil
+}
+
+func tokenString(t json.Token) string {
+ switch v := t.(type) {
+ case json.Delim:
+ switch v {
+ case '{':
+ return "object"
+ case '[':
+ return "array"
+ }
+ case bool:
+ return "bool"
+ case float64:
+ return "number"
+ case json.Number, string:
+ return "string"
+ }
+ return "unknown"
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/primitive_codecs.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/primitive_codecs.go
new file mode 100644
index 000000000..ffb9f0344
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/primitive_codecs.go
@@ -0,0 +1,96 @@
+// 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 bson
+
+import (
+ "fmt"
+ "reflect"
+)
+
+var (
+ tRawValue = reflect.TypeOf(RawValue{})
+ tRaw = reflect.TypeOf(Raw(nil))
+)
+
+// registerPrimitiveCodecs will register the encode and decode methods attached to PrimitiveCodecs
+// with the provided RegistryBuilder. if rb is nil, a new empty RegistryBuilder will be created.
+func registerPrimitiveCodecs(reg *Registry) {
+ reg.RegisterTypeEncoder(tRawValue, ValueEncoderFunc(rawValueEncodeValue))
+ reg.RegisterTypeEncoder(tRaw, ValueEncoderFunc(rawEncodeValue))
+ reg.RegisterTypeDecoder(tRawValue, ValueDecoderFunc(rawValueDecodeValue))
+ reg.RegisterTypeDecoder(tRaw, ValueDecoderFunc(rawDecodeValue))
+}
+
+// rawValueEncodeValue is the ValueEncoderFunc for RawValue.
+//
+// If the RawValue's Type is "invalid" and the RawValue's Value is not empty or
+// nil, then this method will return an error.
+func rawValueEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tRawValue {
+ return ValueEncoderError{
+ Name: "RawValueEncodeValue",
+ Types: []reflect.Type{tRawValue},
+ Received: val,
+ }
+ }
+
+ rawvalue := val.Interface().(RawValue)
+
+ if !rawvalue.Type.IsValid() {
+ return fmt.Errorf("the RawValue Type specifies an invalid BSON type: %#x", byte(rawvalue.Type))
+ }
+
+ return copyValueFromBytes(vw, rawvalue.Type, rawvalue.Value)
+}
+
+// rawValueDecodeValue is the ValueDecoderFunc for RawValue.
+func rawValueDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tRawValue {
+ return ValueDecoderError{Name: "RawValueDecodeValue", Types: []reflect.Type{tRawValue}, Received: val}
+ }
+
+ t, value, err := copyValueToBytes(vr)
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(RawValue{Type: t, Value: value}))
+ return nil
+}
+
+// rawEncodeValue is the ValueEncoderFunc for Reader.
+func rawEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tRaw {
+ return ValueEncoderError{Name: "RawEncodeValue", Types: []reflect.Type{tRaw}, Received: val}
+ }
+
+ rdr := val.Interface().(Raw)
+
+ return copyDocumentFromBytes(vw, rdr)
+}
+
+// rawDecodeValue is the ValueDecoderFunc for Reader.
+func rawDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tRaw {
+ return ValueDecoderError{Name: "RawDecodeValue", Types: []reflect.Type{tRaw}, Received: val}
+ }
+ vrType := vr.Type()
+ isDocument := vrType == Type(0) || vrType == TypeEmbeddedDocument || vrType == TypeArray
+ if !isDocument {
+ return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
+ }
+
+ if val.IsNil() {
+ val.Set(reflect.MakeSlice(val.Type(), 0, 0))
+ }
+
+ val.SetLen(0)
+
+ rdr, err := appendDocumentBytes(val.Interface().(Raw), vr)
+ val.Set(reflect.ValueOf(rdr))
+ return err
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/bson/raw.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/raw.go
index 130da61ba..1c49faee6 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw.go
@@ -10,7 +10,7 @@ import (
"errors"
"io"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// ErrNilReader indicates that an operation was attempted on a nil bson.Reader.
@@ -29,14 +29,6 @@ func ReadDocument(r io.Reader) (Raw, error) {
return Raw(doc), err
}
-// NewFromIOReader reads a BSON document from the io.Reader and returns it as a bson.Raw. If the
-// reader contains multiple BSON documents, only the first document is read.
-//
-// Deprecated: Use ReadDocument instead.
-func NewFromIOReader(r io.Reader) (Raw, error) {
- return ReadDocument(r)
-}
-
// Validate validates the document. This method only validates the first document in
// the slice, to validate other documents, the slice must be resliced.
func (r Raw) Validate() (err error) { return bsoncore.Document(r).Validate() }
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_array.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_array.go
new file mode 100644
index 000000000..1d2e9be7b
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_array.go
@@ -0,0 +1,73 @@
+// Copyright (C) MongoDB, Inc. 2024-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 bson
+
+import (
+ "io"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+// RawArray is a raw bytes representation of a BSON array.
+type RawArray []byte
+
+// ReadArray reads a BSON array from the io.Reader and returns it as a
+// bson.RawArray.
+func ReadArray(r io.Reader) (RawArray, error) {
+ doc, err := bsoncore.NewArrayFromReader(r)
+
+ return RawArray(doc), err
+}
+
+// Index searches for and retrieves the value at the given index. This method
+// will panic if the array is invalid or if the index is out of bounds.
+func (a RawArray) Index(index uint) RawValue {
+ return convertFromCoreValue(bsoncore.Array(a).Index(index))
+}
+
+// IndexErr searches for and retrieves the value at the given index.
+func (a RawArray) IndexErr(index uint) (RawValue, error) {
+ elem, err := bsoncore.Array(a).IndexErr(index)
+
+ return convertFromCoreValue(elem), err
+}
+
+// DebugString outputs a human readable version of Array. It will attempt to
+// stringify the valid components of the array even if the entire array is not
+// valid.
+func (a RawArray) DebugString() string {
+ return bsoncore.Array(a).DebugString()
+}
+
+// String outputs an ExtendedJSON version of Array. If the Array is not valid,
+// this method returns an empty string.
+func (a RawArray) String() string {
+ return bsoncore.Array(a).String()
+}
+
+// Values returns this array as a slice of values. The returned slice will
+// contain valid values. If the array is not valid, the values up to the invalid
+// point will be returned along with an error.
+func (a RawArray) Values() ([]RawValue, error) {
+ vals, err := bsoncore.Array(a).Values()
+ if err != nil {
+ return nil, err
+ }
+
+ rvals := make([]RawValue, 0, len(vals))
+ for _, val := range vals {
+ rvals = append(rvals, convertFromCoreValue(val))
+ }
+
+ return rvals, err
+}
+
+// Validate validates the array and ensures the elements contained within are
+// valid.
+func (a RawArray) Validate() error {
+ return bsoncore.Array(a).Validate()
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_element.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/bson/raw_element.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/raw_element.go
index 8ce13c2cc..75a00350e 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_element.go
@@ -7,7 +7,7 @@
package bson
import (
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// RawElement is a raw encoded BSON document or array element.
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_value.go
similarity index 81%
rename from vendor/go.mongodb.org/mongo-driver/bson/raw_value.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/raw_value.go
index a8088e1e3..6bcabd548 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/raw_value.go
@@ -13,11 +13,7 @@ import (
"reflect"
"time"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// ErrNilContext is returned when the provided DecodeContext is nil.
@@ -31,10 +27,10 @@ var ErrNilRegistry = errors.New("Registry cannot be nil")
//
// A RawValue must be an individual BSON value. Use the Raw type for full BSON documents.
type RawValue struct {
- Type bsontype.Type
+ Type Type
Value []byte
- r *bsoncodec.Registry
+ r *Registry
}
// IsZero reports whether the RawValue is zero, i.e. no data is present on
@@ -47,10 +43,10 @@ func (rv RawValue) IsZero() bool {
// error is returned. This method will use the registry used to create the RawValue, if the RawValue
// was created from partial BSON processing, or it will use the default registry. Users wishing to
// specify the registry to use should use UnmarshalWithRegistry.
-func (rv RawValue) Unmarshal(val interface{}) error {
+func (rv RawValue) Unmarshal(val any) error {
reg := rv.r
if reg == nil {
- reg = DefaultRegistry
+ reg = defaultRegistry
}
return rv.UnmarshalWithRegistry(reg, val)
}
@@ -70,12 +66,12 @@ func (rv RawValue) Equal(rv2 RawValue) bool {
// UnmarshalWithRegistry performs the same unmarshalling as Unmarshal but uses the provided registry
// instead of the one attached or the default registry.
-func (rv RawValue) UnmarshalWithRegistry(r *bsoncodec.Registry, val interface{}) error {
+func (rv RawValue) UnmarshalWithRegistry(r *Registry, val any) error {
if r == nil {
return ErrNilRegistry
}
- vr := bsonrw.NewBSONValueReader(rv.Type, rv.Value)
+ vr := newBufferedValueReader(rv.Type, rv.Value)
rval := reflect.ValueOf(val)
if rval.Kind() != reflect.Ptr {
return fmt.Errorf("argument to Unmarshal* must be a pointer to a type, but got %v", rval)
@@ -85,21 +81,17 @@ func (rv RawValue) UnmarshalWithRegistry(r *bsoncodec.Registry, val interface{})
if err != nil {
return err
}
- return dec.DecodeValue(bsoncodec.DecodeContext{Registry: r}, vr, rval)
+ return dec.DecodeValue(DecodeContext{Registry: r}, vr, rval)
}
-// UnmarshalWithContext performs the same unmarshalling as Unmarshal but uses
-// the provided DecodeContext instead of the one attached or the default
-// registry.
-//
-// Deprecated: Use [RawValue.UnmarshalWithRegistry] with a custom registry to customize
-// unmarshal behavior instead.
-func (rv RawValue) UnmarshalWithContext(dc *bsoncodec.DecodeContext, val interface{}) error {
+// UnmarshalWithContext performs the same unmarshalling as Unmarshal but uses the provided DecodeContext
+// instead of the one attached or the default registry.
+func (rv RawValue) UnmarshalWithContext(dc *DecodeContext, val any) error {
if dc == nil {
return ErrNilContext
}
- vr := bsonrw.NewBSONValueReader(rv.Type, rv.Value)
+ vr := newBufferedValueReader(rv.Type, rv.Value)
rval := reflect.ValueOf(val)
if rval.Kind() != reflect.Ptr {
return fmt.Errorf("argument to Unmarshal* must be a pointer to a type, but got %v", rval)
@@ -112,9 +104,12 @@ func (rv RawValue) UnmarshalWithContext(dc *bsoncodec.DecodeContext, val interfa
return dec.DecodeValue(*dc, vr, rval)
}
-func convertFromCoreValue(v bsoncore.Value) RawValue { return RawValue{Type: v.Type, Value: v.Data} }
+func convertFromCoreValue(v bsoncore.Value) RawValue {
+ return RawValue{Type: Type(v.Type), Value: v.Data}
+}
+
func convertToCoreValue(v RawValue) bsoncore.Value {
- return bsoncore.Value{Type: v.Type, Data: v.Value}
+ return bsoncore.Value{Type: bsoncore.Type(v.Type), Data: v.Value}
}
// Validate ensures the value is a valid BSON value.
@@ -132,14 +127,14 @@ func (rv RawValue) String() string { return convertToCoreValue(rv).String() }
func (rv RawValue) DebugString() string { return convertToCoreValue(rv).DebugString() }
// Double returns the float64 value for this element.
-// It panics if e's BSON type is not bsontype.Double.
+// It panics if e's BSON type is not bson.TypeDouble.
func (rv RawValue) Double() float64 { return convertToCoreValue(rv).Double() }
// DoubleOK is the same as Double, but returns a boolean instead of panicking.
func (rv RawValue) DoubleOK() (float64, bool) { return convertToCoreValue(rv).DoubleOK() }
// StringValue returns the string value for this element.
-// It panics if e's BSON type is not bsontype.String.
+// It panics if e's BSON type is not bson.TypeString.
//
// NOTE: This method is called StringValue to avoid a collision with the String method which
// implements the fmt.Stringer interface.
@@ -162,13 +157,14 @@ func (rv RawValue) DocumentOK() (Raw, bool) {
// Array returns the BSON array the Value represents as an Array. It panics if the
// value is a BSON type other than array.
-func (rv RawValue) Array() Raw { return Raw(convertToCoreValue(rv).Array()) }
+func (rv RawValue) Array() RawArray { return RawArray(convertToCoreValue(rv).Array()) }
// ArrayOK is the same as Array, except it returns a boolean instead
// of panicking.
-func (rv RawValue) ArrayOK() (Raw, bool) {
+func (rv RawValue) ArrayOK() (RawArray, bool) {
doc, ok := convertToCoreValue(rv).ArrayOK()
- return Raw(doc), ok
+
+ return RawArray(doc), ok
}
// Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
@@ -183,11 +179,11 @@ func (rv RawValue) BinaryOK() (subtype byte, data []byte, ok bool) {
// ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON
// type other than objectid.
-func (rv RawValue) ObjectID() primitive.ObjectID { return convertToCoreValue(rv).ObjectID() }
+func (rv RawValue) ObjectID() ObjectID { return convertToCoreValue(rv).ObjectID() }
// ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
// panicking.
-func (rv RawValue) ObjectIDOK() (primitive.ObjectID, bool) {
+func (rv RawValue) ObjectIDOK() (ObjectID, bool) {
return convertToCoreValue(rv).ObjectIDOK()
}
@@ -227,13 +223,13 @@ func (rv RawValue) RegexOK() (pattern, options string, ok bool) {
// DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON
// type other than DBPointer.
-func (rv RawValue) DBPointer() (string, primitive.ObjectID) {
+func (rv RawValue) DBPointer() (string, ObjectID) {
return convertToCoreValue(rv).DBPointer()
}
// DBPointerOK is the same as DBPoitner, except that it returns a boolean
// instead of panicking.
-func (rv RawValue) DBPointerOK() (string, primitive.ObjectID, bool) {
+func (rv RawValue) DBPointerOK() (string, ObjectID, bool) {
return convertToCoreValue(rv).DBPointerOK()
}
@@ -275,20 +271,6 @@ func (rv RawValue) Int32() int32 { return convertToCoreValue(rv).Int32() }
// panicking.
func (rv RawValue) Int32OK() (int32, bool) { return convertToCoreValue(rv).Int32OK() }
-// AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
-// will panic.
-//
-// Deprecated: Use AsInt64 instead. If an int32 is required, convert the returned value to an int32
-// and perform any required overflow/underflow checking.
-func (rv RawValue) AsInt32() int32 { return convertToCoreValue(rv).AsInt32() }
-
-// AsInt32OK is the same as AsInt32, except that it returns a boolean instead of
-// panicking.
-//
-// Deprecated: Use AsInt64OK instead. If an int32 is required, convert the returned value to an
-// int32 and perform any required overflow/underflow checking.
-func (rv RawValue) AsInt32OK() (int32, bool) { return convertToCoreValue(rv).AsInt32OK() }
-
// Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
// BSON type other than timestamp.
func (rv RawValue) Timestamp() (t, i uint32) { return convertToCoreValue(rv).Timestamp() }
@@ -313,12 +295,21 @@ func (rv RawValue) AsInt64() int64 { return convertToCoreValue(rv).AsInt64() }
// panicking.
func (rv RawValue) AsInt64OK() (int64, bool) { return convertToCoreValue(rv).AsInt64OK() }
+// AsFloat64 returns a BSON number as a float64. If the BSON type is not a numeric one, this method
+// will panic.
+func (rv RawValue) AsFloat64() float64 { return convertToCoreValue(rv).AsFloat64() }
+
+// AsFloat64OK is the same as AsFloat64, except that it returns a boolean instead of
+// panicking.
+func (rv RawValue) AsFloat64OK() (float64, bool) { return convertToCoreValue(rv).AsFloat64OK() }
+
// Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than
// decimal.
-func (rv RawValue) Decimal128() primitive.Decimal128 { return convertToCoreValue(rv).Decimal128() }
+func (rv RawValue) Decimal128() Decimal128 { return NewDecimal128(convertToCoreValue(rv).Decimal128()) }
// Decimal128OK is the same as Decimal128, except that it returns a boolean
// instead of panicking.
-func (rv RawValue) Decimal128OK() (primitive.Decimal128, bool) {
- return convertToCoreValue(rv).Decimal128OK()
+func (rv RawValue) Decimal128OK() (Decimal128, bool) {
+ h, l, ok := convertToCoreValue(rv).Decimal128OK()
+ return NewDecimal128(h, l), ok
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/reader.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/reader.go
index 324b10b61..955d2e9fd 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/reader.go
@@ -4,12 +4,7 @@
// 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 bsonrw
-
-import (
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
+package bson
// ArrayReader is implemented by types that allow reading values from a BSON
// array.
@@ -27,7 +22,7 @@ type DocumentReader interface {
// is implemented by several types with different underlying representations of
// BSON, such as a bson.Document, raw BSON bytes, or extended JSON.
type ValueReader interface {
- Type() bsontype.Type
+ Type() Type
Skip() error
ReadArray() (ArrayReader, error)
@@ -35,9 +30,9 @@ type ValueReader interface {
ReadBoolean() (bool, error)
ReadDocument() (DocumentReader, error)
ReadCodeWithScope() (code string, dr DocumentReader, err error)
- ReadDBPointer() (ns string, oid primitive.ObjectID, err error)
+ ReadDBPointer() (ns string, oid ObjectID, err error)
ReadDateTime() (int64, error)
- ReadDecimal128() (primitive.Decimal128, error)
+ ReadDecimal128() (Decimal128, error)
ReadDouble() (float64, error)
ReadInt32() (int32, error)
ReadInt64() (int64, error)
@@ -45,21 +40,10 @@ type ValueReader interface {
ReadMaxKey() error
ReadMinKey() error
ReadNull() error
- ReadObjectID() (primitive.ObjectID, error)
+ ReadObjectID() (ObjectID, error)
ReadRegex() (pattern, options string, err error)
ReadString() (string, error)
ReadSymbol() (symbol string, err error)
ReadTimestamp() (t, i uint32, err error)
ReadUndefined() error
}
-
-// BytesReader is a generic interface used to read BSON bytes from a
-// ValueReader. This imterface is meant to be a superset of ValueReader, so that
-// types that implement ValueReader may also implement this interface.
-//
-// The bytes of the value will be appended to dst.
-//
-// Deprecated: BytesReader will not be supported in Go Driver 2.0.
-type BytesReader interface {
- ReadValueBytes(dst []byte) (bsontype.Type, []byte, error)
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/registry.go
similarity index 54%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/registry.go
index 196c491bb..21057da4c 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/registry.go
@@ -4,237 +4,82 @@
// 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 bsoncodec
+package bson
import (
"errors"
"fmt"
"reflect"
"sync"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
-// ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder.
-//
-// Deprecated: ErrNilType will not be supported in Go Driver 2.0.
-var ErrNilType = errors.New("cannot perform a decoder lookup on ")
-
-// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
-//
-// Deprecated: ErrNotPointer will not be supported in Go Driver 2.0.
-var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
+// defaultRegistry is the default Registry. It contains the default codecs and the
+// primitive codecs.
+var defaultRegistry = NewRegistry()
-// ErrNoEncoder is returned when there wasn't an encoder available for a type.
-//
-// Deprecated: ErrNoEncoder will not be supported in Go Driver 2.0.
-type ErrNoEncoder struct {
+// errNoEncoder is returned when there wasn't an encoder available for a type.
+type errNoEncoder struct {
Type reflect.Type
}
-func (ene ErrNoEncoder) Error() string {
+func (ene errNoEncoder) Error() string {
if ene.Type == nil {
return "no encoder found for "
}
return "no encoder found for " + ene.Type.String()
}
-// ErrNoDecoder is returned when there wasn't a decoder available for a type.
-//
-// Deprecated: ErrNoDecoder will not be supported in Go Driver 2.0.
-type ErrNoDecoder struct {
+// errNoDecoder is returned when there wasn't a decoder available for a type.
+type errNoDecoder struct {
Type reflect.Type
}
-func (end ErrNoDecoder) Error() string {
+func (end errNoDecoder) Error() string {
return "no decoder found for " + end.Type.String()
}
-// ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
-//
-// Deprecated: ErrNoTypeMapEntry will not be supported in Go Driver 2.0.
-type ErrNoTypeMapEntry struct {
- Type bsontype.Type
+// errNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
+type errNoTypeMapEntry struct {
+ Type Type
}
-func (entme ErrNoTypeMapEntry) Error() string {
+func (entme errNoTypeMapEntry) Error() string {
return "no type map entry found for " + entme.Type.String()
}
-// ErrNotInterface is returned when the provided type is not an interface.
-//
-// Deprecated: ErrNotInterface will not be supported in Go Driver 2.0.
-var ErrNotInterface = errors.New("The provided type is not an interface")
-
-// A RegistryBuilder is used to build a Registry. This type is not goroutine
-// safe.
-//
-// Deprecated: Use Registry instead.
-type RegistryBuilder struct {
- registry *Registry
-}
-
-// NewRegistryBuilder creates a new empty RegistryBuilder.
-//
-// Deprecated: Use NewRegistry instead.
-func NewRegistryBuilder() *RegistryBuilder {
- return &RegistryBuilder{
- registry: NewRegistry(),
- }
-}
-
-// RegisterCodec will register the provided ValueCodec for the provided type.
-//
-// Deprecated: Use Registry.RegisterTypeEncoder and Registry.RegisterTypeDecoder instead.
-func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
- rb.RegisterTypeEncoder(t, codec)
- rb.RegisterTypeDecoder(t, codec)
- return rb
-}
-
-// RegisterTypeEncoder will register the provided ValueEncoder for the provided type.
+// A Registry is a store for ValueEncoders, ValueDecoders, and a type map. See the Registry type
+// documentation for examples of registering various custom encoders and decoders. A Registry can
+// have four main types of codecs:
//
-// The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered
-// for a pointer to that type.
+// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and
+// RegisterTypeDecoder methods. The registered codec will be invoked when encoding/decoding a value
+// whose type matches the registered type exactly.
+// If the registered type is an interface, the codec will be invoked when encoding or decoding
+// values whose type is the interface, but not for values with concrete types that implement the
+// interface.
//
-// If the given type is an interface, the encoder will be called when marshaling a type that is that interface. It
-// will not be called when marshaling a non-interface type that implements the interface.
+// 2. Interface encoders/decoders - These can be registered using the RegisterInterfaceEncoder and
+// RegisterInterfaceDecoder methods. These methods only accept interface types and the registered codecs
+// will be invoked when encoding or decoding values whose types implement the interface. An example
+// of an interface defined by the driver is bson.Marshaler. The driver will call the MarshalBSON method
+// for any value whose type implements bson.Marshaler, regardless of the value's concrete type.
//
-// Deprecated: Use Registry.RegisterTypeEncoder instead.
-func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
- rb.registry.RegisterTypeEncoder(t, enc)
- return rb
-}
-
-// RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when
-// marshaling a type if the type implements t or a pointer to the type implements t. If the provided type is not
-// an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
+// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type
+// associations are used when decoding into a bson.D/bson.M or a struct field of type any.
+// For example, by default, BSON int32 and int64 values decode as Go int32 and int64 instances,
+// respectively, when decoding into a bson.D. The following code would change the behavior so these
+// values decode as Go int instances instead:
//
-// Deprecated: Use Registry.RegisterInterfaceEncoder instead.
-func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
- rb.registry.RegisterInterfaceEncoder(t, enc)
- return rb
-}
-
-// RegisterTypeDecoder will register the provided ValueDecoder for the provided type.
+// intType := reflect.TypeOf(int(0))
+// registry.RegisterTypeMapEntry(bson.TypeInt32, intType).RegisterTypeMapEntry(bson.TypeInt64, intType)
//
-// The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered
-// for a pointer to that type.
-//
-// If the given type is an interface, the decoder will be called when unmarshaling into a type that is that interface.
-// It will not be called when unmarshaling into a non-interface type that implements the interface.
-//
-// Deprecated: Use Registry.RegisterTypeDecoder instead.
-func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
- rb.registry.RegisterTypeDecoder(t, dec)
- return rb
-}
-
-// RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when
-// unmarshaling into a type if the type implements t or a pointer to the type implements t. If the provided type is not
-// an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
-//
-// Deprecated: Use Registry.RegisterInterfaceDecoder instead.
-func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
- rb.registry.RegisterInterfaceDecoder(t, dec)
- return rb
-}
-
-// RegisterEncoder registers the provided type and encoder pair.
+// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and
+// RegisterDefaultDecoder methods. The registered codec will be invoked when encoding or decoding
+// values whose reflect.Kind matches the registered reflect.Kind as long as the value's type doesn't
+// match a registered type or interface encoder/decoder first. These methods should be used to change the
+// behavior for all values for a specific kind.
//
-// Deprecated: Use Registry.RegisterTypeEncoder or Registry.RegisterInterfaceEncoder instead.
-func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
- if t == tEmpty {
- rb.registry.RegisterTypeEncoder(t, enc)
- return rb
- }
- switch t.Kind() {
- case reflect.Interface:
- rb.registry.RegisterInterfaceEncoder(t, enc)
- default:
- rb.registry.RegisterTypeEncoder(t, enc)
- }
- return rb
-}
-
-// RegisterDecoder registers the provided type and decoder pair.
-//
-// Deprecated: Use Registry.RegisterTypeDecoder or Registry.RegisterInterfaceDecoder instead.
-func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
- if t == nil {
- rb.registry.RegisterTypeDecoder(t, dec)
- return rb
- }
- if t == tEmpty {
- rb.registry.RegisterTypeDecoder(t, dec)
- return rb
- }
- switch t.Kind() {
- case reflect.Interface:
- rb.registry.RegisterInterfaceDecoder(t, dec)
- default:
- rb.registry.RegisterTypeDecoder(t, dec)
- }
- return rb
-}
-
-// RegisterDefaultEncoder will register the provided ValueEncoder to the provided
-// kind.
-//
-// Deprecated: Use Registry.RegisterKindEncoder instead.
-func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
- rb.registry.RegisterKindEncoder(kind, enc)
- return rb
-}
-
-// RegisterDefaultDecoder will register the provided ValueDecoder to the
-// provided kind.
-//
-// Deprecated: Use Registry.RegisterKindDecoder instead.
-func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
- rb.registry.RegisterKindDecoder(kind, dec)
- return rb
-}
-
-// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
-// mapping is decoding situations where an empty interface is used and a default type needs to be
-// created and decoded into.
-//
-// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
-// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
-// to decode to bson.Raw, use the following code:
-//
-// rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
-//
-// Deprecated: Use Registry.RegisterTypeMapEntry instead.
-func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
- rb.registry.RegisterTypeMapEntry(bt, rt)
- return rb
-}
-
-// Build creates a Registry from the current state of this RegistryBuilder.
-//
-// Deprecated: Use NewRegistry instead.
-func (rb *RegistryBuilder) Build() *Registry {
- r := &Registry{
- interfaceEncoders: append([]interfaceValueEncoder(nil), rb.registry.interfaceEncoders...),
- interfaceDecoders: append([]interfaceValueDecoder(nil), rb.registry.interfaceDecoders...),
- typeEncoders: rb.registry.typeEncoders.Clone(),
- typeDecoders: rb.registry.typeDecoders.Clone(),
- kindEncoders: rb.registry.kindEncoders.Clone(),
- kindDecoders: rb.registry.kindDecoders.Clone(),
- }
- rb.registry.typeMap.Range(func(k, v interface{}) bool {
- if k != nil && v != nil {
- r.typeMap.Store(k, v)
- }
- return true
- })
- return r
-}
-
-// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
-// typed passed around and Encoders and Decoders are constructed from it.
+// Read [Registry.LookupDecoder] and [Registry.LookupEncoder] for Registry lookup procedure.
type Registry struct {
interfaceEncoders []interfaceValueEncoder
interfaceDecoders []interfaceValueDecoder
@@ -242,17 +87,21 @@ type Registry struct {
typeDecoders *typeDecoderCache
kindEncoders *kindEncoderCache
kindDecoders *kindDecoderCache
- typeMap sync.Map // map[bsontype.Type]reflect.Type
+ typeMap sync.Map // map[Type]reflect.Type
}
// NewRegistry creates a new empty Registry.
func NewRegistry() *Registry {
- return &Registry{
+ reg := &Registry{
typeEncoders: new(typeEncoderCache),
typeDecoders: new(typeDecoderCache),
kindEncoders: new(kindEncoderCache),
kindDecoders: new(kindDecoderCache),
}
+ registerDefaultEncoders(reg)
+ registerDefaultDecoders(reg)
+ registerPrimitiveCodecs(reg)
+ return reg
}
// RegisterTypeEncoder registers the provided ValueEncoder for the provided type.
@@ -365,12 +214,12 @@ func (r *Registry) RegisterInterfaceDecoder(iface reflect.Type, dec ValueDecoder
// mapping is decoding situations where an empty interface is used and a default type needs to be
// created and decoded into.
//
-// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
-// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
+// By default, BSON documents will decode into any values as bson.D. To change the default type for BSON
+// documents, a type map entry for TypeEmbeddedDocument should be registered. For example, to force BSON documents
// to decode to bson.Raw, use the following code:
//
-// reg.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
-func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) {
+// reg.RegisterTypeMapEntry(TypeEmbeddedDocument, reflect.TypeOf(bson.Raw{}))
+func (r *Registry) RegisterTypeMapEntry(bt Type, rt reflect.Type) {
r.typeMap.Store(bt, rt)
}
@@ -381,7 +230,11 @@ func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) {
// registered using RegisterTypeEncoder for that interface will be selected.
//
// 2. An encoder registered using RegisterInterfaceEncoder for an interface implemented by the type
-// or by a pointer to the type.
+// or by a pointer to the type. If the value matches multiple interfaces (e.g. the type implements
+// bson.Marshaler and bson.ValueMarshaler), the first one registered will be selected.
+// Note that registries constructed using bson.NewRegistry have driver-defined interfaces registered
+// for the bson.Marshaler, bson.ValueMarshaler, and bson.Proxy interfaces, so those will take
+// precedence over any new interfaces.
//
// 3. An encoder registered using RegisterKindEncoder for the kind of value.
//
@@ -389,12 +242,12 @@ func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) {
// concurrent use by multiple goroutines after all codecs and encoders are registered.
func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) {
if valueType == nil {
- return nil, ErrNoEncoder{Type: valueType}
+ return nil, errNoEncoder{Type: valueType}
}
enc, found := r.lookupTypeEncoder(valueType)
if found {
if enc == nil {
- return nil, ErrNoEncoder{Type: valueType}
+ return nil, errNoEncoder{Type: valueType}
}
return enc, nil
}
@@ -407,7 +260,7 @@ func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) {
if v, ok := r.kindEncoders.Load(valueType.Kind()); ok {
return r.storeTypeEncoder(valueType, v), nil
}
- return nil, ErrNoEncoder{Type: valueType}
+ return nil, errNoEncoder{Type: valueType}
}
func (r *Registry) storeTypeEncoder(rt reflect.Type, enc ValueEncoder) ValueEncoder {
@@ -446,7 +299,11 @@ func (r *Registry) lookupInterfaceEncoder(valueType reflect.Type, allowAddr bool
// registered using RegisterTypeDecoder for that interface will be selected.
//
// 2. A decoder registered using RegisterInterfaceDecoder for an interface implemented by the type or by
-// a pointer to the type.
+// a pointer to the type. If the value matches multiple interfaces (e.g. the type implements
+// bson.Unmarshaler and bson.ValueUnmarshaler), the first one registered will be selected.
+// Note that registries constructed using bson.NewRegistry have driver-defined interfaces registered
+// for the bson.Unmarshaler and bson.ValueUnmarshaler interfaces, so those will take
+// precedence over any new interfaces.
//
// 3. A decoder registered using RegisterKindDecoder for the kind of value.
//
@@ -454,12 +311,12 @@ func (r *Registry) lookupInterfaceEncoder(valueType reflect.Type, allowAddr bool
// concurrent use by multiple goroutines after all codecs and decoders are registered.
func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error) {
if valueType == nil {
- return nil, ErrNilType
+ return nil, errors.New("cannot perform a decoder lookup on ")
}
dec, found := r.lookupTypeDecoder(valueType)
if found {
if dec == nil {
- return nil, ErrNoDecoder{Type: valueType}
+ return nil, errNoDecoder{Type: valueType}
}
return dec, nil
}
@@ -472,7 +329,7 @@ func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error) {
if v, ok := r.kindDecoders.Load(valueType.Kind()); ok {
return r.storeTypeDecoder(valueType, v), nil
}
- return nil, ErrNoDecoder{Type: valueType}
+ return nil, errNoDecoder{Type: valueType}
}
func (r *Registry) lookupTypeDecoder(valueType reflect.Type) (ValueDecoder, bool) {
@@ -505,10 +362,10 @@ func (r *Registry) lookupInterfaceDecoder(valueType reflect.Type, allowAddr bool
// type. If no type is found, ErrNoTypeMapEntry is returned.
//
// LookupTypeMapEntry should not be called concurrently with any other Registry method.
-func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
+func (r *Registry) LookupTypeMapEntry(bt Type) (reflect.Type, error) {
v, ok := r.typeMap.Load(bt)
if v == nil || !ok {
- return nil, ErrNoTypeMapEntry{Type: bt}
+ return nil, errNoTypeMapEntry{Type: bt}
}
return v.(reflect.Type), nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/slice_codec.go
similarity index 56%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/slice_codec.go
index 14c9fd256..c8719dcc1 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/slice_codec.go
@@ -4,68 +4,28 @@
// 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 bsoncodec
+package bson
import (
"errors"
"fmt"
"reflect"
-
- "go.mongodb.org/mongo-driver/bson/bsonoptions"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
)
-var defaultSliceCodec = NewSliceCodec()
-
-// SliceCodec is the Codec used for slice values.
-//
-// Deprecated: SliceCodec will not be directly configurable in Go Driver 2.0. To
-// configure the slice encode and decode behavior, use the configuration methods
-// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
-// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the slice encode and
-// decode behavior for a mongo.Client, use
-// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
-//
-// For example, to configure a mongo.Client to marshal nil Go slices as empty
-// BSON arrays, use:
-//
-// opt := options.Client().SetBSONOptions(&options.BSONOptions{
-// NilSliceAsEmpty: true,
-// })
-//
-// See the deprecation notice for each field in SliceCodec for the corresponding
-// settings.
-type SliceCodec struct {
- // EncodeNilAsEmpty causes EncodeValue to marshal nil Go slices as empty BSON arrays instead of
+// sliceCodec is the Codec used for slice values.
+type sliceCodec struct {
+ // encodeNilAsEmpty causes EncodeValue to marshal nil Go slices as empty BSON arrays instead of
// BSON null.
- //
- // Deprecated: Use bson.Encoder.NilSliceAsEmpty instead.
- EncodeNilAsEmpty bool
-}
-
-// NewSliceCodec returns a MapCodec with options opts.
-//
-// Deprecated: NewSliceCodec will not be available in Go Driver 2.0. See
-// [SliceCodec] for more details.
-func NewSliceCodec(opts ...*bsonoptions.SliceCodecOptions) *SliceCodec {
- sliceOpt := bsonoptions.MergeSliceCodecOptions(opts...)
-
- codec := SliceCodec{}
- if sliceOpt.EncodeNilAsEmpty != nil {
- codec.EncodeNilAsEmpty = *sliceOpt.EncodeNilAsEmpty
- }
- return &codec
+ encodeNilAsEmpty bool
}
// EncodeValue is the ValueEncoder for slice types.
-func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (sc *sliceCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Kind() != reflect.Slice {
return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
}
- if val.IsNil() && !sc.EncodeNilAsEmpty && !ec.nilSliceAsEmpty {
+ if val.IsNil() && !sc.encodeNilAsEmpty && !ec.nilSliceAsEmpty {
return vw.WriteNull()
}
@@ -76,9 +36,9 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
return vw.WriteBinary(byteSlice)
}
- // If we have a []primitive.E we want to treat it as a document instead of as an array.
+ // If we have a []E we want to treat it as a document instead of as an array.
if val.Type() == tD || val.Type().ConvertibleTo(tD) {
- d := val.Convert(tD).Interface().(primitive.D)
+ d := val.Convert(tD).Interface().(D)
dw, err := vw.WriteDocument()
if err != nil {
@@ -107,7 +67,7 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
}
for idx := 0; idx < val.Len(); idx++ {
- currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.Index(idx))
+ currEncoder, currVal, lookupErr := lookupElementEncoder(ec, encoder, val.Index(idx))
if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
return lookupErr
}
@@ -134,24 +94,24 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
}
// DecodeValue is the ValueDecoder for slice types.
-func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (sc *sliceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Kind() != reflect.Slice {
return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
}
switch vrType := vr.Type(); vrType {
- case bsontype.Array:
- case bsontype.Null:
+ case TypeArray:
+ case TypeNull:
val.Set(reflect.Zero(val.Type()))
return vr.ReadNull()
- case bsontype.Undefined:
+ case TypeUndefined:
val.Set(reflect.Zero(val.Type()))
return vr.ReadUndefined()
- case bsontype.Type(0), bsontype.EmbeddedDocument:
+ case Type(0), TypeEmbeddedDocument:
if val.Type().Elem() != tE {
return fmt.Errorf("cannot decode document into %s", val.Type())
}
- case bsontype.Binary:
+ case TypeBinary:
if val.Type().Elem() != tByte {
return fmt.Errorf("SliceDecodeValue can only decode a binary into a byte array, got %v", vrType)
}
@@ -159,8 +119,8 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r
if err != nil {
return err
}
- if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
- return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
+ if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld {
+ return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", TypeBinary, subtype)
}
if val.IsNil() {
@@ -169,7 +129,7 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r
val.SetLen(0)
val.Set(reflect.AppendSlice(val, reflect.ValueOf(data)))
return nil
- case bsontype.String:
+ case TypeString:
if sliceType := val.Type().Elem(); sliceType != tByte {
return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", sliceType)
}
@@ -189,13 +149,12 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r
return fmt.Errorf("cannot decode %v into a slice", vrType)
}
- var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error)
+ var elemsFunc func(DecodeContext, ValueReader, reflect.Value) ([]reflect.Value, error)
switch val.Type().Elem() {
case tE:
- dc.Ancestor = val.Type()
- elemsFunc = defaultValueDecoders.decodeD
+ elemsFunc = decodeD
default:
- elemsFunc = defaultValueDecoders.decodeDefault
+ elemsFunc = decodeDefault
}
elems, err := elemsFunc(dc, vr, val)
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/streaming_byte_src.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/streaming_byte_src.go
new file mode 100644
index 000000000..f326dd243
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/streaming_byte_src.go
@@ -0,0 +1,132 @@
+// Copyright (C) MongoDB, Inc. 2025-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 bson
+
+import (
+ "bufio"
+ "io"
+)
+
+// streamingByteSrc reads from an ioReader wrapped in a bufio.Reader. It
+// first reads the BSON length header, then ensures it only ever reads exactly
+// that many bytes.
+//
+// Note: this approach trades memory usage for extra buffering and reader calls,
+// so it is less performanted than the in-memory bufferedValueReader.
+type streamingByteSrc struct {
+ br *bufio.Reader
+ offset int64 // offset is the current read position in the buffer
+}
+
+var _ byteSrc = (*streamingByteSrc)(nil)
+
+// Read reads up to len(p) bytes from the underlying bufio.Reader, advancing
+// the offset by the number of bytes read.
+func (s *streamingByteSrc) readExact(p []byte) (int, error) {
+ n, err := io.ReadFull(s.br, p)
+ if err == nil {
+ s.offset += int64(n)
+ }
+
+ return n, err
+}
+
+// ReadByte returns the single byte at buf[offset] and advances offset by 1.
+func (s *streamingByteSrc) ReadByte() (byte, error) {
+ c, err := s.br.ReadByte()
+ if err == nil {
+ s.offset++
+ }
+ return c, err
+}
+
+// peek returns buf[offset:offset+n] without advancing offset.
+func (s *streamingByteSrc) peek(n int) ([]byte, error) {
+ return s.br.Peek(n)
+}
+
+// discard advances offset by n bytes, returning the number of bytes discarded.
+func (s *streamingByteSrc) discard(n int) (int, error) {
+ m, err := s.br.Discard(n)
+ s.offset += int64(m)
+ return m, err
+}
+
+// readSlice reads until the first occurrence of delim, returning a slice
+// containing the data up to and including the delimiter, and advances offset
+// past it; errors if delim not found.
+func (s *streamingByteSrc) readSlice(delim byte) ([]byte, error) {
+ var full [][]byte
+ var frag []byte
+ var err error
+ var n int
+
+ for {
+ if l := len(frag); l > 0 {
+ // Make a copy of the fragment to accumulate full buffers.
+ buf := make([]byte, l)
+ copy(buf, frag)
+ full = append(full, buf)
+ }
+ frag, err = s.br.ReadSlice(delim)
+ n += len(frag)
+ if err != bufio.ErrBufferFull {
+ break
+ }
+ }
+ s.offset += int64(n)
+
+ // If ReadSlice is only called once, we can return the fragment directly.
+ if len(full) == 0 {
+ return frag, err
+ }
+
+ // Allocate new buffer to hold the full buffers and the fragment.
+ buf := make([]byte, n)
+ n = 0
+ for i := range full {
+ n += copy(buf[n:], full[i])
+ }
+ copy(buf[n:], frag)
+ return buf, err
+}
+
+// pos returns the current read position in the buffer.
+func (s *streamingByteSrc) pos() int64 {
+ return s.offset
+}
+
+// regexLength will return the total byte length of a BSON regex value.
+func (s *streamingByteSrc) regexLength() (int32, error) {
+ var (
+ count int32
+ nulCount int
+ )
+
+ for nulCount < 2 {
+ buf, err := s.br.Peek(int(count) + 1)
+ if err != nil {
+ return 0, err
+ }
+
+ b := buf[count]
+ count++
+ if b == 0x00 {
+ nulCount++
+ }
+ }
+
+ return count, nil
+}
+
+func (*streamingByteSrc) streamable() bool {
+ return true
+}
+
+func (s *streamingByteSrc) reset() {
+ s.offset = 0
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/string_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/string_codec.go
new file mode 100644
index 000000000..456028c1d
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/string_codec.go
@@ -0,0 +1,107 @@
+// 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 bson
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// stringCodec is the Codec used for string values.
+type stringCodec struct{}
+
+// Assert that stringCodec satisfies the typeDecoder interface, which allows it to be
+// used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+// collection.
+var _ typeDecoder = &stringCodec{}
+
+// EncodeValue is the ValueEncoder for string types.
+func (sc *stringCodec) EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if val.Kind() != reflect.String {
+ return ValueEncoderError{
+ Name: "StringEncodeValue",
+ Kinds: []reflect.Kind{reflect.String},
+ Received: val,
+ }
+ }
+
+ return vw.WriteString(val.String())
+}
+
+func (sc *stringCodec) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t.Kind() != reflect.String {
+ return emptyValue, ValueDecoderError{
+ Name: "StringDecodeValue",
+ Kinds: []reflect.Kind{reflect.String},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var str string
+ var err error
+ switch vr.Type() {
+ case TypeString:
+ str, err = vr.ReadString()
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeObjectID:
+ if dc.objectIDAsHexString {
+ oid, err := vr.ReadObjectID()
+ if err != nil {
+ return emptyValue, err
+ }
+ str = oid.Hex()
+ } else {
+ const msg = "decoding an object ID into a string is not supported by default " +
+ "(set Decoder.ObjectIDAsHexString to enable decoding as a hexadecimal string)"
+ return emptyValue, errors.New(msg)
+ }
+ case TypeSymbol:
+ str, err = vr.ReadSymbol()
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeBinary:
+ data, subtype, err := vr.ReadBinary()
+ if err != nil {
+ return emptyValue, err
+ }
+ if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld {
+ return emptyValue, decodeBinaryError{subtype: subtype, typeName: "string"}
+ }
+ str = string(data)
+ case TypeNull:
+ if err = vr.ReadNull(); err != nil {
+ return emptyValue, err
+ }
+ case TypeUndefined:
+ if err = vr.ReadUndefined(); err != nil {
+ return emptyValue, err
+ }
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a string type", vr.Type())
+ }
+
+ return reflect.ValueOf(str), nil
+}
+
+// DecodeValue is the ValueDecoder for string types.
+func (sc *stringCodec) DecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Kind() != reflect.String {
+ return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val}
+ }
+
+ elem, err := sc.decodeType(dctx, vr, val.Type())
+ if err != nil {
+ return err
+ }
+
+ val.SetString(elem.String())
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/struct_codec.go
similarity index 77%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/struct_codec.go
index f8d9690c1..83b63f5f6 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/struct_codec.go
@@ -4,7 +4,7 @@
// 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 bsoncodec
+package bson
import (
"errors"
@@ -14,10 +14,6 @@ import (
"strings"
"sync"
"time"
-
- "go.mongodb.org/mongo-driver/bson/bsonoptions"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
// DecodeError represents an error that occurs when unmarshalling BSON bytes into a native Go type.
@@ -51,108 +47,53 @@ func (de *DecodeError) Keys() []string {
return reversedKeys
}
-// Zeroer allows custom struct types to implement a report of zero
-// state. All struct types that don't implement Zeroer or where IsZero
-// returns false are considered to be not zero.
-type Zeroer interface {
- IsZero() bool
+// mapElementsEncoder handles encoding of the values of an inline map.
+type mapElementsEncoder interface {
+ encodeMapElements(EncodeContext, DocumentWriter, reflect.Value, func(string) bool) error
}
-// StructCodec is the Codec used for struct values.
-//
-// Deprecated: StructCodec will not be directly configurable in Go Driver 2.0.
-// To configure the struct encode and decode behavior, use the configuration
-// methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or
-// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the struct encode
-// and decode behavior for a mongo.Client, use
-// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
-//
-// For example, to configure a mongo.Client to omit zero-value structs when
-// using the "omitempty" struct tag, use:
-//
-// opt := options.Client().SetBSONOptions(&options.BSONOptions{
-// OmitZeroStruct: true,
-// })
-//
-// See the deprecation notice for each field in StructCodec for the corresponding
-// settings.
-type StructCodec struct {
- cache sync.Map // map[reflect.Type]*structDescription
- parser StructTagParser
+// structCodec is the Codec used for struct values.
+type structCodec struct {
+ cache sync.Map // map[reflect.Type]*structDescription
+ inlineMapEncoder mapElementsEncoder
- // DecodeZeroStruct causes DecodeValue to delete any existing values from Go structs in the
+ // decodeZeroStruct causes DecodeValue to delete any existing values from Go structs in the
// destination value passed to Decode before unmarshaling BSON documents into them.
- //
- // Deprecated: Use bson.Decoder.ZeroStructs or options.BSONOptions.ZeroStructs instead.
- DecodeZeroStruct bool
+ decodeZeroStruct bool
- // DecodeDeepZeroInline causes DecodeValue to delete any existing values from Go structs in the
+ // decodeDeepZeroInline causes DecodeValue to delete any existing values from Go structs in the
// destination value passed to Decode before unmarshaling BSON documents into them.
- //
- // Deprecated: DecodeDeepZeroInline will not be supported in Go Driver 2.0.
- DecodeDeepZeroInline bool
+ decodeDeepZeroInline bool
- // EncodeOmitDefaultStruct causes the Encoder to consider the zero value for a struct (e.g.
+ // encodeOmitDefaultStruct causes the Encoder to consider the zero value for a struct (e.g.
// MyStruct{}) as empty and omit it from the marshaled BSON when the "omitempty" struct tag
// option is set.
- //
- // Deprecated: Use bson.Encoder.OmitZeroStruct or options.BSONOptions.OmitZeroStruct instead.
- EncodeOmitDefaultStruct bool
+ encodeOmitDefaultStruct bool
- // AllowUnexportedFields allows encoding and decoding values from un-exported struct fields.
- //
- // Deprecated: AllowUnexportedFields does not work on recent versions of Go and will not be
- // supported in Go Driver 2.0.
- AllowUnexportedFields bool
+ // allowUnexportedFields allows encoding and decoding values from un-exported struct fields.
+ allowUnexportedFields bool
- // OverwriteDuplicatedInlinedFields, if false, causes EncodeValue to return an error if there is
+ // overwriteDuplicatedInlinedFields, if false, causes EncodeValue to return an error if there is
// a duplicate field in the marshaled BSON when the "inline" struct tag option is set. The
// default value is true.
- //
- // Deprecated: Use bson.Encoder.ErrorOnInlineDuplicates or
- // options.BSONOptions.ErrorOnInlineDuplicates instead.
- OverwriteDuplicatedInlinedFields bool
+ overwriteDuplicatedInlinedFields bool
}
-var _ ValueEncoder = &StructCodec{}
-var _ ValueDecoder = &StructCodec{}
-
-// NewStructCodec returns a StructCodec that uses p for struct tag parsing.
-//
-// Deprecated: NewStructCodec will not be available in Go Driver 2.0. See
-// [StructCodec] for more details.
-func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) (*StructCodec, error) {
- if p == nil {
- return nil, errors.New("a StructTagParser must be provided to NewStructCodec")
- }
-
- structOpt := bsonoptions.MergeStructCodecOptions(opts...)
-
- codec := &StructCodec{
- parser: p,
- }
+var (
+ _ ValueEncoder = &structCodec{}
+ _ ValueDecoder = &structCodec{}
+)
- if structOpt.DecodeZeroStruct != nil {
- codec.DecodeZeroStruct = *structOpt.DecodeZeroStruct
- }
- if structOpt.DecodeDeepZeroInline != nil {
- codec.DecodeDeepZeroInline = *structOpt.DecodeDeepZeroInline
- }
- if structOpt.EncodeOmitDefaultStruct != nil {
- codec.EncodeOmitDefaultStruct = *structOpt.EncodeOmitDefaultStruct
- }
- if structOpt.OverwriteDuplicatedInlinedFields != nil {
- codec.OverwriteDuplicatedInlinedFields = *structOpt.OverwriteDuplicatedInlinedFields
+// newStructCodec returns a StructCodec that uses p for struct tag parsing.
+func newStructCodec(elemEncoder mapElementsEncoder) *structCodec {
+ return &structCodec{
+ inlineMapEncoder: elemEncoder,
+ overwriteDuplicatedInlinedFields: true,
}
- if structOpt.AllowUnexportedFields != nil {
- codec.AllowUnexportedFields = *structOpt.AllowUnexportedFields
- }
-
- return codec, nil
}
// EncodeValue handles encoding generic struct types.
-func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (sc *structCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Kind() != reflect.Struct {
return ValueEncoderError{Name: "StructCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
}
@@ -177,7 +118,11 @@ func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
}
}
- desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(ec, desc.encoder, rv)
+ if ec.omitEmpty {
+ desc.omitEmpty = true
+ }
+
+ desc.encoder, rv, err = lookupElementEncoder(ec, desc.encoder, rv)
if err != nil && !errors.Is(err, errInvalidValue) {
return err
@@ -199,20 +144,18 @@ func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
}
if desc.encoder == nil {
- return ErrNoEncoder{Type: rv.Type()}
+ return errNoEncoder{Type: rv.Type()}
}
encoder := desc.encoder
var empty bool
- if cz, ok := encoder.(CodecZeroer); ok {
- empty = cz.IsTypeZero(rv.Interface())
- } else if rv.Kind() == reflect.Interface {
+ if rv.Kind() == reflect.Interface {
// isEmpty will not treat an interface rv as an interface, so we need to check for the
// nil interface separately.
empty = rv.IsNil()
} else {
- empty = isEmpty(rv, sc.EncodeOmitDefaultStruct || ec.omitZeroStruct)
+ empty = isEmpty(rv, sc.encodeOmitDefaultStruct || ec.omitZeroStruct)
}
if desc.omitEmpty && empty {
continue
@@ -225,7 +168,7 @@ func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
ectx := EncodeContext{
Registry: ec.Registry,
- MinSize: desc.minSize || ec.MinSize,
+ minSize: desc.minSize || ec.minSize,
errorOnInlineDuplicates: ec.errorOnInlineDuplicates,
stringifyMapKeysWithFmt: ec.stringifyMapKeysWithFmt,
nilMapAsEmpty: ec.nilMapAsEmpty,
@@ -247,7 +190,10 @@ func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
return exists
}
- return defaultMapCodec.mapEncodeValue(ec, dw, rv, collisionFn)
+ err = sc.inlineMapEncoder.encodeMapElements(ec, dw, rv, collisionFn)
+ if err != nil {
+ return err
+ }
}
return dw.WriteDocumentEnd()
@@ -269,21 +215,21 @@ func newDecodeError(key string, original error) error {
// DecodeValue implements the Codec interface.
// By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr.
// For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared.
-func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (sc *structCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Kind() != reflect.Struct {
return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
}
switch vrType := vr.Type(); vrType {
- case bsontype.Type(0), bsontype.EmbeddedDocument:
- case bsontype.Null:
+ case Type(0), TypeEmbeddedDocument:
+ case TypeNull:
if err := vr.ReadNull(); err != nil {
return err
}
val.Set(reflect.Zero(val.Type()))
return nil
- case bsontype.Undefined:
+ case TypeUndefined:
if err := vr.ReadUndefined(); err != nil {
return err
}
@@ -299,10 +245,10 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
return err
}
- if sc.DecodeZeroStruct || dc.zeroStructs {
+ if sc.decodeZeroStruct || dc.zeroStructs {
val.Set(reflect.Zero(val.Type()))
}
- if sc.DecodeDeepZeroInline && sd.inline {
+ if sc.decodeDeepZeroInline && sd.inline {
val.Set(deepZero(val.Type()))
}
@@ -323,7 +269,7 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
for {
name, vr, err := dr.ReadElement()
- if errors.Is(err, bsonrw.ErrEOD) {
+ if errors.Is(err, ErrEOD) {
break
}
if err != nil {
@@ -354,7 +300,6 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
}
elem := reflect.New(inlineMap.Type().Elem()).Elem()
- dc.Ancestor = inlineMap.Type()
err = decoder.DecodeValue(dc, vr, elem)
if err != nil {
return err
@@ -373,6 +318,19 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
}
}
+ if field.Kind() == reflect.Interface && !field.IsNil() && field.Elem().Kind() == reflect.Ptr {
+ v := field.Elem().Elem()
+ decoder, err = dc.LookupDecoder(v.Type())
+ if err != nil {
+ return err
+ }
+ err = decoder.DecodeValue(dc, vr, v)
+ if err != nil {
+ return newDecodeError(fd.name, err)
+ }
+ continue
+ }
+
if !field.CanSet() { // Being settable is a super set of being addressable.
innerErr := fmt.Errorf("field %v is not settable", field)
return newDecodeError(fd.name, innerErr)
@@ -384,9 +342,10 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
dctx := DecodeContext{
Registry: dc.Registry,
- Truncate: fd.truncate || dc.Truncate,
+ truncate: fd.truncate || dc.truncate,
defaultDocumentType: dc.defaultDocumentType,
binaryAsSlice: dc.binaryAsSlice,
+ objectIDAsHexString: dc.objectIDAsHexString,
useJSONStructTags: dc.useJSONStructTags,
useLocalTimeZone: dc.useLocalTimeZone,
zeroMaps: dc.zeroMaps,
@@ -394,7 +353,7 @@ func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
}
if fd.decoder == nil {
- return newDecodeError(fd.name, ErrNoDecoder{Type: field.Elem().Type()})
+ return newDecodeError(fd.name, errNoDecoder{Type: field.Elem().Type()})
}
err = fd.decoder.DecodeValue(dctx, vr, field.Elem())
@@ -485,7 +444,7 @@ func (bi byIndex) Less(i, j int) bool {
return len(bi[i].inline) < len(bi[j].inline)
}
-func (sc *StructCodec) describeStruct(
+func (sc *structCodec) describeStruct(
r *Registry,
t reflect.Type,
useJSONStructTags bool,
@@ -508,7 +467,7 @@ func (sc *StructCodec) describeStruct(
return ds, nil
}
-func (sc *StructCodec) describeStructSlow(
+func (sc *structCodec) describeStructSlow(
r *Registry,
t reflect.Type,
useJSONStructTags bool,
@@ -524,7 +483,7 @@ func (sc *StructCodec) describeStructSlow(
var fields []fieldDescription
for i := 0; i < numFields; i++ {
sf := t.Field(i)
- if sf.PkgPath != "" && (!sc.AllowUnexportedFields || !sf.Anonymous) {
+ if sf.PkgPath != "" && (!sc.allowUnexportedFields || !sf.Anonymous) {
// field is private or unexported fields aren't allowed, ignore
continue
}
@@ -546,13 +505,13 @@ func (sc *StructCodec) describeStructSlow(
decoder: decoder,
}
- var stags StructTags
+ var stags *structTags
// If the caller requested that we use JSON struct tags, use the JSONFallbackStructTagParser
// instead of the parser defined on the codec.
if useJSONStructTags {
- stags, err = JSONFallbackStructTagParser.ParseStructTags(sf)
+ stags, err = parseJSONStructTags(sf)
} else {
- stags, err = sc.parser.ParseStructTags(sf)
+ stags, err = parseStructTags(sf)
}
if err != nil {
return nil, err
@@ -635,7 +594,7 @@ func (sc *StructCodec) describeStructSlow(
continue
}
dominant, ok := dominantField(fields[i : i+advance])
- if !ok || !sc.OverwriteDuplicatedInlinedFields || errorOnDuplicates {
+ if !ok || !sc.overwriteDuplicatedInlinedFields || errorOnDuplicates {
return nil, fmt.Errorf("struct %s has duplicated key %s", t.String(), name)
}
sd.fl = append(sd.fl, dominant)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/struct_tag_parser.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/struct_tag_parser.go
index 18d85bfb0..47955639b 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/struct_tag_parser.go
@@ -4,32 +4,14 @@
// 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 bsoncodec
+package bson
import (
"reflect"
"strings"
)
-// StructTagParser returns the struct tags for a given struct field.
-//
-// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
-type StructTagParser interface {
- ParseStructTags(reflect.StructField) (StructTags, error)
-}
-
-// StructTagParserFunc is an adapter that allows a generic function to be used
-// as a StructTagParser.
-//
-// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
-type StructTagParserFunc func(reflect.StructField) (StructTags, error)
-
-// ParseStructTags implements the StructTagParser interface.
-func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructTags, error) {
- return stpf(sf)
-}
-
-// StructTags represents the struct tag fields that the StructCodec uses during
+// structTags represents the struct tag fields that the StructCodec uses during
// the encoding and decoding process.
//
// In the case of a struct, the lowercased field name is used as the key for each exported
@@ -53,9 +35,7 @@ func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructT
//
// Skip This struct field should be skipped. This is usually denoted by parsing a "-"
// for the name.
-//
-// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
-type StructTags struct {
+type structTags struct {
Name string
OmitEmpty bool
MinSize bool
@@ -89,22 +69,36 @@ type StructTags struct {
// A struct tag either consisting entirely of '-' or with a bson key with a
// value consisting entirely of '-' will return a StructTags with Skip true and
// the remaining fields will be their default values.
-//
-// Deprecated: DefaultStructTagParser will be removed in Go Driver 2.0.
-var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
+func parseStructTags(sf reflect.StructField) (*structTags, error) {
+ key := strings.ToLower(sf.Name)
+ tag, ok := sf.Tag.Lookup("bson")
+ if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
+ tag = string(sf.Tag)
+ }
+ return parseTags(key, tag)
+}
+
+// jsonStructTagParser has the same behavior as DefaultStructTagParser
+// but will also fallback to parsing the json tag instead on a field where the
+// bson tag isn't available.
+func parseJSONStructTags(sf reflect.StructField) (*structTags, error) {
key := strings.ToLower(sf.Name)
tag, ok := sf.Tag.Lookup("bson")
+ if !ok {
+ tag, ok = sf.Tag.Lookup("json")
+ }
if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
tag = string(sf.Tag)
}
+
return parseTags(key, tag)
}
-func parseTags(key string, tag string) (StructTags, error) {
- var st StructTags
+func parseTags(key string, tag string) (*structTags, error) {
+ var st structTags
if tag == "-" {
st.Skip = true
- return st, nil
+ return &st, nil
}
for idx, str := range strings.Split(tag, ",") {
@@ -125,24 +119,5 @@ func parseTags(key string, tag string) (StructTags, error) {
st.Name = key
- return st, nil
-}
-
-// JSONFallbackStructTagParser has the same behavior as DefaultStructTagParser
-// but will also fallback to parsing the json tag instead on a field where the
-// bson tag isn't available.
-//
-// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] and
-// [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead.
-var JSONFallbackStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
- key := strings.ToLower(sf.Name)
- tag, ok := sf.Tag.Lookup("bson")
- if !ok {
- tag, ok = sf.Tag.Lookup("json")
- }
- if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
- tag = string(sf.Tag)
- }
-
- return parseTags(key, tag)
+ return &st, nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/time_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/time_codec.go
new file mode 100644
index 000000000..7577fb2b9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/time_codec.go
@@ -0,0 +1,109 @@
+// 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 bson
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+)
+
+const (
+ timeFormatString = "2006-01-02T15:04:05.999Z07:00"
+)
+
+// timeCodec is the Codec used for time.Time values.
+type timeCodec struct {
+ // useLocalTimeZone specifies if we should decode into the local time zone. Defaults to false.
+ useLocalTimeZone bool
+}
+
+// Assert that timeCodec satisfies the typeDecoder interface, which allows it to be used
+// by collection type decoders (e.g. map, slice, etc) to set individual values in a collection.
+var _ typeDecoder = &timeCodec{}
+
+func (tc *timeCodec) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
+ if t != tTime {
+ return emptyValue, ValueDecoderError{
+ Name: "TimeDecodeValue",
+ Types: []reflect.Type{tTime},
+ Received: reflect.Zero(t),
+ }
+ }
+
+ var timeVal time.Time
+ switch vrType := vr.Type(); vrType {
+ case TypeDateTime:
+ dt, err := vr.ReadDateTime()
+ if err != nil {
+ return emptyValue, err
+ }
+ timeVal = time.Unix(dt/1000, dt%1000*1000000)
+ case TypeString:
+ // assume strings are in the isoTimeFormat
+ timeStr, err := vr.ReadString()
+ if err != nil {
+ return emptyValue, err
+ }
+ timeVal, err = time.Parse(timeFormatString, timeStr)
+ if err != nil {
+ return emptyValue, err
+ }
+ case TypeInt64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return emptyValue, err
+ }
+ timeVal = time.Unix(i64/1000, i64%1000*1000000)
+ case TypeTimestamp:
+ t, _, err := vr.ReadTimestamp()
+ if err != nil {
+ return emptyValue, err
+ }
+ timeVal = time.Unix(int64(t), 0)
+ case TypeNull:
+ if err := vr.ReadNull(); err != nil {
+ return emptyValue, err
+ }
+ case TypeUndefined:
+ if err := vr.ReadUndefined(); err != nil {
+ return emptyValue, err
+ }
+ default:
+ return emptyValue, fmt.Errorf("cannot decode %v into a time.Time", vrType)
+ }
+
+ if !tc.useLocalTimeZone && !dc.useLocalTimeZone {
+ timeVal = timeVal.UTC()
+ }
+ return reflect.ValueOf(timeVal), nil
+}
+
+// DecodeValue is the ValueDecoderFunc for time.Time.
+func (tc *timeCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tTime {
+ return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val}
+ }
+
+ elem, err := tc.decodeType(dc, vr, tTime)
+ if err != nil {
+ return err
+ }
+
+ val.Set(elem)
+ return nil
+}
+
+// EncodeValue is the ValueEncoderFunc for time.Time.
+func (tc *timeCodec) EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
+ if !val.IsValid() || val.Type() != tTime {
+ return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
+ }
+ tt := val.Interface().(time.Time)
+ dt := NewDateTimeFromTime(tt)
+ return vw.WriteDateTime(int64(dt))
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/types.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/types.go
new file mode 100644
index 000000000..cb3af848b
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/types.go
@@ -0,0 +1,128 @@
+// 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 bson
+
+import (
+ "encoding/json"
+ "net/url"
+ "reflect"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+// Type represents a BSON type.
+type Type byte
+
+// String returns the string representation of the BSON type's name.
+func (bt Type) String() string {
+ return bsoncore.Type(bt).String()
+}
+
+// IsValid will return true if the Type is valid.
+func (bt Type) IsValid() bool {
+ switch bt {
+ case TypeDouble, TypeString, TypeEmbeddedDocument, TypeArray, TypeBinary,
+ TypeUndefined, TypeObjectID, TypeBoolean, TypeDateTime, TypeNull, TypeRegex,
+ TypeDBPointer, TypeJavaScript, TypeSymbol, TypeCodeWithScope, TypeInt32,
+ TypeTimestamp, TypeInt64, TypeDecimal128, TypeMinKey, TypeMaxKey:
+ return true
+ default:
+ return false
+ }
+}
+
+// BSON element types as described in https://bsonspec.org/spec.html.
+const (
+ TypeDouble Type = 0x01
+ TypeString Type = 0x02
+ TypeEmbeddedDocument Type = 0x03
+ TypeArray Type = 0x04
+ TypeBinary Type = 0x05
+ TypeUndefined Type = 0x06
+ TypeObjectID Type = 0x07
+ TypeBoolean Type = 0x08
+ TypeDateTime Type = 0x09
+ TypeNull Type = 0x0A
+ TypeRegex Type = 0x0B
+ TypeDBPointer Type = 0x0C
+ TypeJavaScript Type = 0x0D
+ TypeSymbol Type = 0x0E
+ TypeCodeWithScope Type = 0x0F
+ TypeInt32 Type = 0x10
+ TypeTimestamp Type = 0x11
+ TypeInt64 Type = 0x12
+ TypeDecimal128 Type = 0x13
+ TypeMaxKey Type = 0x7F
+ TypeMinKey Type = 0xFF
+)
+
+// BSON binary element subtypes as described in https://bsonspec.org/spec.html.
+const (
+ TypeBinaryGeneric byte = 0x00
+ TypeBinaryFunction byte = 0x01
+ TypeBinaryBinaryOld byte = 0x02
+ TypeBinaryUUIDOld byte = 0x03
+ TypeBinaryUUID byte = 0x04
+ TypeBinaryMD5 byte = 0x05
+ TypeBinaryEncrypted byte = 0x06
+ TypeBinaryColumn byte = 0x07
+ TypeBinarySensitive byte = 0x08
+ TypeBinaryVector byte = 0x09
+ TypeBinaryUserDefined byte = 0x80
+)
+
+var (
+ tBool = reflect.TypeOf(false)
+ tFloat64 = reflect.TypeOf(float64(0))
+ tInt32 = reflect.TypeOf(int32(0))
+ tInt64 = reflect.TypeOf(int64(0))
+ tString = reflect.TypeOf("")
+ tTime = reflect.TypeOf(time.Time{})
+)
+
+var (
+ tEmpty = reflect.TypeOf((*any)(nil)).Elem()
+ tByteSlice = reflect.TypeOf([]byte(nil))
+ tByte = reflect.TypeOf(byte(0x00))
+ tURL = reflect.TypeOf(url.URL{})
+ tJSONNumber = reflect.TypeOf(json.Number(""))
+)
+
+var (
+ tValueMarshaler = reflect.TypeOf((*ValueMarshaler)(nil)).Elem()
+ tValueUnmarshaler = reflect.TypeOf((*ValueUnmarshaler)(nil)).Elem()
+ tMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem()
+ tUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+ tZeroer = reflect.TypeOf((*Zeroer)(nil)).Elem()
+)
+
+var (
+ tBinary = reflect.TypeOf(Binary{})
+ tUndefined = reflect.TypeOf(Undefined{})
+ tOID = reflect.TypeOf(ObjectID{})
+ tDateTime = reflect.TypeOf(DateTime(0))
+ tNull = reflect.TypeOf(Null{})
+ tRegex = reflect.TypeOf(Regex{})
+ tCodeWithScope = reflect.TypeOf(CodeWithScope{})
+ tDBPointer = reflect.TypeOf(DBPointer{})
+ tJavaScript = reflect.TypeOf(JavaScript(""))
+ tSymbol = reflect.TypeOf(Symbol(""))
+ tTimestamp = reflect.TypeOf(Timestamp{})
+ tDecimal = reflect.TypeOf(Decimal128{})
+ tVector = reflect.TypeOf(Vector{})
+ tMinKey = reflect.TypeOf(MinKey{})
+ tMaxKey = reflect.TypeOf(MaxKey{})
+ tD = reflect.TypeOf(D{})
+ tA = reflect.TypeOf(A{})
+ tE = reflect.TypeOf(E{})
+)
+
+var (
+ tCoreDocument = reflect.TypeOf(bsoncore.Document{})
+ tCoreArray = reflect.TypeOf(bsoncore.Array{})
+)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/uint_codec.go
similarity index 59%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/uint_codec.go
index 39b07135b..0cdcc635d 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/uint_codec.go
@@ -4,68 +4,27 @@
// 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 bsoncodec
+package bson
import (
"fmt"
"math"
"reflect"
-
- "go.mongodb.org/mongo-driver/bson/bsonoptions"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
)
-// UIntCodec is the Codec used for uint values.
-//
-// Deprecated: UIntCodec will not be directly configurable in Go Driver 2.0. To
-// configure the uint encode and decode behavior, use the configuration methods
-// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
-// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the uint encode and
-// decode behavior for a mongo.Client, use
-// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
-//
-// For example, to configure a mongo.Client to marshal Go uint values as the
-// minimum BSON int size that can represent the value, use:
-//
-// opt := options.Client().SetBSONOptions(&options.BSONOptions{
-// IntMinSize: true,
-// })
-//
-// See the deprecation notice for each field in UIntCodec for the corresponding
-// settings.
-type UIntCodec struct {
- // EncodeToMinSize causes EncodeValue to marshal Go uint values (excluding uint64) as the
+// uintCodec is the Codec used for uint values.
+type uintCodec struct {
+ // encodeToMinSize causes EncodeValue to marshal Go uint values (excluding uint64) as the
// minimum BSON int size (either 32-bit or 64-bit) that can represent the integer value.
- //
- // Deprecated: Use bson.Encoder.IntMinSize or options.BSONOptions.IntMinSize instead.
- EncodeToMinSize bool
+ encodeToMinSize bool
}
-var (
- defaultUIntCodec = NewUIntCodec()
-
- // Assert that defaultUIntCodec satisfies the typeDecoder interface, which allows it to be used
- // by collection type decoders (e.g. map, slice, etc) to set individual values in a collection.
- _ typeDecoder = defaultUIntCodec
-)
-
-// NewUIntCodec returns a UIntCodec with options opts.
-//
-// Deprecated: NewUIntCodec will not be available in Go Driver 2.0. See
-// [UIntCodec] for more details.
-func NewUIntCodec(opts ...*bsonoptions.UIntCodecOptions) *UIntCodec {
- uintOpt := bsonoptions.MergeUIntCodecOptions(opts...)
-
- codec := UIntCodec{}
- if uintOpt.EncodeToMinSize != nil {
- codec.EncodeToMinSize = *uintOpt.EncodeToMinSize
- }
- return &codec
-}
+// Assert that uintCodec satisfies the typeDecoder interface, which allows it to be used
+// by collection type decoders (e.g. map, slice, etc) to set individual values in a collection.
+var _ typeDecoder = &uintCodec{}
// EncodeValue is the ValueEncoder for uint types.
-func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (uic *uintCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
switch val.Kind() {
case reflect.Uint8, reflect.Uint16:
return vw.WriteInt32(int32(val.Uint()))
@@ -73,7 +32,7 @@ func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val r
u64 := val.Uint()
// If ec.MinSize or if encodeToMinSize is true for a non-uint64 value we should write val as an int32
- useMinSize := ec.MinSize || (uic.EncodeToMinSize && val.Kind() != reflect.Uint64)
+ useMinSize := ec.minSize || (uic.encodeToMinSize && val.Kind() != reflect.Uint64)
if u64 <= math.MaxInt32 && useMinSize {
return vw.WriteInt32(int32(u64))
@@ -91,34 +50,34 @@ func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val r
}
}
-func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (uic *uintCodec) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
var i64 int64
var err error
switch vrType := vr.Type(); vrType {
- case bsontype.Int32:
+ case TypeInt32:
i32, err := vr.ReadInt32()
if err != nil {
return emptyValue, err
}
i64 = int64(i32)
- case bsontype.Int64:
+ case TypeInt64:
i64, err = vr.ReadInt64()
if err != nil {
return emptyValue, err
}
- case bsontype.Double:
+ case TypeDouble:
f64, err := vr.ReadDouble()
if err != nil {
return emptyValue, err
}
- if !dc.Truncate && math.Floor(f64) != f64 {
+ if !dc.truncate && math.Floor(f64) != f64 {
return emptyValue, errCannotTruncate
}
if f64 > float64(math.MaxInt64) {
return emptyValue, fmt.Errorf("%g overflows int64", f64)
}
i64 = int64(f64)
- case bsontype.Boolean:
+ case TypeBoolean:
b, err := vr.ReadBoolean()
if err != nil {
return emptyValue, err
@@ -126,11 +85,11 @@ func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t refl
if b {
i64 = 1
}
- case bsontype.Null:
+ case TypeNull:
if err = vr.ReadNull(); err != nil {
return emptyValue, err
}
- case bsontype.Undefined:
+ case TypeUndefined:
if err = vr.ReadUndefined(); err != nil {
return emptyValue, err
}
@@ -183,7 +142,7 @@ func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t refl
}
// DecodeValue is the ValueDecoder for uint types.
-func (uic *UIntCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (uic *uintCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
if !val.CanSet() {
return ValueDecoderError{
Name: "UintDecodeValue",
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/unmarshal.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/unmarshal.go
new file mode 100644
index 000000000..4377c4e42
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/unmarshal.go
@@ -0,0 +1,90 @@
+// 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 bson
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Unmarshaler is the interface implemented by types that can unmarshal a BSON
+// document representation of themselves. The input can be assumed to be a valid
+// encoding of a BSON document. UnmarshalBSON must copy the JSON data if it
+// wishes to retain the data after returning.
+//
+// Unmarshaler is only used to unmarshal full BSON documents. To create custom
+// BSON unmarshaling behavior for individual values in a BSON document,
+// implement the ValueUnmarshaler interface instead.
+type Unmarshaler interface {
+ UnmarshalBSON([]byte) error
+}
+
+// ValueUnmarshaler is the interface implemented by types that can unmarshal a
+// BSON value representation of themselves. The input can be assumed to be a
+// valid encoding of a BSON value. UnmarshalBSONValue must copy the BSON value
+// bytes if it wishes to retain the data after returning.
+//
+// ValueUnmarshaler is only used to unmarshal individual values in a BSON
+// document. To create custom BSON unmarshaling behavior for an entire BSON
+// document, implement the Unmarshaler interface instead.
+type ValueUnmarshaler interface {
+ UnmarshalBSONValue(typ byte, data []byte) error
+}
+
+// Unmarshal parses the BSON-encoded data and stores the result in the value
+// pointed to by val. If val is nil or not a pointer, Unmarshal returns an
+// error.
+//
+// When unmarshaling BSON, if the BSON value is null and the Go value is a
+// pointer, the pointer is set to nil without calling UnmarshalBSONValue.
+func Unmarshal(data []byte, val any) error {
+ vr := getBufferedDocumentReader(data)
+ defer putBufferedDocumentReader(vr)
+
+ if l, err := vr.peekLength(); err != nil {
+ return err
+ } else if int(l) != len(data) {
+ return fmt.Errorf("invalid document length")
+ }
+ return unmarshalFromReader(DecodeContext{Registry: defaultRegistry}, vr, val)
+}
+
+// UnmarshalValue parses the BSON value of type t with bson.NewRegistry() and
+// stores the result in the value pointed to by val. If val is nil or not a pointer,
+// UnmarshalValue returns an error.
+func UnmarshalValue(t Type, data []byte, val any) error {
+ vr := newBufferedValueReader(t, data)
+ return unmarshalFromReader(DecodeContext{Registry: defaultRegistry}, vr, val)
+}
+
+// UnmarshalExtJSON parses the extended JSON-encoded data and stores the result
+// in the value pointed to by val. If val is nil or not a pointer, UnmarshalExtJSON
+// returns an error.
+//
+// If canonicalOnly is true, UnmarshalExtJSON returns an error if the Extended
+// JSON was not marshaled in canonical mode.
+//
+// For more information about Extended JSON, see
+// https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/
+func UnmarshalExtJSON(data []byte, canonicalOnly bool, val any) error {
+ ejvr, err := NewExtJSONValueReader(bytes.NewReader(data), canonicalOnly)
+ if err != nil {
+ return err
+ }
+
+ return unmarshalFromReader(DecodeContext{Registry: defaultRegistry}, ejvr, val)
+}
+
+func unmarshalFromReader(dc DecodeContext, vr ValueReader, val any) error {
+ dec := decPool.Get().(*Decoder)
+ defer decPool.Put(dec)
+
+ dec.Reset(vr)
+ dec.dc = dc
+
+ return dec.Decode(val)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/value_reader.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/value_reader.go
new file mode 100644
index 000000000..e5bcc1985
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/value_reader.go
@@ -0,0 +1,960 @@
+// 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 bson
+
+import (
+ "bufio"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "sync"
+)
+
+type byteSrc interface {
+ io.ByteReader
+
+ readExact(p []byte) (int, error)
+
+ // Peek returns the next n bytes without advancing the cursor. It must return
+ // exactly n bytes or n error if fewer are available.
+ peek(n int) ([]byte, error)
+
+ // discard advanced the cursor by n bytes, returning the actual number
+ // discarded or an error if fewer were available.
+ discard(n int) (int, error)
+
+ // readSlice reads until (and including) the first occurrence of delim,
+ // returning the entire slice [start...delimiter] and advancing the cursor.
+ // past it. Returns an error if delim is not found.
+ readSlice(delim byte) ([]byte, error)
+
+ // pos returns the number of bytes consumed so far.
+ pos() int64
+
+ // regexLength returns the total byte length of a BSON regex value (two
+ // C-strings including their terminating NULs) in buffered mode.
+ regexLength() (int32, error)
+
+ // streamable returns true if this source can be used in a streaming context.
+ streamable() bool
+
+ // reset resets the source to its initial state.
+ reset()
+}
+
+var _ ValueReader = &valueReader{}
+
+// ErrEOA is the error returned when the end of a BSON array has been reached.
+var ErrEOA = errors.New("end of array")
+
+// ErrEOD is the error returned when the end of a BSON document has been reached.
+var ErrEOD = errors.New("end of document")
+
+type vrState struct {
+ mode mode
+ vType Type
+ end int64
+}
+
+var vrPool = sync.Pool{
+ New: func() any {
+ return &valueReader{
+ stack: make([]vrState, 1, 5),
+ }
+ },
+}
+
+// valueReader is for reading BSON values.
+type valueReader struct {
+ src byteSrc
+ offset int64
+
+ stack []vrState
+ frame int64
+}
+
+func getBufferedDocumentReader(b []byte) *valueReader {
+ return newBufferedDocumentReader(b)
+}
+
+func putBufferedDocumentReader(vr *valueReader) {
+ if vr == nil {
+ return
+ }
+
+ vr.src.reset()
+
+ // Reset src and stack to avoid holding onto memory.
+ vr.src = nil
+ vr.frame = 0
+ vr.stack = vr.stack[:0]
+
+ vrPool.Put(vr)
+}
+
+// NewDocumentReader returns a ValueReader using b for the underlying BSON
+// representation.
+func NewDocumentReader(r io.Reader) ValueReader {
+ stack := make([]vrState, 1, 5)
+ stack[0] = vrState{
+ mode: mTopLevel,
+ }
+
+ return &valueReader{
+ src: &streamingByteSrc{br: bufio.NewReader(r), offset: 0},
+ stack: stack,
+ }
+}
+
+// newBufferedValueReader returns a ValueReader that starts in the Value mode
+// instead of in top level document mode. This enables the creation of a
+// ValueReader for a single BSON value.
+func newBufferedValueReader(t Type, b []byte) ValueReader {
+ bVR := newBufferedDocumentReader(b)
+
+ bVR.stack[0].vType = t
+ bVR.stack[0].mode = mValue
+
+ return bVR
+}
+
+func newBufferedDocumentReader(b []byte) *valueReader {
+ vr := vrPool.Get().(*valueReader)
+
+ vr.src = &bufferedByteSrc{
+ buf: b,
+ offset: 0,
+ }
+
+ // Reset parse state.
+ vr.frame = 0
+ if cap(vr.stack) < 1 {
+ vr.stack = make([]vrState, 1, 5)
+ } else {
+ vr.stack = vr.stack[:1]
+ }
+
+ vr.stack[0] = vrState{
+ mode: mTopLevel,
+ end: int64(len(b)),
+ }
+
+ return vr
+}
+
+func (vr *valueReader) advanceFrame() {
+ if vr.frame+1 >= int64(len(vr.stack)) { // We need to grow the stack
+ length := len(vr.stack)
+ if length+1 >= cap(vr.stack) {
+ // double it
+ buf := make([]vrState, 2*cap(vr.stack)+1)
+ copy(buf, vr.stack)
+ vr.stack = buf
+ }
+ vr.stack = vr.stack[:length+1]
+ }
+ vr.frame++
+
+ // Clean the stack
+ vr.stack[vr.frame].mode = 0
+ vr.stack[vr.frame].vType = 0
+ vr.stack[vr.frame].end = 0
+}
+
+func (vr *valueReader) pop() error {
+ var cnt int
+ switch vr.stack[vr.frame].mode {
+ case mElement, mValue:
+ cnt = 1
+ case mDocument, mArray, mCodeWithScope:
+ cnt = 2 // we pop twice to jump over the vrElement: vrDocument -> vrElement -> vrDocument/TopLevel/etc...
+ }
+ for i := 0; i < cnt && vr.frame > 0; i++ {
+ if vr.src.pos() < vr.stack[vr.frame].end {
+ _, err := vr.src.discard(int(vr.stack[vr.frame].end - vr.src.pos()))
+ if err != nil {
+ return err
+ }
+ }
+ vr.frame--
+ }
+
+ if vr.src.streamable() {
+ if vr.frame == 0 {
+ if vr.stack[0].end > vr.src.pos() {
+ vr.stack[0].end -= vr.src.pos()
+ } else {
+ vr.stack[0].end = 0
+ }
+
+ vr.src.reset()
+ }
+ }
+
+ return nil
+}
+
+func (vr *valueReader) invalidTransitionErr(destination mode, name string, modes []mode) error {
+ te := TransitionError{
+ name: name,
+ current: vr.stack[vr.frame].mode,
+ destination: destination,
+ modes: modes,
+ action: "read",
+ }
+ if vr.frame != 0 {
+ te.parent = vr.stack[vr.frame-1].mode
+ }
+ return te
+}
+
+func (vr *valueReader) typeError(t Type) error {
+ return fmt.Errorf("positioned on %s, but attempted to read %s", vr.stack[vr.frame].vType, t)
+}
+
+func (vr *valueReader) invalidDocumentLengthError() error {
+ return fmt.Errorf("document is invalid, end byte is at %d, but null byte found at %d", vr.stack[vr.frame].end, vr.offset)
+}
+
+func (vr *valueReader) ensureElementValue(t Type, destination mode, callerName string) error {
+ switch vr.stack[vr.frame].mode {
+ case mElement, mValue:
+ if vr.stack[vr.frame].vType != t {
+ return vr.typeError(t)
+ }
+ default:
+ return vr.invalidTransitionErr(destination, callerName, []mode{mElement, mValue})
+ }
+
+ return nil
+}
+
+func (vr *valueReader) Type() Type {
+ return vr.stack[vr.frame].vType
+}
+
+// peekNextValueSize returns the length of the next value in the stream without
+// offsetting the reader position.
+func peekNextValueSize(vr *valueReader) (int32, error) {
+ var length int32
+ var err error
+ switch vr.stack[vr.frame].vType {
+ case TypeArray, TypeEmbeddedDocument, TypeCodeWithScope:
+ length, err = vr.peekLength()
+ case TypeBinary:
+ length, err = vr.peekLength()
+ length += 4 + 1 // binary length + subtype byte
+ case TypeBoolean:
+ length = 1
+ case TypeDBPointer:
+ length, err = vr.peekLength()
+ length += 4 + 12 // string length + ObjectID length
+ case TypeDateTime, TypeDouble, TypeInt64, TypeTimestamp:
+ length = 8
+ case TypeDecimal128:
+ length = 16
+ case TypeInt32:
+ length = 4
+ case TypeJavaScript, TypeString, TypeSymbol:
+ length, err = vr.peekLength()
+ length += 4
+ case TypeMaxKey, TypeMinKey, TypeNull, TypeUndefined:
+ length = 0
+ case TypeObjectID:
+ length = 12
+ case TypeRegex:
+ length, err = vr.src.regexLength()
+ default:
+ return 0, fmt.Errorf("attempted to read bytes of unknown BSON type %v", vr.stack[vr.frame].vType)
+ }
+
+ return length, err
+}
+
+// readBytes tries to grab the next n bytes zero-allocation using peek+discard.
+// If peek fails (e.g. bufio buffer full), it falls back to io.ReadFull.
+func readBytes(src byteSrc, n int) ([]byte, error) {
+ if src.streamable() {
+ data := make([]byte, n)
+ if _, err := src.readExact(data); err != nil {
+ return nil, err
+ }
+
+ return data, nil
+ }
+
+ // Zero-allocation path.
+ buf, err := src.peek(n)
+ if err != nil {
+ return nil, err
+ }
+
+ _, _ = src.discard(n) // Discard the bytes from the source.
+ return buf, nil
+}
+
+// readBytesValueReader returns a subslice [offset, offset+length) or EOF.
+func (vr *valueReader) readBytes(n int32) ([]byte, error) {
+ if n < 0 {
+ return nil, fmt.Errorf("invalid length: %d", n)
+ }
+
+ return readBytes(vr.src, int(n))
+}
+
+//nolint:unparam
+func (vr *valueReader) readValueBytes(dst []byte) (Type, []byte, error) {
+ switch vr.stack[vr.frame].mode {
+ case mTopLevel:
+ length, err := vr.peekLength()
+ if err != nil {
+ return 0, nil, err
+ }
+ b, err := vr.readBytes(length)
+ return Type(0), append(dst, b...), err
+ case mElement, mValue:
+ t := vr.stack[vr.frame].vType
+
+ length, err := peekNextValueSize(vr)
+ if err != nil {
+ return t, dst, err
+ }
+
+ b, err := vr.readBytes(length)
+
+ if err := vr.pop(); err != nil {
+ return Type(0), nil, err
+ }
+
+ return t, append(dst, b...), err
+
+ default:
+ return Type(0), nil, vr.invalidTransitionErr(0, "readValueBytes", []mode{mElement, mValue})
+ }
+}
+
+func (vr *valueReader) Skip() error {
+ switch vr.stack[vr.frame].mode {
+ case mElement, mValue:
+ default:
+ return vr.invalidTransitionErr(0, "Skip", []mode{mElement, mValue})
+ }
+
+ length, err := peekNextValueSize(vr)
+ if err != nil {
+ return err
+ }
+
+ _, err = vr.src.discard(int(length))
+ if err != nil {
+ return err
+ }
+
+ return vr.pop()
+}
+
+// ReadArray returns an ArrayReader for the next BSON array in the valueReader
+// source, advancing the reader position to the end of the array.
+func (vr *valueReader) ReadArray() (ArrayReader, error) {
+ if err := vr.ensureElementValue(TypeArray, mArray, "ReadArray"); err != nil {
+ return nil, err
+ }
+
+ // Push a new frame for the array.
+ vr.advanceFrame()
+
+ // Read the 4-byte length.
+ size, err := vr.readLength()
+ if err != nil {
+ return nil, err
+ }
+
+ // Compute the end position: current position + total size - length.
+ vr.stack[vr.frame].mode = mArray
+ vr.stack[vr.frame].end = vr.src.pos() + int64(size) - 4
+
+ return vr, nil
+}
+
+// ReadBinary reads a BSON binary value, returning the byte slice and the
+// type of the binary data (0x02 for old binary, 0x00 for new binary, etc.),
+// advancing the reader position to the end of the binary value.
+func (vr *valueReader) ReadBinary() ([]byte, byte, error) {
+ if err := vr.ensureElementValue(TypeBinary, 0, "ReadBinary"); err != nil {
+ return nil, 0, err
+ }
+
+ length, err := vr.readLength()
+ if err != nil {
+ return nil, 0, err
+ }
+
+ btype, err := vr.readByte()
+ if err != nil {
+ return nil, 0, err
+ }
+
+ // Check length in case it is an old binary without a length.
+ if btype == 0x02 && length > 4 {
+ length, err = vr.readLength()
+ if err != nil {
+ return nil, 0, err
+ }
+ }
+
+ b, err := vr.readBytes(length)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ // copy so user doesn’t share underlying buffer
+ cp := make([]byte, len(b))
+ copy(cp, b)
+
+ if err := vr.pop(); err != nil {
+ return nil, 0, err
+ }
+
+ return cp, btype, nil
+}
+
+// ReadBoolean reads a BSON boolean value, returning true or false, advancing
+// the reader position to the end of the boolean value.
+func (vr *valueReader) ReadBoolean() (bool, error) {
+ if err := vr.ensureElementValue(TypeBoolean, 0, "ReadBoolean"); err != nil {
+ return false, err
+ }
+
+ b, err := vr.readByte()
+ if err != nil {
+ return false, err
+ }
+
+ if b > 1 {
+ return false, fmt.Errorf("invalid byte for boolean, %b", b)
+ }
+
+ if err := vr.pop(); err != nil {
+ return false, err
+ }
+ return b == 1, nil
+}
+
+// ReadDocument reads a BSON embedded document, returning a DocumentReader,
+// advancing the reader position to the end of the document.
+func (vr *valueReader) ReadDocument() (DocumentReader, error) {
+ switch vr.stack[vr.frame].mode {
+ case mTopLevel:
+ length, err := vr.readLength()
+ if err != nil {
+ return nil, err
+ }
+ if length <= 4 {
+ return nil, fmt.Errorf("invalid string length: %d", length)
+ }
+
+ vr.stack[vr.frame].end = int64(length) + vr.src.pos() - 4
+ return vr, nil
+ case mElement, mValue:
+ if vr.stack[vr.frame].vType != TypeEmbeddedDocument {
+ return nil, vr.typeError(TypeEmbeddedDocument)
+ }
+ default:
+ return nil, vr.invalidTransitionErr(mDocument, "ReadDocument", []mode{mTopLevel, mElement, mValue})
+ }
+
+ vr.advanceFrame()
+
+ size, err := vr.readLength()
+ if err != nil {
+ return nil, err
+ }
+
+ vr.stack[vr.frame].mode = mDocument
+ vr.stack[vr.frame].end = int64(size) + vr.src.pos() - 4
+
+ return vr, nil
+}
+
+// ReadCodeWithScope reads a BSON CodeWithScope value, returning the code as a
+// string, advancing the reader position to the end of the CodeWithScope value.
+func (vr *valueReader) ReadCodeWithScope() (string, DocumentReader, error) {
+ if err := vr.ensureElementValue(TypeCodeWithScope, 0, "ReadCodeWithScope"); err != nil {
+ return "", nil, err
+ }
+
+ totalLength, err := vr.readLength()
+ if err != nil {
+ return "", nil, err
+ }
+ strLength, err := vr.readLength()
+ if err != nil {
+ return "", nil, err
+ }
+ if strLength <= 0 {
+ return "", nil, fmt.Errorf("invalid string length: %d", strLength)
+ }
+ buf, err := vr.readBytes(strLength)
+ if err != nil {
+ return "", nil, err
+ }
+
+ code := string(buf[:len(buf)-1])
+ vr.advanceFrame()
+
+ // Use readLength to ensure that we are not out of bounds.
+ size, err := vr.readLength()
+ if err != nil {
+ return "", nil, err
+ }
+
+ vr.stack[vr.frame].mode = mCodeWithScope
+ vr.stack[vr.frame].end = vr.src.pos() + int64(size) - 4
+
+ // The total length should equal:
+ // 4 (total length) + strLength + 4 (the length of str itself) + (document length)
+ componentsLength := int64(4+strLength+4) + int64(size)
+ if int64(totalLength) != componentsLength {
+ return "", nil, fmt.Errorf(
+ "length of CodeWithScope does not match lengths of components; total: %d; components: %d",
+ totalLength, componentsLength,
+ )
+ }
+ return code, vr, nil
+}
+
+// ReadDBPointer reads a BSON DBPointer value, returning the namespace, the
+// object ID, and an error if any, advancing the reader position to the end of
+// the DBPointer value.
+func (vr *valueReader) ReadDBPointer() (string, ObjectID, error) {
+ if err := vr.ensureElementValue(TypeDBPointer, 0, "ReadDBPointer"); err != nil {
+ return "", ObjectID{}, err
+ }
+ ns, err := vr.readString()
+ if err != nil {
+ return "", ObjectID{}, err
+ }
+
+ oidBytes, err := vr.readBytes(12)
+ if err != nil {
+ return "", ObjectID{}, err
+ }
+
+ var oid ObjectID
+ copy(oid[:], oidBytes)
+
+ if err := vr.pop(); err != nil {
+ return "", ObjectID{}, err
+ }
+ return ns, oid, nil
+}
+
+// ReadDateTime reads a BSON DateTime value, advancing the reader position to
+// the end of the DateTime value.
+func (vr *valueReader) ReadDateTime() (int64, error) {
+ if err := vr.ensureElementValue(TypeDateTime, 0, "ReadDateTime"); err != nil {
+ return 0, err
+ }
+
+ i, err := vr.readi64()
+ if err != nil {
+ return 0, err
+ }
+
+ if err := vr.pop(); err != nil {
+ return 0, err
+ }
+ return i, nil
+}
+
+// ReadDecimal128 reads a BSON Decimal128 value, advancing the reader
+// to the end of the Decimal128 value.
+func (vr *valueReader) ReadDecimal128() (Decimal128, error) {
+ if err := vr.ensureElementValue(TypeDecimal128, 0, "ReadDecimal128"); err != nil {
+ return Decimal128{}, err
+ }
+ b, err := vr.readBytes(16)
+ if err != nil {
+ return Decimal128{}, err
+ }
+ l := binary.LittleEndian.Uint64(b[0:8])
+ h := binary.LittleEndian.Uint64(b[8:16])
+
+ if err := vr.pop(); err != nil {
+ return Decimal128{}, err
+ }
+ return NewDecimal128(h, l), nil
+}
+
+// ReadDouble reads a BSON double value, advancing the reader position to
+// to the end of the double value.
+func (vr *valueReader) ReadDouble() (float64, error) {
+ if err := vr.ensureElementValue(TypeDouble, 0, "ReadDouble"); err != nil {
+ return 0, err
+ }
+
+ u, err := vr.readu64()
+ if err != nil {
+ return 0, err
+ }
+
+ if err := vr.pop(); err != nil {
+ return 0, err
+ }
+ return math.Float64frombits(u), nil
+}
+
+// ReadInt32 reads a BSON int32 value, advancing the reader position to the end
+// of the int32 value.
+func (vr *valueReader) ReadInt32() (int32, error) {
+ if err := vr.ensureElementValue(TypeInt32, 0, "ReadInt32"); err != nil {
+ return 0, err
+ }
+ i, err := vr.readi32()
+ if err != nil {
+ return 0, err
+ }
+
+ if err := vr.pop(); err != nil {
+ return 0, err
+ }
+ return i, nil
+}
+
+// ReadInt64 reads a BSON int64 value, advancing the reader position to the end
+// of the int64 value.
+func (vr *valueReader) ReadInt64() (int64, error) {
+ if err := vr.ensureElementValue(TypeInt64, 0, "ReadInt64"); err != nil {
+ return 0, err
+ }
+ i, err := vr.readi64()
+ if err != nil {
+ return 0, err
+ }
+
+ if err := vr.pop(); err != nil {
+ return 0, err
+ }
+ return i, nil
+}
+
+// ReadJavascript reads a BSON JavaScript value, advancing the reader
+// to the end of the JavaScript value.
+func (vr *valueReader) ReadJavascript() (string, error) {
+ if err := vr.ensureElementValue(TypeJavaScript, 0, "ReadJavascript"); err != nil {
+ return "", err
+ }
+ s, err := vr.readString()
+ if err != nil {
+ return "", err
+ }
+
+ if err := vr.pop(); err != nil {
+ return "", err
+ }
+ return s, nil
+}
+
+// ReadMaxKey reads a BSON MaxKey value, advancing the reader position to the
+// end of the MaxKey value.
+func (vr *valueReader) ReadMaxKey() error {
+ if err := vr.ensureElementValue(TypeMaxKey, 0, "ReadMaxKey"); err != nil {
+ return err
+ }
+
+ return vr.pop()
+}
+
+// ReadMinKey reads a BSON MinKey value, advancing the reader position to the
+// end of the MinKey value.
+func (vr *valueReader) ReadMinKey() error {
+ if err := vr.ensureElementValue(TypeMinKey, 0, "ReadMinKey"); err != nil {
+ return err
+ }
+
+ return vr.pop()
+}
+
+// REadNull reads a BSON Null value, advancing the reader position to the
+// end of the Null value.
+func (vr *valueReader) ReadNull() error {
+ if err := vr.ensureElementValue(TypeNull, 0, "ReadNull"); err != nil {
+ return err
+ }
+
+ return vr.pop()
+}
+
+// ReadObjectID reads a BSON ObjectID value, advancing the reader to the end of
+// the ObjectID value.
+func (vr *valueReader) ReadObjectID() (ObjectID, error) {
+ if err := vr.ensureElementValue(TypeObjectID, 0, "ReadObjectID"); err != nil {
+ return ObjectID{}, err
+ }
+
+ oidBytes, err := vr.readBytes(12)
+ if err != nil {
+ return ObjectID{}, err
+ }
+
+ var oid ObjectID
+ copy(oid[:], oidBytes)
+
+ if err := vr.pop(); err != nil {
+ return ObjectID{}, err
+ }
+ return oid, nil
+}
+
+// ReadRegex reads a BSON Regex value, advancing the reader position to the
+// regex value.
+func (vr *valueReader) ReadRegex() (string, string, error) {
+ if err := vr.ensureElementValue(TypeRegex, 0, "ReadRegex"); err != nil {
+ return "", "", err
+ }
+
+ pattern, err := vr.readCString()
+ if err != nil {
+ return "", "", err
+ }
+
+ options, err := vr.readCString()
+ if err != nil {
+ return "", "", err
+ }
+
+ if err := vr.pop(); err != nil {
+ return "", "", err
+ }
+ return pattern, options, nil
+}
+
+// ReadString reads a BSON String value, advancing the reader position to the
+// end of the String value.
+func (vr *valueReader) ReadString() (string, error) {
+ if err := vr.ensureElementValue(TypeString, 0, "ReadString"); err != nil {
+ return "", err
+ }
+ s, err := vr.readString()
+ if err != nil {
+ return "", err
+ }
+
+ if err := vr.pop(); err != nil {
+ return "", err
+ }
+ return s, nil
+}
+
+// ReadSymbol reads a BSON Symbol value, advancing the reader position to the
+// end of the Symbol value.
+func (vr *valueReader) ReadSymbol() (string, error) {
+ if err := vr.ensureElementValue(TypeSymbol, 0, "ReadSymbol"); err != nil {
+ return "", err
+ }
+ s, err := vr.readString()
+ if err != nil {
+ return "", err
+ }
+ if err := vr.pop(); err != nil {
+ return "", err
+ }
+ return s, nil
+}
+
+// ReadTimestamp reads a BSON Timestamp value, advancing the reader to the end
+// of the Timestamp value.
+func (vr *valueReader) ReadTimestamp() (uint32, uint32, error) {
+ if err := vr.ensureElementValue(TypeTimestamp, 0, "ReadTimestamp"); err != nil {
+ return 0, 0, err
+ }
+
+ i, err := vr.readu32()
+ if err != nil {
+ return 0, 0, err
+ }
+
+ t, err := vr.readu32()
+ if err != nil {
+ return 0, 0, err
+ }
+
+ if err := vr.pop(); err != nil {
+ return 0, 0, err
+ }
+ return t, i, nil
+}
+
+// ReadUndefined reads a BSON Undefined value, advancing the reader position
+// to the end of the Undefined value.
+func (vr *valueReader) ReadUndefined() error {
+ if err := vr.ensureElementValue(TypeUndefined, 0, "ReadUndefined"); err != nil {
+ return err
+ }
+
+ return vr.pop()
+}
+
+// ReadElement reads the next element in the BSON document, advancing the
+// reader position to the end of the element.
+func (vr *valueReader) ReadElement() (string, ValueReader, error) {
+ switch vr.stack[vr.frame].mode {
+ case mTopLevel, mDocument, mCodeWithScope:
+ default:
+ return "", nil, vr.invalidTransitionErr(mElement, "ReadElement", []mode{mTopLevel, mDocument, mCodeWithScope})
+ }
+
+ t, err := vr.readByte()
+ if err != nil {
+ return "", nil, err
+ }
+
+ if t == 0 {
+ if vr.src.pos() != vr.stack[vr.frame].end {
+ return "", nil, vr.invalidDocumentLengthError()
+ }
+
+ _ = vr.pop() // Ignore the error because the call here never reads from the underlying reader.
+ return "", nil, ErrEOD
+ }
+
+ name, err := vr.readCString()
+ if err != nil {
+ return "", nil, err
+ }
+
+ vr.advanceFrame()
+
+ vr.stack[vr.frame].mode = mElement
+ vr.stack[vr.frame].vType = Type(t)
+ return name, vr, nil
+}
+
+// ReadValue reads the next value in the BSON array, advancing the to the end of
+// the value.
+func (vr *valueReader) ReadValue() (ValueReader, error) {
+ switch vr.stack[vr.frame].mode {
+ case mArray:
+ default:
+ return nil, vr.invalidTransitionErr(mValue, "ReadValue", []mode{mArray})
+ }
+
+ t, err := vr.readByte()
+ if err != nil {
+ return nil, err
+ }
+
+ if t == 0 {
+ if vr.src.pos() != vr.stack[vr.frame].end {
+ return nil, vr.invalidDocumentLengthError()
+ }
+
+ _ = vr.pop() // Ignore the error because the call here never reads from the underlying reader.
+ return nil, ErrEOA
+ }
+
+ _, err = vr.src.readSlice(0x00)
+ if err != nil {
+ return nil, err
+ }
+
+ vr.advanceFrame()
+
+ vr.stack[vr.frame].mode = mValue
+ vr.stack[vr.frame].vType = Type(t)
+ return vr, nil
+}
+
+func (vr *valueReader) readByte() (byte, error) {
+ b, err := vr.src.ReadByte()
+ if err != nil {
+ return 0x0, err
+ }
+ return b, nil
+}
+
+func (vr *valueReader) readCString() (string, error) {
+ data, err := vr.src.readSlice(0x00)
+ if err != nil {
+ return "", err
+ }
+ return string(data[:len(data)-1]), nil
+}
+
+func (vr *valueReader) readString() (string, error) {
+ length, err := vr.readLength()
+ if err != nil {
+ return "", err
+ }
+
+ if length <= 0 {
+ return "", fmt.Errorf("invalid string length: %d", length)
+ }
+
+ raw, err := readBytes(vr.src, int(length))
+ if err != nil {
+ return "", err
+ }
+
+ // Check that the last byte is the NUL terminator.
+ if raw[len(raw)-1] != 0x00 {
+ return "", fmt.Errorf("string does not end with null byte, but with %v", raw[len(raw)-1])
+ }
+
+ // Convert and strip the trailing NUL.
+ return string(raw[:len(raw)-1]), nil
+}
+
+func (vr *valueReader) peekLength() (int32, error) {
+ buf, err := vr.src.peek(4)
+ if err != nil {
+ return 0, err
+ }
+ return int32(binary.LittleEndian.Uint32(buf)), nil
+}
+
+func (vr *valueReader) readLength() (int32, error) {
+ return vr.readi32()
+}
+
+func (vr *valueReader) readi32() (int32, error) {
+ raw, err := readBytes(vr.src, 4)
+ if err != nil {
+ return 0, err
+ }
+
+ return int32(binary.LittleEndian.Uint32(raw)), nil
+}
+
+func (vr *valueReader) readu32() (uint32, error) {
+ raw, err := readBytes(vr.src, 4)
+ if err != nil {
+ return 0, err
+ }
+
+ return binary.LittleEndian.Uint32(raw), nil
+}
+
+func (vr *valueReader) readi64() (int64, error) {
+ raw, err := readBytes(vr.src, 8)
+ if err != nil {
+ return 0, err
+ }
+
+ return int64(binary.LittleEndian.Uint64(raw)), nil
+}
+
+func (vr *valueReader) readu64() (uint64, error) {
+ raw, err := readBytes(vr.src, 8)
+ if err != nil {
+ return 0, err
+ }
+
+ return binary.LittleEndian.Uint64(raw), nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/value_writer.go
similarity index 69%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/value_writer.go
index 501c6d7f9..9dd8912d0 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/value_writer.go
@@ -4,7 +4,7 @@
// 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 bsonrw
+package bson
import (
"errors"
@@ -15,15 +15,13 @@ import (
"strings"
"sync"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
-var _ ValueWriter = (*valueWriter)(nil)
+var _ ValueWriter = &valueWriter{}
var vwPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
return new(valueWriter)
},
}
@@ -35,68 +33,33 @@ func putValueWriter(vw *valueWriter) {
}
}
-// BSONValueWriterPool is a pool for BSON ValueWriters.
-//
-// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
-type BSONValueWriterPool struct {
- pool sync.Pool
-}
-
-// NewBSONValueWriterPool creates a new pool for ValueWriter instances that write to BSON.
-//
-// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
-func NewBSONValueWriterPool() *BSONValueWriterPool {
- return &BSONValueWriterPool{
- pool: sync.Pool{
- New: func() interface{} {
- return new(valueWriter)
- },
- },
- }
+var documentWriterPool = sync.Pool{
+ New: func() any {
+ return newDocumentWriter(nil)
+ },
}
-// Get retrieves a BSON ValueWriter from the pool and resets it to use w as the destination.
-//
-// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
-func (bvwp *BSONValueWriterPool) Get(w io.Writer) ValueWriter {
- vw := bvwp.pool.Get().(*valueWriter)
+func getDocumentWriter(w io.Writer) *valueWriter {
+ vw := documentWriterPool.Get().(*valueWriter)
- // TODO: Having to call reset here with the same buffer doesn't really make sense.
vw.reset(vw.buf)
vw.buf = vw.buf[:0]
vw.w = w
- return vw
-}
-// GetAtModeElement retrieves a ValueWriterFlusher from the pool and resets it to use w as the destination.
-//
-// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
-func (bvwp *BSONValueWriterPool) GetAtModeElement(w io.Writer) ValueWriterFlusher {
- vw := bvwp.Get(w).(*valueWriter)
- vw.push(mElement)
return vw
}
-// Put inserts a ValueWriter into the pool. If the ValueWriter is not a BSON ValueWriter, nothing
-// happens and ok will be false.
-//
-// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
-func (bvwp *BSONValueWriterPool) Put(vw ValueWriter) (ok bool) {
- bvw, ok := vw.(*valueWriter)
- if !ok {
- return false
+func putDocumentWriter(vw *valueWriter) {
+ if vw != nil {
+ vw.w = nil // don't leak the writer
+ documentWriterPool.Put(vw)
}
-
- bvwp.pool.Put(bvw)
- return true
}
// This is here so that during testing we can change it and not require
// allocating a 4GB slice.
var maxSize = math.MaxInt32
-var errNilWriter = errors.New("cannot create a ValueWriter from a nil io.Writer")
-
type errMaxDocumentSizeExceeded struct {
size int64
}
@@ -188,18 +151,15 @@ func (vw *valueWriter) pop() {
}
}
-// NewBSONValueWriter creates a ValueWriter that writes BSON to w.
+// NewDocumentWriter creates a ValueWriter that writes BSON to w.
//
// This ValueWriter will only write entire documents to the io.Writer and it
// will buffer the document as it is built.
-func NewBSONValueWriter(w io.Writer) (ValueWriter, error) {
- if w == nil {
- return nil, errNilWriter
- }
- return newValueWriter(w), nil
+func NewDocumentWriter(w io.Writer) ValueWriter {
+ return newDocumentWriter(w)
}
-func newValueWriter(w io.Writer) *valueWriter {
+func newDocumentWriter(w io.Writer) *valueWriter {
vw := new(valueWriter)
stack := make([]vwState, 1, 5)
stack[0] = vwState{mode: mTopLevel}
@@ -209,7 +169,6 @@ func newValueWriter(w io.Writer) *valueWriter {
return vw
}
-// TODO: only used in tests
func newValueWriterFromSlice(buf []byte) *valueWriter {
vw := new(valueWriter)
stack := make([]vwState, 1, 5)
@@ -245,7 +204,7 @@ func (vw *valueWriter) invalidTransitionError(destination mode, name string, mod
return te
}
-func (vw *valueWriter) writeElementHeader(t bsontype.Type, destination mode, callerName string, addmodes ...mode) error {
+func (vw *valueWriter) writeElementHeader(t Type, destination mode, callerName string, addmodes ...mode) error {
frame := &vw.stack[vw.frame]
switch frame.mode {
case mElement:
@@ -267,7 +226,7 @@ func (vw *valueWriter) writeElementHeader(t bsontype.Type, destination mode, cal
return nil
}
-func (vw *valueWriter) WriteValueBytes(t bsontype.Type, b []byte) error {
+func (vw *valueWriter) writeValueBytes(t Type, b []byte) error {
if err := vw.writeElementHeader(t, mode(0), "WriteValueBytes"); err != nil {
return err
}
@@ -277,7 +236,7 @@ func (vw *valueWriter) WriteValueBytes(t bsontype.Type, b []byte) error {
}
func (vw *valueWriter) WriteArray() (ArrayWriter, error) {
- if err := vw.writeElementHeader(bsontype.Array, mArray, "WriteArray"); err != nil {
+ if err := vw.writeElementHeader(TypeArray, mArray, "WriteArray"); err != nil {
return nil, err
}
@@ -291,7 +250,7 @@ func (vw *valueWriter) WriteBinary(b []byte) error {
}
func (vw *valueWriter) WriteBinaryWithSubtype(b []byte, btype byte) error {
- if err := vw.writeElementHeader(bsontype.Binary, mode(0), "WriteBinaryWithSubtype"); err != nil {
+ if err := vw.writeElementHeader(TypeBinary, mode(0), "WriteBinaryWithSubtype"); err != nil {
return err
}
@@ -301,7 +260,7 @@ func (vw *valueWriter) WriteBinaryWithSubtype(b []byte, btype byte) error {
}
func (vw *valueWriter) WriteBoolean(b bool) error {
- if err := vw.writeElementHeader(bsontype.Boolean, mode(0), "WriteBoolean"); err != nil {
+ if err := vw.writeElementHeader(TypeBoolean, mode(0), "WriteBoolean"); err != nil {
return err
}
@@ -311,7 +270,7 @@ func (vw *valueWriter) WriteBoolean(b bool) error {
}
func (vw *valueWriter) WriteCodeWithScope(code string) (DocumentWriter, error) {
- if err := vw.writeElementHeader(bsontype.CodeWithScope, mCodeWithScope, "WriteCodeWithScope"); err != nil {
+ if err := vw.writeElementHeader(TypeCodeWithScope, mCodeWithScope, "WriteCodeWithScope"); err != nil {
return nil, err
}
@@ -327,8 +286,8 @@ func (vw *valueWriter) WriteCodeWithScope(code string) (DocumentWriter, error) {
return vw, nil
}
-func (vw *valueWriter) WriteDBPointer(ns string, oid primitive.ObjectID) error {
- if err := vw.writeElementHeader(bsontype.DBPointer, mode(0), "WriteDBPointer"); err != nil {
+func (vw *valueWriter) WriteDBPointer(ns string, oid ObjectID) error {
+ if err := vw.writeElementHeader(TypeDBPointer, mode(0), "WriteDBPointer"); err != nil {
return err
}
@@ -338,7 +297,7 @@ func (vw *valueWriter) WriteDBPointer(ns string, oid primitive.ObjectID) error {
}
func (vw *valueWriter) WriteDateTime(dt int64) error {
- if err := vw.writeElementHeader(bsontype.DateTime, mode(0), "WriteDateTime"); err != nil {
+ if err := vw.writeElementHeader(TypeDateTime, mode(0), "WriteDateTime"); err != nil {
return err
}
@@ -347,18 +306,19 @@ func (vw *valueWriter) WriteDateTime(dt int64) error {
return nil
}
-func (vw *valueWriter) WriteDecimal128(d128 primitive.Decimal128) error {
- if err := vw.writeElementHeader(bsontype.Decimal128, mode(0), "WriteDecimal128"); err != nil {
+func (vw *valueWriter) WriteDecimal128(d128 Decimal128) error {
+ if err := vw.writeElementHeader(TypeDecimal128, mode(0), "WriteDecimal128"); err != nil {
return err
}
- vw.buf = bsoncore.AppendDecimal128(vw.buf, d128)
+ h, l := d128.GetBytes()
+ vw.buf = bsoncore.AppendDecimal128(vw.buf, h, l)
vw.pop()
return nil
}
func (vw *valueWriter) WriteDouble(f float64) error {
- if err := vw.writeElementHeader(bsontype.Double, mode(0), "WriteDouble"); err != nil {
+ if err := vw.writeElementHeader(TypeDouble, mode(0), "WriteDouble"); err != nil {
return err
}
@@ -368,7 +328,7 @@ func (vw *valueWriter) WriteDouble(f float64) error {
}
func (vw *valueWriter) WriteInt32(i32 int32) error {
- if err := vw.writeElementHeader(bsontype.Int32, mode(0), "WriteInt32"); err != nil {
+ if err := vw.writeElementHeader(TypeInt32, mode(0), "WriteInt32"); err != nil {
return err
}
@@ -378,7 +338,7 @@ func (vw *valueWriter) WriteInt32(i32 int32) error {
}
func (vw *valueWriter) WriteInt64(i64 int64) error {
- if err := vw.writeElementHeader(bsontype.Int64, mode(0), "WriteInt64"); err != nil {
+ if err := vw.writeElementHeader(TypeInt64, mode(0), "WriteInt64"); err != nil {
return err
}
@@ -388,7 +348,7 @@ func (vw *valueWriter) WriteInt64(i64 int64) error {
}
func (vw *valueWriter) WriteJavascript(code string) error {
- if err := vw.writeElementHeader(bsontype.JavaScript, mode(0), "WriteJavascript"); err != nil {
+ if err := vw.writeElementHeader(TypeJavaScript, mode(0), "WriteJavascript"); err != nil {
return err
}
@@ -398,7 +358,7 @@ func (vw *valueWriter) WriteJavascript(code string) error {
}
func (vw *valueWriter) WriteMaxKey() error {
- if err := vw.writeElementHeader(bsontype.MaxKey, mode(0), "WriteMaxKey"); err != nil {
+ if err := vw.writeElementHeader(TypeMaxKey, mode(0), "WriteMaxKey"); err != nil {
return err
}
@@ -407,7 +367,7 @@ func (vw *valueWriter) WriteMaxKey() error {
}
func (vw *valueWriter) WriteMinKey() error {
- if err := vw.writeElementHeader(bsontype.MinKey, mode(0), "WriteMinKey"); err != nil {
+ if err := vw.writeElementHeader(TypeMinKey, mode(0), "WriteMinKey"); err != nil {
return err
}
@@ -416,7 +376,7 @@ func (vw *valueWriter) WriteMinKey() error {
}
func (vw *valueWriter) WriteNull() error {
- if err := vw.writeElementHeader(bsontype.Null, mode(0), "WriteNull"); err != nil {
+ if err := vw.writeElementHeader(TypeNull, mode(0), "WriteNull"); err != nil {
return err
}
@@ -424,8 +384,8 @@ func (vw *valueWriter) WriteNull() error {
return nil
}
-func (vw *valueWriter) WriteObjectID(oid primitive.ObjectID) error {
- if err := vw.writeElementHeader(bsontype.ObjectID, mode(0), "WriteObjectID"); err != nil {
+func (vw *valueWriter) WriteObjectID(oid ObjectID) error {
+ if err := vw.writeElementHeader(TypeObjectID, mode(0), "WriteObjectID"); err != nil {
return err
}
@@ -438,7 +398,7 @@ func (vw *valueWriter) WriteRegex(pattern string, options string) error {
if !isValidCString(pattern) || !isValidCString(options) {
return errors.New("BSON regex values cannot contain null bytes")
}
- if err := vw.writeElementHeader(bsontype.Regex, mode(0), "WriteRegex"); err != nil {
+ if err := vw.writeElementHeader(TypeRegex, mode(0), "WriteRegex"); err != nil {
return err
}
@@ -448,7 +408,7 @@ func (vw *valueWriter) WriteRegex(pattern string, options string) error {
}
func (vw *valueWriter) WriteString(s string) error {
- if err := vw.writeElementHeader(bsontype.String, mode(0), "WriteString"); err != nil {
+ if err := vw.writeElementHeader(TypeString, mode(0), "WriteString"); err != nil {
return err
}
@@ -462,7 +422,7 @@ func (vw *valueWriter) WriteDocument() (DocumentWriter, error) {
vw.reserveLength()
return vw, nil
}
- if err := vw.writeElementHeader(bsontype.EmbeddedDocument, mDocument, "WriteDocument", mTopLevel); err != nil {
+ if err := vw.writeElementHeader(TypeEmbeddedDocument, mDocument, "WriteDocument", mTopLevel); err != nil {
return nil, err
}
@@ -471,7 +431,7 @@ func (vw *valueWriter) WriteDocument() (DocumentWriter, error) {
}
func (vw *valueWriter) WriteSymbol(symbol string) error {
- if err := vw.writeElementHeader(bsontype.Symbol, mode(0), "WriteSymbol"); err != nil {
+ if err := vw.writeElementHeader(TypeSymbol, mode(0), "WriteSymbol"); err != nil {
return err
}
@@ -481,7 +441,7 @@ func (vw *valueWriter) WriteSymbol(symbol string) error {
}
func (vw *valueWriter) WriteTimestamp(t uint32, i uint32) error {
- if err := vw.writeElementHeader(bsontype.Timestamp, mode(0), "WriteTimestamp"); err != nil {
+ if err := vw.writeElementHeader(TypeTimestamp, mode(0), "WriteTimestamp"); err != nil {
return err
}
@@ -491,7 +451,7 @@ func (vw *valueWriter) WriteTimestamp(t uint32, i uint32) error {
}
func (vw *valueWriter) WriteUndefined() error {
- if err := vw.writeElementHeader(bsontype.Undefined, mode(0), "WriteUndefined"); err != nil {
+ if err := vw.writeElementHeader(TypeUndefined, mode(0), "WriteUndefined"); err != nil {
return err
}
@@ -627,14 +587,14 @@ func isValidCString(cs string) bool {
// key is a valid C string since the caller has already checked for that.
//
// The caller of this function must check if key is a valid C string.
-func (vw *valueWriter) appendHeader(t bsontype.Type, key string) {
- vw.buf = bsoncore.AppendType(vw.buf, t)
+func (vw *valueWriter) appendHeader(t Type, key string) {
+ vw.buf = bsoncore.AppendType(vw.buf, bsoncore.Type(t))
vw.buf = append(vw.buf, key...)
vw.buf = append(vw.buf, 0x00)
}
-func (vw *valueWriter) appendIntHeader(t bsontype.Type, key int) {
- vw.buf = bsoncore.AppendType(vw.buf, t)
+func (vw *valueWriter) appendIntHeader(t Type, key int) {
+ vw.buf = bsoncore.AppendType(vw.buf, bsoncore.Type(t))
vw.buf = strconv.AppendInt(vw.buf, int64(key), 10)
vw.buf = append(vw.buf, 0x00)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/vector.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/vector.go
new file mode 100644
index 000000000..31a10bd5b
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/vector.go
@@ -0,0 +1,268 @@
+// Copyright (C) MongoDB, Inc. 2024-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 bson
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "math"
+)
+
+// BSON binary vector types as described in https://bsonspec.org/spec.html.
+const (
+ Int8Vector byte = 0x03
+ Float32Vector byte = 0x27
+ PackedBitVector byte = 0x10
+)
+
+// These are vector conversion errors.
+var (
+ errInsufficientVectorData = errors.New("insufficient data")
+ errNonZeroVectorPadding = errors.New("padding must be 0")
+ errVectorPaddingTooLarge = errors.New("padding cannot be larger than 7")
+)
+
+type vectorTypeError struct {
+ Method string
+ Type byte
+}
+
+// Error implements the error interface.
+func (vte vectorTypeError) Error() string {
+ t := "invalid"
+ switch vte.Type {
+ case Int8Vector:
+ t = "int8"
+ case Float32Vector:
+ t = "float32"
+ case PackedBitVector:
+ t = "packed bit"
+ }
+ return fmt.Sprintf("cannot call %s, on a type %s vector", vte.Method, t)
+}
+
+// Vector represents a densely packed array of numbers / bits.
+type Vector struct {
+ dType byte
+ int8Data []int8
+ float32Data []float32
+ bitData []byte
+ bitPadding uint8
+}
+
+// Type returns the vector type.
+func (v Vector) Type() byte {
+ return v.dType
+}
+
+// Int8 returns the int8 slice hold by the vector.
+// It panics if v is not an int8 vector.
+func (v Vector) Int8() []int8 {
+ d, ok := v.Int8OK()
+ if !ok {
+ panic(vectorTypeError{"bson.Vector.Int8", v.dType})
+ }
+ return d
+}
+
+// Int8OK is the same as Int8, but returns a boolean instead of panicking.
+func (v Vector) Int8OK() ([]int8, bool) {
+ if v.dType != Int8Vector {
+ return nil, false
+ }
+ return v.int8Data, true
+}
+
+// Float32 returns the float32 slice hold by the vector.
+// It panics if v is not a float32 vector.
+func (v Vector) Float32() []float32 {
+ d, ok := v.Float32OK()
+ if !ok {
+ panic(vectorTypeError{"bson.Vector.Float32", v.dType})
+ }
+ return d
+}
+
+// Float32OK is the same as Float32, but returns a boolean instead of panicking.
+func (v Vector) Float32OK() ([]float32, bool) {
+ if v.dType != Float32Vector {
+ return nil, false
+ }
+ return v.float32Data, true
+}
+
+// PackedBit returns the byte slice representing the binary quantized (packed bit) vector and the byte padding, which
+// is the number of bits in the final byte that are to be ignored.
+// It panics if v is not a packed bit vector.
+func (v Vector) PackedBit() ([]byte, uint8) {
+ d, p, ok := v.PackedBitOK()
+ if !ok {
+ panic(vectorTypeError{"bson.Vector.PackedBit", v.dType})
+ }
+ return d, p
+}
+
+// PackedBitOK is the same as PackedBit, but returns a boolean instead of panicking.
+func (v Vector) PackedBitOK() ([]byte, uint8, bool) {
+ if v.dType != PackedBitVector {
+ return nil, 0, false
+ }
+ return v.bitData, v.bitPadding, true
+}
+
+// Binary returns the BSON Binary representation of the Vector.
+func (v Vector) Binary() Binary {
+ switch v.Type() {
+ case Int8Vector:
+ return binaryFromInt8Vector(v.Int8())
+ case Float32Vector:
+ return binaryFromFloat32Vector(v.Float32())
+ case PackedBitVector:
+ return binaryFromBitVector(v.PackedBit())
+ default:
+ panic(fmt.Sprintf("invalid Vector data type: %d", v.dType))
+ }
+}
+
+func binaryFromInt8Vector(v []int8) Binary {
+ data := make([]byte, len(v)+2)
+ data[0] = Int8Vector
+ data[1] = 0
+
+ for i, e := range v {
+ data[i+2] = byte(e)
+ }
+
+ return Binary{
+ Subtype: TypeBinaryVector,
+ Data: data,
+ }
+}
+
+func binaryFromFloat32Vector(v []float32) Binary {
+ data := make([]byte, 2, len(v)*4+2)
+ data[0] = Float32Vector
+ data[1] = 0
+ var a [4]byte
+ for _, e := range v {
+ binary.LittleEndian.PutUint32(a[:], math.Float32bits(e))
+ data = append(data, a[:]...)
+ }
+
+ return Binary{
+ Subtype: TypeBinaryVector,
+ Data: data,
+ }
+}
+
+func binaryFromBitVector(bits []byte, padding uint8) Binary {
+ data := make([]byte, len(bits)+2)
+ data[0] = PackedBitVector
+ data[1] = padding
+ copy(data[2:], bits)
+ return Binary{
+ Subtype: TypeBinaryVector,
+ Data: data,
+ }
+}
+
+// NewVector constructs a Vector from a slice of int8 or float32.
+func NewVector[T int8 | float32](data []T) Vector {
+ var v Vector
+ switch a := any(data).(type) {
+ case []int8:
+ v.dType = Int8Vector
+ v.int8Data = make([]int8, len(data))
+ copy(v.int8Data, a)
+ case []float32:
+ v.dType = Float32Vector
+ v.float32Data = make([]float32, len(data))
+ copy(v.float32Data, a)
+ default:
+ panic(fmt.Errorf("unsupported type %T", data))
+ }
+ return v
+}
+
+// NewPackedBitVector constructs a Vector from a byte slice and a value of byte padding.
+func NewPackedBitVector(bits []byte, padding uint8) (Vector, error) {
+ var v Vector
+ if padding > 7 {
+ return v, errVectorPaddingTooLarge
+ }
+ if padding > 0 && len(bits) == 0 {
+ return v, errNonZeroVectorPadding
+ }
+ v.dType = PackedBitVector
+ v.bitData = make([]byte, len(bits))
+ copy(v.bitData, bits)
+ v.bitPadding = padding
+ return v, nil
+}
+
+// NewVectorFromBinary unpacks a BSON Binary into a Vector.
+func NewVectorFromBinary(b Binary) (Vector, error) {
+ var v Vector
+ if b.Subtype != TypeBinaryVector {
+ return v, errors.New("not a vector")
+ }
+ if len(b.Data) < 2 {
+ return v, errInsufficientVectorData
+ }
+ switch t := b.Data[0]; t {
+ case Int8Vector:
+ return newInt8Vector(b.Data[1:])
+ case Float32Vector:
+ return newFloat32Vector(b.Data[1:])
+ case PackedBitVector:
+ return newBitVector(b.Data[1:])
+ default:
+ return v, fmt.Errorf("invalid Vector data type: %d", t)
+ }
+}
+
+func newInt8Vector(b []byte) (Vector, error) {
+ var v Vector
+ if len(b) == 0 {
+ return v, errInsufficientVectorData
+ }
+ if padding := b[0]; padding > 0 {
+ return v, errNonZeroVectorPadding
+ }
+ s := make([]int8, 0, len(b)-1)
+ for i := 1; i < len(b); i++ {
+ s = append(s, int8(b[i]))
+ }
+ return NewVector(s), nil
+}
+
+func newFloat32Vector(b []byte) (Vector, error) {
+ var v Vector
+ if len(b) == 0 {
+ return v, errInsufficientVectorData
+ }
+ if padding := b[0]; padding > 0 {
+ return v, errNonZeroVectorPadding
+ }
+ l := (len(b) - 1) / 4
+ if l*4 != len(b)-1 {
+ return v, errInsufficientVectorData
+ }
+ s := make([]float32, 0, l)
+ for i := 1; i < len(b); i += 4 {
+ s = append(s, math.Float32frombits(binary.LittleEndian.Uint32(b[i:i+4])))
+ }
+ return NewVector(s), nil
+}
+
+func newBitVector(b []byte) (Vector, error) {
+ if len(b) == 0 {
+ return Vector{}, errInsufficientVectorData
+ }
+ return NewPackedBitVector(b[1:], b[0])
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/writer.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go
rename to vendor/go.mongodb.org/mongo-driver/v2/bson/writer.go
index 628f45293..84cad0dda 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/writer.go
@@ -4,12 +4,7 @@
// 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 bsonrw
-
-import (
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
+package bson
// ArrayWriter is the interface used to create a BSON or BSON adjacent array.
// Callers must ensure they call WriteArrayEnd when they have finished creating
@@ -36,9 +31,9 @@ type ValueWriter interface {
WriteBinaryWithSubtype(b []byte, btype byte) error
WriteBoolean(bool) error
WriteCodeWithScope(code string) (DocumentWriter, error)
- WriteDBPointer(ns string, oid primitive.ObjectID) error
+ WriteDBPointer(ns string, oid ObjectID) error
WriteDateTime(dt int64) error
- WriteDecimal128(primitive.Decimal128) error
+ WriteDecimal128(Decimal128) error
WriteDouble(float64) error
WriteInt32(int32) error
WriteInt64(int64) error
@@ -46,7 +41,7 @@ type ValueWriter interface {
WriteMaxKey() error
WriteMinKey() error
WriteNull() error
- WriteObjectID(primitive.ObjectID) error
+ WriteObjectID(ObjectID) error
WriteRegex(pattern, options string) error
WriteString(string) error
WriteDocument() (DocumentWriter, error)
@@ -55,32 +50,11 @@ type ValueWriter interface {
WriteUndefined() error
}
-// ValueWriterFlusher is a superset of ValueWriter that exposes functionality to flush to the underlying buffer.
-//
-// Deprecated: ValueWriterFlusher will not be supported in Go Driver 2.0.
-type ValueWriterFlusher interface {
- ValueWriter
- Flush() error
-}
-
-// BytesWriter is the interface used to write BSON bytes to a ValueWriter.
-// This interface is meant to be a superset of ValueWriter, so that types that
-// implement ValueWriter may also implement this interface.
-//
-// Deprecated: BytesWriter will not be supported in Go Driver 2.0.
-type BytesWriter interface {
- WriteValueBytes(t bsontype.Type, b []byte) error
-}
-
-// SliceWriter allows a pointer to a slice of bytes to be used as an io.Writer.
-//
-// Deprecated: SliceWriter will not be supported in Go Driver 2.0.
-type SliceWriter []byte
+// sliceWriter allows a pointer to a slice of bytes to be used as an io.Writer.
+type sliceWriter []byte
// Write writes the bytes to the underlying slice.
-//
-// Deprecated: SliceWriter will not be supported in Go Driver 2.0.
-func (sw *SliceWriter) Write(p []byte) (int, error) {
+func (sw *sliceWriter) Write(p []byte) (int, error) {
written := len(p)
*sw = append(*sw, p...)
return written, nil
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/event/description.go b/vendor/go.mongodb.org/mongo-driver/v2/event/description.go
new file mode 100644
index 000000000..d605b9707
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/event/description.go
@@ -0,0 +1,58 @@
+// Copyright (C) MongoDB, Inc. 2024-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 event
+
+import (
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/tag"
+)
+
+// ServerDescription contains information about a node in a cluster. This is
+// created from hello command responses. If the value of the Kind field is
+// LoadBalancer, only the Addr and Kind fields will be set. All other fields
+// will be set to the zero value of the field's type.
+type ServerDescription struct {
+ Addr address.Address
+ Arbiters []string
+ Compression []string // compression methods returned by server
+ CanonicalAddr address.Address
+ ElectionID bson.ObjectID
+ IsCryptd bool
+ HelloOK bool
+ Hosts []string
+ Kind string
+ LastWriteTime time.Time
+ MaxBatchCount uint32
+ MaxDocumentSize uint32
+ MaxMessageSize uint32
+ MaxWireVersion int32
+ MinWireVersion int32
+ Members []address.Address
+ Passives []string
+ Passive bool
+ Primary address.Address
+ ReadOnly bool
+ ServiceID *bson.ObjectID // Only set for servers that are deployed behind a load balancer.
+ SessionTimeoutMinutes *int64
+ SetName string
+ SetVersion uint32
+ Tags tag.Set
+ TopologyVersionProcessID bson.ObjectID
+ TopologyVersionCounter int64
+}
+
+// TopologyDescription contains information about a MongoDB cluster.
+type TopologyDescription struct {
+ Servers []ServerDescription
+ SetName string
+ Kind string
+ SessionTimeoutMinutes *int64
+ CompatibilityErr error
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/event/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/event/doc.go
similarity index 89%
rename from vendor/go.mongodb.org/mongo-driver/event/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/event/doc.go
index da1da4d47..9bade98cf 100644
--- a/vendor/go.mongodb.org/mongo-driver/event/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/event/doc.go
@@ -21,7 +21,7 @@
// },
// }
// clientOpts := options.Client().ApplyURI("mongodb://localhost:27017").SetMonitor(cmdMonitor)
-// client, err := mongo.Connect(context.Background(), clientOpts)
+// client, err := mongo.Connect( clientOpts)
//
// Monitoring the connection pool requires specifying a PoolMonitor when constructing
// a mongo.Client. The following code tracks the number of checked out connections:
@@ -30,15 +30,15 @@
// poolMonitor := &event.PoolMonitor{
// Event: func(evt *event.PoolEvent) {
// switch evt.Type {
-// case event.GetSucceeded:
+// case event.ConnectionCheckedOut:
// connsCheckedOut++
-// case event.ConnectionReturned:
+// case event.ConnectionCheckedIn:
// connsCheckedOut--
// }
// },
// }
// clientOpts := options.Client().ApplyURI("mongodb://localhost:27017").SetPoolMonitor(poolMonitor)
-// client, err := mongo.Connect(context.Background(), clientOpts)
+// client, err := mongo.Connect( clientOpts)
//
// Monitoring server changes specifying a ServerMonitor object when constructing
// a mongo.Client. Different functions can be set on the ServerMonitor to
@@ -52,5 +52,5 @@
// }
// }
// clientOpts := options.Client().ApplyURI("mongodb://localhost:27017").SetServerMonitor(svrMonitor)
-// client, err := mongo.Connect(context.Background(), clientOpts)
+// client, err := mongo.Connect( clientOpts)
package event
diff --git a/vendor/go.mongodb.org/mongo-driver/event/monitoring.go b/vendor/go.mongodb.org/mongo-driver/v2/event/monitoring.go
similarity index 63%
rename from vendor/go.mongodb.org/mongo-driver/event/monitoring.go
rename to vendor/go.mongodb.org/mongo-driver/v2/event/monitoring.go
index ddc7abacf..2ca98969d 100644
--- a/vendor/go.mongodb.org/mongo-driver/event/monitoring.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/event/monitoring.go
@@ -4,16 +4,14 @@
// 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 event // import "go.mongodb.org/mongo-driver/event"
+package event
import (
"context"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
)
// CommandStartedEvent represents an event generated when a command is sent to a server.
@@ -23,41 +21,27 @@ type CommandStartedEvent struct {
CommandName string
RequestID int64
ConnectionID string
- // ServerConnectionID contains the connection ID from the server of the operation. If the server does not return
- // this value (e.g. on MDB < 4.2), it is unset. If the server connection ID would cause an int32 overflow, then
- // then this field will be nil.
- //
- // Deprecated: Use ServerConnectionID64.
- ServerConnectionID *int32
// ServerConnectionID64 contains the connection ID from the server of the operation. If the server does not
// return this value (e.g. on MDB < 4.2), it is unset.
- ServerConnectionID64 *int64
+ ServerConnectionID *int64
// ServiceID contains the ID of the server to which the command was sent if it is running behind a load balancer.
// Otherwise, it is unset.
- ServiceID *primitive.ObjectID
+ ServiceID *bson.ObjectID
}
// CommandFinishedEvent represents a generic command finishing.
type CommandFinishedEvent struct {
- // Deprecated: Use Duration instead.
- DurationNanos int64
- Duration time.Duration
- CommandName string
- DatabaseName string
- RequestID int64
- ConnectionID string
- // ServerConnectionID contains the connection ID from the server of the operation. If the server does not return
- // this value (e.g. on MDB < 4.2), it is unset.If the server connection ID would cause an int32 overflow, then
- // this field will be nil.
- //
- // Deprecated: Use ServerConnectionID64.
- ServerConnectionID *int32
+ Duration time.Duration
+ CommandName string
+ DatabaseName string
+ RequestID int64
+ ConnectionID string
// ServerConnectionID64 contains the connection ID from the server of the operation. If the server does not
// return this value (e.g. on MDB < 4.2), it is unset.
- ServerConnectionID64 *int64
+ ServerConnectionID *int64
// ServiceID contains the ID of the server to which the command was sent if it is running behind a load balancer.
// Otherwise, it is unset.
- ServiceID *primitive.ObjectID
+ ServiceID *bson.ObjectID
}
// CommandSucceededEvent represents an event generated when a command's execution succeeds.
@@ -69,7 +53,7 @@ type CommandSucceededEvent struct {
// CommandFailedEvent represents an event generated when a command's execution fails.
type CommandFailedEvent struct {
CommandFinishedEvent
- Failure string
+ Failure error
}
// CommandMonitor represents a monitor that is triggered for different events.
@@ -91,17 +75,17 @@ const (
// strings for pool command monitoring types
const (
- PoolCreated = "ConnectionPoolCreated"
- PoolReady = "ConnectionPoolReady"
- PoolCleared = "ConnectionPoolCleared"
- PoolClosedEvent = "ConnectionPoolClosed"
- ConnectionCreated = "ConnectionCreated"
- ConnectionReady = "ConnectionReady"
- ConnectionClosed = "ConnectionClosed"
- GetStarted = "ConnectionCheckOutStarted"
- GetFailed = "ConnectionCheckOutFailed"
- GetSucceeded = "ConnectionCheckedOut"
- ConnectionReturned = "ConnectionCheckedIn"
+ ConnectionPoolCreated = "ConnectionPoolCreated"
+ ConnectionPoolReady = "ConnectionPoolReady"
+ ConnectionPoolCleared = "ConnectionPoolCleared"
+ ConnectionPoolClosed = "ConnectionPoolClosed"
+ ConnectionCreated = "ConnectionCreated"
+ ConnectionReady = "ConnectionReady"
+ ConnectionClosed = "ConnectionClosed"
+ ConnectionCheckOutStarted = "ConnectionCheckOutStarted"
+ ConnectionCheckOutFailed = "ConnectionCheckOutFailed"
+ ConnectionCheckedOut = "ConnectionCheckedOut"
+ ConnectionCheckedIn = "ConnectionCheckedIn"
)
// MonitorPoolOptions contains pool options as formatted in pool events
@@ -115,15 +99,15 @@ type MonitorPoolOptions struct {
type PoolEvent struct {
Type string `json:"type"`
Address string `json:"address"`
- ConnectionID uint64 `json:"connectionId"`
+ ConnectionID int64 `json:"connectionId"`
PoolOptions *MonitorPoolOptions `json:"options"`
Duration time.Duration `json:"duration"`
Reason string `json:"reason"`
// ServiceID is only set if the Type is PoolCleared and the server is deployed behind a load balancer. This field
// can be used to distinguish between individual servers in a load balanced deployment.
- ServiceID *primitive.ObjectID `json:"serviceId"`
- Interruption bool `json:"interruptInUseConnections"`
- Error error `json:"error"`
+ ServiceID *bson.ObjectID `json:"serviceId"`
+ Interruption bool `json:"interruptInUseConnections"`
+ Error error `json:"error"`
}
// PoolMonitor is a function that allows the user to gain access to events occurring in the pool
@@ -134,38 +118,38 @@ type PoolMonitor struct {
// ServerDescriptionChangedEvent represents a server description change.
type ServerDescriptionChangedEvent struct {
Address address.Address
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
- PreviousDescription description.Server
- NewDescription description.Server
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
+ PreviousDescription ServerDescription
+ NewDescription ServerDescription
}
// ServerOpeningEvent is an event generated when the server is initialized.
type ServerOpeningEvent struct {
Address address.Address
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
}
// ServerClosedEvent is an event generated when the server is closed.
type ServerClosedEvent struct {
Address address.Address
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
}
// TopologyDescriptionChangedEvent represents a topology description change.
type TopologyDescriptionChangedEvent struct {
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
- PreviousDescription description.Topology
- NewDescription description.Topology
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
+ PreviousDescription TopologyDescription
+ NewDescription TopologyDescription
}
// TopologyOpeningEvent is an event generated when the topology is initialized.
type TopologyOpeningEvent struct {
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
}
// TopologyClosedEvent is an event generated when the topology is closed.
type TopologyClosedEvent struct {
- TopologyID primitive.ObjectID // A unique identifier for the topology this server is a part of
+ TopologyID bson.ObjectID // A unique identifier for the topology this server is a part of
}
// ServerHeartbeatStartedEvent is an event generated when the heartbeat is started.
@@ -176,22 +160,18 @@ type ServerHeartbeatStartedEvent struct {
// ServerHeartbeatSucceededEvent is an event generated when the heartbeat succeeds.
type ServerHeartbeatSucceededEvent struct {
- // Deprecated: Use Duration instead.
- DurationNanos int64
- Duration time.Duration
- Reply description.Server
- ConnectionID string // The address this heartbeat was sent to with a unique identifier
- Awaited bool // If this heartbeat was awaitable
+ Duration time.Duration
+ Reply ServerDescription
+ ConnectionID string // The address this heartbeat was sent to with a unique identifier
+ Awaited bool // If this heartbeat was awaitable
}
// ServerHeartbeatFailedEvent is an event generated when the heartbeat fails.
type ServerHeartbeatFailedEvent struct {
- // Deprecated: Use Duration instead.
- DurationNanos int64
- Duration time.Duration
- Failure error
- ConnectionID string // The address this heartbeat was sent to with a unique identifier
- Awaited bool // If this heartbeat was awaitable
+ Duration time.Duration
+ Failure error
+ ConnectionID string // The address this heartbeat was sent to with a unique identifier
+ Awaited bool // If this heartbeat was awaitable
}
// ServerMonitor represents a monitor that is triggered for different server events. The client
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/awserr/error.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/error.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/awserr/error.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/error.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/awserr/types.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/types.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/awserr/types.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/types.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/chain_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/chain_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go
index 684392715..4f593c097 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/chain_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go
@@ -11,7 +11,7 @@
package credentials
import (
- "go.mongodb.org/mongo-driver/internal/aws/awserr"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/awserr"
)
// A ChainProvider will search for a provider which returns credentials
@@ -46,7 +46,7 @@ func NewChainCredentials(providers []Provider) *Credentials {
// If a provider is found it will be cached and any calls to IsExpired()
// will return the expired state of the cached provider.
func (c *ChainProvider) Retrieve() (Value, error) {
- var errs = make([]error, 0, len(c.Providers))
+ errs := make([]error, 0, len(c.Providers))
for _, p := range c.Providers {
creds, err := p.Retrieve()
if err == nil {
@@ -57,7 +57,7 @@ func (c *ChainProvider) Retrieve() (Value, error) {
}
c.curr = nil
- var err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
+ err := awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
return Value{}, err
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/credentials.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/credentials.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go
index 53181aa16..919d0819b 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/aws/credentials/credentials.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go
@@ -15,7 +15,7 @@ import (
"sync"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/awserr"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/awserr"
"golang.org/x/sync/singleflight"
)
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/header_rules.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/header_rules.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/header_rules.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/header_rules.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/request.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/request.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/request.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/request.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/uri_path.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/uri_path.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/uri_path.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/uri_path.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/v4.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/v4.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go
index 6cf4586bb..eaf5cca3e 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/aws/signer/v4/v4.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go
@@ -23,8 +23,8 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/internal/aws"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/aws/types.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/types.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/aws/types.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/aws/types.go
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/binaryutil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/binaryutil.go
new file mode 100644
index 000000000..fe9c9979a
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/binaryutil.go
@@ -0,0 +1,135 @@
+// Copyright (C) MongoDB, Inc. 2025-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 binaryutil provides utility functions for working with binary data.
+package binaryutil
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+// Append32 appends a uint32 or int32 value to dst in little-endian byte order.
+// Byte shifting is done directly to prevent overflow security errors, in
+// compliance with gosec G115.
+//
+// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=92
+func Append32[T ~uint32 | ~int32](dst []byte, v T) []byte {
+ return append(dst,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24),
+ )
+}
+
+// Append64 appends a uint64 or int64 value to dst in little-endian byte order.
+// Byte shifting is done directly to prevent overflow security errors, in
+// compliance with gosec G115.
+//
+// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=119
+func Append64[T ~uint64 | ~int64](dst []byte, v T) []byte {
+ return append(dst,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24),
+ byte(v>>32),
+ byte(v>>40),
+ byte(v>>48),
+ byte(v>>56),
+ )
+}
+
+// ReadU32 reads a uint32 from src in little-endian byte order. ReadU32 and
+// ReadI32 are separate functions to avoid unsafe casting between unsigned and
+// signed integers.
+func ReadU32(src []byte) (uint32, []byte, bool) {
+ if len(src) < 4 {
+ return 0, src, false
+ }
+
+ return binary.LittleEndian.Uint32(src), src[4:], true
+}
+
+// ReadI32 reads an int32 from src in little-endian byte order.
+// Byte shifting is done directly to prevent overflow security errors, in
+// compliance with gosec G115. ReadU32 and ReadI32 are separate functions to
+// avoid unsafe casting between unsigned and signed integers.
+//
+// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=79
+func ReadI32(src []byte) (int32, []byte, bool) {
+ if len(src) < 4 {
+ return 0, src, false
+ }
+
+ _ = src[3] // bounds check hint to compiler
+
+ value := int32(src[0]) |
+ int32(src[1])<<8 |
+ int32(src[2])<<16 |
+ int32(src[3])<<24
+
+ return value, src[4:], true
+}
+
+// ReadU64 reads a uint64 from src in little-endian byte order. ReadU64 and
+// ReadI64 are separate functions to avoid unsafe casting between unsigned and
+// signed integers.
+func ReadU64(src []byte) (uint64, []byte, bool) {
+ if len(src) < 8 {
+ return 0, src, false
+ }
+
+ return binary.LittleEndian.Uint64(src), src[8:], true
+}
+
+// ReadI64 reads an int64 from src in little-endian byte order.
+// Byte shifting is done directly to prevent overflow security errors, in
+// compliance with gosec G115. ReadU64 and ReadI64 are separate functions to
+// avoid unsafe casting between unsigned and signed integers.
+//
+// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=101
+func ReadI64(src []byte) (int64, []byte, bool) {
+ if len(src) < 8 {
+ return 0, src, false
+ }
+
+ _ = src[7] // bounds check hint to compiler
+
+ value := int64(src[0]) |
+ int64(src[1])<<8 |
+ int64(src[2])<<16 |
+ int64(src[3])<<24 |
+ int64(src[4])<<32 |
+ int64(src[5])<<40 |
+ int64(src[6])<<48 |
+ int64(src[7])<<56
+
+ return value, src[8:], true
+}
+
+// ReadCStringBytes reads a null-terminated C string from src as a byte slice.
+// This is the base implementation used by ReadCString to ensure a single source
+// of truth for C string parsing logic.
+func ReadCStringBytes(src []byte) ([]byte, []byte, bool) {
+ idx := bytes.IndexByte(src, 0x00)
+ if idx < 0 {
+ return nil, src, false
+ }
+ return src[:idx], src[idx+1:], true
+}
+
+// ReadCString reads a null-terminated C string from src as a string.
+// It delegates to ReadCStringBytes to maintain a single source of truth for
+// C string parsing logic.
+func ReadCString(src []byte) (string, []byte, bool) {
+ cstr, rem, ok := ReadCStringBytes(src)
+ if !ok {
+ return "", src, false
+ }
+ return string(cstr), rem, true
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/doc.go
new file mode 100644
index 000000000..d4f5a2063
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/doc.go
@@ -0,0 +1,38 @@
+// Copyright (C) MongoDB, Inc. 2026-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 binaryutil provides functions for reading binary primitives from
+// byte slices. It is used internally for BSON parsing and wire protocol
+// operations.
+//
+// The functions in this package are designed for use in BSON operations.
+// Signed integer functions (ReadI32, ReadI64) use manual bit-shifting rather
+// than encoding/binary to avoid unsafe signed/unsigned conversions and comply
+// with gosec G115. Bounds-check elimination (BCE) hints help the compiler
+// inline these functions.
+//
+// Benchmarking across different ARM64 architectures (Apple M-series)
+// revealed non-deterministic performance discrepancies between using the
+// "encoding/binary" standard library and manual bit-shifting ("straight-lining").
+//
+// Without Loss of Generality (WLOG), benchmarking observed that:
+// - On Apple M1 Pro: Standard library (ReadU32) outperformed manual
+// bit-shifting (ReadI32) by ~2x (~0.08ns vs ~0.16ns).
+// - On Apple M4 Max: Manual bit-shifting (ReadI32) outperformed the
+// standard library (ReadU32) by ~1.6x (~0.03ns vs ~0.05ns).
+//
+// Further testing showed that "straight-lining" the ReadU32 implementation
+// to match ReadI32 normalized performance to ~0.03ns on the M4 Max, even
+// though the generated assembly for both approaches is virtually equivalent.
+//
+// The generated assembly is nearly identical for both approaches. These
+// sub-nanosecond variations likely stem from microarchitecture differences
+// (instruction caching, branch prediction) rather than the code itself.
+//
+// Since network I/O dominates driver latency, these differences do not have a
+// significant impact on driver performance. The implementation favors security
+// compliance and readability over hardware-specific tuning.
+package binaryutil
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go
new file mode 100644
index 000000000..7acdb2f1b
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go
@@ -0,0 +1,40 @@
+// Copyright (C) MongoDB, Inc. 2024-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 bsoncoreutil
+
+// Truncate truncates a given string for a certain width
+func Truncate(str string, width int) string {
+ if width <= 0 {
+ return ""
+ }
+
+ if len(str) <= width {
+ return str
+ }
+
+ // Truncate the byte slice of the string to the given width.
+ newStr := str[:width]
+
+ // Check if the last byte is at the beginning of a multi-byte character.
+ // If it is, then remove the last byte.
+ if newStr[len(newStr)-1]&0xC0 == 0xC0 {
+ return newStr[:len(newStr)-1]
+ }
+
+ // Check if the last byte is a multi-byte character
+ if newStr[len(newStr)-1]&0xC0 == 0x80 {
+ // If it is, step back until you we are at the start of a character
+ for i := len(newStr) - 1; i >= 0; i-- {
+ if newStr[i]&0xC0 == 0xC0 {
+ // Truncate at the end of the character before the character we stepped back to
+ return newStr[:i]
+ }
+ }
+ }
+
+ return newStr
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/bsonutil/bsonutil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go
similarity index 81%
rename from vendor/go.mongodb.org/mongo-driver/internal/bsonutil/bsonutil.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go
index eebb32890..4af8284ea 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/bsonutil/bsonutil.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go
@@ -9,7 +9,7 @@ package bsonutil
import (
"fmt"
- "go.mongodb.org/mongo-driver/bson"
+ "go.mongodb.org/mongo-driver/v2/bson"
)
// StringSliceFromRawValue decodes the provided BSON value into a []string. This function returns an error if the value
@@ -37,9 +37,9 @@ func StringSliceFromRawValue(name string, val bson.RawValue) ([]string, error) {
return strs, nil
}
-// RawToDocuments converts a bson.Raw that is internally an array of documents to []bson.Raw.
-func RawToDocuments(doc bson.Raw) []bson.Raw {
- values, err := doc.Values()
+// RawArrayToDocuments converts an array of documents to []bson.Raw.
+func RawArrayToDocuments(arr bson.RawArray) []bson.Raw {
+ values, err := arr.Values()
if err != nil {
panic(fmt.Sprintf("error converting BSON document to values: %v", err))
}
@@ -52,9 +52,9 @@ func RawToDocuments(doc bson.Raw) []bson.Raw {
return out
}
-// RawToInterfaces takes one or many bson.Raw documents and returns them as a []interface{}.
-func RawToInterfaces(docs ...bson.Raw) []interface{} {
- out := make([]interface{}, len(docs))
+// RawToInterfaces takes one or many bson.Raw documents and returns them as a []any.
+func RawToInterfaces(docs ...bson.Raw) []any {
+ out := make([]any, len(docs))
for i := range docs {
out[i] = docs[i]
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/codecutil/encoding.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go
similarity index 75%
rename from vendor/go.mongodb.org/mongo-driver/internal/codecutil/encoding.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go
index 2aaf8f271..11a74312b 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/codecutil/encoding.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go
@@ -13,8 +13,8 @@ import (
"io"
"reflect"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
var ErrNilValue = errors.New("value is nil")
@@ -22,22 +22,24 @@ var ErrNilValue = errors.New("value is nil")
// MarshalError is returned when attempting to transform a value into a document
// results in an error.
type MarshalError struct {
- Value interface{}
+ Value any
Err error
}
// Error implements the error interface.
func (e MarshalError) Error() string {
- return fmt.Sprintf("cannot transform type %s to a BSON Document: %v",
+ return fmt.Sprintf("cannot marshal type %q to a BSON Document: %v",
reflect.TypeOf(e.Value), e.Err)
}
+func (e MarshalError) Unwrap() error { return e.Err }
+
// EncoderFn is used to functionally construct an encoder for marshaling values.
-type EncoderFn func(io.Writer) (*bson.Encoder, error)
+type EncoderFn func(io.Writer) *bson.Encoder
// MarshalValue will attempt to encode the value with the encoder returned by
// the encoder function.
-func MarshalValue(val interface{}, encFn EncoderFn) (bsoncore.Value, error) {
+func MarshalValue(val any, encFn EncoderFn) (bsoncore.Value, error) {
// If the val is already a bsoncore.Value, then do nothing.
if bval, ok := val.(bsoncore.Value); ok {
return bval, nil
@@ -49,14 +51,11 @@ func MarshalValue(val interface{}, encFn EncoderFn) (bsoncore.Value, error) {
buf := new(bytes.Buffer)
- enc, err := encFn(buf)
- if err != nil {
- return bsoncore.Value{}, err
- }
+ enc := encFn(buf)
// Encode the value in a single-element document with an empty key. Use
// bsoncore to extract the first element and return the BSON value.
- err = enc.Encode(bson.D{{Key: "", Value: val}})
+ err := enc.Encode(bson.D{{Key: "", Value: val}})
if err != nil {
return bsoncore.Value{}, MarshalError{Value: val, Err: err}
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/assume_role_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/assume_role_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go
index 3a95cf401..eec2247c7 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/assume_role_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go
@@ -15,8 +15,8 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
- "go.mongodb.org/mongo-driver/internal/uuid"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/uuid"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/ec2_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/ec2_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go
index 771bfca13..df15a7f2c 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/ec2_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go
@@ -15,7 +15,7 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/ecs_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/ecs_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go
index 0c3a27e62..6816a3182 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/ecs_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go
@@ -14,7 +14,7 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/env_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/env_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go
index 59ca63363..cf6bb60b3 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/env_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go
@@ -9,7 +9,7 @@ package credproviders
import (
"os"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
// envProviderName provides a name of Env provider
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/imds_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/imds_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go
index 96dad1a82..f3674c727 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/imds_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go
@@ -15,7 +15,7 @@ import (
"net/url"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/static_provider.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go
similarity index 94%
rename from vendor/go.mongodb.org/mongo-driver/internal/credproviders/static_provider.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go
index 6b4961394..c7194cd0f 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/credproviders/static_provider.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go
@@ -9,7 +9,7 @@ package credproviders
import (
"errors"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
)
// staticProviderName provides a name of Static provider
@@ -38,14 +38,13 @@ func verify(v credentials.Value) error {
return errors.New("AWS_SESSION_TOKEN is set, but ACCESS_KEY_ID and SECRET_ACCESS_KEY are missing")
}
return nil
-
}
// Retrieve returns the credentials or error if the credentials are invalid.
func (s *StaticProvider) Retrieve() (credentials.Value, error) {
if !s.verified {
s.err = verify(s.Value)
- s.Value.ProviderName = staticProviderName
+ s.ProviderName = staticProviderName
s.verified = true
}
return s.Value, s.err
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/csfle/csfle.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go
similarity index 95%
rename from vendor/go.mongodb.org/mongo-driver/internal/csfle/csfle.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go
index 20a6d43a0..7a91045a3 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/csfle/csfle.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go
@@ -10,7 +10,7 @@ import (
"errors"
"fmt"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go
new file mode 100644
index 000000000..1e7b1901e
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go
@@ -0,0 +1,106 @@
+// Copyright (C) MongoDB, Inc. 2022-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 csot
+
+import (
+ "context"
+ "time"
+)
+
+type clientLevel struct{}
+
+func isClientLevel(ctx context.Context) bool {
+ val := ctx.Value(clientLevel{})
+ if val == nil {
+ return false
+ }
+
+ return val.(bool)
+}
+
+// IsTimeoutContext checks if the provided context has been assigned a deadline
+// or has unlimited retries.
+func IsTimeoutContext(ctx context.Context) bool {
+ _, ok := ctx.Deadline()
+
+ return ok || isClientLevel(ctx)
+}
+
+// WithTimeout will set the given timeout on the context, if no deadline has
+// already been set.
+//
+// This function assumes that the timeout field is static, given that the
+// timeout should be sourced from the client. Therefore, once a timeout function
+// parameter has been applied to the context, it will remain for the lifetime
+// of the context.
+func WithTimeout(parent context.Context, timeout *time.Duration) (context.Context, context.CancelFunc) {
+ cancel := func() {}
+
+ if timeout == nil || IsTimeoutContext(parent) {
+ // In the following conditions, do nothing:
+ // 1. The parent already has a deadline
+ // 2. The parent does not have a deadline, but a client-level timeout has
+ // been applied.
+ // 3. The parent does not have a deadline, there is not client-level
+ // timeout, and the timeout parameter DNE.
+ return parent, cancel
+ }
+
+ // If a client-level timeout has not been applied, then apply it.
+ parent = context.WithValue(parent, clientLevel{}, true)
+
+ dur := *timeout
+
+ if dur == 0 {
+ // If the parent does not have a deadline and the timeout is zero, then
+ // do nothing.
+ return parent, cancel
+ }
+
+ // If the parent does not have a dealine and the timeout is non-zero, then
+ // apply the timeout.
+ return context.WithTimeout(parent, dur)
+}
+
+// WithServerSelectionTimeout creates a context with a timeout that is the
+// minimum of serverSelectionTimeoutMS and context deadline. The usage of
+// non-positive values for serverSelectionTimeoutMS are an anti-pattern and are
+// not considered in this calculation.
+func WithServerSelectionTimeout(
+ parent context.Context,
+ serverSelectionTimeout time.Duration,
+) (context.Context, context.CancelFunc) {
+ if serverSelectionTimeout <= 0 {
+ return parent, func() {}
+ }
+
+ return context.WithTimeout(parent, serverSelectionTimeout)
+}
+
+// ZeroRTTMonitor implements the RTTMonitor interface and is used internally for testing. It returns 0 for all
+// RTT calculations and an empty string for RTT statistics.
+type ZeroRTTMonitor struct{}
+
+// EWMA implements the RTT monitor interface.
+func (zrm *ZeroRTTMonitor) EWMA() time.Duration {
+ return 0
+}
+
+// Min implements the RTT monitor interface.
+func (zrm *ZeroRTTMonitor) Min() time.Duration {
+ return 0
+}
+
+// P90 implements the RTT monitor interface.
+func (zrm *ZeroRTTMonitor) P90() time.Duration {
+ return 0
+}
+
+// Stats implements the RTT monitor interface.
+func (zrm *ZeroRTTMonitor) Stats() string {
+ return ""
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decimal128.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decimal128.go
new file mode 100644
index 000000000..abf20542e
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decimal128.go
@@ -0,0 +1,117 @@
+// 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 decimal128
+
+import (
+ "strconv"
+)
+
+// These constants are the maximum and minimum values for the exponent field in a decimal128 value.
+const (
+ MaxDecimal128Exp = 6111
+ MinDecimal128Exp = -6176
+)
+
+func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) {
+ div64 := uint64(div)
+ a := h >> 32
+ aq := a / div64
+ ar := a % div64
+ b := ar<<32 + h&(1<<32-1)
+ bq := b / div64
+ br := b % div64
+ c := br<<32 + l>>32
+ cq := c / div64
+ cr := c % div64
+ d := cr<<32 + l&(1<<32-1)
+ dq := d / div64
+ dr := d % div64
+ return (aq<<32 | bq), (cq<<32 | dq), uint32(dr)
+}
+
+// String returns a string representation of the decimal value.
+func String(h, l uint64) string {
+ var posSign int // positive sign
+ var exp int // exponent
+ var high, low uint64 // significand high/low
+
+ if h>>63&1 == 0 {
+ posSign = 1
+ }
+
+ switch h >> 58 & (1<<5 - 1) {
+ case 0x1F:
+ return "NaN"
+ case 0x1E:
+ return "-Infinity"[posSign:]
+ }
+
+ low = l
+ if h>>61&3 == 3 {
+ // Bits: 1*sign 2*ignored 14*exponent 111*significand.
+ // Implicit 0b100 prefix in significand.
+ exp = int(h >> 47 & (1<<14 - 1))
+ // Spec says all of these values are out of range.
+ high, low = 0, 0
+ } else {
+ // Bits: 1*sign 14*exponent 113*significand
+ exp = int(h >> 49 & (1<<14 - 1))
+ high = h & (1<<49 - 1)
+ }
+ exp += MinDecimal128Exp
+
+ // Would be handled by the logic below, but that's trivial and common.
+ if high == 0 && low == 0 && exp == 0 {
+ return "-0"[posSign:]
+ }
+
+ var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero.
+ last := len(repr)
+ i := len(repr)
+ dot := len(repr) + exp
+ var rem uint32
+Loop:
+ for d9 := 0; d9 < 5; d9++ {
+ high, low, rem = divmod(high, low, 1e9)
+ for d1 := 0; d1 < 9; d1++ {
+ // Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc.
+ if i < len(repr) && (dot == i || low == 0 && high == 0 && rem > 0 && rem < 10 && (dot < i-6 || exp > 0)) {
+ exp += len(repr) - i
+ i--
+ repr[i] = '.'
+ last = i - 1
+ dot = len(repr) // Unmark.
+ }
+ c := '0' + byte(rem%10)
+ rem /= 10
+ i--
+ repr[i] = c
+ // Handle "0E+3", "1E+3", etc.
+ if low == 0 && high == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || exp > 0) {
+ last = i
+ break Loop
+ }
+ if c != '0' {
+ last = i
+ }
+ // Break early. Works without it, but why.
+ if dot > i && low == 0 && high == 0 && rem == 0 {
+ break Loop
+ }
+ }
+ }
+ repr[last-1] = '-'
+ last--
+
+ if exp > 0 {
+ return string(repr[last+posSign:]) + "E+" + strconv.Itoa(exp)
+ }
+ if exp < 0 {
+ return string(repr[last+posSign:]) + "E" + strconv.Itoa(exp)
+ }
+ return string(repr[last+posSign:])
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go
similarity index 65%
rename from vendor/go.mongodb.org/mongo-driver/mongo/description/server.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go
index 19f2760e2..926de0bdf 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go
@@ -1,74 +1,210 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
+// Copyright (C) MongoDB, Inc. 2024-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 description
+package driverutil
import (
"errors"
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/bsonutil"
- "go.mongodb.org/mongo-driver/internal/handshake"
- "go.mongodb.org/mongo-driver/internal/ptrutil"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/tag"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/bsonutil"
+ "go.mongodb.org/mongo-driver/v2/internal/handshake"
+ "go.mongodb.org/mongo-driver/v2/internal/ptrutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/tag"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
-// SelectedServer augments the Server type by also including the TopologyKind of the topology that includes the server.
-// This type should be used to track the state of a server that was selected to perform an operation.
-type SelectedServer struct {
- Server
- Kind TopologyKind
+const (
+ MinWireVersion = 8
+ MaxWireVersion = 25
+)
+
+func equalWireVersion(wv1, wv2 *description.VersionRange) bool {
+ if wv1 == nil && wv2 == nil {
+ return true
+ }
+
+ if wv1 == nil || wv2 == nil {
+ return false
+ }
+
+ return wv1.Min == wv2.Min && wv1.Max == wv2.Max
+}
+
+// EqualServers compares two server descriptions and returns true if they are
+// equal.
+func EqualServers(srv1, srv2 description.Server) bool {
+ if srv1.CanonicalAddr.String() != srv2.CanonicalAddr.String() {
+ return false
+ }
+
+ if !sliceStringEqual(srv1.Arbiters, srv2.Arbiters) {
+ return false
+ }
+
+ if !sliceStringEqual(srv1.Hosts, srv2.Hosts) {
+ return false
+ }
+
+ if !sliceStringEqual(srv1.Passives, srv2.Passives) {
+ return false
+ }
+
+ if srv1.Primary != srv2.Primary {
+ return false
+ }
+
+ if srv1.SetName != srv2.SetName {
+ return false
+ }
+
+ if srv1.Kind != srv2.Kind {
+ return false
+ }
+
+ if srv1.LastError != nil || srv2.LastError != nil {
+ if srv1.LastError == nil || srv2.LastError == nil {
+ return false
+ }
+ if srv1.LastError.Error() != srv2.LastError.Error() {
+ return false
+ }
+ }
+
+ if !equalWireVersion(srv1.WireVersion, srv2.WireVersion) {
+ return false
+ }
+
+ if len(srv1.Tags) != len(srv2.Tags) || !srv1.Tags.ContainsAll(srv2.Tags) {
+ return false
+ }
+
+ if srv1.SetVersion != srv2.SetVersion {
+ return false
+ }
+
+ if srv1.ElectionID != srv2.ElectionID {
+ return false
+ }
+
+ if ptrutil.CompareInt64(srv1.SessionTimeoutMinutes, srv2.SessionTimeoutMinutes) != 0 {
+ return false
+ }
+
+ // If TopologyVersion is nil for both servers, CompareToIncoming will return -1 because it assumes that the
+ // incoming response is newer. We want the descriptions to be considered equal in this case, though, so an
+ // explicit check is required.
+ if srv1.TopologyVersion == nil && srv2.TopologyVersion == nil {
+ return true
+ }
+
+ return CompareTopologyVersions(srv1.TopologyVersion, srv2.TopologyVersion) == 0
+}
+
+// IsServerLoadBalanced checks if a description.Server describes a server that
+// is load balanced.
+func IsServerLoadBalanced(srv description.Server) bool {
+ return srv.Kind == description.ServerKindLoadBalancer || srv.ServiceID != nil
+}
+
+// stringSliceFromRawElement decodes the provided BSON element into a []string.
+// This internally calls StringSliceFromRawValue on the element's value. The
+// error conditions outlined in that function's documentation apply for this
+// function as well.
+func stringSliceFromRawElement(element bson.RawElement) ([]string, error) {
+ return bsonutil.StringSliceFromRawValue(element.Key(), element.Value())
+}
+
+func decodeStringMap(element bson.RawElement, name string) (map[string]string, error) {
+ doc, ok := element.Value().DocumentOK()
+ if !ok {
+ return nil, fmt.Errorf("expected '%s' to be a document but it's a BSON %s", name, element.Value().Type)
+ }
+ elements, err := doc.Elements()
+ if err != nil {
+ return nil, err
+ }
+ m := make(map[string]string)
+ for _, element := range elements {
+ key := element.Key()
+ value, ok := element.Value().StringValueOK()
+ if !ok {
+ return nil, fmt.Errorf("expected '%s' to be a document of strings, but found a BSON %s", name, element.Value().Type)
+ }
+ m[key] = value
+ }
+ return m, nil
+}
+
+// NewTopologyVersion creates a TopologyVersion based on doc
+func NewTopologyVersion(doc bson.Raw) (*description.TopologyVersion, error) {
+ elements, err := doc.Elements()
+ if err != nil {
+ return nil, err
+ }
+ var tv description.TopologyVersion
+ var ok bool
+ for _, element := range elements {
+ switch element.Key() {
+ case "processId":
+ tv.ProcessID, ok = element.Value().ObjectIDOK()
+ if !ok {
+ return nil, fmt.Errorf("expected 'processId' to be a objectID but it's a BSON %s", element.Value().Type)
+ }
+ case "counter":
+ tv.Counter, ok = element.Value().Int64OK()
+ if !ok {
+ return nil, fmt.Errorf("expected 'counter' to be an int64 but it's a BSON %s", element.Value().Type)
+ }
+ }
+ }
+ return &tv, nil
+}
+
+// NewVersionRange creates a new VersionRange given a min and a max.
+func NewVersionRange(min, max int32) description.VersionRange {
+ return description.VersionRange{Min: min, Max: max}
}
-// Server contains information about a node in a cluster. This is created from hello command responses. If the value
-// of the Kind field is LoadBalancer, only the Addr and Kind fields will be set. All other fields will be set to the
-// zero value of the field's type.
-type Server struct {
- Addr address.Address
-
- Arbiters []string
- AverageRTT time.Duration
- AverageRTTSet bool
- Compression []string // compression methods returned by server
- CanonicalAddr address.Address
- ElectionID primitive.ObjectID
- HeartbeatInterval time.Duration
- HelloOK bool
- Hosts []string
- IsCryptd bool
- LastError error
- LastUpdateTime time.Time
- LastWriteTime time.Time
- MaxBatchCount uint32
- MaxDocumentSize uint32
- MaxMessageSize uint32
- Members []address.Address
- Passives []string
- Passive bool
- Primary address.Address
- ReadOnly bool
- ServiceID *primitive.ObjectID // Only set for servers that are deployed behind a load balancer.
- // Deprecated: Use SessionTimeoutMinutesPtr instead.
- SessionTimeoutMinutes uint32
- SessionTimeoutMinutesPtr *int64
- SetName string
- SetVersion uint32
- Tags tag.Set
- TopologyVersion *TopologyVersion
- Kind ServerKind
- WireVersion *VersionRange
+// VersionRangeIncludes returns a bool indicating whether the supplied integer
+// is included in the range.
+func VersionRangeIncludes(versionRange description.VersionRange, v int32) bool {
+ return v >= versionRange.Min && v <= versionRange.Max
}
-// NewServer creates a new server description from the given hello command response.
-func NewServer(addr address.Address, response bson.Raw) Server {
- desc := Server{Addr: addr, CanonicalAddr: addr, LastUpdateTime: time.Now().UTC()}
+// CompareTopologyVersions compares the receiver, which represents the currently
+// known TopologyVersion for a server, to an incoming TopologyVersion extracted
+// from a server command response.
+//
+// This returns -1 if the receiver version is less than the response, 0 if the
+// versions are equal, and 1 if the receiver version is greater than the
+// response. This comparison is not commutative.
+func CompareTopologyVersions(receiver, response *description.TopologyVersion) int {
+ if receiver == nil || response == nil {
+ return -1
+ }
+ if receiver.ProcessID != response.ProcessID {
+ return -1
+ }
+ if receiver.Counter == response.Counter {
+ return 0
+ }
+ if receiver.Counter < response.Counter {
+ return -1
+ }
+ return 1
+}
+
+// NewServerDescription creates a new server description from the given hello
+// command response.
+func NewServerDescription(addr address.Address, response bson.Raw) description.Server {
+ desc := description.Server{Addr: addr, CanonicalAddr: addr, LastUpdateTime: time.Now().UTC()}
elements, err := response.Elements()
if err != nil {
desc.LastError = err
@@ -77,7 +213,7 @@ func NewServer(addr address.Address, response bson.Raw) Server {
var ok bool
var isReplicaSet, isWritablePrimary, hidden, secondary, arbiterOnly bool
var msg string
- var versionRange VersionRange
+ var versionRange description.VersionRange
for _, element := range elements {
switch element.Key() {
case "arbiters":
@@ -171,8 +307,7 @@ func NewServer(addr address.Address, response bson.Raw) Server {
return desc
}
- desc.SessionTimeoutMinutes = uint32(i64)
- desc.SessionTimeoutMinutesPtr = &i64
+ desc.SessionTimeoutMinutes = &i64
case "maxBsonObjectSize":
i64, ok := element.Value().AsInt64OK()
if !ok {
@@ -202,13 +337,15 @@ func NewServer(addr address.Address, response bson.Raw) Server {
}
desc.CanonicalAddr = address.Address(me).Canonicalize()
case "maxWireVersion":
- versionRange.Max, ok = element.Value().AsInt32OK()
+ verMax, ok := element.Value().AsInt64OK()
+ versionRange.Max = int32(verMax)
if !ok {
desc.LastError = fmt.Errorf("expected 'maxWireVersion' to be an integer but it's a BSON %s", element.Value().Type)
return desc
}
case "minWireVersion":
- versionRange.Min, ok = element.Value().AsInt32OK()
+ verMin, ok := element.Value().AsInt64OK()
+ versionRange.Min = int32(verMin)
if !ok {
desc.LastError = fmt.Errorf("expected 'minWireVersion' to be an integer but it's a BSON %s", element.Value().Type)
return desc
@@ -220,7 +357,7 @@ func NewServer(addr address.Address, response bson.Raw) Server {
return desc
}
case "ok":
- okay, ok := element.Value().AsInt32OK()
+ okay, ok := element.Value().AsInt64OK()
if !ok {
desc.LastError = fmt.Errorf("expected 'ok' to be a boolean but it's a BSON %s", element.Value().Type)
return desc
@@ -314,26 +451,26 @@ func NewServer(addr address.Address, response bson.Raw) Server {
desc.Members = append(desc.Members, address.Address(arbiter).Canonicalize())
}
- desc.Kind = Standalone
+ desc.Kind = description.ServerKindStandalone
switch {
case isReplicaSet:
- desc.Kind = RSGhost
+ desc.Kind = description.ServerKindRSGhost
case desc.SetName != "":
switch {
case isWritablePrimary:
- desc.Kind = RSPrimary
+ desc.Kind = description.ServerKindRSPrimary
case hidden:
- desc.Kind = RSMember
+ desc.Kind = description.ServerKindRSMember
case secondary:
- desc.Kind = RSSecondary
+ desc.Kind = description.ServerKindRSSecondary
case arbiterOnly:
- desc.Kind = RSArbiter
+ desc.Kind = description.ServerKindRSArbiter
default:
- desc.Kind = RSMember
+ desc.Kind = description.ServerKindRSMember
}
case msg == "isdbgrid":
- desc.Kind = Mongos
+ desc.Kind = description.ServerKindMongos
}
desc.WireVersion = &versionRange
@@ -341,164 +478,16 @@ func NewServer(addr address.Address, response bson.Raw) Server {
return desc
}
-// NewDefaultServer creates a new unknown server description with the given address.
-func NewDefaultServer(addr address.Address) Server {
- return NewServerFromError(addr, nil, nil)
-}
-
-// NewServerFromError creates a new unknown server description with the given parameters.
-func NewServerFromError(addr address.Address, err error, tv *TopologyVersion) Server {
- return Server{
- Addr: addr,
- LastError: err,
- Kind: Unknown,
- TopologyVersion: tv,
- }
-}
-
-// SetAverageRTT sets the average round trip time for this server description.
-func (s Server) SetAverageRTT(rtt time.Duration) Server {
- s.AverageRTT = rtt
- s.AverageRTTSet = true
- return s
-}
-
-// DataBearing returns true if the server is a data bearing server.
-func (s Server) DataBearing() bool {
- return s.Kind == RSPrimary ||
- s.Kind == RSSecondary ||
- s.Kind == Mongos ||
- s.Kind == Standalone
-}
-
-// LoadBalanced returns true if the server is a load balancer or is behind a load balancer.
-func (s Server) LoadBalanced() bool {
- return s.Kind == LoadBalancer || s.ServiceID != nil
-}
-
-// String implements the Stringer interface
-func (s Server) String() string {
- str := fmt.Sprintf("Addr: %s, Type: %s",
- s.Addr, s.Kind)
- if len(s.Tags) != 0 {
- str += fmt.Sprintf(", Tag sets: %s", s.Tags)
- }
-
- if s.AverageRTTSet {
- str += fmt.Sprintf(", Average RTT: %d", s.AverageRTT)
- }
-
- if s.LastError != nil {
- str += fmt.Sprintf(", Last error: %s", s.LastError)
- }
- return str
-}
-
-func decodeStringMap(element bson.RawElement, name string) (map[string]string, error) {
- doc, ok := element.Value().DocumentOK()
- if !ok {
- return nil, fmt.Errorf("expected '%s' to be a document but it's a BSON %s", name, element.Value().Type)
- }
- elements, err := doc.Elements()
- if err != nil {
- return nil, err
- }
- m := make(map[string]string)
- for _, element := range elements {
- key := element.Key()
- value, ok := element.Value().StringValueOK()
- if !ok {
- return nil, fmt.Errorf("expected '%s' to be a document of strings, but found a BSON %s", name, element.Value().Type)
- }
- m[key] = value
- }
- return m, nil
-}
-
-// Equal compares two server descriptions and returns true if they are equal
-func (s Server) Equal(other Server) bool {
- if s.CanonicalAddr.String() != other.CanonicalAddr.String() {
- return false
- }
-
- if !sliceStringEqual(s.Arbiters, other.Arbiters) {
- return false
- }
-
- if !sliceStringEqual(s.Hosts, other.Hosts) {
- return false
- }
-
- if !sliceStringEqual(s.Passives, other.Passives) {
- return false
- }
-
- if s.Primary != other.Primary {
- return false
- }
-
- if s.SetName != other.SetName {
- return false
- }
-
- if s.Kind != other.Kind {
- return false
- }
-
- if s.LastError != nil || other.LastError != nil {
- if s.LastError == nil || other.LastError == nil {
- return false
- }
- if s.LastError.Error() != other.LastError.Error() {
- return false
- }
- }
-
- if !s.WireVersion.Equals(other.WireVersion) {
- return false
- }
-
- if len(s.Tags) != len(other.Tags) || !s.Tags.ContainsAll(other.Tags) {
- return false
- }
-
- if s.SetVersion != other.SetVersion {
- return false
- }
-
- if s.ElectionID != other.ElectionID {
- return false
- }
-
- if ptrutil.CompareInt64(s.SessionTimeoutMinutesPtr, other.SessionTimeoutMinutesPtr) != 0 {
- return false
- }
-
- // If TopologyVersion is nil for both servers, CompareToIncoming will return -1 because it assumes that the
- // incoming response is newer. We want the descriptions to be considered equal in this case, though, so an
- // explicit check is required.
- if s.TopologyVersion == nil && other.TopologyVersion == nil {
- return true
- }
- return s.TopologyVersion.CompareToIncoming(other.TopologyVersion) == 0
-}
-
func sliceStringEqual(a []string, b []string) bool {
if len(a) != len(b) {
return false
}
+
for i, v := range a {
if v != b[i] {
return false
}
}
- return true
-}
-// stringSliceFromRawElement decodes the provided BSON element into a []string.
-// This internally calls StringSliceFromRawValue on the element's value. The
-// error conditions outlined in that function's documentation apply for this
-// function as well.
-func stringSliceFromRawElement(element bson.RawElement) ([]string, error) {
- return bsonutil.StringSliceFromRawValue(element.Key(), element.Value())
+ return true
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/driverutil/hello.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/hello.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/driverutil/hello.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/hello.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/driverutil/operation.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go
similarity index 62%
rename from vendor/go.mongodb.org/mongo-driver/internal/driverutil/operation.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go
index 32704312f..74142a56e 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/driverutil/operation.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go
@@ -6,6 +6,12 @@
package driverutil
+import (
+ "context"
+ "math"
+ "time"
+)
+
// Operation Names should be sourced from the command reference documentation:
// https://www.mongodb.com/docs/manual/reference/command/
const (
@@ -28,4 +34,36 @@ const (
ListIndexesOp = "listIndexes" // ListIndexesOp is the name for listing indexes
ListDatabasesOp = "listDatabases" // ListDatabasesOp is the name for listing databases
UpdateOp = "update" // UpdateOp is the name for updating
+ BulkWriteOp = "bulkWrite" // BulkWriteOp is the name for client-level bulk write
)
+
+// CalculateMaxTimeMS calculates the maxTimeMS value to send to the server
+// based on the context deadline and the minimum round trip time. If the
+// calculated maxTimeMS is likely to cause a socket timeout, then this function
+// will return 0 and false.
+func CalculateMaxTimeMS(ctx context.Context, rttMin time.Duration) (int64, bool) {
+ deadline, ok := ctx.Deadline()
+ if !ok {
+ return 0, true
+ }
+
+ remainingTimeout := time.Until(deadline)
+
+ // Always round up to the next millisecond value so we never truncate the calculated
+ // maxTimeMS value (e.g. 400 microseconds evaluates to 1ms, not 0ms).
+ maxTimeMS := int64((remainingTimeout - rttMin + time.Millisecond - 1) / time.Millisecond)
+ if maxTimeMS <= 0 {
+ return 0, false
+ }
+
+ // The server will return a "BadValue" error if maxTimeMS is greater
+ // than the maximum positive int32 value (about 24.9 days). If the
+ // user specified a timeout value greater than that, omit maxTimeMS
+ // and let the client-side timeout handle cancelling the op if the
+ // timeout is ever reached.
+ if maxTimeMS > math.MaxInt32 {
+ return 0, true
+ }
+
+ return maxTimeMS, true
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/handshake/handshake.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/handshake/handshake.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/handshake/handshake.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/handshake/handshake.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/httputil/httputil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/internal/httputil/httputil.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go
index db0dd5f12..761ad14df 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/httputil/httputil.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go
@@ -10,9 +10,17 @@ import (
"net/http"
)
-// DefaultHTTPClient is the default HTTP client used across the driver.
-var DefaultHTTPClient = &http.Client{
- Transport: http.DefaultTransport.(*http.Transport).Clone(),
+var DefaultHTTPClient = &http.Client{}
+
+// NewHTTPClient will return the globally-defined DefaultHTTPClient, updating
+// the transport if it differs from the http package DefaultTransport.
+func NewHTTPClient() *http.Client {
+ client := DefaultHTTPClient
+ if _, ok := http.DefaultTransport.(*http.Transport); !ok {
+ client.Transport = http.DefaultTransport
+ }
+
+ return client
}
// CloseIdleHTTPConnections closes any connections which were previously
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/logger/component.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/internal/logger/component.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go
index 0a3d55320..ef6649ece 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/logger/component.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go
@@ -10,7 +10,7 @@ import (
"os"
"strconv"
- "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/v2/bson"
)
const (
@@ -75,10 +75,10 @@ const (
)
// KeyValues is a list of key-value pairs.
-type KeyValues []interface{}
+type KeyValues []any
// Add adds a key-value pair to an instance of a KeyValues list.
-func (kvs *KeyValues) Add(key string, value interface{}) {
+func (kvs *KeyValues) Add(key string, value any) {
*kvs = append(*kvs, key, value)
}
@@ -144,23 +144,22 @@ func EnvHasComponentVariables() bool {
// Command is a struct defining common fields that must be included in all
// commands.
type Command struct {
- // TODO(GODRIVER-2824): change the DriverConnectionID type to int64.
- DriverConnectionID uint64 // Driver's ID for the connection
- Name string // Command name
- DatabaseName string // Database name
- Message string // Message associated with the command
- OperationID int32 // Driver-generated operation ID
- RequestID int64 // Driver-generated request ID
- ServerConnectionID *int64 // Server's ID for the connection used for the command
- ServerHost string // Hostname or IP address for the server
- ServerPort string // Port for the server
- ServiceID *primitive.ObjectID // ID for the command in load balancer mode
+ DriverConnectionID int64 // Driver's ID for the connection
+ Name string // Command name
+ DatabaseName string // Database name
+ Message string // Message associated with the command
+ OperationID int32 // Driver-generated operation ID
+ RequestID int64 // Driver-generated request ID
+ ServerConnectionID *int64 // Server's ID for the connection used for the command
+ ServerHost string // Hostname or IP address for the server
+ ServerPort string // Port for the server
+ ServiceID *bson.ObjectID // ID for the command in load balancer mode
}
// SerializeCommand takes a command and a variable number of key-value pairs and
-// returns a slice of interface{} that can be passed to the logger for
+// returns a slice of any that can be passed to the logger for
// structured logging.
-func SerializeCommand(cmd Command, extraKeysAndValues ...interface{}) KeyValues {
+func SerializeCommand(cmd Command, extraKeysAndValues ...any) KeyValues {
// Initialize the boilerplate keys and values.
keysAndValues := KeyValues{
KeyCommandName, cmd.Name,
@@ -204,7 +203,7 @@ type Connection struct {
// SerializeConnection serializes a Connection message into a slice of keys and
// values that can be passed to a logger.
-func SerializeConnection(conn Connection, extraKeysAndValues ...interface{}) KeyValues {
+func SerializeConnection(conn Connection, extraKeysAndValues ...any) KeyValues {
// Initialize the boilerplate keys and values.
keysAndValues := KeyValues{
KeyMessage, conn.Message,
@@ -226,17 +225,17 @@ func SerializeConnection(conn Connection, extraKeysAndValues ...interface{}) Key
// Server contains data that all server messages MAY contain.
type Server struct {
- DriverConnectionID uint64 // Driver's ID for the connection
- TopologyID primitive.ObjectID // Driver's unique ID for this topology
- Message string // Message associated with the topology
- ServerConnectionID *int64 // Server's ID for the connection
- ServerHost string // Hostname or IP address for the server
- ServerPort string // Port for the server
+ DriverConnectionID int64 // Driver's ID for the connection
+ TopologyID bson.ObjectID // Driver's unique ID for this topology
+ Message string // Message associated with the topology
+ ServerConnectionID *int64 // Server's ID for the connection
+ ServerHost string // Hostname or IP address for the server
+ ServerPort string // Port for the server
}
// SerializeServer serializes a Server message into a slice of keys and
// values that can be passed to a logger.
-func SerializeServer(srv Server, extraKV ...interface{}) KeyValues {
+func SerializeServer(srv Server, extraKV ...any) KeyValues {
// Initialize the boilerplate keys and values.
keysAndValues := KeyValues{
KeyDriverConnectionID, srv.DriverConnectionID,
@@ -273,7 +272,7 @@ type ServerSelection struct {
// SerializeServerSelection serializes a Topology message into a slice of keys
// and values that can be passed to a logger.
-func SerializeServerSelection(srvSelection ServerSelection, extraKV ...interface{}) KeyValues {
+func SerializeServerSelection(srvSelection ServerSelection, extraKV ...any) KeyValues {
keysAndValues := KeyValues{
KeySelector, srvSelection.Selector,
KeyOperation, srvSelection.Operation,
@@ -294,13 +293,13 @@ func SerializeServerSelection(srvSelection ServerSelection, extraKV ...interface
// Topology contains data that all topology messages MAY contain.
type Topology struct {
- ID primitive.ObjectID // Driver's unique ID for this topology
- Message string // Message associated with the topology
+ ID bson.ObjectID // Driver's unique ID for this topology
+ Message string // Message associated with the topology
}
// SerializeTopology serializes a Topology message into a slice of keys and
// values that can be passed to a logger.
-func SerializeTopology(topo Topology, extraKV ...interface{}) KeyValues {
+func SerializeTopology(topo Topology, extraKV ...any) KeyValues {
keysAndValues := KeyValues{
KeyTopologyID, topo.ID.Hex(),
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/logger/context.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/context.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/logger/context.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/logger/context.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/logger/io_sink.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/internal/logger/io_sink.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go
index 0a6c1bdca..3edceb619 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/logger/io_sink.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go
@@ -36,12 +36,12 @@ func NewIOSink(out io.Writer) *IOSink {
}
// Info will write a JSON-encoded message to the io.Writer.
-func (sink *IOSink) Info(_ int, msg string, keysAndValues ...interface{}) {
+func (sink *IOSink) Info(_ int, msg string, keysAndValues ...any) {
mapSize := len(keysAndValues) / 2
if math.MaxInt-mapSize >= 2 {
mapSize += 2
}
- kvMap := make(map[string]interface{}, mapSize)
+ kvMap := make(map[string]any, mapSize)
kvMap[KeyTimestamp] = time.Now().UnixNano()
kvMap[KeyMessage] = msg
@@ -57,7 +57,7 @@ func (sink *IOSink) Info(_ int, msg string, keysAndValues ...interface{}) {
}
// Error will write a JSON-encoded error message to the io.Writer.
-func (sink *IOSink) Error(err error, msg string, kv ...interface{}) {
+func (sink *IOSink) Error(err error, msg string, kv ...any) {
kv = append(kv, KeyError, err.Error())
sink.Info(0, msg, kv...)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/logger/level.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/level.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/logger/level.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/logger/level.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/logger/logger.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go
similarity index 84%
rename from vendor/go.mongodb.org/mongo-driver/internal/logger/logger.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go
index 2250286e4..d34e36e9f 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/logger/logger.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go
@@ -13,6 +13,10 @@ import (
"os"
"strconv"
"strings"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// DefaultMaxDocumentLength is the default maximum number of bytes that can be
@@ -24,18 +28,20 @@ const DefaultMaxDocumentLength = 1000
// toward the max document length.
const TruncationSuffix = "..."
-const logSinkPathEnvVar = "MONGODB_LOG_PATH"
-const maxDocumentLengthEnvVar = "MONGODB_LOG_MAX_DOCUMENT_LENGTH"
+const (
+ logSinkPathEnvVar = "MONGODB_LOG_PATH"
+ maxDocumentLengthEnvVar = "MONGODB_LOG_MAX_DOCUMENT_LENGTH"
+)
// LogSink represents a logging implementation, this interface should be 1-1
// with the exported "LogSink" interface in the mongo/options package.
type LogSink interface {
// Info logs a non-error message with the given key/value pairs. The
// level argument is provided for optional logging.
- Info(level int, msg string, keysAndValues ...interface{})
+ Info(level int, msg string, keysAndValues ...any)
// Error logs an error, with the given message and key/value pairs.
- Error(err error, msg string, keysAndValues ...interface{})
+ Error(err error, msg string, keysAndValues ...any)
}
// Logger represents the configuration for the internal logger.
@@ -108,7 +114,7 @@ func (logger *Logger) LevelComponentEnabled(level Level, component Component) bo
// this function is implemented based on the go-logr/logr LogSink interface,
// which is why "Print" has a message parameter. Any duplication in code is
// intentional to adhere to the logr pattern.
-func (logger *Logger) Print(level Level, component Component, msg string, keysAndValues ...interface{}) {
+func (logger *Logger) Print(level Level, component Component, msg string, keysAndValues ...any) {
// If the level is not enabled for the component, then
// skip the message.
if !logger.LevelComponentEnabled(level, component) {
@@ -126,7 +132,7 @@ func (logger *Logger) Print(level Level, component Component, msg string, keysAn
// Error logs an error, with the given message and key/value pairs.
// It functions similarly to Print, but may have unique behavior, and should be
// preferred for logging errors.
-func (logger *Logger) Error(err error, msg string, keysAndValues ...interface{}) {
+func (logger *Logger) Error(err error, msg string, keysAndValues ...any) {
if logger.Sink == nil {
return
}
@@ -181,7 +187,7 @@ func selectLogSink(sink LogSink) (LogSink, *os.File, error) {
}
if path != "" {
- logFile, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
+ logFile, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o666)
if err != nil {
return nil, nil, fmt.Errorf("unable to open log file: %w", err)
}
@@ -230,46 +236,31 @@ func selectComponentLevels(componentLevels map[Component]Level) map[Component]Le
return selected
}
-// truncate will truncate a string to the given width, appending "..." to the
-// end of the string if it is truncated. This routine is safe for multi-byte
-// characters.
-func truncate(str string, width uint) string {
- if width == 0 {
- return ""
- }
-
- if len(str) <= int(width) {
- return str
+// FormatDocument formats a BSON document or RawValue for logging. The document is truncated
+// to the given width.
+func FormatDocument(msg bson.Raw, width uint) string {
+ if len(msg) == 0 {
+ return "{}"
}
- // Truncate the byte slice of the string to the given width.
- newStr := str[:width]
-
- // Check if the last byte is at the beginning of a multi-byte character.
- // If it is, then remove the last byte.
- if newStr[len(newStr)-1]&0xC0 == 0xC0 {
- return newStr[:len(newStr)-1] + TruncationSuffix
- }
+ str, truncated := bsoncore.Document(msg).StringN(int(width))
- // Check if the last byte is in the middle of a multi-byte character. If
- // it is, then step back until we find the beginning of the character.
- if newStr[len(newStr)-1]&0xC0 == 0x80 {
- for i := len(newStr) - 1; i >= 0; i-- {
- if newStr[i]&0xC0 == 0xC0 {
- return newStr[:i] + TruncationSuffix
- }
- }
+ if truncated {
+ str += TruncationSuffix
}
- return newStr + TruncationSuffix
+ return str
}
-// FormatMessage formats a BSON document for logging. The document is truncated
+// FormatString formats a String for logging. The string is truncated
// to the given width.
-func FormatMessage(msg string, width uint) string {
- if len(msg) == 0 {
- return "{}"
+func FormatString(str string, width uint) string {
+ strTrunc := bsoncoreutil.Truncate(str, int(width))
+
+ // Checks if the string was truncating by comparing the lengths of the two strings.
+ if len(strTrunc) < len(str) {
+ strTrunc += TruncationSuffix
}
- return truncate(msg, width)
+ return strTrunc
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go
new file mode 100644
index 000000000..be58d38bf
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go
@@ -0,0 +1,101 @@
+// Copyright (C) MongoDB, Inc. 2024-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 mongoutil
+
+import (
+ "context"
+ "reflect"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+)
+
+// NewOptions will functionally merge a slice of mongo.Options in a
+// "last-one-wins" manner, where nil options are ignored.
+func NewOptions[T any](opts ...options.Lister[T]) (*T, error) {
+ args := new(T)
+ for _, opt := range opts {
+ if opt == nil || reflect.ValueOf(opt).IsNil() {
+ // Do nothing if the option is nil or if opt is nil but implicitly cast as
+ // an Options interface by the NewArgsFromOptions function. The latter
+ // case would look something like this:
+ continue
+ }
+
+ for _, setArgs := range opt.List() {
+ if setArgs == nil {
+ continue
+ }
+
+ if err := setArgs(args); err != nil {
+ return nil, err
+ }
+ }
+ }
+ return args, nil
+}
+
+// OptionsLister implements an options.SetterLister object for an arbitrary
+// options type.
+type OptionsLister[T any] struct {
+ Options *T // Arguments to set on the option type
+ Callback func(*T) error // A callback for further modification
+}
+
+// List will re-assign the entire argument option to the Args field
+// defined on opts. If a callback exists, that function will be executed to
+// further modify the arguments.
+func (opts *OptionsLister[T]) List() []func(*T) error {
+ return []func(*T) error{
+ func(args *T) error {
+ if opts.Options != nil {
+ *args = *opts.Options
+ }
+
+ if opts.Callback != nil {
+ return opts.Callback(args)
+ }
+
+ return nil
+ },
+ }
+}
+
+// NewOptionsLister will construct a SetterLister from the provided Options
+// object.
+func NewOptionsLister[T any](args *T, callback func(*T) error) *OptionsLister[T] {
+ return &OptionsLister[T]{Options: args, Callback: callback}
+}
+
+// AuthFromURI will create a Credentials object given the provided URI.
+func AuthFromURI(uri string) (*options.Credential, error) {
+ opts := options.Client().ApplyURI(uri)
+
+ return opts.Auth, nil
+}
+
+// HostsFromURI will parse the hosts in the URI and return them as a slice of
+// strings.
+func HostsFromURI(uri string) ([]string, error) {
+ opts := options.Client().ApplyURI(uri)
+
+ return opts.Hosts, nil
+}
+
+// TimeoutWithinContext will return true if the provided timeout is nil or if
+// it is less than the context deadline. If the context does not have a
+// deadline, it will return true.
+func TimeoutWithinContext(ctx context.Context, timeout time.Duration) bool {
+ deadline, ok := ctx.Deadline()
+ if !ok {
+ return true
+ }
+
+ ctxTimeout := time.Until(deadline)
+
+ return ctxTimeout <= 0 || timeout < ctxTimeout
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go
new file mode 100644
index 000000000..5e7527c99
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go
@@ -0,0 +1,45 @@
+// Copyright (C) MongoDB, Inc. 2025-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 optionsutil
+
+// Options stores internal options.
+type Options struct {
+ values map[string]any
+}
+
+// WithValue sets an option value with the associated key.
+func WithValue(opts Options, key string, option any) Options {
+ if opts.values == nil {
+ opts.values = make(map[string]any)
+ }
+ opts.values[key] = option
+ return opts
+}
+
+// Value returns the value associated with the options for key.
+func Value(opts Options, key string) any {
+ if opts.values == nil {
+ return nil
+ }
+ if val, ok := opts.values[key]; ok {
+ return val
+ }
+ return nil
+}
+
+// Equal compares two Options instances for equality.
+func Equal(opts1, opts2 Options) bool {
+ if len(opts1.values) != len(opts2.values) {
+ return false
+ }
+ for key, val1 := range opts1.values {
+ if val2, ok := opts2.values[key]; !ok || val1 != val2 {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/ptrutil/int64.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/int64.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/ptrutil/int64.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/int64.go
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/util.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go
similarity index 57%
rename from vendor/go.mongodb.org/mongo-driver/mongo/util.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go
index 270fa24a2..bf64aad17 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/util.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go
@@ -1,7 +1,12 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
+// Copyright (C) MongoDB, Inc. 2024-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 mongo
+package ptrutil
+
+// Ptr will return the memory location of the given value.
+func Ptr[T any](val T) *T {
+ return &val
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/rand/bits.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/bits.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/rand/bits.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/rand/bits.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/rand/exp.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/internal/rand/exp.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go
index 859e4e0e4..f8ce78627 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/rand/exp.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go
@@ -100,6 +100,7 @@ var ke = [256]uint32{
0xf7b577d2, 0xf69c650c, 0xf51530f0, 0xf2cb0e3c, 0xeeefb15d,
0xe6da6ecf,
}
+
var we = [256]float32{
2.0249555e-09, 1.486674e-11, 2.4409617e-11, 3.1968806e-11,
3.844677e-11, 4.4228204e-11, 4.9516443e-11, 5.443359e-11,
@@ -166,6 +167,7 @@ var we = [256]float32{
1.2393786e-09, 1.276585e-09, 1.3193139e-09, 1.3695435e-09,
1.4305498e-09, 1.508365e-09, 1.6160854e-09, 1.7921248e-09,
}
+
var fe = [256]float32{
1, 0.9381437, 0.90046996, 0.87170434, 0.8477855, 0.8269933,
0.8084217, 0.7915276, 0.77595687, 0.7614634, 0.7478686,
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/rand/normal.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/internal/rand/normal.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go
index 8c74a358d..fcb067392 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/rand/normal.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go
@@ -94,6 +94,7 @@ var kn = [128]uint32{
0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a,
0x7ba90bdc, 0x7a722176, 0x77d664e5,
}
+
var wn = [128]float32{
1.7290405e-09, 1.2680929e-10, 1.6897518e-10, 1.9862688e-10,
2.2232431e-10, 2.4244937e-10, 2.601613e-10, 2.7611988e-10,
@@ -128,6 +129,7 @@ var wn = [128]float32{
1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09,
1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09,
}
+
var fn = [128]float32{
1, 0.9635997, 0.9362827, 0.9130436, 0.89228165, 0.87324303,
0.8555006, 0.8387836, 0.8229072, 0.8077383, 0.793177,
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/rand/rand.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rand.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/rand/rand.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rand.go
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/rand/rng.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rng.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/internal/rand/rng.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rng.go
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/jitter.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/jitter.go
new file mode 100644
index 000000000..5b221392a
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/jitter.go
@@ -0,0 +1,28 @@
+// Copyright (C) MongoDB, Inc. 2022-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 randutil
+
+var globalRand = NewLockedRand()
+
+var jitterInt63n func(int64) int64 = globalRand.Int63n
+
+// JitterInt63n returns, as an int64, a non-negative pseudo-random number in
+// the half-open interval [0,n). It panics if n <= 0.
+//
+// If a test jitter function is set by calling SetJitterForTesting, JitterInt63n
+// returns the value from the custom function.
+func JitterInt63n(n int64) int64 {
+ return jitterInt63n(n)
+}
+
+// SetJitterForTesting sets a custom jitter function for testing and returns a restore function.
+func SetJitterForTesting(f func(int64) int64) func() {
+ jitterInt63n = f
+ return func() {
+ jitterInt63n = globalRand.Int63n
+ }
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go
index dd8c6d6f4..82c8b8d00 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go
@@ -12,14 +12,14 @@ import (
"fmt"
"io"
- xrand "go.mongodb.org/mongo-driver/internal/rand"
+ xrand "go.mongodb.org/mongo-driver/v2/internal/rand"
)
// NewLockedRand returns a new "x/exp/rand" pseudo-random number generator seeded with a
// cryptographically-secure random number.
// It is safe to use from multiple goroutines.
func NewLockedRand() *xrand.Rand {
- var randSrc = new(xrand.LockedSource)
+ randSrc := new(xrand.LockedSource)
randSrc.Seed(cryptoSeed())
return xrand.New(randSrc)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go
new file mode 100644
index 000000000..81f06476a
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go
@@ -0,0 +1,413 @@
+// Copyright (C) MongoDB, Inc. 2024-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 serverselector
+
+import (
+ "fmt"
+ "math"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/tag"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+)
+
+// Composite combines multiple selectors into a single selector by applying them
+// in order to the candidates list.
+//
+// For example, if the initial candidates list is [s0, s1, s2, s3] and two
+// selectors are provided where the first matches s0 and s1 and the second
+// matches s1 and s2, the following would occur during server selection:
+//
+// 1. firstSelector([s0, s1, s2, s3]) -> [s0, s1]
+// 2. secondSelector([s0, s1]) -> [s1]
+//
+// The final list of candidates returned by the composite selector would be
+// [s1].
+type Composite struct {
+ Selectors []description.ServerSelector
+}
+
+var _ description.ServerSelector = &Composite{}
+
+// SelectServer combines multiple selectors into a single selector.
+func (selector *Composite) SelectServer(
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ var err error
+ for _, sel := range selector.Selectors {
+ candidates, err = sel.SelectServer(topo, candidates)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return candidates, nil
+}
+
+// Latency creates a ServerSelector which selects servers based on their average
+// RTT values.
+type Latency struct {
+ Latency time.Duration
+}
+
+var _ description.ServerSelector = &Latency{}
+
+// SelectServer selects servers based on average RTT.
+func (selector *Latency) SelectServer(
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ if selector.Latency < 0 {
+ return candidates, nil
+ }
+ if topo.Kind == description.TopologyKindLoadBalanced {
+ // In LoadBalanced mode, there should only be one server in the topology and
+ // it must be selected.
+ return candidates, nil
+ }
+
+ switch len(candidates) {
+ case 0, 1:
+ return candidates, nil
+ default:
+ min := time.Duration(math.MaxInt64)
+ for _, candidate := range candidates {
+ if candidate.AverageRTTSet {
+ if candidate.AverageRTT < min {
+ min = candidate.AverageRTT
+ }
+ }
+ }
+
+ if min == math.MaxInt64 {
+ return candidates, nil
+ }
+
+ max := min + selector.Latency
+
+ viableIndexes := make([]int, 0, len(candidates))
+ for i, candidate := range candidates {
+ if candidate.AverageRTTSet {
+ if candidate.AverageRTT <= max {
+ viableIndexes = append(viableIndexes, i)
+ }
+ }
+ }
+ if len(viableIndexes) == len(candidates) {
+ return candidates, nil
+ }
+ result := make([]description.Server, len(viableIndexes))
+ for i, idx := range viableIndexes {
+ result[i] = candidates[idx]
+ }
+ return result, nil
+ }
+}
+
+// ReadPref selects servers based on the provided read preference.
+type ReadPref struct {
+ ReadPref *readpref.ReadPref
+ IsOutputAggregate bool
+}
+
+var _ description.ServerSelector = &ReadPref{}
+
+// SelectServer selects servers based on read preference.
+func (selector *ReadPref) SelectServer(
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ if topo.Kind == description.TopologyKindLoadBalanced {
+ // In LoadBalanced mode, there should only be one server in the topology and
+ // it must be selected. We check this before checking MaxStaleness support
+ // because there's no monitoring in this mode, so the candidate server
+ // wouldn't have a wire version set, which would result in an error.
+ return candidates, nil
+ }
+
+ switch topo.Kind {
+ case description.TopologyKindSingle:
+ return candidates, nil
+ case description.TopologyKindReplicaSetNoPrimary, description.TopologyKindReplicaSetWithPrimary:
+ return selectForReplicaSet(selector.ReadPref, selector.IsOutputAggregate, topo, candidates)
+ case description.TopologyKindSharded:
+ return selectByKind(candidates, description.ServerKindMongos), nil
+ }
+
+ return nil, nil
+}
+
+// Write selects all the writable servers.
+type Write struct{}
+
+var _ description.ServerSelector = &Write{}
+
+// SelectServer selects all writable servers.
+func (selector *Write) SelectServer(
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ switch topo.Kind {
+ case description.TopologyKindSingle, description.TopologyKindLoadBalanced:
+ return candidates, nil
+ default:
+ // Determine the capacity of the results slice.
+ selected := 0
+ for _, candidate := range candidates {
+ switch candidate.Kind {
+ case description.ServerKindMongos, description.ServerKindRSPrimary, description.ServerKindStandalone:
+ selected++
+ }
+ }
+
+ // Append candidates to the results slice.
+ result := make([]description.Server, 0, selected)
+ for _, candidate := range candidates {
+ switch candidate.Kind {
+ case description.ServerKindMongos, description.ServerKindRSPrimary, description.ServerKindStandalone:
+ result = append(result, candidate)
+ }
+ }
+ return result, nil
+ }
+}
+
+// Deprioritized filters out deprioritized servers from candidates.
+// If all candidates are deprioritized, returns all candidates as fallback.
+type Deprioritized struct {
+ deprioritizedServers []description.Server
+ innerSelector description.ServerSelector
+}
+
+var _ description.ServerSelector = &Deprioritized{}
+
+// SelectServer filters out deprioritized servers from candidates.
+func (d *Deprioritized) SelectServer(
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ if len(d.deprioritizedServers) == 0 {
+ return d.innerSelector.SelectServer(topo, candidates)
+ }
+
+ deprioritizedAddrs := make(map[address.Address]struct{})
+ for _, srv := range d.deprioritizedServers {
+ deprioritizedAddrs[srv.Addr] = struct{}{}
+ }
+
+ allowed := []description.Server{}
+
+ // Iterate over the candidates and append them to the allowed slice if
+ // they are not in the deprioritizedServers list.
+ for _, candidate := range candidates {
+ if _, ok := deprioritizedAddrs[candidate.Addr]; !ok {
+ allowed = append(allowed, candidate)
+ }
+ }
+
+ if len(allowed) > 0 {
+ result, err := d.innerSelector.SelectServer(topo, allowed)
+ if err != nil {
+ return nil, err
+ }
+ if len(result) > 0 {
+ return result, nil
+ }
+ }
+ return d.innerSelector.SelectServer(topo, candidates)
+}
+
+// NewDeprioritized wraps an inner selector to filter out deprioritized servers.
+func NewDeprioritized(inner description.ServerSelector, deprioritized []description.Server) description.ServerSelector {
+ return &Deprioritized{
+ deprioritizedServers: deprioritized,
+ innerSelector: inner,
+ }
+}
+
+// Func is a function that can be used as a ServerSelector.
+type Func func(description.Topology, []description.Server) ([]description.Server, error)
+
+// SelectServer implements the ServerSelector interface.
+func (ssf Func) SelectServer(
+ t description.Topology,
+ s []description.Server,
+) ([]description.Server, error) {
+ return ssf(t, s)
+}
+
+func verifyMaxStaleness(rp *readpref.ReadPref, topo description.Topology) error {
+ maxStaleness, set := rp.MaxStaleness()
+ if !set {
+ return nil
+ }
+
+ if maxStaleness < 90*time.Second {
+ return fmt.Errorf("max staleness (%s) must be greater than or equal to 90s", maxStaleness)
+ }
+
+ if len(topo.Servers) < 1 {
+ // Maybe we should return an error here instead?
+ return nil
+ }
+
+ // we'll assume all candidates have the same heartbeat interval.
+ s := topo.Servers[0]
+ idleWritePeriod := 10 * time.Second
+
+ if maxStaleness < s.HeartbeatInterval+idleWritePeriod {
+ return fmt.Errorf(
+ "max staleness (%s) must be greater than or equal to the heartbeat interval (%s) plus idle write period (%s)",
+ maxStaleness, s.HeartbeatInterval, idleWritePeriod,
+ )
+ }
+
+ return nil
+}
+
+func selectByKind(candidates []description.Server, kind description.ServerKind) []description.Server {
+ // Record the indices of viable candidates first and then append those to the returned slice
+ // to avoid appending costly Server structs directly as an optimization.
+ viableIndexes := make([]int, 0, len(candidates))
+ for i, s := range candidates {
+ if s.Kind == kind {
+ viableIndexes = append(viableIndexes, i)
+ }
+ }
+ if len(viableIndexes) == len(candidates) {
+ return candidates
+ }
+ result := make([]description.Server, len(viableIndexes))
+ for i, idx := range viableIndexes {
+ result[i] = candidates[idx]
+ }
+ return result
+}
+
+func selectSecondaries(rp *readpref.ReadPref, candidates []description.Server) []description.Server {
+ secondaries := selectByKind(candidates, description.ServerKindRSSecondary)
+ if len(secondaries) == 0 {
+ return secondaries
+ }
+ if maxStaleness, set := rp.MaxStaleness(); set {
+ primaries := selectByKind(candidates, description.ServerKindRSPrimary)
+ if len(primaries) == 0 {
+ baseTime := secondaries[0].LastWriteTime
+ for i := 1; i < len(secondaries); i++ {
+ if secondaries[i].LastWriteTime.After(baseTime) {
+ baseTime = secondaries[i].LastWriteTime
+ }
+ }
+
+ var selected []description.Server
+ for _, secondary := range secondaries {
+ estimatedStaleness := baseTime.Sub(secondary.LastWriteTime) + secondary.HeartbeatInterval
+ if estimatedStaleness <= maxStaleness {
+ selected = append(selected, secondary)
+ }
+ }
+
+ return selected
+ }
+
+ primary := primaries[0]
+
+ var selected []description.Server
+ for _, secondary := range secondaries {
+ estimatedStaleness := secondary.LastUpdateTime.Sub(secondary.LastWriteTime) -
+ primary.LastUpdateTime.Sub(primary.LastWriteTime) + secondary.HeartbeatInterval
+ if estimatedStaleness <= maxStaleness {
+ selected = append(selected, secondary)
+ }
+ }
+ return selected
+ }
+
+ return secondaries
+}
+
+func selectByTagSet(candidates []description.Server, tagSets []tag.Set) []description.Server {
+ if len(tagSets) == 0 {
+ return candidates
+ }
+
+ for _, ts := range tagSets {
+ // If this tag set is empty, we can take a fast path because the empty list
+ // is a subset of all tag sets, so all candidate servers will be selected.
+ if len(ts) == 0 {
+ return candidates
+ }
+
+ var results []description.Server
+ for _, s := range candidates {
+ // ts is non-empty, so only servers with a non-empty set of tags need to be checked.
+ if len(s.Tags) > 0 && s.Tags.ContainsAll(ts) {
+ results = append(results, s)
+ }
+ }
+
+ if len(results) > 0 {
+ return results
+ }
+ }
+
+ return []description.Server{}
+}
+
+func selectForReplicaSet(
+ rp *readpref.ReadPref,
+ isOutputAggregate bool,
+ topo description.Topology,
+ candidates []description.Server,
+) ([]description.Server, error) {
+ if err := verifyMaxStaleness(rp, topo); err != nil {
+ return nil, err
+ }
+
+ // If underlying operation is an aggregate with an output stage, only apply read preference
+ // if all candidates are 5.0+. Otherwise, operate under primary read preference.
+ if isOutputAggregate {
+ for _, s := range candidates {
+ if s.WireVersion.Max < 13 {
+ return selectByKind(candidates, description.ServerKindRSPrimary), nil
+ }
+ }
+ }
+
+ switch rp.Mode() {
+ case readpref.PrimaryMode:
+ return selectByKind(candidates, description.ServerKindRSPrimary), nil
+ case readpref.PrimaryPreferredMode:
+ selected := selectByKind(candidates, description.ServerKindRSPrimary)
+
+ if len(selected) == 0 {
+ selected = selectSecondaries(rp, candidates)
+ return selectByTagSet(selected, rp.TagSets()), nil
+ }
+
+ return selected, nil
+ case readpref.SecondaryPreferredMode:
+ selected := selectSecondaries(rp, candidates)
+ selected = selectByTagSet(selected, rp.TagSets())
+ if len(selected) > 0 {
+ return selected, nil
+ }
+ return selectByKind(candidates, description.ServerKindRSPrimary), nil
+ case readpref.SecondaryMode:
+ selected := selectSecondaries(rp, candidates)
+ return selectByTagSet(selected, rp.TagSets()), nil
+ case readpref.NearestMode:
+ selected := selectByKind(candidates, description.ServerKindRSPrimary)
+ selected = append(selected, selectSecondaries(rp, candidates)...)
+ return selectByTagSet(selected, rp.TagSets()), nil
+ }
+
+ return nil, fmt.Errorf("unsupported mode: %d", rp.Mode())
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/internal/uuid/uuid.go b/vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/internal/uuid/uuid.go
rename to vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go
index 86c2a33a7..be233bb96 100644
--- a/vendor/go.mongodb.org/mongo-driver/internal/uuid/uuid.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go
@@ -10,7 +10,7 @@ import (
"encoding/hex"
"io"
- "go.mongodb.org/mongo-driver/internal/randutil"
+ "go.mongodb.org/mongo-driver/v2/internal/randutil"
)
// UUID represents a UUID.
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/address/addr.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/address/addr.go
similarity index 89%
rename from vendor/go.mongodb.org/mongo-driver/mongo/address/addr.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/address/addr.go
index fb6abbcd7..e740ad9c8 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/address/addr.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/address/addr.go
@@ -5,7 +5,7 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Package address provides structured representations of network addresses.
-package address // import "go.mongodb.org/mongo-driver/mongo/address"
+package address
import (
"net"
@@ -29,8 +29,11 @@ func (a Address) Network() string {
// String is the canonical version of this address, e.g. localhost:27017,
// 1.2.3.4:27017, example.com:27017.
func (a Address) String() string {
- // TODO: unicode case folding?
- s := strings.ToLower(string(a))
+ s := string(a)
+ if a.Network() != "unix" {
+ // TODO: unicode case folding?
+ s = strings.ToLower(string(a))
+ }
if len(s) == 0 {
return ""
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/background_context.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/background_context.go
similarity index 94%
rename from vendor/go.mongodb.org/mongo-driver/mongo/background_context.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/background_context.go
index e4146e8b7..0fac08689 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/background_context.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/background_context.go
@@ -29,6 +29,6 @@ func newBackgroundContext(ctx context.Context) context.Context {
}
}
-func (b *backgroundContext) Value(key interface{}) interface{} {
+func (b *backgroundContext) Value(key any) any {
return b.childValuesCtx.Value(key)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/batch_cursor.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/batch_cursor.go
similarity index 81%
rename from vendor/go.mongodb.org/mongo-driver/mongo/batch_cursor.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/batch_cursor.go
index 51d59d0ff..fc6f76040 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/batch_cursor.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/batch_cursor.go
@@ -10,8 +10,8 @@ import (
"context"
"time"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
// batchCursor is the interface implemented by types that can provide batches of document results.
@@ -25,7 +25,7 @@ type batchCursor interface {
// Batch will return a DocumentSequence for the current batch of documents. The returned
// DocumentSequence is only valid until the next call to Next or Close.
- Batch() *bsoncore.DocumentSequence
+ Batch() *bsoncore.Iterator
// Server returns a pointer to the cursor's server.
Server() driver.Server
@@ -40,17 +40,22 @@ type batchCursor interface {
// the cursor that implements it.
SetBatchSize(int32)
- // SetMaxTime will set the maximum amount of time the server will allow
+ // SetMaxAwaitTime will set the maximum amount of time the server will allow
// the operations to execute. The server will error if this field is set
// but the cursor is not configured with awaitData=true.
//
// The time.Duration value passed by this setter will be converted and
// rounded down to the nearest millisecond.
- SetMaxTime(time.Duration)
+ SetMaxAwaitTime(time.Duration)
// SetComment will set a user-configurable comment that can be used to
// identify the operation in server logs.
- SetComment(interface{})
+ SetComment(any)
+
+ // MaxAwaitTime returns the maximum amount of time the server will allow
+ // the operations to execute. This is only valid for tailable awaitData
+ // cursors.
+ MaxAwaitTime() *time.Duration
}
// changeStreamCursor is the interface implemented by batch cursors that also provide the functionality for retrieving
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write.go
similarity index 73%
rename from vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write.go
index 81dfbb1d8..1065cdfd0 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write.go
@@ -9,16 +9,16 @@ package mongo
import (
"context"
"errors"
-
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "fmt"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
type bulkWriteBatch struct {
@@ -29,7 +29,7 @@ type bulkWriteBatch struct {
// bulkWrite performs a bulkwrite operation
type bulkWrite struct {
- comment interface{}
+ comment any
ordered *bool
bypassDocumentValidation *bool
models []WriteModel
@@ -38,8 +38,9 @@ type bulkWrite struct {
selector description.ServerSelector
writeConcern *writeconcern.WriteConcern
result BulkWriteResult
- let interface{}
- bypassEmptyTsReplacement *bool
+ let any
+ rawData *bool
+ additionalCmd bson.D
}
func (bw *bulkWrite) execute(ctx context.Context) error {
@@ -50,7 +51,7 @@ func (bw *bulkWrite) execute(ctx context.Context) error {
batches := createBatches(bw.models, ordered)
bw.result = BulkWriteResult{
- UpsertedIDs: make(map[int64]interface{}),
+ UpsertedIDs: make(map[int64]any),
}
bwErr := BulkWriteException{
@@ -89,10 +90,14 @@ func (bw *bulkWrite) execute(ctx context.Context) error {
}
bw.result.MatchedCount -= bw.result.UpsertedCount
- if lastErr != nil {
- _, lastErr = processWriteError(lastErr)
- return lastErr
+
+ rr, err := processWriteError(lastErr)
+ if err != nil {
+ return err
}
+
+ bw.result.Acknowledged = rr.isAcknowledged()
+
if len(bwErr.WriteErrors) > 0 || bwErr.WriteConcernError != nil {
return bwErr
}
@@ -101,7 +106,7 @@ func (bw *bulkWrite) execute(ctx context.Context) error {
func (bw *bulkWrite) runBatch(ctx context.Context, batch bulkWriteBatch) (BulkWriteResult, BulkWriteException, error) {
batchRes := BulkWriteResult{
- UpsertedIDs: make(map[int64]interface{}),
+ UpsertedIDs: make(map[int64]any),
}
batchErr := BulkWriteException{}
@@ -163,53 +168,69 @@ func (bw *bulkWrite) runBatch(ctx context.Context, batch bulkWriteBatch) (BulkWr
return batchRes, batchErr, nil
}
-func (bw *bulkWrite) runInsert(ctx context.Context, batch bulkWriteBatch) (operation.InsertResult, error) {
+func (bw *bulkWrite) runInsert(ctx context.Context, batch bulkWriteBatch) (insertResult, error) {
docs := make([]bsoncore.Document, len(batch.models))
- var i int
- for _, model := range batch.models {
+ for i, model := range batch.models {
converted := model.(*InsertOneModel)
doc, err := marshal(converted.Document, bw.collection.bsonOpts, bw.collection.registry)
if err != nil {
- return operation.InsertResult{}, err
+ return insertResult{}, err
}
- doc, _, err = ensureID(doc, primitive.NilObjectID, bw.collection.bsonOpts, bw.collection.registry)
+ doc, _, err = ensureID(doc, bson.NilObjectID, bw.collection.bsonOpts, bw.collection.registry)
if err != nil {
- return operation.InsertResult{}, err
+ return insertResult{}, err
}
docs[i] = doc
- i++
}
- op := operation.NewInsert(docs...).
- Session(bw.session).WriteConcern(bw.writeConcern).CommandMonitor(bw.collection.client.monitor).
- ServerSelector(bw.selector).ClusterClock(bw.collection.client.clock).
- Database(bw.collection.db.name).Collection(bw.collection.name).
- Deployment(bw.collection.client.deployment).Crypt(bw.collection.client.cryptFLE).
- ServerAPI(bw.collection.client.serverAPI).Timeout(bw.collection.client.timeout).
- Logger(bw.collection.client.logger).Authenticator(bw.collection.client.authenticator)
+ maxAdaptiveRetries := bw.collection.client.effectiveAdaptiveRetries(bw.collection.client.retryWrites)
+
+ op := insert{
+ documents: docs,
+ session: bw.session,
+ writeConcern: bw.writeConcern,
+ monitor: bw.collection.client.monitor,
+ selector: bw.selector,
+ clock: bw.collection.client.clock,
+ database: bw.collection.db.name,
+ collection: bw.collection.name,
+ deployment: bw.collection.client.deployment,
+ crypt: bw.collection.client.cryptFLE,
+ serverAPI: bw.collection.client.serverAPI,
+ timeout: bw.collection.client.timeout,
+ logger: bw.collection.client.logger,
+ authenticator: bw.collection.client.authenticator,
+
+ maxAdaptiveRetries: maxAdaptiveRetries,
+ enableOverloadRetargeting: bw.collection.client.enableOverloadRetargeting,
+ }
+
if bw.comment != nil {
comment, err := marshalValue(bw.comment, bw.collection.bsonOpts, bw.collection.registry)
if err != nil {
return op.Result(), err
}
- op.Comment(comment)
+ op.comment = comment
}
if bw.bypassDocumentValidation != nil && *bw.bypassDocumentValidation {
- op = op.BypassDocumentValidation(*bw.bypassDocumentValidation)
+ op.bypassDocumentValidation = bw.bypassDocumentValidation
}
if bw.ordered != nil {
- op = op.Ordered(*bw.ordered)
+ op.ordered = bw.ordered
}
retry := driver.RetryNone
if bw.collection.client.retryWrites && batch.canRetry {
retry = driver.RetryOncePerCommand
}
- op = op.Retry(retry)
+ op.retry = &retry
- if bw.bypassEmptyTsReplacement != nil {
- op.BypassEmptyTsReplacement(*bw.bypassEmptyTsReplacement)
+ if bw.rawData != nil {
+ op.rawData = bw.rawData
+ }
+ if len(bw.additionalCmd) > 0 {
+ op.additionalCmd = bw.additionalCmd
}
err := op.Execute(ctx)
@@ -255,10 +276,19 @@ func (bw *bulkWrite) runDelete(ctx context.Context, batch bulkWriteBatch) (opera
i++
}
+ retry := driver.RetryNone
+ if bw.collection.client.retryWrites && batch.canRetry {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := bw.collection.client.effectiveAdaptiveRetries(bw.collection.client.retryWrites)
+
op := operation.NewDelete(docs...).
Session(bw.session).WriteConcern(bw.writeConcern).CommandMonitor(bw.collection.client.monitor).
ServerSelector(bw.selector).ClusterClock(bw.collection.client.clock).
Database(bw.collection.db.name).Collection(bw.collection.name).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(bw.collection.client.enableOverloadRetargeting).
Deployment(bw.collection.client.deployment).Crypt(bw.collection.client.cryptFLE).Hint(hasHint).
ServerAPI(bw.collection.client.serverAPI).Timeout(bw.collection.client.timeout).
Logger(bw.collection.client.logger).Authenticator(bw.collection.client.authenticator)
@@ -279,11 +309,10 @@ func (bw *bulkWrite) runDelete(ctx context.Context, batch bulkWriteBatch) (opera
if bw.ordered != nil {
op = op.Ordered(*bw.ordered)
}
- retry := driver.RetryNone
- if bw.collection.client.retryWrites && batch.canRetry {
- retry = driver.RetryOncePerCommand
+
+ if bw.rawData != nil {
+ op.RawData(*bw.rawData)
}
- op = op.Retry(retry)
err := op.Execute(ctx)
@@ -291,13 +320,16 @@ func (bw *bulkWrite) runDelete(ctx context.Context, batch bulkWriteBatch) (opera
}
func createDeleteDoc(
- filter interface{},
+ filter any,
collation *options.Collation,
- hint interface{},
+ hint any,
deleteOne bool,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
) (bsoncore.Document, error) {
+ if filter == nil {
+ return nil, fmt.Errorf("delete filter cannot be nil")
+ }
f, err := marshal(filter, bsonOpts, registry)
if err != nil {
return nil, err
@@ -311,7 +343,7 @@ func createDeleteDoc(
doc = bsoncore.AppendDocumentElement(doc, "q", f)
doc = bsoncore.AppendInt32Element(doc, "limit", limit)
if collation != nil {
- doc = bsoncore.AppendDocumentElement(doc, "collation", collation.ToDocument())
+ doc = bsoncore.AppendDocumentElement(doc, "collation", toDocument(collation))
}
if hint != nil {
if isUnorderedMap(hint) {
@@ -338,44 +370,39 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera
switch converted := model.(type) {
case *ReplaceOneModel:
- doc, err = createUpdateDoc(
- converted.Filter,
- converted.Replacement,
- converted.Hint,
- nil,
- converted.Collation,
- converted.Upsert,
- false,
- false,
- bw.collection.bsonOpts,
- bw.collection.registry)
+ doc, err = updateDoc{
+ filter: converted.Filter,
+ update: converted.Replacement,
+ hint: converted.Hint,
+ sort: converted.Sort,
+ collation: converted.Collation,
+ upsert: converted.Upsert,
+ }.marshal(bw.collection.bsonOpts, bw.collection.registry)
hasHint = hasHint || (converted.Hint != nil)
case *UpdateOneModel:
- doc, err = createUpdateDoc(
- converted.Filter,
- converted.Update,
- converted.Hint,
- converted.ArrayFilters,
- converted.Collation,
- converted.Upsert,
- false,
- true,
- bw.collection.bsonOpts,
- bw.collection.registry)
+ doc, err = updateDoc{
+ filter: converted.Filter,
+ update: converted.Update,
+ hint: converted.Hint,
+ sort: converted.Sort,
+ arrayFilters: converted.ArrayFilters,
+ collation: converted.Collation,
+ upsert: converted.Upsert,
+ checkDollarKey: true,
+ }.marshal(bw.collection.bsonOpts, bw.collection.registry)
hasHint = hasHint || (converted.Hint != nil)
hasArrayFilters = hasArrayFilters || (converted.ArrayFilters != nil)
case *UpdateManyModel:
- doc, err = createUpdateDoc(
- converted.Filter,
- converted.Update,
- converted.Hint,
- converted.ArrayFilters,
- converted.Collation,
- converted.Upsert,
- true,
- true,
- bw.collection.bsonOpts,
- bw.collection.registry)
+ doc, err = updateDoc{
+ filter: converted.Filter,
+ update: converted.Update,
+ hint: converted.Hint,
+ arrayFilters: converted.ArrayFilters,
+ collation: converted.Collation,
+ upsert: converted.Upsert,
+ multi: true,
+ checkDollarKey: true,
+ }.marshal(bw.collection.bsonOpts, bw.collection.registry)
hasHint = hasHint || (converted.Hint != nil)
hasArrayFilters = hasArrayFilters || (converted.ArrayFilters != nil)
}
@@ -386,10 +413,19 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera
docs[i] = doc
}
+ retry := driver.RetryNone
+ if bw.collection.client.retryWrites && batch.canRetry {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := bw.collection.client.effectiveAdaptiveRetries(bw.collection.client.retryWrites)
+
op := operation.NewUpdate(docs...).
Session(bw.session).WriteConcern(bw.writeConcern).CommandMonitor(bw.collection.client.monitor).
ServerSelector(bw.selector).ClusterClock(bw.collection.client.clock).
Database(bw.collection.db.name).Collection(bw.collection.name).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(bw.collection.client.enableOverloadRetargeting).
Deployment(bw.collection.client.deployment).Crypt(bw.collection.client.cryptFLE).Hint(hasHint).
ArrayFilters(hasArrayFilters).ServerAPI(bw.collection.client.serverAPI).
Timeout(bw.collection.client.timeout).Logger(bw.collection.client.logger).
@@ -414,14 +450,12 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera
if bw.bypassDocumentValidation != nil && *bw.bypassDocumentValidation {
op = op.BypassDocumentValidation(*bw.bypassDocumentValidation)
}
- retry := driver.RetryNone
- if bw.collection.client.retryWrites && batch.canRetry {
- retry = driver.RetryOncePerCommand
- }
- op = op.Retry(retry)
- if bw.bypassEmptyTsReplacement != nil {
- op.BypassEmptyTsReplacement(*bw.bypassEmptyTsReplacement)
+ if bw.rawData != nil {
+ op.RawData(*bw.rawData)
+ }
+ if len(bw.additionalCmd) > 0 {
+ op.AdditionalCmd(bw.additionalCmd)
}
err := op.Execute(ctx)
@@ -429,19 +463,23 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera
return op.Result(), err
}
-func createUpdateDoc(
- filter interface{},
- update interface{},
- hint interface{},
- arrayFilters *options.ArrayFilters,
- collation *options.Collation,
- upsert *bool,
- multi bool,
- checkDollarKey bool,
- bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
-) (bsoncore.Document, error) {
- f, err := marshal(filter, bsonOpts, registry)
+type updateDoc struct {
+ filter any
+ update any
+ hint any
+ sort any
+ arrayFilters []any
+ collation *options.Collation
+ upsert *bool
+ multi bool
+ checkDollarKey bool
+}
+
+func (doc updateDoc) marshal(bsonOpts *options.BSONOptions, registry *bson.Registry) (bsoncore.Document, error) {
+ if doc.filter == nil {
+ return nil, fmt.Errorf("update filter cannot be nil")
+ }
+ f, err := marshal(doc.filter, bsonOpts, registry)
if err != nil {
return nil, err
}
@@ -449,42 +487,49 @@ func createUpdateDoc(
uidx, updateDoc := bsoncore.AppendDocumentStart(nil)
updateDoc = bsoncore.AppendDocumentElement(updateDoc, "q", f)
- u, err := marshalUpdateValue(update, bsonOpts, registry, checkDollarKey)
+ u, err := marshalUpdateValue(doc.update, bsonOpts, registry, doc.checkDollarKey)
if err != nil {
return nil, err
}
updateDoc = bsoncore.AppendValueElement(updateDoc, "u", u)
- if multi {
- updateDoc = bsoncore.AppendBooleanElement(updateDoc, "multi", multi)
+ if doc.multi {
+ updateDoc = bsoncore.AppendBooleanElement(updateDoc, "multi", doc.multi)
+ }
+ if doc.sort != nil {
+ if isUnorderedMap(doc.sort) {
+ return nil, ErrMapForOrderedArgument{"sort"}
+ }
+ s, err := marshal(doc.sort, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ updateDoc = bsoncore.AppendDocumentElement(updateDoc, "sort", s)
}
- if arrayFilters != nil {
+ if doc.arrayFilters != nil {
reg := registry
- if arrayFilters.Registry != nil {
- reg = arrayFilters.Registry
- }
- arr, err := marshalValue(arrayFilters.Filters, bsonOpts, reg)
+ arr, err := marshalValue(doc.arrayFilters, bsonOpts, reg)
if err != nil {
return nil, err
}
updateDoc = bsoncore.AppendArrayElement(updateDoc, "arrayFilters", arr.Data)
}
- if collation != nil {
- updateDoc = bsoncore.AppendDocumentElement(updateDoc, "collation", bsoncore.Document(collation.ToDocument()))
+ if doc.collation != nil {
+ updateDoc = bsoncore.AppendDocumentElement(updateDoc, "collation", bsoncore.Document(toDocument(doc.collation)))
}
- if upsert != nil {
- updateDoc = bsoncore.AppendBooleanElement(updateDoc, "upsert", *upsert)
+ if doc.upsert != nil {
+ updateDoc = bsoncore.AppendBooleanElement(updateDoc, "upsert", *doc.upsert)
}
- if hint != nil {
- if isUnorderedMap(hint) {
+ if doc.hint != nil {
+ if isUnorderedMap(doc.hint) {
return nil, ErrMapForOrderedArgument{"hint"}
}
- hintVal, err := marshalValue(hint, bsonOpts, registry)
+ hintVal, err := marshalValue(doc.hint, bsonOpts, registry)
if err != nil {
return nil, err
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write_models.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write_models.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/mongo/bulk_write_models.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write_models.go
index 64f458918..f28af163b 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write_models.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write_models.go
@@ -7,7 +7,7 @@
package mongo
import (
- "go.mongodb.org/mongo-driver/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
)
// WriteModel is an interface implemented by models that can be used in a BulkWrite operation. Each WriteModel
@@ -20,8 +20,10 @@ type WriteModel interface {
}
// InsertOneModel is used to insert a single document in a BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
type InsertOneModel struct {
- Document interface{}
+ Document any
}
// NewInsertOneModel creates a new InsertOneModel.
@@ -32,7 +34,7 @@ func NewInsertOneModel() *InsertOneModel {
// SetDocument specifies the document to be inserted. The document cannot be nil. If it does not have an _id field when
// transformed into BSON, one will be added automatically to the marshalled document. The original document will not be
// modified.
-func (iom *InsertOneModel) SetDocument(doc interface{}) *InsertOneModel {
+func (iom *InsertOneModel) SetDocument(doc any) *InsertOneModel {
iom.Document = doc
return iom
}
@@ -40,10 +42,12 @@ func (iom *InsertOneModel) SetDocument(doc interface{}) *InsertOneModel {
func (*InsertOneModel) writeModel() {}
// DeleteOneModel is used to delete at most one document in a BulkWriteOperation.
+//
+// See corresponding setter methods for documentation.
type DeleteOneModel struct {
- Filter interface{}
+ Filter any
Collation *options.Collation
- Hint interface{}
+ Hint any
}
// NewDeleteOneModel creates a new DeleteOneModel.
@@ -54,7 +58,7 @@ func NewDeleteOneModel() *DeleteOneModel {
// SetFilter specifies a filter to use to select the document to delete. The filter must be a document containing query
// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
// documents.
-func (dom *DeleteOneModel) SetFilter(filter interface{}) *DeleteOneModel {
+func (dom *DeleteOneModel) SetFilter(filter any) *DeleteOneModel {
dom.Filter = filter
return dom
}
@@ -66,13 +70,14 @@ func (dom *DeleteOneModel) SetCollation(collation *options.Collation) *DeleteOne
return dom
}
-// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
-// specification as a document. This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.4 will
-// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
-// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
-// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
-// means that no hint will be sent.
-func (dom *DeleteOneModel) SetHint(hint interface{}) *DeleteOneModel {
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 4.4. Server versions < 4.4 will
+// return an error if this option is specified. The driver will return an error
+// if this option is specified during an unacknowledged write operation. The
+// driver will return an error if the hint parameter is a multi-key map. The
+// default value is nil, which means that no hint will be sent.
+func (dom *DeleteOneModel) SetHint(hint any) *DeleteOneModel {
dom.Hint = hint
return dom
}
@@ -80,10 +85,12 @@ func (dom *DeleteOneModel) SetHint(hint interface{}) *DeleteOneModel {
func (*DeleteOneModel) writeModel() {}
// DeleteManyModel is used to delete multiple documents in a BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
type DeleteManyModel struct {
- Filter interface{}
+ Filter any
Collation *options.Collation
- Hint interface{}
+ Hint any
}
// NewDeleteManyModel creates a new DeleteManyModel.
@@ -93,7 +100,7 @@ func NewDeleteManyModel() *DeleteManyModel {
// SetFilter specifies a filter to use to select documents to delete. The filter must be a document containing query
// operators. It cannot be nil.
-func (dmm *DeleteManyModel) SetFilter(filter interface{}) *DeleteManyModel {
+func (dmm *DeleteManyModel) SetFilter(filter any) *DeleteManyModel {
dmm.Filter = filter
return dmm
}
@@ -105,13 +112,14 @@ func (dmm *DeleteManyModel) SetCollation(collation *options.Collation) *DeleteMa
return dmm
}
-// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
-// specification as a document. This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.4 will
-// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
-// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
-// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
-// means that no hint will be sent.
-func (dmm *DeleteManyModel) SetHint(hint interface{}) *DeleteManyModel {
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 4.4. Server versions < 4.4 will
+// return an error if this option is specified. The driver will return an error
+// if this option is specified during an unacknowledged write operation. The
+// driver will return an error if the hint parameter is a multi-key map. The
+// default value is nil, which means that no hint will be sent.
+func (dmm *DeleteManyModel) SetHint(hint any) *DeleteManyModel {
dmm.Hint = hint
return dmm
}
@@ -119,12 +127,15 @@ func (dmm *DeleteManyModel) SetHint(hint interface{}) *DeleteManyModel {
func (*DeleteManyModel) writeModel() {}
// ReplaceOneModel is used to replace at most one document in a BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
type ReplaceOneModel struct {
Collation *options.Collation
Upsert *bool
- Filter interface{}
- Replacement interface{}
- Hint interface{}
+ Filter any
+ Replacement any
+ Hint any
+ Sort any
}
// NewReplaceOneModel creates a new ReplaceOneModel.
@@ -132,13 +143,14 @@ func NewReplaceOneModel() *ReplaceOneModel {
return &ReplaceOneModel{}
}
-// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
-// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
-// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
-// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
-// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
-// means that no hint will be sent.
-func (rom *ReplaceOneModel) SetHint(hint interface{}) *ReplaceOneModel {
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 4.2. Server versions < 4.2 will
+// return an error if this option is specified. The driver will return an error
+// if this option is specified during an unacknowledged write operation. The
+// driver will return an error if the hint parameter is a multi-key map. The
+// default value is nil, which means that no hint will be sent.
+func (rom *ReplaceOneModel) SetHint(hint any) *ReplaceOneModel {
rom.Hint = hint
return rom
}
@@ -146,14 +158,14 @@ func (rom *ReplaceOneModel) SetHint(hint interface{}) *ReplaceOneModel {
// SetFilter specifies a filter to use to select the document to replace. The filter must be a document containing query
// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
// documents.
-func (rom *ReplaceOneModel) SetFilter(filter interface{}) *ReplaceOneModel {
+func (rom *ReplaceOneModel) SetFilter(filter any) *ReplaceOneModel {
rom.Filter = filter
return rom
}
// SetReplacement specifies a document that will be used to replace the selected document. It cannot be nil and cannot
// contain any update operators (https://www.mongodb.com/docs/manual/reference/operator/update/).
-func (rom *ReplaceOneModel) SetReplacement(rep interface{}) *ReplaceOneModel {
+func (rom *ReplaceOneModel) SetReplacement(rep any) *ReplaceOneModel {
rom.Replacement = rep
return rom
}
@@ -173,16 +185,28 @@ func (rom *ReplaceOneModel) SetUpsert(upsert bool) *ReplaceOneModel {
return rom
}
+// SetSort specifies which document the operation replaces if the query matches multiple documents. The first document
+// matched by the sort order will be replaced. This option is only valid for MongoDB versions >= 8.0. The sort parameter
+// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
+// default value is nil.
+func (rom *ReplaceOneModel) SetSort(sort any) *ReplaceOneModel {
+ rom.Sort = sort
+ return rom
+}
+
func (*ReplaceOneModel) writeModel() {}
// UpdateOneModel is used to update at most one document in a BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
type UpdateOneModel struct {
Collation *options.Collation
Upsert *bool
- Filter interface{}
- Update interface{}
- ArrayFilters *options.ArrayFilters
- Hint interface{}
+ Filter any
+ Update any
+ ArrayFilters []any
+ Hint any
+ Sort any
}
// NewUpdateOneModel creates a new UpdateOneModel.
@@ -190,13 +214,14 @@ func NewUpdateOneModel() *UpdateOneModel {
return &UpdateOneModel{}
}
-// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
-// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
-// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
-// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
-// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
-// means that no hint will be sent.
-func (uom *UpdateOneModel) SetHint(hint interface{}) *UpdateOneModel {
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 4.2. Server versions < 4.2 will
+// return an error if this option is specified. The driver will return an error
+// if this option is specified during an unacknowledged write operation. The
+// driver will return an error if the hint parameter is a multi-key map. The
+// default value is nil, which means that no hint will be sent.
+func (uom *UpdateOneModel) SetHint(hint any) *UpdateOneModel {
uom.Hint = hint
return uom
}
@@ -204,22 +229,22 @@ func (uom *UpdateOneModel) SetHint(hint interface{}) *UpdateOneModel {
// SetFilter specifies a filter to use to select the document to update. The filter must be a document containing query
// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
// documents.
-func (uom *UpdateOneModel) SetFilter(filter interface{}) *UpdateOneModel {
+func (uom *UpdateOneModel) SetFilter(filter any) *UpdateOneModel {
uom.Filter = filter
return uom
}
// SetUpdate specifies the modifications to be made to the selected document. The value must be a document containing
// update operators (https://www.mongodb.com/docs/manual/reference/operator/update/). It cannot be nil or empty.
-func (uom *UpdateOneModel) SetUpdate(update interface{}) *UpdateOneModel {
+func (uom *UpdateOneModel) SetUpdate(update any) *UpdateOneModel {
uom.Update = update
return uom
}
// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
// field.
-func (uom *UpdateOneModel) SetArrayFilters(filters options.ArrayFilters) *UpdateOneModel {
- uom.ArrayFilters = &filters
+func (uom *UpdateOneModel) SetArrayFilters(filters []any) *UpdateOneModel {
+ uom.ArrayFilters = filters
return uom
}
@@ -238,16 +263,27 @@ func (uom *UpdateOneModel) SetUpsert(upsert bool) *UpdateOneModel {
return uom
}
+// SetSort specifies which document the operation updates if the query matches multiple documents. The first document
+// matched by the sort order will be updated. This option is only valid for MongoDB versions >= 8.0. The sort parameter
+// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
+// default value is nil.
+func (uom *UpdateOneModel) SetSort(sort any) *UpdateOneModel {
+ uom.Sort = sort
+ return uom
+}
+
func (*UpdateOneModel) writeModel() {}
// UpdateManyModel is used to update multiple documents in a BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
type UpdateManyModel struct {
Collation *options.Collation
Upsert *bool
- Filter interface{}
- Update interface{}
- ArrayFilters *options.ArrayFilters
- Hint interface{}
+ Filter any
+ Update any
+ ArrayFilters []any
+ Hint any
}
// NewUpdateManyModel creates a new UpdateManyModel.
@@ -255,35 +291,36 @@ func NewUpdateManyModel() *UpdateManyModel {
return &UpdateManyModel{}
}
-// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
-// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
-// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
-// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
-// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
-// means that no hint will be sent.
-func (umm *UpdateManyModel) SetHint(hint interface{}) *UpdateManyModel {
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 4.2. Server versions < 4.2 will
+// return an error if this option is specified. The driver will return an error
+// if this option is specified during an unacknowledged write operation. The
+// driver will return an error if the hint parameter is a multi-key map. The
+// default value is nil, which means that no hint will be sent.
+func (umm *UpdateManyModel) SetHint(hint any) *UpdateManyModel {
umm.Hint = hint
return umm
}
// SetFilter specifies a filter to use to select documents to update. The filter must be a document containing query
// operators. It cannot be nil.
-func (umm *UpdateManyModel) SetFilter(filter interface{}) *UpdateManyModel {
+func (umm *UpdateManyModel) SetFilter(filter any) *UpdateManyModel {
umm.Filter = filter
return umm
}
// SetUpdate specifies the modifications to be made to the selected documents. The value must be a document containing
// update operators (https://www.mongodb.com/docs/manual/reference/operator/update/). It cannot be nil or empty.
-func (umm *UpdateManyModel) SetUpdate(update interface{}) *UpdateManyModel {
+func (umm *UpdateManyModel) SetUpdate(update any) *UpdateManyModel {
umm.Update = update
return umm
}
// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
// field.
-func (umm *UpdateManyModel) SetArrayFilters(filters options.ArrayFilters) *UpdateManyModel {
- umm.ArrayFilters = &filters
+func (umm *UpdateManyModel) SetArrayFilters(filters []any) *UpdateManyModel {
+ umm.ArrayFilters = filters
return umm
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream.go
similarity index 73%
rename from vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream.go
index 3ea8baf1f..647e0a596 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream.go
@@ -12,20 +12,20 @@ import (
"fmt"
"reflect"
"strconv"
- "time"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
var (
@@ -81,11 +81,11 @@ type ChangeStream struct {
sess *session.Client
client *Client
bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
+ registry *bson.Registry
streamType StreamType
options *options.ChangeStreamOptions
selector description.ServerSelector
- operationTime *primitive.Timestamp
+ operationTime *bson.Timestamp
wireVersion *description.VersionRange
}
@@ -94,33 +94,41 @@ type changeStreamConfig struct {
readPreference *readpref.ReadPref
client *Client
bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
+ registry *bson.Registry
streamType StreamType
collectionName string
databaseName string
crypt driver.Crypt
}
-func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline interface{},
- opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline any,
+ opts ...options.Lister[options.ChangeStreamOptions],
+) (*ChangeStream, error) {
if ctx == nil {
ctx = context.Background()
}
- cursorOpts := config.client.createBaseCursorOptions()
+ cursorOpts := config.client.createBaseCursorOptions(config.client.retryReads)
cursorOpts.MarshalValueEncoderFn = newEncoderFn(config.bsonOpts, config.registry)
+ args, err := mongoutil.NewOptions[options.ChangeStreamOptions](opts...)
+ if err != nil {
+ return nil, err
+ }
+
cs := &ChangeStream{
client: config.client,
bsonOpts: config.bsonOpts,
registry: config.registry,
streamType: config.streamType,
- options: options.MergeChangeStreamOptions(opts...),
- selector: description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(config.readPreference),
- description.LatencySelector(config.client.localThreshold),
- }),
+ options: args,
+ selector: &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: config.readPreference},
+ &serverselector.Latency{Latency: config.client.localThreshold},
+ },
+ },
cursorOptions: cursorOpts,
}
@@ -136,41 +144,42 @@ func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline in
cs.aggregate = operation.NewAggregate(nil).
ReadPreference(config.readPreference).ReadConcern(config.readConcern).
Deployment(cs.client.deployment).ClusterClock(cs.client.clock).
- CommandMonitor(cs.client.monitor).Session(cs.sess).ServerSelector(cs.selector).Retry(driver.RetryNone).
+ CommandMonitor(cs.client.monitor).Session(cs.sess).ServerSelector(cs.selector).
+ Retry(driver.RetryNone).MaxAdaptiveRetries(cursorOpts.MaxAdaptiveRetries).
+ EnableOverloadRetargeting(cursorOpts.EnableOverloadRetargeting).
ServerAPI(cs.client.serverAPI).Crypt(config.crypt).Timeout(cs.client.timeout).
Authenticator(cs.client.authenticator)
if cs.options.Collation != nil {
- cs.aggregate.Collation(bsoncore.Document(cs.options.Collation.ToDocument()))
+ cs.aggregate.Collation(bsoncore.Document(toDocument(cs.options.Collation)))
}
- if comment := cs.options.Comment; comment != nil {
- cs.aggregate.Comment(*comment)
-
- commentVal, err := marshalValue(comment, cs.bsonOpts, cs.registry)
+ if cs.options.Comment != nil {
+ comment, err := marshalValue(cs.options.Comment, cs.bsonOpts, cs.registry)
if err != nil {
return nil, err
}
- cs.cursorOptions.Comment = commentVal
+
+ cs.aggregate.Comment(comment)
+ cs.cursorOptions.Comment = comment
}
if cs.options.BatchSize != nil {
cs.aggregate.BatchSize(*cs.options.BatchSize)
cs.cursorOptions.BatchSize = *cs.options.BatchSize
}
if cs.options.MaxAwaitTime != nil {
- cs.cursorOptions.MaxTimeMS = int64(*cs.options.MaxAwaitTime / time.Millisecond)
+ cs.cursorOptions.SetMaxAwaitTime(*cs.options.MaxAwaitTime)
}
if cs.options.Custom != nil {
// Marshal all custom options before passing to the initial aggregate. Return
// any errors from Marshaling.
customOptions := make(map[string]bsoncore.Value)
for optionName, optionValue := range cs.options.Custom {
- bsonType, bsonData, err := bson.MarshalValueWithRegistry(cs.registry, optionValue)
+ optionValueBSON, err := marshalValue(optionValue, nil, cs.registry)
if err != nil {
cs.err = err
closeImplicitSession(cs.sess)
return nil, cs.Err()
}
- optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData}
customOptions[optionName] = optionValueBSON
}
cs.aggregate.CustomOptions(customOptions)
@@ -180,13 +189,12 @@ func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline in
// any errors from Marshaling.
cs.pipelineOptions = make(map[string]bsoncore.Value)
for optionName, optionValue := range cs.options.CustomPipeline {
- bsonType, bsonData, err := bson.MarshalValueWithRegistry(cs.registry, optionValue)
+ optionValueBSON, err := marshalValue(optionValue, nil, cs.registry)
if err != nil {
cs.err = err
closeImplicitSession(cs.sess)
return nil, cs.Err()
}
- optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData}
cs.pipelineOptions[optionName] = optionValueBSON
}
}
@@ -234,28 +242,63 @@ func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline in
return cs, cs.Err()
}
-func (cs *ChangeStream) createOperationDeployment(server driver.Server, connection driver.Connection) driver.Deployment {
- return &changeStreamDeployment{
+func (cs *ChangeStream) createOperationDeployment(ctx context.Context) (*changeStreamDeployment, error) {
+ var cancel context.CancelFunc
+
+ deployment := &changeStreamDeployment{
topologyKind: cs.client.deployment.Kind(),
- server: server,
- conn: connection,
}
+ deployment.close = func() error {
+ var err error
+ if deployment.conn != nil {
+ err = deployment.conn.Close()
+ }
+ if cancel != nil {
+ cancel()
+ }
+ return err
+ }
+ deployment.reset = func() error {
+ _ = deployment.close()
+
+ var err error
+ var connCtx context.Context
+ connCtx, cancel = csot.WithServerSelectionTimeout(ctx, cs.client.deployment.GetServerSelectionTimeout())
+ deployment.server, err = cs.client.deployment.SelectServer(connCtx, cs.selector)
+ if err != nil {
+ cancel()
+ return err
+ }
+ deployment.conn, err = deployment.server.Connection(connCtx)
+ if err != nil {
+ cancel()
+ return err
+ }
+ cs.wireVersion = deployment.conn.Description().WireVersion
+ return nil
+ }
+ if err := deployment.reset(); err != nil {
+ return nil, err
+ }
+ return deployment, nil
}
func (cs *ChangeStream) executeOperation(ctx context.Context, resuming bool) error {
- var server driver.Server
- var conn driver.Connection
+ var deployment *changeStreamDeployment
- if server, cs.err = cs.client.deployment.SelectServer(ctx, cs.selector); cs.err != nil {
- return cs.Err()
- }
- if conn, cs.err = server.Connection(ctx); cs.err != nil {
+ // Apply the client-level timeout if the operation-level timeout is not set.
+ ctx, cancel := csot.WithTimeout(ctx, cs.client.timeout)
+ defer cancel()
+
+ deployment, cs.err = cs.createOperationDeployment(ctx)
+ if cs.err != nil {
return cs.Err()
}
- defer conn.Close()
- cs.wireVersion = conn.Description().WireVersion
+ defer func() {
+ _ = deployment.close()
+ }()
- cs.aggregate.Deployment(cs.createOperationDeployment(server, conn))
+ cs.aggregate.Deployment(deployment)
if resuming {
cs.replaceOptions(cs.wireVersion)
@@ -278,17 +321,6 @@ func (cs *ChangeStream) executeOperation(ctx context.Context, resuming bool) err
cs.aggregate.Pipeline(plArr)
}
- // If cs.client.timeout is set and context is not already a Timeout context,
- // honor cs.client.timeout in new Timeout context for change stream
- // operation execution and potential retry.
- if cs.client.timeout != nil && !csot.IsTimeoutContext(ctx) {
- newCtx, cancelFunc := csot.MakeTimeoutContext(ctx, *cs.client.timeout)
- // Redefine ctx to be the new timeout-derived context.
- ctx = newCtx
- // Cancel the timeout-derived context at the end of executeOperation to avoid a context leak.
- defer cancelFunc()
- }
-
// Execute the aggregate, retrying on retryable errors once (1) if retryable reads are enabled and
// infinitely (-1) if context is a Timeout context.
var retries int
@@ -308,8 +340,8 @@ AggregateExecuteLoop:
break AggregateExecuteLoop
}
- switch tt := err.(type) {
- case driver.Error:
+ var tt driver.Error
+ if errors.As(err, &tt) {
// If error is not retryable, do not retry.
if !tt.RetryableRead() {
break AggregateExecuteLoop
@@ -318,38 +350,27 @@ AggregateExecuteLoop:
// If error is retryable: subtract 1 from retries, redo server selection, checkout
// a connection, and restart loop.
retries--
- server, err = cs.client.deployment.SelectServer(ctx, cs.selector)
- if err != nil {
- break AggregateExecuteLoop
- }
- conn.Close()
- conn, err = server.Connection(ctx)
+ // Reset deployment.
+ err = deployment.reset()
if err != nil {
break AggregateExecuteLoop
}
- defer conn.Close()
-
- // Update the wire version with data from the new connection.
- cs.wireVersion = conn.Description().WireVersion
-
- // Reset deployment.
- cs.aggregate.Deployment(cs.createOperationDeployment(server, conn))
- default:
+ } else {
// Do not retry if error is not a driver error.
break AggregateExecuteLoop
}
}
if err != nil {
- cs.err = replaceErrors(err)
+ cs.err = wrapErrors(err)
return cs.err
}
cr := cs.aggregate.ResultCursorResponse()
- cr.Server = server
+ cr.Server = deployment.server
cs.cursor, cs.err = driver.NewBatchCursor(cr, cs.sess, cs.client.clock, cs.cursorOptions)
- if cs.err = replaceErrors(cs.err); cs.err != nil {
+ if cs.err = wrapErrors(cs.err); cs.err != nil {
return cs.Err()
}
@@ -394,9 +415,9 @@ func (cs *ChangeStream) storeResumeToken() error {
return nil
}
-func (cs *ChangeStream) buildPipelineSlice(pipeline interface{}) error {
+func (cs *ChangeStream) buildPipelineSlice(pipeline any) error {
val := reflect.ValueOf(pipeline)
- if !val.IsValid() || !(val.Kind() == reflect.Slice) {
+ if !val.IsValid() || (val.Kind() != reflect.Slice) {
cs.err = errors.New("can only marshal slices and arrays into aggregation pipelines, but got invalid")
return cs.err
}
@@ -498,9 +519,9 @@ func (cs *ChangeStream) pipelineToBSON() (bsoncore.Document, error) {
func (cs *ChangeStream) replaceOptions(wireVersion *description.VersionRange) {
// Cached resume token: use the resume token as the resumeAfter option and set no other resume options
if cs.resumeToken != nil {
- cs.options.SetResumeAfter(cs.resumeToken)
- cs.options.SetStartAfter(nil)
- cs.options.SetStartAtOperationTime(nil)
+ cs.options.ResumeAfter = cs.resumeToken
+ cs.options.StartAfter = nil
+ cs.options.StartAtOperationTime = nil
return
}
@@ -512,16 +533,16 @@ func (cs *ChangeStream) replaceOptions(wireVersion *description.VersionRange) {
opTime = cs.sess.OperationTime
}
- cs.options.SetStartAtOperationTime(opTime)
- cs.options.SetResumeAfter(nil)
- cs.options.SetStartAfter(nil)
+ cs.options.StartAtOperationTime = opTime
+ cs.options.ResumeAfter = nil
+ cs.options.StartAfter = nil
return
}
// No cached resume token or operation time: set none of the resume options
- cs.options.SetResumeAfter(nil)
- cs.options.SetStartAfter(nil)
- cs.options.SetStartAtOperationTime(nil)
+ cs.options.ResumeAfter = nil
+ cs.options.StartAfter = nil
+ cs.options.StartAtOperationTime = nil
}
// ID returns the ID for this change stream, or 0 if the cursor has been closed or exhausted.
@@ -550,28 +571,25 @@ func (cs *ChangeStream) SetBatchSize(size int32) {
// Decode will unmarshal the current event document into val and return any errors from the unmarshalling process
// without any modification. If val is nil or is a typed nil, an error will be returned.
-func (cs *ChangeStream) Decode(val interface{}) error {
+func (cs *ChangeStream) Decode(val any) error {
if cs.cursor == nil {
return ErrNilCursor
}
- dec, err := getDecoder(cs.Current, cs.bsonOpts, cs.registry)
- if err != nil {
- return fmt.Errorf("error configuring BSON decoder: %w", err)
- }
+ dec := getDecoder(cs.Current, cs.bsonOpts, cs.registry)
return dec.Decode(val)
}
// Err returns the last error seen by the change stream, or nil if no errors has occurred.
func (cs *ChangeStream) Err() error {
if cs.err != nil {
- return replaceErrors(cs.err)
+ return wrapErrors(cs.err)
}
if cs.cursor == nil {
return nil
}
- return replaceErrors(cs.cursor.Err())
+ return wrapErrors(cs.cursor.Err())
}
// Close closes this change stream and the underlying cursor. Next and TryNext must not be called after Close has been
@@ -587,7 +605,7 @@ func (cs *ChangeStream) Close(ctx context.Context) error {
return nil // cursor is already closed
}
- cs.err = replaceErrors(cs.cursor.Close(ctx))
+ cs.err = wrapErrors(cs.cursor.Close(ctx))
cs.cursor = nil
return cs.Err()
}
@@ -598,26 +616,35 @@ func (cs *ChangeStream) ResumeToken() bson.Raw {
return cs.resumeToken
}
-// Next gets the next event for this change stream. It returns true if there were no errors and the next event document
-// is available.
+// Next gets the next event for this change stream. It returns true if there
+// were no errors and the next event document is available.
//
-// Next blocks until an event is available, an error occurs, or ctx expires. If ctx expires, the error
-// will be set to ctx.Err(). In an error case, Next will return false.
+// Next blocks until an event is available, an error occurs, or ctx expires.
+// If ctx expires, the error will be set to ctx.Err(). In an error case, Next
+// will return false.
//
// If Next returns false, subsequent calls will also return false.
func (cs *ChangeStream) Next(ctx context.Context) bool {
return cs.next(ctx, false)
}
-// TryNext attempts to get the next event for this change stream. It returns true if there were no errors and the next
-// event document is available.
+// TryNext attempts to get the next event for this change stream. It returns
+// true if there were no errors and the next event document is available.
//
-// TryNext returns false if the change stream is closed by the server, an error occurs when getting changes from the
-// server, the next change is not yet available, or ctx expires. If ctx expires, the error will be set to ctx.Err().
+// TryNext returns false if the change stream is closed by the server, an error
+// occurs when getting changes from the server, the next change is not yet
+// available, or ctx expires.
//
-// If TryNext returns false and an error occurred or the change stream was closed
-// (i.e. cs.Err() != nil || cs.ID() == 0), subsequent attempts will also return false. Otherwise, it is safe to call
-// TryNext again until a change is available.
+// If ctx expires, the error will be set to ctx.Err(). Users can either call
+// TryNext again or close the existing change stream and create a new one. It is
+// suggested to close and re-create the stream with ah higher timeout if the
+// timeout occurs before any events have been received, which is a signal that
+// the server is timing out before it can finish processing the existing oplog.
+//
+// If TryNext returns false and an error occurred or the change stream was
+// closed (i.e. cs.Err() != nil || cs.ID() == 0), subsequent attempts will also
+// return false. Otherwise, it is safe to call TryNext again until a change is
+// available.
//
// This method requires driver version >= 1.2.0.
func (cs *ChangeStream) TryNext(ctx context.Context) bool {
@@ -637,7 +664,7 @@ func (cs *ChangeStream) next(ctx context.Context, nonBlocking bool) bool {
if len(cs.batch) == 0 {
cs.loopNext(ctx, nonBlocking)
if cs.err != nil {
- cs.err = replaceErrors(cs.err)
+ cs.err = wrapErrors(cs.err)
return false
}
if len(cs.batch) == 0 {
@@ -655,6 +682,41 @@ func (cs *ChangeStream) next(ctx context.Context, nonBlocking bool) bool {
}
func (cs *ChangeStream) loopNext(ctx context.Context, nonBlocking bool) {
+ // To avoid unnecessary socket timeouts, we attempt to short-circuit tailable
+ // awaitData "getMore" operations by ensuring that the maxAwaitTimeMS is less
+ // than the operation timeout.
+ //
+ // The specifications assume that drivers iteratively apply the timeout
+ // provided at the constructor level (e.g., (*collection).Find) for tailable
+ // awaitData cursors:
+ //
+ // If set, drivers MUST apply the timeoutMS option to the initial aggregate
+ // operation. Drivers MUST also apply the original timeoutMS value to each
+ // next call on the change stream but MUST NOT use it to derive a maxTimeMS
+ // field for getMore commands.
+ //
+ // The Go Driver might decide to support the above behavior with DRIVERS-2722.
+ // The principal concern is that it would be unexpected for users to apply an
+ // operation-level timeout via contexts to a constructor and then that timeout
+ // later be applied while working with a resulting cursor. Instead, it is more
+ // idiomatic to apply the timeout to the context passed to Next or TryNext.
+ if cs.options != nil && !nonBlocking {
+ maxAwaitTime := cs.cursorOptions.MaxAwaitTime
+
+ // If maxAwaitTime is not set, this check is unnecessary.
+ if maxAwaitTime != nil && !mongoutil.TimeoutWithinContext(ctx, *maxAwaitTime) {
+ cs.err = fmt.Errorf("MaxAwaitTime must be less than the operation timeout")
+
+ return
+ }
+ }
+
+ // Apply the client-level timeout if the operation-level timeout is not set.
+ // This calculation is also done in "executeOperation" but cursor.Next is also
+ // blocking and should honor client-level timeouts.
+ ctx, cancel := csot.WithTimeout(ctx, cs.client.timeout)
+ defer cancel()
+
for {
if cs.cursor == nil {
return
@@ -666,7 +728,7 @@ func (cs *ChangeStream) loopNext(ctx context.Context, nonBlocking bool) {
return
}
- cs.err = replaceErrors(cs.cursor.Err())
+ cs.err = wrapErrors(cs.cursor.Err())
if cs.err == nil {
// Check if cursor is alive
if cs.ID() == 0 {
@@ -707,7 +769,7 @@ func (cs *ChangeStream) isResumableError() bool {
}
// For wire versions 9 and above, a server error is resumable if it has the ResumableChangeStreamError label.
- if cs.wireVersion != nil && cs.wireVersion.Includes(minResumableLabelWireVersion) {
+ if cs.wireVersion != nil && driverutil.VersionRangeIncludes(*cs.wireVersion, minResumableLabelWireVersion) {
return commandErr.HasErrorLabel(resumableErrorLabel)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream_deployment.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream_deployment.go
new file mode 100644
index 000000000..f100efe46
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream_deployment.go
@@ -0,0 +1,66 @@
+// 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 mongo
+
+import (
+ "context"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+)
+
+type changeStreamDeployment struct {
+ topologyKind description.TopologyKind
+ server driver.Server
+ conn *mnet.Connection
+
+ reset func() error
+ close func() error
+}
+
+var (
+ _ driver.Deployment = (*changeStreamDeployment)(nil)
+ _ driver.Server = (*changeStreamDeployment)(nil)
+ _ driver.ErrorProcessor = (*changeStreamDeployment)(nil)
+)
+
+func (c *changeStreamDeployment) SelectServer(context.Context, description.ServerSelector) (driver.Server, error) {
+ return c, nil
+}
+
+func (c *changeStreamDeployment) Kind() description.TopologyKind {
+ return c.topologyKind
+}
+
+func (c *changeStreamDeployment) Connection(context.Context) (*mnet.Connection, error) {
+ var err error
+ if c.conn == nil || c.conn.Closed() {
+ err = c.reset()
+ }
+ return c.conn, err
+}
+
+func (c *changeStreamDeployment) RTTMonitor() driver.RTTMonitor {
+ return c.server.RTTMonitor()
+}
+
+func (c *changeStreamDeployment) ProcessError(err error, describer mnet.Describer) driver.ProcessErrorResult {
+ ep, ok := c.server.(driver.ErrorProcessor)
+ if !ok {
+ return driver.NoChange
+ }
+
+ return ep.ProcessError(err, describer)
+}
+
+// GetServerSelectionTimeout returns zero as a server selection timeout is not
+// applicable for change stream deployments.
+func (*changeStreamDeployment) GetServerSelectionTimeout() time.Duration {
+ return 0
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/client.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client.go
similarity index 54%
rename from vendor/go.mongodb.org/mongo-driver/mongo/client.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/client.go
index 232d0a3c5..14b65b68b 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/client.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client.go
@@ -11,38 +11,44 @@ import (
"errors"
"fmt"
"net/http"
+ "sync"
+ "sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/httputil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/internal/uuid"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt"
- mcopts "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/internal/ptrutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/internal/uuid"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt"
+ mcopts "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology"
)
const (
- defaultLocalThreshold = 15 * time.Millisecond
- defaultMaxPoolSize = 100
+ defaultLocalThreshold = 15 * time.Millisecond
+ defaultMaxPoolSize = 100
+ defaultAdaptiveRetries uint = 2
)
var (
// keyVaultCollOpts specifies options used to communicate with the key vault collection
keyVaultCollOpts = options.Collection().SetReadConcern(readconcern.Majority()).
- SetWriteConcern(writeconcern.New(writeconcern.WMajority()))
+ SetWriteConcern(writeconcern.Majority())
endSessionsBatchSize = 10000
)
@@ -53,71 +59,67 @@ var (
// The Client type opens and closes connections automatically and maintains a pool of idle connections. For
// connection pool configuration options, see documentation for the ClientOptions type in the mongo/options package.
type Client struct {
- id uuid.UUID
- deployment driver.Deployment
- localThreshold time.Duration
- retryWrites bool
- retryReads bool
- clock *session.ClusterClock
- readPreference *readpref.ReadPref
- readConcern *readconcern.ReadConcern
- writeConcern *writeconcern.WriteConcern
- bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
- monitor *event.CommandMonitor
- serverAPI *driver.ServerAPIOptions
- serverMonitor *event.ServerMonitor
- sessionPool *session.Pool
- timeout *time.Duration
- httpClient *http.Client
- logger *logger.Logger
-
- // client-side encryption fields
- keyVaultClientFLE *Client
- keyVaultCollFLE *Collection
- mongocryptdFLE *mongocryptdClient
- cryptFLE driver.Crypt
- metadataClientFLE *Client
- internalClientFLE *Client
- encryptedFieldsMap map[string]interface{}
- authenticator driver.Authenticator
+ id uuid.UUID
+ deployment driver.Deployment
+ localThreshold time.Duration
+ retryWrites bool
+ retryReads bool
+ maxAdaptiveRetries *uint
+ enableOverloadRetargeting bool
+ clock *session.ClusterClock
+ readPreference *readpref.ReadPref
+ readConcern *readconcern.ReadConcern
+ writeConcern *writeconcern.WriteConcern
+ bsonOpts *options.BSONOptions
+ registry *bson.Registry
+ monitor *event.CommandMonitor
+ serverAPI *driver.ServerAPIOptions
+ serverMonitor *event.ServerMonitor
+ sessionPool *session.Pool
+ timeout *time.Duration
+ httpClient *http.Client
+ logger *logger.Logger
+ currentDriverInfo *atomic.Pointer[options.DriverInfo]
+ seenDriverInfo sync.Map
+
+ // in-use encryption fields
+ isAutoEncryptionSet bool
+ keyVaultClientFLE *Client
+ keyVaultCollFLE *Collection
+ mongocryptdFLE *mongocryptdClient
+ cryptFLE driver.Crypt
+ metadataClientFLE *Client
+ internalClientFLE *Client
+ encryptedFieldsMap map[string]any
+ authenticator driver.Authenticator
}
-// Connect creates a new Client and then initializes it using the Connect method. This is equivalent to calling
-// NewClient followed by Client.Connect.
+// Connect creates a new Client with the given configuration options.
//
-// When creating an options.ClientOptions, the order the methods are called matters. Later Set*
-// methods will overwrite the values from previous Set* method invocations. This includes the
-// ApplyURI method. This allows callers to determine the order of precedence for option
-// application. For instance, if ApplyURI is called before SetAuth, the Credential from
-// SetAuth will overwrite the values from the connection string. If ApplyURI is called
-// after SetAuth, then its values will overwrite those from SetAuth.
-//
-// The opts parameter is processed using options.MergeClientOptions, which will overwrite entire
-// option fields of previous options, there is no partial overwriting. For example, if Username is
-// set in the Auth field for the first option, and Password is set for the second but with no
-// Username, after the merge the Username field will be empty.
-//
-// The NewClient function does not do any I/O and returns an error if the given options are invalid.
-// The Client.Connect method starts background goroutines to monitor the state of the deployment and does not do
-// any I/O in the main goroutine to prevent the main goroutine from blocking. Therefore, it will not error if the
-// deployment is down.
+// Connect returns an error if the configuration options are invalid, but does
+// not validate that the MongoDB deployment is reachable. To verify that the
+// deployment is reachable, call [Client.Ping].
//
-// The Client.Ping method can be used to verify that the deployment is successfully connected and the
-// Client was correctly configured.
-func Connect(ctx context.Context, opts ...*options.ClientOptions) (*Client, error) {
- c, err := NewClient(opts...)
+// When creating an [options.ClientOptions], the order the methods are called
+// matters. Later option setter calls overwrite the values from previous option
+// setter calls, including the ApplyURI method. This allows callers to
+// determine the order of precedence for setting options. For instance, if
+// ApplyURI is called before SetAuth, the Credential from SetAuth will
+// overwrite the values from the connection string. If ApplyURI is called
+// after SetAuth, then its values will overwrite those from SetAuth.
+func Connect(opts ...*options.ClientOptions) (*Client, error) {
+ c, err := newClient(opts...)
if err != nil {
return nil, err
}
- err = c.Connect(ctx)
+ err = c.connect()
if err != nil {
return nil, err
}
return c, nil
}
-// NewClient creates a new client to connect to a deployment specified by the uri.
+// newClient creates a new client to connect to a deployment specified by the uri.
//
// When creating an options.ClientOptions, the order the methods are called matters. Later Set*
// methods will overwrite the values from previous Set* method invocations. This includes the
@@ -130,114 +132,134 @@ func Connect(ctx context.Context, opts ...*options.ClientOptions) (*Client, erro
// option fields of previous options, there is no partial overwriting. For example, if Username is
// set in the Auth field for the first option, and Password is set for the second but with no
// Username, after the merge the Username field will be empty.
-//
-// Deprecated: Use [Connect] instead.
-func NewClient(opts ...*options.ClientOptions) (*Client, error) {
- clientOpt := options.MergeClientOptions(opts...)
+func newClient(opts ...*options.ClientOptions) (*Client, error) {
+ clientOpts := options.MergeClientOptions(opts...)
id, err := uuid.New()
if err != nil {
return nil, err
}
- client := &Client{id: id}
+
+ client := &Client{
+ id: id,
+ currentDriverInfo: &atomic.Pointer[options.DriverInfo]{},
+ }
// ClusterClock
client.clock = new(session.ClusterClock)
// LocalThreshold
client.localThreshold = defaultLocalThreshold
- if clientOpt.LocalThreshold != nil {
- client.localThreshold = *clientOpt.LocalThreshold
+ if clientOpts.LocalThreshold != nil {
+ client.localThreshold = *clientOpts.LocalThreshold
}
// Monitor
- if clientOpt.Monitor != nil {
- client.monitor = clientOpt.Monitor
+ if clientOpts.Monitor != nil {
+ client.monitor = clientOpts.Monitor
}
// ServerMonitor
- if clientOpt.ServerMonitor != nil {
- client.serverMonitor = clientOpt.ServerMonitor
+ if clientOpts.ServerMonitor != nil {
+ client.serverMonitor = clientOpts.ServerMonitor
}
// ReadConcern
- client.readConcern = readconcern.New()
- if clientOpt.ReadConcern != nil {
- client.readConcern = clientOpt.ReadConcern
+ client.readConcern = &readconcern.ReadConcern{}
+ if clientOpts.ReadConcern != nil {
+ client.readConcern = clientOpts.ReadConcern
}
// ReadPreference
client.readPreference = readpref.Primary()
- if clientOpt.ReadPreference != nil {
- client.readPreference = clientOpt.ReadPreference
+ if clientOpts.ReadPreference != nil {
+ client.readPreference = clientOpts.ReadPreference
}
// BSONOptions
- if clientOpt.BSONOptions != nil {
- client.bsonOpts = clientOpt.BSONOptions
+ if clientOpts.BSONOptions != nil {
+ client.bsonOpts = clientOpts.BSONOptions
}
// Registry
- client.registry = bson.DefaultRegistry
- if clientOpt.Registry != nil {
- client.registry = clientOpt.Registry
+ client.registry = defaultRegistry
+ if clientOpts.Registry != nil {
+ client.registry = clientOpts.Registry
}
// RetryWrites
client.retryWrites = true // retry writes on by default
- if clientOpt.RetryWrites != nil {
- client.retryWrites = *clientOpt.RetryWrites
+ if clientOpts.RetryWrites != nil {
+ client.retryWrites = *clientOpts.RetryWrites
}
client.retryReads = true
- if clientOpt.RetryReads != nil {
- client.retryReads = *clientOpt.RetryReads
+ if clientOpts.RetryReads != nil {
+ client.retryReads = *clientOpts.RetryReads
}
+ client.maxAdaptiveRetries = clientOpts.MaxAdaptiveRetries
+ client.enableOverloadRetargeting = clientOpts.EnableOverloadRetargeting != nil &&
+ *clientOpts.EnableOverloadRetargeting
// Timeout
- client.timeout = clientOpt.Timeout
- client.httpClient = clientOpt.HTTPClient
+ client.timeout = clientOpts.Timeout
+ client.httpClient = clientOpts.HTTPClient
// WriteConcern
- if clientOpt.WriteConcern != nil {
- client.writeConcern = clientOpt.WriteConcern
+ if clientOpts.WriteConcern != nil {
+ client.writeConcern = clientOpts.WriteConcern
}
// AutoEncryptionOptions
- if clientOpt.AutoEncryptionOptions != nil {
- if err := client.configureAutoEncryption(clientOpt); err != nil {
+ if clientOpts.AutoEncryptionOptions != nil {
+ client.isAutoEncryptionSet = true
+ if err := client.configureAutoEncryption(clientOpts); err != nil {
return nil, err
}
} else {
- client.cryptFLE = clientOpt.Crypt
+ client.cryptFLE = clientOpts.Crypt
}
// Deployment
- if clientOpt.Deployment != nil {
- client.deployment = clientOpt.Deployment
+ if clientOpts.Deployment != nil {
+ client.deployment = clientOpts.Deployment
}
// Set default options
- if clientOpt.MaxPoolSize == nil {
- clientOpt.SetMaxPoolSize(defaultMaxPoolSize)
+ if clientOpts.MaxPoolSize == nil {
+ defaultMaxPoolSize := uint64(defaultMaxPoolSize)
+ clientOpts.MaxPoolSize = &defaultMaxPoolSize
}
- if clientOpt.Auth != nil {
+ if clientOpts.Auth != nil {
client.authenticator, err = auth.CreateAuthenticator(
- clientOpt.Auth.AuthMechanism,
- topology.ConvertCreds(clientOpt.Auth),
- clientOpt.HTTPClient,
+ clientOpts.Auth.AuthMechanism,
+ topology.ConvertCreds(clientOpts.Auth),
+ clientOpts.HTTPClient,
)
if err != nil {
return nil, fmt.Errorf("error creating authenticator: %w", err)
}
}
- cfg, err := topology.NewConfigWithAuthenticator(clientOpt, client.clock, client.authenticator)
+ if clientOpts.DriverInfo != nil {
+ client.AppendDriverInfo(*clientOpts.DriverInfo)
+ }
+
+ cfg, err := topology.NewAuthenticatorConfig(client.authenticator,
+ topology.WithAuthConfigClock(client.clock),
+ topology.WithAuthConfigClientOptions(clientOpts),
+ topology.WithAuthConfigDriverInfo(client.currentDriverInfo),
+ )
if err != nil {
return nil, err
}
- client.serverAPI = topology.ServerAPIFromServerOptions(cfg.ServerOpts)
+ var connectTimeout time.Duration
+ if clientOpts.ConnectTimeout != nil {
+ connectTimeout = *clientOpts.ConnectTimeout
+ }
+
+ client.serverAPI = topology.ServerAPIFromServerOptions(connectTimeout, cfg.ServerOpts)
if client.deployment == nil {
client.deployment, err = topology.New(cfg)
if err != nil {
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
}
// Create a logger for the client.
- client.logger, err = newLogger(clientOpt.LoggerOptions)
+ client.logger, err = newLogger(clientOpts.LoggerOptions)
if err != nil {
return nil, fmt.Errorf("invalid logger options: %w", err)
}
@@ -250,36 +272,34 @@ func NewClient(opts ...*options.ClientOptions) (*Client, error) {
//
// Connect starts background goroutines to monitor the state of the deployment and does not do any I/O in the main
// goroutine. The Client.Ping method can be used to verify that the connection was created successfully.
-//
-// Deprecated: Use [mongo.Connect] instead.
-func (c *Client) Connect(ctx context.Context) error {
+func (c *Client) connect() error {
if connector, ok := c.deployment.(driver.Connector); ok {
err := connector.Connect()
if err != nil {
- return replaceErrors(err)
+ return wrapErrors(err)
}
}
if c.mongocryptdFLE != nil {
- if err := c.mongocryptdFLE.connect(ctx); err != nil {
+ if err := c.mongocryptdFLE.connect(); err != nil {
return err
}
}
if c.internalClientFLE != nil {
- if err := c.internalClientFLE.Connect(ctx); err != nil {
+ if err := c.internalClientFLE.connect(); err != nil {
return err
}
}
if c.keyVaultClientFLE != nil && c.keyVaultClientFLE != c.internalClientFLE && c.keyVaultClientFLE != c {
- if err := c.keyVaultClientFLE.Connect(ctx); err != nil {
+ if err := c.keyVaultClientFLE.connect(); err != nil {
return err
}
}
if c.metadataClientFLE != nil && c.metadataClientFLE != c.internalClientFLE && c.metadataClientFLE != c {
- if err := c.metadataClientFLE.Connect(ctx); err != nil {
+ if err := c.metadataClientFLE.connect(); err != nil {
return err
}
}
@@ -288,7 +308,7 @@ func (c *Client) Connect(ctx context.Context) error {
if subscriber, ok := c.deployment.(driver.Subscriber); ok {
sub, err := subscriber.Subscribe()
if err != nil {
- return replaceErrors(err)
+ return wrapErrors(err)
}
updateChan = sub.Updates
}
@@ -296,6 +316,45 @@ func (c *Client) Connect(ctx context.Context) error {
return nil
}
+// AppendDriverInfo appends the provided [options.DriverInfo] to the metadata
+// (e.g. name, version, platform) that will be sent to the server in handshake
+// requests when establishing new connections.
+//
+// Repeated calls to AppendDriverInfo with equivalent DriverInfo is a no-op.
+//
+// Metadata is limited to 512 bytes; any excess will be truncated.
+func (c *Client) AppendDriverInfo(info options.DriverInfo) {
+ if _, loaded := c.seenDriverInfo.LoadOrStore(info, struct{}{}); loaded {
+ return
+ }
+
+ if old := c.currentDriverInfo.Load(); old != nil {
+ if old.Name != "" && info.Name != "" && old.Name != info.Name {
+ info.Name = old.Name + "|" + info.Name
+ } else if old.Name != "" {
+ info.Name = old.Name
+ }
+
+ if old.Version != "" && info.Version != "" && old.Version != info.Version {
+ info.Version = old.Version + "|" + info.Version
+ } else if old.Version != "" {
+ info.Version = old.Version
+ }
+
+ if old.Platform != "" && info.Platform != "" && old.Platform != info.Platform {
+ info.Platform = old.Platform + "|" + info.Platform
+ } else if old.Platform != "" {
+ info.Platform = old.Platform
+ }
+ }
+
+ // Copy-on-write so that the info stored in the client is immutable.
+ infoCopy := new(options.DriverInfo)
+ *infoCopy = info
+
+ c.currentDriverInfo.Store(infoCopy)
+}
+
// Disconnect closes sockets to the topology referenced by this Client. It will
// shut down any monitoring goroutines, close the idle connection pool, and will
// wait until all the in use connections have been returned to the connection
@@ -345,7 +404,7 @@ func (c *Client) Disconnect(ctx context.Context) error {
}
if disconnector, ok := c.deployment.(driver.Disconnector); ok {
- return replaceErrors(disconnector.Disconnect(ctx))
+ return wrapErrors(disconnector.Disconnect(ctx))
}
return nil
@@ -376,7 +435,7 @@ func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error {
{"ping", 1},
}, options.RunCmd().SetReadPreference(rp))
- return replaceErrors(res.Err())
+ return wrapErrors(res.Err())
}
// StartSession starts a new session configured with the given options.
@@ -389,46 +448,55 @@ func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error {
//
// If the DefaultReadConcern, DefaultWriteConcern, or DefaultReadPreference options are not set, the client's read
// concern, write concern, or read preference will be used, respectively.
-func (c *Client) StartSession(opts ...*options.SessionOptions) (Session, error) {
- if c.sessionPool == nil {
- return nil, ErrClientDisconnected
+func (c *Client) StartSession(opts ...options.Lister[options.SessionOptions]) (*Session, error) {
+ sessArgs, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
+ if sessArgs.CausalConsistency == nil && (sessArgs.Snapshot == nil || !*sessArgs.Snapshot) {
+ sessArgs.CausalConsistency = &options.DefaultCausalConsistency
}
-
- sopts := options.MergeSessionOptions(opts...)
coreOpts := &session.ClientOptions{
DefaultReadConcern: c.readConcern,
DefaultReadPreference: c.readPreference,
DefaultWriteConcern: c.writeConcern,
}
- if sopts.CausalConsistency != nil {
- coreOpts.CausalConsistency = sopts.CausalConsistency
+ if sessArgs.CausalConsistency != nil {
+ coreOpts.CausalConsistency = sessArgs.CausalConsistency
}
- if sopts.DefaultReadConcern != nil {
- coreOpts.DefaultReadConcern = sopts.DefaultReadConcern
- }
- if sopts.DefaultWriteConcern != nil {
- coreOpts.DefaultWriteConcern = sopts.DefaultWriteConcern
- }
- if sopts.DefaultReadPreference != nil {
- coreOpts.DefaultReadPreference = sopts.DefaultReadPreference
+ if bldr := sessArgs.DefaultTransactionOptions; bldr != nil {
+ txnOpts, err := mongoutil.NewOptions[options.TransactionOptions](bldr)
+ if err != nil {
+ return nil, err
+ }
+
+ if rc := txnOpts.ReadConcern; rc != nil {
+ coreOpts.DefaultReadConcern = rc
+ }
+
+ if wc := txnOpts.WriteConcern; wc != nil {
+ coreOpts.DefaultWriteConcern = wc
+ }
+
+ if rp := txnOpts.ReadPreference; rp != nil {
+ coreOpts.DefaultReadPreference = rp
+ }
}
- if sopts.DefaultMaxCommitTime != nil {
- coreOpts.DefaultMaxCommitTime = sopts.DefaultMaxCommitTime
+
+ if sessArgs.Snapshot != nil {
+ coreOpts.Snapshot = sessArgs.Snapshot
}
- if sopts.Snapshot != nil {
- coreOpts.Snapshot = sopts.Snapshot
+
+ if sessArgs.SnapshotTime != nil {
+ coreOpts.SnapshotTime = sessArgs.SnapshotTime
}
sess, err := session.NewClientSession(c.sessionPool, c.id, coreOpts)
if err != nil {
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- // Writes are not retryable on standalones, so let operation determine whether to retry
- sess.RetryWrite = false
- sess.RetryRead = c.retryReads
-
- return &sessionImpl{
+ return &Session{
clientSession: sess,
client: c,
deployment: c.deployment,
@@ -436,14 +504,12 @@ func (c *Client) StartSession(opts ...*options.SessionOptions) (Session, error)
}
func (c *Client) endSessions(ctx context.Context) {
- if c.sessionPool == nil {
- return
- }
-
sessionIDs := c.sessionPool.IDSlice()
op := operation.NewEndSessions(nil).ClusterClock(c.clock).Deployment(c.deployment).
- ServerSelector(description.ReadPrefSelector(readpref.PrimaryPreferred())).CommandMonitor(c.monitor).
- Database("admin").Crypt(c.cryptFLE).ServerAPI(c.serverAPI)
+ ServerSelector(&serverselector.ReadPref{ReadPref: readpref.PrimaryPreferred()}).
+ CommandMonitor(c.monitor).Database("admin").Crypt(c.cryptFLE).ServerAPI(c.serverAPI).
+ MaxAdaptiveRetries(c.effectiveAdaptiveRetries(true)).
+ EnableOverloadRetargeting(c.enableOverloadRetargeting)
totalNumIDs := len(sessionIDs)
var currentBatch []bsoncore.Document
@@ -463,53 +529,58 @@ func (c *Client) endSessions(ctx context.Context) {
}
}
-func (c *Client) configureAutoEncryption(clientOpts *options.ClientOptions) error {
- c.encryptedFieldsMap = clientOpts.AutoEncryptionOptions.EncryptedFieldsMap
- if err := c.configureKeyVaultClientFLE(clientOpts); err != nil {
+func (c *Client) configureAutoEncryption(args *options.ClientOptions) error {
+ c.encryptedFieldsMap = args.AutoEncryptionOptions.EncryptedFieldsMap
+ if err := c.configureKeyVaultClientFLE(args); err != nil {
return err
}
- if err := c.configureMetadataClientFLE(clientOpts); err != nil {
+
+ if err := c.configureMetadataClientFLE(args); err != nil {
return err
}
- mc, err := c.newMongoCrypt(clientOpts.AutoEncryptionOptions)
+ mc, err := c.newMongoCrypt(args.AutoEncryptionOptions)
if err != nil {
return err
}
// If the crypt_shared library was not loaded, try to spawn and connect to mongocryptd.
if mc.CryptSharedLibVersionString() == "" {
- mongocryptdFLE, err := newMongocryptdClient(clientOpts.AutoEncryptionOptions)
+ mongocryptdFLE, err := newMongocryptdClient(args.AutoEncryptionOptions)
if err != nil {
return err
}
c.mongocryptdFLE = mongocryptdFLE
}
- c.configureCryptFLE(mc, clientOpts.AutoEncryptionOptions)
+ c.configureCryptFLE(mc, args.AutoEncryptionOptions)
return nil
}
-func (c *Client) getOrCreateInternalClient(clientOpts *options.ClientOptions) (*Client, error) {
+func (c *Client) getOrCreateInternalClient(args *options.ClientOptions) (*Client, error) {
if c.internalClientFLE != nil {
return c.internalClientFLE, nil
}
- internalClientOpts := options.MergeClientOptions(clientOpts)
- internalClientOpts.AutoEncryptionOptions = nil
- internalClientOpts.SetMinPoolSize(0)
+ argsCopy := *args
+
+ argsCopy.AutoEncryptionOptions = nil
+ argsCopy.MinPoolSize = ptrutil.Ptr[uint64](0)
+
var err error
- c.internalClientFLE, err = NewClient(internalClientOpts)
+ c.internalClientFLE, err = newClient(&argsCopy)
+
return c.internalClientFLE, err
}
func (c *Client) configureKeyVaultClientFLE(clientOpts *options.ClientOptions) error {
- // parse key vault options and create new key vault client
- var err error
aeOpts := clientOpts.AutoEncryptionOptions
+
+ var err error
+
switch {
case aeOpts.KeyVaultClientOptions != nil:
- c.keyVaultClientFLE, err = NewClient(aeOpts.KeyVaultClientOptions)
+ c.keyVaultClientFLE, err = newClient(aeOpts.KeyVaultClientOptions)
case clientOpts.MaxPoolSize != nil && *clientOpts.MaxPoolSize == 0:
c.keyVaultClientFLE = c
default:
@@ -526,8 +597,8 @@ func (c *Client) configureKeyVaultClientFLE(clientOpts *options.ClientOptions) e
}
func (c *Client) configureMetadataClientFLE(clientOpts *options.ClientOptions) error {
- // parse key vault options and create new key vault client
aeOpts := clientOpts.AutoEncryptionOptions
+
if aeOpts.BypassAutoEncryption != nil && *aeOpts.BypassAutoEncryption {
// no need for a metadata client.
return nil
@@ -539,6 +610,7 @@ func (c *Client) configureMetadataClientFLE(clientOpts *options.ClientOptions) e
var err error
c.metadataClientFLE, err = c.getOrCreateInternalClient(clientOpts)
+
return err
}
@@ -591,14 +663,16 @@ func (c *Client) newMongoCrypt(opts *options.AutoEncryptionOptions) (*mongocrypt
bypassAutoEncryption := opts.BypassAutoEncryption != nil && *opts.BypassAutoEncryption
bypassQueryAnalysis := opts.BypassQueryAnalysis != nil && *opts.BypassQueryAnalysis
- mc, err := mongocrypt.NewMongoCrypt(mcopts.MongoCrypt().
- SetKmsProviders(kmsProviders).
- SetLocalSchemaMap(cryptSchemaMap).
- SetBypassQueryAnalysis(bypassQueryAnalysis).
- SetEncryptedFieldsMap(cryptEncryptedFieldsMap).
- SetCryptSharedLibDisabled(cryptSharedLibDisabled || bypassAutoEncryption).
- SetCryptSharedLibOverridePath(cryptSharedLibPath).
- SetHTTPClient(opts.HTTPClient))
+ mc, err := mongocrypt.NewMongoCrypt(&mcopts.MongoCryptOptions{
+ KmsProviders: kmsProviders,
+ LocalSchemaMap: cryptSchemaMap,
+ BypassQueryAnalysis: bypassQueryAnalysis,
+ EncryptedFieldsMap: cryptEncryptedFieldsMap,
+ CryptSharedLibDisabled: cryptSharedLibDisabled || bypassAutoEncryption,
+ CryptSharedLibOverridePath: cryptSharedLibPath,
+ HTTPClient: opts.HTTPClient,
+ KeyExpiration: opts.KeyExpiration,
+ })
if err != nil {
return nil, err
}
@@ -655,7 +729,7 @@ func (c *Client) validSession(sess *session.Client) error {
}
// Database returns a handle for a database with the given name configured with the given DatabaseOptions.
-func (c *Client) Database(name string, opts ...*options.DatabaseOptions) *Database {
+func (c *Client) Database(name string, opts ...options.Lister[options.DatabaseOptions]) *Database {
return newDatabase(c, name, opts...)
}
@@ -668,7 +742,7 @@ func (c *Client) Database(name string, opts ...*options.DatabaseOptions) *Databa
// The opts parameter can be used to specify options for this operation (see the options.ListDatabasesOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/listDatabases/.
-func (c *Client) ListDatabases(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) (ListDatabasesResult, error) {
+func (c *Client) ListDatabases(ctx context.Context, filter any, opts ...options.Lister[options.ListDatabasesOptions]) (ListDatabasesResult, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -694,34 +768,45 @@ func (c *Client) ListDatabases(ctx context.Context, filter interface{}, opts ...
return ListDatabasesResult{}, err
}
- selector := description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(readpref.Primary()),
- description.LatencySelector(c.localThreshold),
- })
+ retry := driver.RetryNone
+ if c.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := c.effectiveAdaptiveRetries(c.retryReads)
+
+ var selector description.ServerSelector
+
+ selector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: readpref.Primary()},
+ &serverselector.Latency{Latency: c.localThreshold},
+ },
+ }
+
selector = makeReadPrefSelector(sess, selector, c.localThreshold)
- ldo := options.MergeListDatabasesOptions(opts...)
+ lda, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return ListDatabasesResult{}, err
+ }
op := operation.NewListDatabases(filterDoc).
Session(sess).ReadPreference(c.readPreference).CommandMonitor(c.monitor).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(c.enableOverloadRetargeting).
ServerSelector(selector).ClusterClock(c.clock).Database("admin").Deployment(c.deployment).Crypt(c.cryptFLE).
ServerAPI(c.serverAPI).Timeout(c.timeout).Authenticator(c.authenticator)
- if ldo.NameOnly != nil {
- op = op.NameOnly(*ldo.NameOnly)
- }
- if ldo.AuthorizedDatabases != nil {
- op = op.AuthorizedDatabases(*ldo.AuthorizedDatabases)
+ if lda.NameOnly != nil {
+ op = op.NameOnly(*lda.NameOnly)
}
-
- retry := driver.RetryNone
- if c.retryReads {
- retry = driver.RetryOncePerCommand
+ if lda.AuthorizedDatabases != nil {
+ op = op.AuthorizedDatabases(*lda.AuthorizedDatabases)
}
- op.Retry(retry)
err = op.Execute(ctx)
if err != nil {
- return ListDatabasesResult{}, replaceErrors(err)
+ return ListDatabasesResult{}, wrapErrors(err)
}
return newListDatabasesResultFromOperation(op.Result()), nil
@@ -738,7 +823,7 @@ func (c *Client) ListDatabases(ctx context.Context, filter interface{}, opts ...
// documentation.)
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/listDatabases/.
-func (c *Client) ListDatabaseNames(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) ([]string, error) {
+func (c *Client) ListDatabaseNames(ctx context.Context, filter any, opts ...options.Lister[options.ListDatabasesOptions]) ([]string, error) {
opts = append(opts, options.ListDatabases().SetNameOnly(true))
res, err := c.ListDatabases(ctx, filter, opts...)
@@ -754,40 +839,51 @@ func (c *Client) ListDatabaseNames(ctx context.Context, filter interface{}, opts
return names, nil
}
-// WithSession creates a new SessionContext from the ctx and sess parameters and uses it to call the fn callback. The
-// SessionContext must be used as the Context parameter for any operations in the fn callback that should be executed
-// under the session.
+// WithSession creates a new session context from the ctx and sess parameters
+// and uses it to call the fn callback.
//
-// WithSession is safe to call from multiple goroutines concurrently. However, the SessionContext passed to the
-// WithSession callback function is not safe for concurrent use by multiple goroutines.
+// WithSession is safe to call from multiple goroutines concurrently. However,
+// the context passed to the WithSession callback function is not safe for
+// concurrent use by multiple goroutines.
//
-// If the ctx parameter already contains a Session, that Session will be replaced with the one provided.
+// If the ctx parameter already contains a Session, that Session will be
+// replaced with the one provided.
//
-// Any error returned by the fn callback will be returned without any modifications.
-func WithSession(ctx context.Context, sess Session, fn func(SessionContext) error) error {
+// Any error returned by the fn callback will be returned without any
+// modifications.
+func WithSession(ctx context.Context, sess *Session, fn func(context.Context) error) error {
return fn(NewSessionContext(ctx, sess))
}
-// UseSession creates a new Session and uses it to create a new SessionContext, which is used to call the fn callback.
-// The SessionContext parameter must be used as the Context parameter for any operations in the fn callback that should
-// be executed under a session. After the callback returns, the created Session is ended, meaning that any in-progress
-// transactions started by fn will be aborted even if fn returns an error.
+// UseSession creates a new Session and uses it to create a new session context,
+// which is used to call the fn callback. After the callback returns, the
+// created Session is ended, meaning that any in-progress transactions started
+// by fn will be aborted even if fn returns an error.
//
-// UseSession is safe to call from multiple goroutines concurrently. However, the SessionContext passed to the
-// UseSession callback function is not safe for concurrent use by multiple goroutines.
+// UseSession is safe to call from multiple goroutines concurrently. However,
+// the context passed to the UseSession callback function is not safe for
+// concurrent use by multiple goroutines.
//
-// If the ctx parameter already contains a Session, that Session will be replaced with the newly created one.
+// If the ctx parameter already contains a Session, that Session will be
+// replaced with the newly created one.
//
-// Any error returned by the fn callback will be returned without any modifications.
-func (c *Client) UseSession(ctx context.Context, fn func(SessionContext) error) error {
+// Any error returned by the fn callback will be returned without any
+// modifications.
+func (c *Client) UseSession(ctx context.Context, fn func(context.Context) error) error {
return c.UseSessionWithOptions(ctx, options.Session(), fn)
}
-// UseSessionWithOptions operates like UseSession but uses the given SessionOptions to create the Session.
+// UseSessionWithOptions operates like UseSession but uses the given
+// SessionOptions to create the Session.
//
-// UseSessionWithOptions is safe to call from multiple goroutines concurrently. However, the SessionContext passed to
-// the UseSessionWithOptions callback function is not safe for concurrent use by multiple goroutines.
-func (c *Client) UseSessionWithOptions(ctx context.Context, opts *options.SessionOptions, fn func(SessionContext) error) error {
+// UseSessionWithOptions is safe to call from multiple goroutines concurrently.
+// However, the context passed to the UseSessionWithOptions callback function is
+// not safe for concurrent use by multiple goroutines.
+func (c *Client) UseSessionWithOptions(
+ ctx context.Context,
+ opts *options.SessionOptionsBuilder,
+ fn func(context.Context) error,
+) error {
defaultSess, err := c.StartSession(opts)
if err != nil {
return err
@@ -810,12 +906,9 @@ func (c *Client) UseSessionWithOptions(ctx context.Context, opts *options.Sessio
//
// The opts parameter can be used to specify options for change stream creation (see the options.ChangeStreamOptions
// documentation).
-func (c *Client) Watch(ctx context.Context, pipeline interface{},
- opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
- if c.sessionPool == nil {
- return nil, ErrClientDisconnected
- }
-
+func (c *Client) Watch(ctx context.Context, pipeline any,
+ opts ...options.Lister[options.ChangeStreamOptions],
+) (*ChangeStream, error) {
csConfig := changeStreamConfig{
readConcern: c.readConcern,
readPreference: c.readPreference,
@@ -838,17 +931,131 @@ func (c *Client) NumberSessionsInProgress() int {
return int(c.sessionPool.CheckedOut())
}
-// Timeout returns the timeout set for this client.
-func (c *Client) Timeout() *time.Duration {
- return c.timeout
+func (c *Client) createBaseCursorOptions(retryOverload bool) driver.CursorOptions {
+ return driver.CursorOptions{
+ CommandMonitor: c.monitor,
+ Crypt: c.cryptFLE,
+ ServerAPI: c.serverAPI,
+ MaxAdaptiveRetries: c.effectiveAdaptiveRetries(retryOverload),
+ EnableOverloadRetargeting: c.enableOverloadRetargeting,
+ }
}
-func (c *Client) createBaseCursorOptions() driver.CursorOptions {
- return driver.CursorOptions{
- CommandMonitor: c.monitor,
- Crypt: c.cryptFLE,
- ServerAPI: c.serverAPI,
+func (c *Client) effectiveAdaptiveRetries(retryOverload bool) uint {
+ if !retryOverload {
+ return 0
+ }
+ if c.maxAdaptiveRetries != nil {
+ return *c.maxAdaptiveRetries
+ }
+ return defaultAdaptiveRetries
+}
+
+// ClientBulkWrite is a struct that can be used in a client-level BulkWrite operation.
+type ClientBulkWrite struct {
+ Database string
+ Collection string
+ Model ClientWriteModel
+}
+
+// BulkWrite performs a client-level bulk write operation.
+func (c *Client) BulkWrite(ctx context.Context, writes []ClientBulkWrite,
+ opts ...options.Lister[options.ClientBulkWriteOptions],
+) (*ClientBulkWriteResult, error) {
+ // TODO(GODRIVER-3403): Remove after support for QE with Client.bulkWrite.
+ if c.isAutoEncryptionSet {
+ return nil, errors.New("bulkWrite does not currently support automatic encryption")
+ }
+
+ if len(writes) == 0 {
+ return nil, fmt.Errorf("invalid writes: %w", ErrEmptySlice)
+ }
+ bwo, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
}
+
+ if ctx == nil {
+ ctx = context.Background()
+ }
+
+ sess := sessionFromContext(ctx)
+ if sess == nil && c.sessionPool != nil {
+ sess = session.NewImplicitClientSession(c.sessionPool, c.id)
+ defer sess.EndSession()
+ }
+
+ err = c.validSession(sess)
+ if err != nil {
+ return nil, err
+ }
+
+ transactionRunning := sess.TransactionRunning()
+ wc := c.writeConcern
+ if transactionRunning {
+ wc = nil
+ }
+ if bwo.WriteConcern != nil {
+ if transactionRunning {
+ return nil, errors.New("cannot set write concern after starting a transaction")
+ }
+ wc = bwo.WriteConcern
+ }
+ acknowledged := wc.Acknowledged()
+ if !acknowledged {
+ if bwo.Ordered == nil || *bwo.Ordered {
+ return nil, errors.New("cannot request unacknowledged write concern and ordered writes")
+ }
+ sess = nil
+ }
+
+ maxAdaptiveRetries := c.effectiveAdaptiveRetries(c.retryWrites)
+
+ writeSelector := &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.Write{},
+ &serverselector.Latency{Latency: c.localThreshold},
+ },
+ }
+ selector := makePinnedSelector(sess, writeSelector)
+
+ writePairs := make([]clientBulkWritePair, len(writes))
+ for i, w := range writes {
+ writePairs[i] = clientBulkWritePair{
+ namespace: fmt.Sprintf("%s.%s", w.Database, w.Collection),
+ model: w.Model,
+ }
+ }
+
+ op := clientBulkWrite{
+ writePairs: writePairs,
+ ordered: bwo.Ordered,
+ bypassDocumentValidation: bwo.BypassDocumentValidation,
+ comment: bwo.Comment,
+ let: bwo.Let,
+ session: sess,
+ client: c,
+ selector: selector,
+ writeConcern: wc,
+
+ maxAdaptiveRetries: maxAdaptiveRetries,
+ enableOverloadRetargeting: c.enableOverloadRetargeting,
+ }
+ if rawData, ok := optionsutil.Value(bwo.Internal, "rawData").(bool); ok {
+ op.rawData = &rawData
+ }
+ if additionalCmd, ok := optionsutil.Value(bwo.Internal, "addCommandFields").(bson.D); ok {
+ op.additionalCmd = additionalCmd
+ }
+ if bwo.VerboseResults == nil || !(*bwo.VerboseResults) {
+ op.errorsOnly = true
+ } else if !acknowledged {
+ return nil, errors.New("cannot request unacknowledged write concern and verbose results")
+ }
+ op.result.Acknowledged = acknowledged
+ op.result.HasVerboseResults = !op.errorsOnly
+ err = op.execute(ctx)
+ return &op.result, wrapErrors(err)
}
// newLogger will use the LoggerOptions to create an internal logger and publish
@@ -861,9 +1068,7 @@ func newLogger(opts *options.LoggerOptions) (*logger.Logger, error) {
// If there are no component-level options and the environment does not
// contain component variables, then do nothing.
- if (len(opts.ComponentLevels) == 0) &&
- !logger.EnvHasComponentVariables() {
-
+ if len(opts.ComponentLevels) == 0 && !logger.EnvHasComponentVariables() {
return nil, nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write.go
new file mode 100644
index 000000000..bf3a1e530
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write.go
@@ -0,0 +1,736 @@
+// Copyright (C) MongoDB, Inc. 2024-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 mongo
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
+)
+
+const (
+ database = "admin"
+)
+
+type clientBulkWritePair struct {
+ namespace string
+ model any
+}
+
+type clientBulkWrite struct {
+ writePairs []clientBulkWritePair
+ errorsOnly bool
+ ordered *bool
+ bypassDocumentValidation *bool
+ comment any
+ let any
+ session *session.Client
+ client *Client
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ rawData *bool
+ additionalCmd bson.D
+
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+
+ result ClientBulkWriteResult
+}
+
+func (bw *clientBulkWrite) execute(ctx context.Context) error {
+ if len(bw.writePairs) == 0 {
+ return fmt.Errorf("invalid writes: %w", ErrEmptySlice)
+ }
+ for i, m := range bw.writePairs {
+ if m.model == nil {
+ return fmt.Errorf("error from model at index %d: %w", i, ErrNilDocument)
+ }
+ }
+ batches := &modelBatches{
+ session: bw.session,
+ client: bw.client,
+ ordered: bw.ordered == nil || *bw.ordered,
+ writePairs: bw.writePairs,
+ result: &bw.result,
+ retryMode: driver.RetryOnce,
+ }
+ err := driver.Operation{
+ CommandFn: bw.newCommand(),
+ ProcessResponseFn: batches.processResponse,
+ Client: bw.session,
+ Clock: bw.client.clock,
+ RetryMode: &batches.retryMode,
+ MaxAdaptiveRetries: bw.maxAdaptiveRetries,
+ EnableOverloadRetargeting: bw.enableOverloadRetargeting,
+ Type: driver.Write,
+ Batches: batches,
+ CommandMonitor: bw.client.monitor,
+ Database: database,
+ Deployment: bw.client.deployment,
+ Selector: bw.selector,
+ WriteConcern: bw.writeConcern,
+ Crypt: bw.client.cryptFLE,
+ ServerAPI: bw.client.serverAPI,
+ Timeout: bw.client.timeout,
+ Logger: bw.client.logger,
+ Authenticator: bw.client.authenticator,
+ Name: driverutil.BulkWriteOp,
+ }.Execute(ctx)
+ var exception *ClientBulkWriteException
+
+ var ce CommandError
+ if errors.As(err, &ce) {
+ exception = &ClientBulkWriteException{
+ WriteError: &WriteError{
+ Code: int(ce.Code),
+ Message: ce.Message,
+ Raw: ce.Raw,
+ },
+ }
+ }
+ if len(batches.writeConcernErrors) > 0 || len(batches.writeErrors) > 0 {
+ if exception == nil {
+ exception = new(ClientBulkWriteException)
+ }
+ exception.WriteConcernErrors = batches.writeConcernErrors
+ exception.WriteErrors = batches.writeErrors
+ }
+ if exception != nil {
+ var hasSuccess bool
+ if batches.ordered {
+ _, ok := batches.writeErrors[0]
+ hasSuccess = !ok
+ } else {
+ hasSuccess = len(batches.writeErrors) < len(bw.writePairs)
+ }
+ if hasSuccess {
+ exception.PartialResult = batches.result
+ }
+ return *exception
+ }
+ return err
+}
+
+func (bw *clientBulkWrite) newCommand() func([]byte, description.SelectedServer) ([]byte, error) {
+ return func(dst []byte, desc description.SelectedServer) ([]byte, error) {
+ dst = bsoncore.AppendInt32Element(dst, "bulkWrite", 1)
+
+ dst = bsoncore.AppendBooleanElement(dst, "errorsOnly", bw.errorsOnly)
+ if bw.bypassDocumentValidation != nil && (desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 4)) {
+ dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *bw.bypassDocumentValidation)
+ }
+ if bw.comment != nil {
+ comment, err := marshalValue(bw.comment, bw.client.bsonOpts, bw.client.registry)
+ if err != nil {
+ return nil, err
+ }
+ dst = bsoncore.AppendValueElement(dst, "comment", comment)
+ }
+ dst = bsoncore.AppendBooleanElement(dst, "ordered", bw.ordered == nil || *bw.ordered)
+ if bw.let != nil {
+ let, err := marshal(bw.let, bw.client.bsonOpts, bw.client.registry)
+ if err != nil {
+ return nil, err
+ }
+ dst = bsoncore.AppendDocumentElement(dst, "let", let)
+ }
+ // Set rawData for 8.2+ servers.
+ if bw.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *bw.rawData)
+ }
+ if len(bw.additionalCmd) > 0 {
+ doc, err := bson.Marshal(bw.additionalCmd)
+ if err != nil {
+ return nil, err
+ }
+ dst = append(dst, doc[4:len(doc)-1]...)
+ }
+ return dst, nil
+ }
+}
+
+type cursorInfo struct {
+ Ok bool
+ Idx int32
+ Code *int32
+ Errmsg *string
+ ErrInfo bson.Raw
+ N int32
+ NModified *int32
+ Upserted *struct {
+ ID any `bson:"_id"`
+ }
+}
+
+func (cur *cursorInfo) extractError() *WriteError {
+ if cur.Ok {
+ return nil
+ }
+ err := &WriteError{
+ Index: int(cur.Idx),
+ Details: cur.ErrInfo,
+ }
+ if cur.Code != nil {
+ err.Code = int(*cur.Code)
+ }
+ if cur.Errmsg != nil {
+ err.Message = *cur.Errmsg
+ }
+ return err
+}
+
+type modelBatches struct {
+ session *session.Client
+ client *Client
+
+ ordered bool
+ writePairs []clientBulkWritePair
+
+ offset int
+
+ retryMode driver.RetryMode // RetryNone by default
+ cursorHandlers []func(*cursorInfo, bson.Raw) bool
+ newIDMap map[int]any
+
+ result *ClientBulkWriteResult
+ writeConcernErrors []WriteConcernError
+ writeErrors map[int]WriteError
+}
+
+var _ driver.OperationBatches = &modelBatches{}
+
+func (mb *modelBatches) IsOrdered() *bool {
+ return &mb.ordered
+}
+
+func (mb *modelBatches) AdvanceBatches(n int) {
+ mb.offset += n
+ if mb.offset > len(mb.writePairs) {
+ mb.offset = len(mb.writePairs)
+ }
+}
+
+func (mb *modelBatches) Size() int {
+ if mb.offset > len(mb.writePairs) {
+ return 0
+ }
+ return len(mb.writePairs) - mb.offset
+}
+
+func (mb *modelBatches) AppendBatchSequence(dst []byte, maxCount, totalSize int) (int, []byte, error) {
+ fn := functionSet{
+ appendStart: func(dst []byte, identifier string) (int32, []byte) {
+ var idx int32
+ dst = wiremessage.AppendMsgSectionType(dst, wiremessage.DocumentSequence)
+ idx, dst = bsoncore.ReserveLength(dst)
+ dst = append(dst, identifier...)
+ dst = append(dst, 0x00)
+ return idx, dst
+ },
+ appendDocument: func(dst []byte, _ string, doc []byte) []byte {
+ dst = append(dst, doc...)
+ return dst
+ },
+ updateLength: func(dst []byte, idx, length int32) []byte {
+ dst = bsoncore.UpdateLength(dst, idx, length)
+ return dst
+ },
+ }
+ return mb.appendBatches(fn, dst, maxCount, totalSize)
+}
+
+func (mb *modelBatches) AppendBatchArray(dst []byte, maxCount, totalSize int) (int, []byte, error) {
+ fn := functionSet{
+ appendStart: bsoncore.AppendArrayElementStart,
+ appendDocument: bsoncore.AppendDocumentElement,
+ updateLength: func(dst []byte, idx, _ int32) []byte {
+ dst, _ = bsoncore.AppendArrayEnd(dst, idx)
+ return dst
+ },
+ }
+ return mb.appendBatches(fn, dst, maxCount, totalSize)
+}
+
+type functionSet struct {
+ appendStart func([]byte, string) (int32, []byte)
+ appendDocument func([]byte, string, []byte) []byte
+ updateLength func([]byte, int32, int32) []byte
+}
+
+func (mb *modelBatches) appendBatches(fn functionSet, dst []byte, maxCount, totalSize int) (int, []byte, error) {
+ if mb.Size() == 0 {
+ return 0, dst, io.EOF
+ }
+
+ mb.cursorHandlers = mb.cursorHandlers[:0]
+ mb.newIDMap = make(map[int]any)
+
+ nsMap := make(map[string]int)
+ getNsIndex := func(namespace string) (int, bool) {
+ v, ok := nsMap[namespace]
+ if ok {
+ return v, ok
+ }
+ nsIdx := len(nsMap)
+ nsMap[namespace] = nsIdx
+ return nsIdx, ok
+ }
+
+ canRetry := true
+ l := len(dst)
+
+ opsIdx, dst := fn.appendStart(dst, "ops")
+ nsIdx, nsDst := fn.appendStart(nil, "nsInfo")
+
+ totalSize -= 1000
+ size := len(dst) + len(nsDst)
+ var n int
+ for i := mb.offset; i < len(mb.writePairs); i++ {
+ if n == maxCount {
+ break
+ }
+
+ ns := mb.writePairs[i].namespace
+ nsIdx, exists := getNsIndex(ns)
+
+ var doc bsoncore.Document
+ var err error
+ switch model := mb.writePairs[i].model.(type) {
+ case *ClientInsertOneModel:
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendInsertResult)
+ var id any
+ id, doc, err = (&clientInsertDoc{
+ namespace: nsIdx,
+ document: model.Document,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ if err != nil {
+ break
+ }
+ mb.newIDMap[i] = id
+ case *ClientUpdateOneModel:
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendUpdateResult)
+ doc, err = (&clientUpdateDoc{
+ namespace: nsIdx,
+ filter: model.Filter,
+ update: model.Update,
+ hint: model.Hint,
+ arrayFilters: model.ArrayFilters,
+ collation: model.Collation,
+ upsert: model.Upsert,
+ sort: model.Sort,
+ multi: false,
+ checkDollarKey: true,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ case *ClientUpdateManyModel:
+ canRetry = false
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendUpdateResult)
+ doc, err = (&clientUpdateDoc{
+ namespace: nsIdx,
+ filter: model.Filter,
+ update: model.Update,
+ hint: model.Hint,
+ arrayFilters: model.ArrayFilters,
+ collation: model.Collation,
+ upsert: model.Upsert,
+ multi: true,
+ checkDollarKey: true,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ case *ClientReplaceOneModel:
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendUpdateResult)
+ doc, err = (&clientUpdateDoc{
+ namespace: nsIdx,
+ filter: model.Filter,
+ update: model.Replacement,
+ hint: model.Hint,
+ arrayFilters: nil,
+ collation: model.Collation,
+ upsert: model.Upsert,
+ sort: model.Sort,
+ multi: false,
+ checkDollarKey: false,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ case *ClientDeleteOneModel:
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendDeleteResult)
+ doc, err = (&clientDeleteDoc{
+ namespace: nsIdx,
+ filter: model.Filter,
+ collation: model.Collation,
+ hint: model.Hint,
+ multi: false,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ case *ClientDeleteManyModel:
+ canRetry = false
+ mb.cursorHandlers = append(mb.cursorHandlers, mb.appendDeleteResult)
+ doc, err = (&clientDeleteDoc{
+ namespace: nsIdx,
+ filter: model.Filter,
+ collation: model.Collation,
+ hint: model.Hint,
+ multi: true,
+ }).marshal(mb.client.bsonOpts, mb.client.registry)
+ default:
+ mb.cursorHandlers = append(mb.cursorHandlers, nil)
+ }
+ if err != nil {
+ return 0, nil, err
+ }
+ length := len(doc)
+ if !exists {
+ length += len(ns)
+ }
+ size += length
+ if size >= totalSize {
+ break
+ }
+
+ dst = fn.appendDocument(dst, strconv.Itoa(n), doc)
+ if !exists {
+ idx, doc := bsoncore.AppendDocumentStart(nil)
+ doc = bsoncore.AppendStringElement(doc, "ns", ns)
+ doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
+ nsDst = fn.appendDocument(nsDst, strconv.Itoa(n), doc)
+ }
+ n++
+ }
+ if n == 0 {
+ return 0, dst[:l], nil
+ }
+
+ dst = fn.updateLength(dst, opsIdx, int32(len(dst[opsIdx:])))
+ nsDst = fn.updateLength(nsDst, nsIdx, int32(len(nsDst[nsIdx:])))
+ dst = append(dst, nsDst...)
+
+ mb.retryMode = driver.RetryNone
+ if mb.client.retryWrites && canRetry {
+ mb.retryMode = driver.RetryOnce
+ }
+ return n, dst, nil
+}
+
+func (mb *modelBatches) processResponse(ctx context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ var writeCmdErr driver.WriteCommandError
+ if errors.As(info.Error, &writeCmdErr) && writeCmdErr.WriteConcernError != nil {
+ wce := convertDriverWriteConcernError(writeCmdErr.WriteConcernError)
+ if wce != nil {
+ mb.writeConcernErrors = append(mb.writeConcernErrors, *wce)
+ }
+ }
+ if len(resp) == 0 {
+ return nil
+ }
+ var res struct {
+ Ok bool
+ Cursor bsoncore.Document
+ NDeleted int32
+ NInserted int32
+ NMatched int32
+ NModified int32
+ NUpserted int32
+ NErrors int32
+ Code int32
+ Errmsg string
+ }
+ err := bson.Unmarshal(resp, &res)
+ if err != nil {
+ return err
+ }
+ if !res.Ok {
+ return ClientBulkWriteException{
+ WriteError: &WriteError{
+ Code: int(res.Code),
+ Message: res.Errmsg,
+ Raw: bson.Raw(resp),
+ },
+ WriteConcernErrors: mb.writeConcernErrors,
+ WriteErrors: mb.writeErrors,
+ PartialResult: mb.result,
+ }
+ }
+
+ if mb.result.Acknowledged {
+ mb.result.DeletedCount += int64(res.NDeleted)
+ mb.result.InsertedCount += int64(res.NInserted)
+ mb.result.MatchedCount += int64(res.NMatched)
+ mb.result.ModifiedCount += int64(res.NModified)
+ mb.result.UpsertedCount += int64(res.NUpserted)
+ }
+
+ var cursorRes driver.CursorResponse
+ cursorRes, err = driver.NewCursorResponse(res.Cursor, info)
+ if err != nil {
+ return err
+ }
+ var bCursor *driver.BatchCursor
+ bCursor, err = driver.NewBatchCursor(cursorRes, mb.session, mb.client.clock,
+ driver.CursorOptions{
+ CommandMonitor: mb.client.monitor,
+ Crypt: mb.client.cryptFLE,
+ ServerAPI: mb.client.serverAPI,
+ MarshalValueEncoderFn: newEncoderFn(mb.client.bsonOpts, mb.client.registry),
+ },
+ )
+ if err != nil {
+ return err
+ }
+ var cursor *Cursor
+ cursor, err = newCursor(bCursor, mb.client.bsonOpts, mb.client.registry,
+
+ // This op doesn't return a cursor to the user, so setting the client
+ // timeout should be a no-op.
+ withCursorOptionClientTimeout(mb.client.timeout))
+ if err != nil {
+ return err
+ }
+ defer cursor.Close(ctx)
+
+ ok := true
+ for cursor.Next(ctx) {
+ var cur cursorInfo
+ err = cursor.Decode(&cur)
+ if err != nil {
+ return err
+ }
+ if int(cur.Idx) >= len(mb.cursorHandlers) {
+ continue
+ }
+ ok = mb.cursorHandlers[int(cur.Idx)](&cur, cursor.Current) && ok
+ }
+ err = cursor.Err()
+ if err != nil {
+ return err
+ }
+ if mb.ordered && (writeCmdErr.WriteConcernError != nil || !ok || !res.Ok || res.NErrors > 0) {
+ return ClientBulkWriteException{
+ WriteConcernErrors: mb.writeConcernErrors,
+ WriteErrors: mb.writeErrors,
+ PartialResult: mb.result,
+ }
+ }
+ return nil
+}
+
+func (mb *modelBatches) appendDeleteResult(cur *cursorInfo, raw bson.Raw) bool {
+ idx := int(cur.Idx) + mb.offset
+ if err := cur.extractError(); err != nil {
+ err.Raw = raw
+ if mb.writeErrors == nil {
+ mb.writeErrors = make(map[int]WriteError)
+ }
+ mb.writeErrors[idx] = *err
+ return false
+ }
+
+ if mb.result.Acknowledged {
+ if mb.result.DeleteResults == nil {
+ mb.result.DeleteResults = make(map[int]ClientBulkWriteDeleteResult)
+ }
+ mb.result.DeleteResults[idx] = ClientBulkWriteDeleteResult{int64(cur.N)}
+ }
+
+ return true
+}
+
+func (mb *modelBatches) appendInsertResult(cur *cursorInfo, raw bson.Raw) bool {
+ idx := int(cur.Idx) + mb.offset
+ if err := cur.extractError(); err != nil {
+ err.Raw = raw
+ if mb.writeErrors == nil {
+ mb.writeErrors = make(map[int]WriteError)
+ }
+ mb.writeErrors[idx] = *err
+ return false
+ }
+
+ if mb.result.Acknowledged {
+ if mb.result.InsertResults == nil {
+ mb.result.InsertResults = make(map[int]ClientBulkWriteInsertResult)
+ }
+ mb.result.InsertResults[idx] = ClientBulkWriteInsertResult{mb.newIDMap[idx]}
+ }
+
+ return true
+}
+
+func (mb *modelBatches) appendUpdateResult(cur *cursorInfo, raw bson.Raw) bool {
+ idx := int(cur.Idx) + mb.offset
+ if err := cur.extractError(); err != nil {
+ err.Raw = raw
+ if mb.writeErrors == nil {
+ mb.writeErrors = make(map[int]WriteError)
+ }
+ mb.writeErrors[idx] = *err
+ return false
+ }
+
+ if mb.result.Acknowledged {
+ if mb.result.UpdateResults == nil {
+ mb.result.UpdateResults = make(map[int]ClientBulkWriteUpdateResult)
+ }
+ result := ClientBulkWriteUpdateResult{
+ MatchedCount: int64(cur.N),
+ }
+ if cur.NModified != nil {
+ result.ModifiedCount = int64(*cur.NModified)
+ }
+ if cur.Upserted != nil {
+ result.UpsertedID = cur.Upserted.ID
+ }
+ mb.result.UpdateResults[idx] = result
+ }
+
+ return true
+}
+
+type clientInsertDoc struct {
+ namespace int
+ document any
+}
+
+func (d *clientInsertDoc) marshal(bsonOpts *options.BSONOptions, registry *bson.Registry) (any, bsoncore.Document, error) {
+ uidx, doc := bsoncore.AppendDocumentStart(nil)
+
+ doc = bsoncore.AppendInt32Element(doc, "insert", int32(d.namespace))
+ f, err := marshal(d.document, bsonOpts, registry)
+ if err != nil {
+ return nil, nil, err
+ }
+ var id any
+ f, id, err = ensureID(f, bson.NilObjectID, bsonOpts, registry)
+ if err != nil {
+ return nil, nil, err
+ }
+ doc = bsoncore.AppendDocumentElement(doc, "document", f)
+ doc, err = bsoncore.AppendDocumentEnd(doc, uidx)
+ return id, doc, err
+}
+
+type clientUpdateDoc struct {
+ namespace int
+ filter any
+ update any
+ hint any
+ arrayFilters []any
+ collation *options.Collation
+ sort any
+ upsert *bool
+ multi bool
+ checkDollarKey bool
+}
+
+func (d *clientUpdateDoc) marshal(bsonOpts *options.BSONOptions, registry *bson.Registry) (bsoncore.Document, error) {
+ uidx, doc := bsoncore.AppendDocumentStart(nil)
+
+ doc = bsoncore.AppendInt32Element(doc, "update", int32(d.namespace))
+
+ if d.filter == nil {
+ return nil, fmt.Errorf("update filter cannot be nil")
+ }
+ f, err := marshal(d.filter, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendDocumentElement(doc, "filter", f)
+
+ u, err := marshalUpdateValue(d.update, bsonOpts, registry, d.checkDollarKey)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendValueElement(doc, "updateMods", u)
+ doc = bsoncore.AppendBooleanElement(doc, "multi", d.multi)
+
+ if d.arrayFilters != nil {
+ reg := registry
+ arr, err := marshalValue(d.arrayFilters, bsonOpts, reg)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendArrayElement(doc, "arrayFilters", arr.Data)
+ }
+
+ if d.collation != nil {
+ doc = bsoncore.AppendDocumentElement(doc, "collation", toDocument(d.collation))
+ }
+
+ if d.upsert != nil {
+ doc = bsoncore.AppendBooleanElement(doc, "upsert", *d.upsert)
+ }
+
+ if d.hint != nil {
+ if isUnorderedMap(d.hint) {
+ return nil, ErrMapForOrderedArgument{"hint"}
+ }
+ hintVal, err := marshalValue(d.hint, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendValueElement(doc, "hint", hintVal)
+ }
+
+ if d.sort != nil {
+ if isUnorderedMap(d.sort) {
+ return nil, ErrMapForOrderedArgument{"sort"}
+ }
+ sortVal, err := marshalValue(d.sort, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendValueElement(doc, "sort", sortVal)
+ }
+
+ return bsoncore.AppendDocumentEnd(doc, uidx)
+}
+
+type clientDeleteDoc struct {
+ namespace int
+ filter any
+ collation *options.Collation
+ hint any
+ multi bool
+}
+
+func (d *clientDeleteDoc) marshal(bsonOpts *options.BSONOptions, registry *bson.Registry) (bsoncore.Document, error) {
+ didx, doc := bsoncore.AppendDocumentStart(nil)
+
+ doc = bsoncore.AppendInt32Element(doc, "delete", int32(d.namespace))
+
+ if d.filter == nil {
+ return nil, fmt.Errorf("delete filter cannot be nil")
+ }
+ f, err := marshal(d.filter, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendDocumentElement(doc, "filter", f)
+ doc = bsoncore.AppendBooleanElement(doc, "multi", d.multi)
+
+ if d.collation != nil {
+ doc = bsoncore.AppendDocumentElement(doc, "collation", toDocument(d.collation))
+ }
+ if d.hint != nil {
+ if isUnorderedMap(d.hint) {
+ return nil, ErrMapForOrderedArgument{"hint"}
+ }
+ hintVal, err := marshalValue(d.hint, bsonOpts, registry)
+ if err != nil {
+ return nil, err
+ }
+ doc = bsoncore.AppendValueElement(doc, "hint", hintVal)
+ }
+ return bsoncore.AppendDocumentEnd(doc, didx)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write_models.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write_models.go
new file mode 100644
index 000000000..da0ea18e3
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write_models.go
@@ -0,0 +1,318 @@
+// Copyright (C) MongoDB, Inc. 2024-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 mongo
+
+import (
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+)
+
+// ClientWriteModel is an interface implemented by models that can be used in a client-level BulkWrite operation. Each
+// ClientWriteModel represents a write.
+//
+// This interface is implemented by ClientDeleteOneModel, ClientDeleteManyModel, ClientInsertOneModel,
+// ClientReplaceOneModel, ClientUpdateOneModel, and ClientUpdateManyModel. Custom implementations of this interface must
+// not be used.
+type ClientWriteModel interface {
+ clientWriteModel()
+}
+
+// ClientInsertOneModel is used to insert a single document in a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientInsertOneModel struct {
+ Document any
+}
+
+// NewClientInsertOneModel creates a new ClientInsertOneModel.
+func NewClientInsertOneModel() *ClientInsertOneModel {
+ return &ClientInsertOneModel{}
+}
+
+func (*ClientInsertOneModel) clientWriteModel() {}
+
+// SetDocument specifies the document to be inserted. The document cannot be nil. If it does not have an _id field when
+// transformed into BSON, one will be added automatically to the marshalled document. The original document will not be
+// modified.
+func (iom *ClientInsertOneModel) SetDocument(doc any) *ClientInsertOneModel {
+ iom.Document = doc
+ return iom
+}
+
+// ClientUpdateOneModel is used to update at most one document in a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientUpdateOneModel struct {
+ Collation *options.Collation
+ Upsert *bool
+ Filter any
+ Update any
+ ArrayFilters []any
+ Hint any
+ Sort any
+}
+
+// NewClientUpdateOneModel creates a new ClientUpdateOneModel.
+func NewClientUpdateOneModel() *ClientUpdateOneModel {
+ return &ClientUpdateOneModel{}
+}
+
+func (*ClientUpdateOneModel) clientWriteModel() {}
+
+// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
+// specification as a document. The default value is nil, which means that no hint will be sent.
+func (uom *ClientUpdateOneModel) SetHint(hint any) *ClientUpdateOneModel {
+ uom.Hint = hint
+ return uom
+}
+
+// SetFilter specifies a filter to use to select the document to update. The filter must be a document containing query
+// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
+// documents.
+func (uom *ClientUpdateOneModel) SetFilter(filter any) *ClientUpdateOneModel {
+ uom.Filter = filter
+ return uom
+}
+
+// SetUpdate specifies the modifications to be made to the selected document. The value must be a document containing
+// update operators (https://www.mongodb.com/docs/manual/reference/operator/update/). It cannot be nil or empty.
+func (uom *ClientUpdateOneModel) SetUpdate(update any) *ClientUpdateOneModel {
+ uom.Update = update
+ return uom
+}
+
+// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
+// field.
+func (uom *ClientUpdateOneModel) SetArrayFilters(filters []any) *ClientUpdateOneModel {
+ uom.ArrayFilters = filters
+ return uom
+}
+
+// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
+// used.
+func (uom *ClientUpdateOneModel) SetCollation(collation *options.Collation) *ClientUpdateOneModel {
+ uom.Collation = collation
+ return uom
+}
+
+// SetUpsert specifies whether or not a new document should be inserted if no document matching the filter is found. If
+// an upsert is performed, the _id of the upserted document can be retrieved from the UpdateResults field of the
+// ClientBulkWriteResult.
+func (uom *ClientUpdateOneModel) SetUpsert(upsert bool) *ClientUpdateOneModel {
+ uom.Upsert = &upsert
+ return uom
+}
+
+// SetSort specifies which document the operation updates if the query matches multiple documents. The first document
+// matched by the sort order will be updated. This option is only valid for MongoDB versions >= 8.0. The sort parameter
+// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
+// default value is nil.
+func (uom *ClientUpdateOneModel) SetSort(sort any) *ClientUpdateOneModel {
+ uom.Sort = sort
+ return uom
+}
+
+// ClientUpdateManyModel is used to update multiple documents in a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientUpdateManyModel struct {
+ Collation *options.Collation
+ Upsert *bool
+ Filter any
+ Update any
+ ArrayFilters []any
+ Hint any
+}
+
+// NewClientUpdateManyModel creates a new ClientUpdateManyModel.
+func NewClientUpdateManyModel() *ClientUpdateManyModel {
+ return &ClientUpdateManyModel{}
+}
+
+func (*ClientUpdateManyModel) clientWriteModel() {}
+
+// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
+// specification as a document. The default value is nil, which means that no hint will be sent.
+func (umm *ClientUpdateManyModel) SetHint(hint any) *ClientUpdateManyModel {
+ umm.Hint = hint
+ return umm
+}
+
+// SetFilter specifies a filter to use to select documents to update. The filter must be a document containing query
+// operators. It cannot be nil.
+func (umm *ClientUpdateManyModel) SetFilter(filter any) *ClientUpdateManyModel {
+ umm.Filter = filter
+ return umm
+}
+
+// SetUpdate specifies the modifications to be made to the selected documents. The value must be a document containing
+// update operators (https://www.mongodb.com/docs/manual/reference/operator/update/). It cannot be nil or empty.
+func (umm *ClientUpdateManyModel) SetUpdate(update any) *ClientUpdateManyModel {
+ umm.Update = update
+ return umm
+}
+
+// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
+// field.
+func (umm *ClientUpdateManyModel) SetArrayFilters(filters []any) *ClientUpdateManyModel {
+ umm.ArrayFilters = filters
+ return umm
+}
+
+// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
+// used.
+func (umm *ClientUpdateManyModel) SetCollation(collation *options.Collation) *ClientUpdateManyModel {
+ umm.Collation = collation
+ return umm
+}
+
+// SetUpsert specifies whether or not a new document should be inserted if no document matching the filter is found. If
+// an upsert is performed, the _id of the upserted document can be retrieved from the UpdateResults field of the
+// ClientBulkWriteResult.
+func (umm *ClientUpdateManyModel) SetUpsert(upsert bool) *ClientUpdateManyModel {
+ umm.Upsert = &upsert
+ return umm
+}
+
+// ClientReplaceOneModel is used to replace at most one document in a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientReplaceOneModel struct {
+ Collation *options.Collation
+ Upsert *bool
+ Filter any
+ Replacement any
+ Hint any
+ Sort any
+}
+
+// NewClientReplaceOneModel creates a new ClientReplaceOneModel.
+func NewClientReplaceOneModel() *ClientReplaceOneModel {
+ return &ClientReplaceOneModel{}
+}
+
+func (*ClientReplaceOneModel) clientWriteModel() {}
+
+// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
+// specification as a document. The default value is nil, which means that no hint will be sent.
+func (rom *ClientReplaceOneModel) SetHint(hint any) *ClientReplaceOneModel {
+ rom.Hint = hint
+ return rom
+}
+
+// SetFilter specifies a filter to use to select the document to replace. The filter must be a document containing query
+// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
+// documents.
+func (rom *ClientReplaceOneModel) SetFilter(filter any) *ClientReplaceOneModel {
+ rom.Filter = filter
+ return rom
+}
+
+// SetReplacement specifies a document that will be used to replace the selected document. It cannot be nil and cannot
+// contain any update operators (https://www.mongodb.com/docs/manual/reference/operator/update/).
+func (rom *ClientReplaceOneModel) SetReplacement(rep any) *ClientReplaceOneModel {
+ rom.Replacement = rep
+ return rom
+}
+
+// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
+// used.
+func (rom *ClientReplaceOneModel) SetCollation(collation *options.Collation) *ClientReplaceOneModel {
+ rom.Collation = collation
+ return rom
+}
+
+// SetUpsert specifies whether or not the replacement document should be inserted if no document matching the filter is
+// found. If an upsert is performed, the _id of the upserted document can be retrieved from the UpdateResults field of the
+// BulkWriteResult.
+func (rom *ClientReplaceOneModel) SetUpsert(upsert bool) *ClientReplaceOneModel {
+ rom.Upsert = &upsert
+ return rom
+}
+
+// SetSort specifies which document the operation replaces if the query matches multiple documents. The first document
+// matched by the sort order will be replaced. This option is only valid for MongoDB versions >= 8.0. The sort parameter
+// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
+// default value is nil.
+func (rom *ClientReplaceOneModel) SetSort(sort any) *ClientReplaceOneModel {
+ rom.Sort = sort
+ return rom
+}
+
+// ClientDeleteOneModel is used to delete at most one document in a client-level BulkWriteOperation.
+//
+// See corresponding setter methods for documentation.
+type ClientDeleteOneModel struct {
+ Filter any
+ Collation *options.Collation
+ Hint any
+}
+
+// NewClientDeleteOneModel creates a new ClientDeleteOneModel.
+func NewClientDeleteOneModel() *ClientDeleteOneModel {
+ return &ClientDeleteOneModel{}
+}
+
+func (*ClientDeleteOneModel) clientWriteModel() {}
+
+// SetFilter specifies a filter to use to select the document to delete. The filter must be a document containing query
+// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
+// documents.
+func (dom *ClientDeleteOneModel) SetFilter(filter any) *ClientDeleteOneModel {
+ dom.Filter = filter
+ return dom
+}
+
+// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
+// used.
+func (dom *ClientDeleteOneModel) SetCollation(collation *options.Collation) *ClientDeleteOneModel {
+ dom.Collation = collation
+ return dom
+}
+
+// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
+// specification as a document. The default value is nil, which means that no hint will be sent.
+func (dom *ClientDeleteOneModel) SetHint(hint any) *ClientDeleteOneModel {
+ dom.Hint = hint
+ return dom
+}
+
+// ClientDeleteManyModel is used to delete multiple documents in a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientDeleteManyModel struct {
+ Filter any
+ Collation *options.Collation
+ Hint any
+}
+
+// NewClientDeleteManyModel creates a new ClientDeleteManyModel.
+func NewClientDeleteManyModel() *ClientDeleteManyModel {
+ return &ClientDeleteManyModel{}
+}
+
+func (*ClientDeleteManyModel) clientWriteModel() {}
+
+// SetFilter specifies a filter to use to select documents to delete. The filter must be a document containing query
+// operators. It cannot be nil.
+func (dmm *ClientDeleteManyModel) SetFilter(filter any) *ClientDeleteManyModel {
+ dmm.Filter = filter
+ return dmm
+}
+
+// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
+// used.
+func (dmm *ClientDeleteManyModel) SetCollation(collation *options.Collation) *ClientDeleteManyModel {
+ dmm.Collation = collation
+ return dmm
+}
+
+// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
+// specification as a document. The default value is nil, which means that no hint will be sent.
+func (dmm *ClientDeleteManyModel) SetHint(hint any) *ClientDeleteManyModel {
+ dmm.Hint = hint
+ return dmm
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/client_encryption.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_encryption.go
similarity index 62%
rename from vendor/go.mongodb.org/mongo-driver/mongo/client_encryption.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/client_encryption.go
index 352dac1f0..ceb132937 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/client_encryption.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/client_encryption.go
@@ -7,19 +7,19 @@
package mongo
import (
+ "bytes"
"context"
"errors"
"fmt"
"strings"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt"
- mcopts "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt"
+ mcopts "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options"
)
// ClientEncryption is used to create data keys and explicitly encrypt and decrypt BSON values.
@@ -27,10 +27,11 @@ type ClientEncryption struct {
crypt driver.Crypt
keyVaultClient *Client
keyVaultColl *Collection
+ closed bool
}
// NewClientEncryption creates a new ClientEncryption instance configured with the given options.
-func NewClientEncryption(keyVaultClient *Client, opts ...*options.ClientEncryptionOptions) (*ClientEncryption, error) {
+func NewClientEncryption(keyVaultClient *Client, opts ...options.Lister[options.ClientEncryptionOptions]) (*ClientEncryption, error) {
if keyVaultClient == nil {
return nil, errors.New("keyVaultClient must not be nil")
}
@@ -38,24 +39,29 @@ func NewClientEncryption(keyVaultClient *Client, opts ...*options.ClientEncrypti
ce := &ClientEncryption{
keyVaultClient: keyVaultClient,
}
- ceo := options.MergeClientEncryptionOptions(opts...)
+ cea, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
// create keyVaultColl
- db, coll := splitNamespace(ceo.KeyVaultNamespace)
+ db, coll := splitNamespace(cea.KeyVaultNamespace)
ce.keyVaultColl = ce.keyVaultClient.Database(db).Collection(coll, keyVaultCollOpts)
- kmsProviders, err := marshal(ceo.KmsProviders, nil, nil)
+ kmsProviders, err := marshal(cea.KmsProviders, nil, nil)
if err != nil {
return nil, fmt.Errorf("error creating KMS providers map: %w", err)
}
- mc, err := mongocrypt.NewMongoCrypt(mcopts.MongoCrypt().
- SetKmsProviders(kmsProviders).
+ mc, err := mongocrypt.NewMongoCrypt(&mcopts.MongoCryptOptions{
+ KmsProviders: kmsProviders,
// Explicitly disable loading the crypt_shared library for the Crypt used for
// ClientEncryption because it's only needed for AutoEncryption and we don't expect users to
// have the crypt_shared library installed if they're using ClientEncryption.
- SetCryptSharedLibDisabled(true).
- SetHTTPClient(ceo.HTTPClient))
+ CryptSharedLibDisabled: true,
+ HTTPClient: cea.HTTPClient,
+ KeyExpiration: cea.KeyExpiration,
+ })
if err != nil {
return nil, err
}
@@ -67,7 +73,7 @@ func NewClientEncryption(keyVaultClient *Client, opts ...*options.ClientEncrypti
MongoCrypt: mc,
KeyFn: kr.cryptKeys,
CollInfoFn: cir.cryptCollInfo,
- TLSConfig: ceo.TLSConfig,
+ TLSConfig: cea.TLSConfig,
})
return ce, nil
@@ -76,12 +82,23 @@ func NewClientEncryption(keyVaultClient *Client, opts ...*options.ClientEncrypti
// CreateEncryptedCollection creates a new collection for Queryable Encryption with the help of automatic generation of new encryption data keys for null keyIds.
// It returns the created collection and the encrypted fields document used to create it.
func (ce *ClientEncryption) CreateEncryptedCollection(ctx context.Context,
- db *Database, coll string, createOpts *options.CreateCollectionOptions,
- kmsProvider string, masterKey interface{}) (*Collection, bson.M, error) {
+ db *Database, coll string, createOpts options.Lister[options.CreateCollectionOptions],
+ kmsProvider string, masterKey any,
+) (*Collection, bson.M, error) {
+ if ce.closed {
+ return nil, nil, ErrClientDisconnected
+ }
+
if createOpts == nil {
return nil, nil, errors.New("nil CreateCollectionOptions")
}
- ef := createOpts.EncryptedFields
+
+ createArgs, err := mongoutil.NewOptions[options.CreateCollectionOptions](createOpts)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ ef := createArgs.EncryptedFields
if ef == nil {
return nil, nil, errors.New("no EncryptedFields defined for the collection")
}
@@ -90,11 +107,9 @@ func (ce *ClientEncryption) CreateEncryptedCollection(ctx context.Context,
if err != nil {
return nil, nil, err
}
- r := bsonrw.NewBSONDocumentReader(efBSON)
- dec, err := bson.NewDecoder(r)
- if err != nil {
- return nil, nil, err
- }
+ r := bson.NewDocumentReader(bytes.NewReader(efBSON))
+ dec := bson.NewDecoder(r)
+ dec.DefaultDocumentM()
var m bson.M
err = dec.Decode(&m)
if err != nil {
@@ -113,16 +128,18 @@ func (ce *ClientEncryption) CreateEncryptedCollection(ctx context.Context,
}
keyid, err := ce.CreateDataKey(ctx, kmsProvider, dkOpts)
if err != nil {
- createOpts.EncryptedFields = m
+ createArgs.EncryptedFields = m
return nil, m, err
}
f["keyId"] = keyid
}
}
- createOpts.EncryptedFields = m
+ createArgs.EncryptedFields = m
}
}
- err = db.CreateCollection(ctx, coll, createOpts)
+
+ updatedCreateOpts := mongoutil.NewOptionsLister(createArgs, nil)
+ err = db.CreateCollection(ctx, coll, updatedCreateOpts)
if err != nil {
return nil, m, err
}
@@ -131,7 +148,11 @@ func (ce *ClientEncryption) CreateEncryptedCollection(ctx context.Context,
// AddKeyAltName adds a keyAltName to the keyAltNames array of the key document in the key vault collection with the
// given UUID (BSON binary subtype 0x04). Returns the previous version of the key document.
-func (ce *ClientEncryption) AddKeyAltName(ctx context.Context, id primitive.Binary, keyAltName string) *SingleResult {
+func (ce *ClientEncryption) AddKeyAltName(ctx context.Context, id bson.Binary, keyAltName string) *SingleResult {
+ if ce.closed {
+ return &SingleResult{err: ErrClientDisconnected}
+ }
+
filter := bsoncore.NewDocumentBuilder().AppendBinary("_id", id.Subtype, id.Data).Build()
keyAltNameDoc := bsoncore.NewDocumentBuilder().AppendString("keyAltNames", keyAltName).Build()
update := bsoncore.NewDocumentBuilder().AppendDocument("$addToSet", keyAltNameDoc).Build()
@@ -140,91 +161,136 @@ func (ce *ClientEncryption) AddKeyAltName(ctx context.Context, id primitive.Bina
// CreateDataKey creates a new key document and inserts into the key vault collection. Returns the _id of the created
// document as a UUID (BSON binary subtype 0x04).
-func (ce *ClientEncryption) CreateDataKey(ctx context.Context, kmsProvider string,
- opts ...*options.DataKeyOptions) (primitive.Binary, error) {
+func (ce *ClientEncryption) CreateDataKey(
+ ctx context.Context,
+ kmsProvider string,
+ opts ...options.Lister[options.DataKeyOptions],
+) (bson.Binary, error) {
+ if ce.closed {
+ return bson.Binary{}, ErrClientDisconnected
+ }
- // translate opts to mcopts.DataKeyOptions
- dko := options.MergeDataKeyOptions(opts...)
- co := mcopts.DataKey().SetKeyAltNames(dko.KeyAltNames)
- if dko.MasterKey != nil {
+ args, err := mongoutil.NewOptions[options.DataKeyOptions](opts...)
+ if err != nil {
+ return bson.Binary{}, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ co := &mcopts.DataKeyOptions{
+ KeyAltNames: args.KeyAltNames,
+ KeyMaterial: args.KeyMaterial,
+ }
+ if args.MasterKey != nil {
keyDoc, err := marshal(
- dko.MasterKey,
+ args.MasterKey,
ce.keyVaultClient.bsonOpts,
ce.keyVaultClient.registry)
if err != nil {
- return primitive.Binary{}, err
+ return bson.Binary{}, err
}
- co.SetMasterKey(keyDoc)
- }
- if dko.KeyMaterial != nil {
- co.SetKeyMaterial(dko.KeyMaterial)
+ co.MasterKey = keyDoc
}
// create data key document
dataKeyDoc, err := ce.crypt.CreateDataKey(ctx, kmsProvider, co)
if err != nil {
- return primitive.Binary{}, err
+ return bson.Binary{}, err
}
// insert key into key vault
_, err = ce.keyVaultColl.InsertOne(ctx, dataKeyDoc)
if err != nil {
- return primitive.Binary{}, err
+ return bson.Binary{}, err
}
subtype, data := bson.Raw(dataKeyDoc).Lookup("_id").Binary()
- return primitive.Binary{Subtype: subtype, Data: data}, nil
+ return bson.Binary{Subtype: subtype, Data: data}, nil
}
// transformExplicitEncryptionOptions creates explicit encryption options to be passed to libmongocrypt.
-func transformExplicitEncryptionOptions(opts ...*options.EncryptOptions) *mcopts.ExplicitEncryptionOptions {
- eo := options.MergeEncryptOptions(opts...)
- transformed := mcopts.ExplicitEncryption()
- if eo.KeyID != nil {
- transformed.SetKeyID(*eo.KeyID)
- }
- if eo.KeyAltName != nil {
- transformed.SetKeyAltName(*eo.KeyAltName)
+func transformExplicitEncryptionOptions(opts ...options.Lister[options.EncryptOptions]) (*mcopts.ExplicitEncryptionOptions, error) {
+ args, err := mongoutil.NewOptions[options.EncryptOptions](opts...)
+ if err != nil {
+ return nil, err
}
- transformed.SetAlgorithm(eo.Algorithm)
- transformed.SetQueryType(eo.QueryType)
- if eo.ContentionFactor != nil {
- transformed.SetContentionFactor(*eo.ContentionFactor)
+ transformed := &mcopts.ExplicitEncryptionOptions{
+ KeyID: args.KeyID,
+ KeyAltName: args.KeyAltName,
+ Algorithm: args.Algorithm,
+ QueryType: args.QueryType,
+ ContentionFactor: args.ContentionFactor,
}
- if eo.RangeOptions != nil {
+ if args.RangeOptions != nil {
+ rangeArgs, err := mongoutil.NewOptions[options.RangeOptions](args.RangeOptions)
+ if err != nil {
+ return nil, err
+ }
+
var transformedRange mcopts.ExplicitRangeOptions
- if eo.RangeOptions.Min != nil {
- transformedRange.Min = &bsoncore.Value{Type: eo.RangeOptions.Min.Type, Data: eo.RangeOptions.Min.Value}
+ if rangeArgs.Min != nil {
+ transformedRange.Min = &bsoncore.Value{Type: bsoncore.Type(rangeArgs.Min.Type), Data: rangeArgs.Min.Value}
}
- if eo.RangeOptions.Max != nil {
- transformedRange.Max = &bsoncore.Value{Type: eo.RangeOptions.Max.Type, Data: eo.RangeOptions.Max.Value}
+ if rangeArgs.Max != nil {
+ transformedRange.Max = &bsoncore.Value{Type: bsoncore.Type(rangeArgs.Max.Type), Data: rangeArgs.Max.Value}
}
- if eo.RangeOptions.Precision != nil {
- transformedRange.Precision = eo.RangeOptions.Precision
+ if rangeArgs.Precision != nil {
+ transformedRange.Precision = rangeArgs.Precision
}
- if eo.RangeOptions.Sparsity != nil {
- transformedRange.Sparsity = eo.RangeOptions.Sparsity
+ if rangeArgs.Sparsity != nil {
+ transformedRange.Sparsity = rangeArgs.Sparsity
}
- if eo.RangeOptions.TrimFactor != nil {
- transformedRange.TrimFactor = eo.RangeOptions.TrimFactor
+ if rangeArgs.TrimFactor != nil {
+ transformedRange.TrimFactor = rangeArgs.TrimFactor
}
- transformed.SetRangeOptions(transformedRange)
+ transformed.RangeOptions = &transformedRange
}
- return transformed
+ if args.TextOptions != nil {
+ textArgs, err := mongoutil.NewOptions[options.TextOptions](args.TextOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ transformedText := mcopts.ExplicitTextOptions{
+ CaseSensitive: textArgs.CaseSensitive,
+ DiacriticSensitive: textArgs.DiacriticSensitive,
+ }
+ if textArgs.Substring != nil {
+ substringOpts := mcopts.SubstringOptions(*textArgs.Substring)
+ transformedText.Substring = &substringOpts
+ }
+ if textArgs.Prefix != nil {
+ prefixOpts := mcopts.PrefixOptions(*textArgs.Prefix)
+ transformedText.Prefix = &prefixOpts
+ }
+ if textArgs.Suffix != nil {
+ suffixOpts := mcopts.SuffixOptions(*textArgs.Suffix)
+ transformedText.Suffix = &suffixOpts
+ }
+ transformed.SetTextOptions(transformedText)
+ }
+ return transformed, nil
}
// Encrypt encrypts a BSON value with the given key and algorithm. Returns an encrypted value (BSON binary of subtype 6).
-func (ce *ClientEncryption) Encrypt(ctx context.Context, val bson.RawValue,
- opts ...*options.EncryptOptions) (primitive.Binary, error) {
+func (ce *ClientEncryption) Encrypt(
+ ctx context.Context,
+ val bson.RawValue,
+ opts ...options.Lister[options.EncryptOptions],
+) (bson.Binary, error) {
+ if ce.closed {
+ return bson.Binary{}, ErrClientDisconnected
+ }
- transformed := transformExplicitEncryptionOptions(opts...)
- subtype, data, err := ce.crypt.EncryptExplicit(ctx, bsoncore.Value{Type: val.Type, Data: val.Value}, transformed)
+ transformed, err := transformExplicitEncryptionOptions(opts...)
if err != nil {
- return primitive.Binary{}, err
+ return bson.Binary{}, err
}
- return primitive.Binary{Subtype: subtype, Data: data}, nil
+ subtype, data, err := ce.crypt.EncryptExplicit(ctx, bsoncore.Value{Type: bsoncore.Type(val.Type), Data: val.Value}, transformed)
+ if err != nil {
+ return bson.Binary{}, err
+ }
+ return bson.Binary{Subtype: subtype, Data: data}, nil
}
// EncryptExpression encrypts an expression to query a range index.
@@ -236,8 +302,15 @@ func (ce *ClientEncryption) Encrypt(ctx context.Context, val bson.RawValue,
// {$and: [{$gt: [, ]}, {$lt: [, ]}]
// $gt may also be $gte. $lt may also be $lte.
// Only supported for queryType "range"
-func (ce *ClientEncryption) EncryptExpression(ctx context.Context, expr interface{}, result interface{}, opts ...*options.EncryptOptions) error {
- transformed := transformExplicitEncryptionOptions(opts...)
+func (ce *ClientEncryption) EncryptExpression(ctx context.Context, expr any, result any, opts ...options.Lister[options.EncryptOptions]) error {
+ if ce.closed {
+ return ErrClientDisconnected
+ }
+
+ transformed, err := transformExplicitEncryptionOptions(opts...)
+ if err != nil {
+ return err
+ }
exprDoc, err := marshal(expr, nil, nil)
if err != nil {
@@ -261,38 +334,62 @@ func (ce *ClientEncryption) EncryptExpression(ctx context.Context, expr interfac
}
// Decrypt decrypts an encrypted value (BSON binary of subtype 6) and returns the original BSON value.
-func (ce *ClientEncryption) Decrypt(ctx context.Context, val primitive.Binary) (bson.RawValue, error) {
+func (ce *ClientEncryption) Decrypt(ctx context.Context, val bson.Binary) (bson.RawValue, error) {
+ if ce.closed {
+ return bson.RawValue{}, ErrClientDisconnected
+ }
+
decrypted, err := ce.crypt.DecryptExplicit(ctx, val.Subtype, val.Data)
if err != nil {
return bson.RawValue{}, err
}
- return bson.RawValue{Type: decrypted.Type, Value: decrypted.Data}, nil
+ return bson.RawValue{Type: bson.Type(decrypted.Type), Value: decrypted.Data}, nil
}
// Close cleans up any resources associated with the ClientEncryption instance. This includes disconnecting the
// key-vault Client instance.
func (ce *ClientEncryption) Close(ctx context.Context) error {
+ if ce.closed {
+ return ErrClientDisconnected
+ }
+
ce.crypt.Close()
- return ce.keyVaultClient.Disconnect(ctx)
+ err := ce.keyVaultClient.Disconnect(ctx)
+ if err == nil {
+ ce.closed = true
+ }
+ return err
}
// DeleteKey removes the key document with the given UUID (BSON binary subtype 0x04) from the key vault collection.
// Returns the result of the internal deleteOne() operation on the key vault collection.
-func (ce *ClientEncryption) DeleteKey(ctx context.Context, id primitive.Binary) (*DeleteResult, error) {
+func (ce *ClientEncryption) DeleteKey(ctx context.Context, id bson.Binary) (*DeleteResult, error) {
+ if ce.closed {
+ return nil, ErrClientDisconnected
+ }
+
filter := bsoncore.NewDocumentBuilder().AppendBinary("_id", id.Subtype, id.Data).Build()
return ce.keyVaultColl.DeleteOne(ctx, filter)
}
// GetKeyByAltName returns a key document in the key vault collection with the given keyAltName.
func (ce *ClientEncryption) GetKeyByAltName(ctx context.Context, keyAltName string) *SingleResult {
+ if ce.closed {
+ return &SingleResult{err: ErrClientDisconnected}
+ }
+
filter := bsoncore.NewDocumentBuilder().AppendString("keyAltNames", keyAltName).Build()
return ce.keyVaultColl.FindOne(ctx, filter)
}
// GetKey finds a single key document with the given UUID (BSON binary subtype 0x04). Returns the result of the
// internal find() operation on the key vault collection.
-func (ce *ClientEncryption) GetKey(ctx context.Context, id primitive.Binary) *SingleResult {
+func (ce *ClientEncryption) GetKey(ctx context.Context, id bson.Binary) *SingleResult {
+ if ce.closed {
+ return &SingleResult{err: ErrClientDisconnected}
+ }
+
filter := bsoncore.NewDocumentBuilder().AppendBinary("_id", id.Subtype, id.Data).Build()
return ce.keyVaultColl.FindOne(ctx, filter)
}
@@ -300,16 +397,28 @@ func (ce *ClientEncryption) GetKey(ctx context.Context, id primitive.Binary) *Si
// GetKeys finds all documents in the key vault collection. Returns the result of the internal find() operation on the
// key vault collection.
func (ce *ClientEncryption) GetKeys(ctx context.Context) (*Cursor, error) {
+ if ce.closed {
+ return nil, ErrClientDisconnected
+ }
+
return ce.keyVaultColl.Find(ctx, bson.D{})
}
// RemoveKeyAltName removes a keyAltName from the keyAltNames array of the key document in the key vault collection with
// the given UUID (BSON binary subtype 0x04). Returns the previous version of the key document.
-func (ce *ClientEncryption) RemoveKeyAltName(ctx context.Context, id primitive.Binary, keyAltName string) *SingleResult {
+func (ce *ClientEncryption) RemoveKeyAltName(ctx context.Context, id bson.Binary, keyAltName string) *SingleResult {
+ if ce.closed {
+ return &SingleResult{err: ErrClientDisconnected}
+ }
+
filter := bsoncore.NewDocumentBuilder().AppendBinary("_id", id.Subtype, id.Data).Build()
- update := bson.A{bson.D{{"$set", bson.D{{"keyAltNames", bson.D{{"$cond", bson.A{bson.D{{"$eq",
- bson.A{"$keyAltNames", bson.A{keyAltName}}}}, "$$REMOVE", bson.D{{"$filter",
- bson.D{{"input", "$keyAltNames"}, {"cond", bson.D{{"$ne", bson.A{"$$this", keyAltName}}}}}}}}}}}}}}}
+ update := bson.A{bson.D{{"$set", bson.D{{"keyAltNames", bson.D{{"$cond", bson.A{bson.D{{
+ "$eq",
+ bson.A{"$keyAltNames", bson.A{keyAltName}},
+ }}, "$$REMOVE", bson.D{{
+ "$filter",
+ bson.D{{"input", "$keyAltNames"}, {"cond", bson.D{{"$ne", bson.A{"$$this", keyAltName}}}}},
+ }}}}}}}}}}
return ce.keyVaultColl.FindOneAndUpdate(ctx, filter, update)
}
@@ -338,7 +447,7 @@ func setRewrapManyDataKeyWriteModels(rewrappedDocuments []bsoncore.Document, wri
return err
}
keyMaterialSubtype, keyMaterialData := keyMaterialValue.Binary()
- keyMaterialBinary := primitive.Binary{Subtype: keyMaterialSubtype, Data: keyMaterialData}
+ keyMaterialBinary := bson.Binary{Subtype: keyMaterialSubtype, Data: keyMaterialData}
// Prepare the _id filter for documents to update.
id, err := rewrappedDocument.LookupErr(idKey)
@@ -350,7 +459,7 @@ func setRewrapManyDataKeyWriteModels(rewrappedDocuments []bsoncore.Document, wri
if !ok {
return fmt.Errorf("expected to assert %q as binary, got type %T", idKey, id)
}
- binaryID := primitive.Binary{Subtype: idSubtype, Data: idData}
+ binaryID := bson.Binary{Subtype: idSubtype, Data: idData}
// Append the mutable document to the slice for bulk update.
*writeModels = append(*writeModels, NewUpdateOneModel().
@@ -369,35 +478,44 @@ func setRewrapManyDataKeyWriteModels(rewrappedDocuments []bsoncore.Document, wri
// matching documents, this method will overwrite the "masterKey", "updateDate", and "keyMaterial". On error, some
// matching data keys may have been rewrapped.
// libmongocrypt 1.5.2 is required. An error is returned if the detected version of libmongocrypt is less than 1.5.2.
-func (ce *ClientEncryption) RewrapManyDataKey(ctx context.Context, filter interface{},
- opts ...*options.RewrapManyDataKeyOptions) (*RewrapManyDataKeyResult, error) {
-
+func (ce *ClientEncryption) RewrapManyDataKey(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.RewrapManyDataKeyOptions],
+) (*RewrapManyDataKeyResult, error) {
// libmongocrypt versions 1.5.0 and 1.5.1 have a severe bug in RewrapManyDataKey.
// Check if the version string starts with 1.5.0 or 1.5.1. This accounts for pre-release versions, like 1.5.0-rc0.
+ if ce.closed {
+ return nil, ErrClientDisconnected
+ }
+
libmongocryptVersion := mongocrypt.Version()
if strings.HasPrefix(libmongocryptVersion, "1.5.0") || strings.HasPrefix(libmongocryptVersion, "1.5.1") {
return nil, fmt.Errorf("RewrapManyDataKey requires libmongocrypt 1.5.2 or newer. Detected version: %v", libmongocryptVersion)
}
- rmdko := options.MergeRewrapManyDataKeyOptions(opts...)
if ctx == nil {
ctx = context.Background()
}
+ args, err := mongoutil.NewOptions[options.RewrapManyDataKeyOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
// Transfer rmdko options to /x/ package options to publish the mongocrypt feed.
- co := mcopts.RewrapManyDataKey()
- if rmdko.MasterKey != nil {
+ co := &mcopts.RewrapManyDataKeyOptions{
+ Provider: args.Provider,
+ }
+ if args.MasterKey != nil {
keyDoc, err := marshal(
- rmdko.MasterKey,
+ args.MasterKey,
ce.keyVaultClient.bsonOpts,
ce.keyVaultClient.registry)
if err != nil {
return nil, err
}
- co.SetMasterKey(keyDoc)
- }
- if rmdko.Provider != nil {
- co.SetProvider(*rmdko.Provider)
+ co.MasterKey = keyDoc
}
// Prepare the filters and rewrap the data key using mongocrypt.
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/collection.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/collection.go
similarity index 59%
rename from vendor/go.mongodb.org/mongo-driver/mongo/collection.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/collection.go
index 95889c80a..bd9a5a5ca 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/collection.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/collection.go
@@ -14,20 +14,21 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/csfle"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/csfle"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/internal/ptrutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Collection is a handle to a MongoDB collection. It is safe for concurrent use by multiple goroutines.
@@ -41,25 +42,23 @@ type Collection struct {
readSelector description.ServerSelector
writeSelector description.ServerSelector
bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
+ registry *bson.Registry
}
// aggregateParams is used to store information to configure an Aggregate operation.
type aggregateParams struct {
ctx context.Context
- pipeline interface{}
+ pipeline any
client *Client
bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
+ registry *bson.Registry
readConcern *readconcern.ReadConcern
writeConcern *writeconcern.WriteConcern
- retryRead bool
db string
col string
readSelector description.ServerSelector
writeSelector description.ServerSelector
readPreference *readpref.ReadPref
- opts []*options.AggregateOptions
}
func closeImplicitSession(sess *session.Client) {
@@ -68,43 +67,47 @@ func closeImplicitSession(sess *session.Client) {
}
}
-func newCollection(db *Database, name string, opts ...*options.CollectionOptions) *Collection {
- collOpt := options.MergeCollectionOptions(opts...)
+func newCollection(db *Database, name string, opts ...options.Lister[options.CollectionOptions]) *Collection {
+ args, _ := mongoutil.NewOptions[options.CollectionOptions](opts...)
rc := db.readConcern
- if collOpt.ReadConcern != nil {
- rc = collOpt.ReadConcern
+ if args.ReadConcern != nil {
+ rc = args.ReadConcern
}
wc := db.writeConcern
- if collOpt.WriteConcern != nil {
- wc = collOpt.WriteConcern
+ if args.WriteConcern != nil {
+ wc = args.WriteConcern
}
rp := db.readPreference
- if collOpt.ReadPreference != nil {
- rp = collOpt.ReadPreference
+ if args.ReadPreference != nil {
+ rp = args.ReadPreference
}
bsonOpts := db.bsonOpts
- if collOpt.BSONOptions != nil {
- bsonOpts = collOpt.BSONOptions
+ if args.BSONOptions != nil {
+ bsonOpts = args.BSONOptions
}
reg := db.registry
- if collOpt.Registry != nil {
- reg = collOpt.Registry
+ if args.Registry != nil {
+ reg = args.Registry
}
- readSelector := description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(rp),
- description.LatencySelector(db.client.localThreshold),
- })
+ readSelector := &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: rp},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
- writeSelector := description.CompositeSelector([]description.ServerSelector{
- description.WriteSelector(),
- description.LatencySelector(db.client.localThreshold),
- })
+ writeSelector := &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.Write{},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
coll := &Collection{
client: db.client,
@@ -139,32 +142,35 @@ func (coll *Collection) copy() *Collection {
// Clone creates a copy of the Collection configured with the given CollectionOptions.
// The specified options are merged with the existing options on the collection, with the specified options taking
// precedence.
-func (coll *Collection) Clone(opts ...*options.CollectionOptions) (*Collection, error) {
+func (coll *Collection) Clone(opts ...options.Lister[options.CollectionOptions]) *Collection {
copyColl := coll.copy()
- optsColl := options.MergeCollectionOptions(opts...)
- if optsColl.ReadConcern != nil {
- copyColl.readConcern = optsColl.ReadConcern
+ args, _ := mongoutil.NewOptions[options.CollectionOptions](opts...)
+
+ if args.ReadConcern != nil {
+ copyColl.readConcern = args.ReadConcern
}
- if optsColl.WriteConcern != nil {
- copyColl.writeConcern = optsColl.WriteConcern
+ if args.WriteConcern != nil {
+ copyColl.writeConcern = args.WriteConcern
}
- if optsColl.ReadPreference != nil {
- copyColl.readPreference = optsColl.ReadPreference
+ if args.ReadPreference != nil {
+ copyColl.readPreference = args.ReadPreference
}
- if optsColl.Registry != nil {
- copyColl.registry = optsColl.Registry
+ if args.Registry != nil {
+ copyColl.registry = args.Registry
}
- copyColl.readSelector = description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(copyColl.readPreference),
- description.LatencySelector(copyColl.client.localThreshold),
- })
+ copyColl.readSelector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: copyColl.readPreference},
+ &serverselector.Latency{Latency: copyColl.client.localThreshold},
+ },
+ }
- return copyColl, nil
+ return copyColl
}
// Name returns the name of the collection.
@@ -185,10 +191,10 @@ func (coll *Collection) Database() *Database {
//
// The opts parameter can be used to specify options for the operation (see the options.BulkWriteOptions documentation.)
func (coll *Collection) BulkWrite(ctx context.Context, models []WriteModel,
- opts ...*options.BulkWriteOptions) (*BulkWriteResult, error) {
-
+ opts ...options.Lister[options.BulkWriteOptions],
+) (*BulkWriteResult, error) {
if len(models) == 0 {
- return nil, ErrEmptySlice
+ return nil, fmt.Errorf("invalid models: %w", ErrEmptySlice)
}
if ctx == nil {
@@ -210,46 +216,58 @@ func (coll *Collection) BulkWrite(ctx context.Context, models []WriteModel,
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
selector := makePinnedSelector(sess, coll.writeSelector)
- for _, model := range models {
+ for i, model := range models {
if model == nil {
- return nil, ErrNilDocument
+ return nil, fmt.Errorf("invalid model at index %d: %w", i, ErrNilDocument)
}
}
- bwo := options.MergeBulkWriteOptions(opts...)
+ // Ensure opts have the default case at the front.
+ opts = append([]options.Lister[options.BulkWriteOptions]{options.BulkWrite()}, opts...)
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
op := bulkWrite{
- comment: bwo.Comment,
- ordered: bwo.Ordered,
- bypassDocumentValidation: bwo.BypassDocumentValidation,
+ comment: args.Comment,
+ ordered: args.Ordered,
+ bypassDocumentValidation: args.BypassDocumentValidation,
models: models,
session: sess,
collection: coll,
selector: selector,
writeConcern: wc,
- let: bwo.Let,
- bypassEmptyTsReplacement: bwo.BypassEmptyTsReplacement,
+ let: args.Let,
+ }
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op.rawData = &rawData
+ }
+ if additionalCmd, ok := optionsutil.Value(args.Internal, "addCommandFields").(bson.D); ok {
+ op.additionalCmd = additionalCmd
}
err = op.execute(ctx)
- return &op.result, replaceErrors(err)
+ return &op.result, wrapErrors(err)
}
-func (coll *Collection) insert(ctx context.Context, documents []interface{},
- opts ...*options.InsertManyOptions) ([]interface{}, error) {
-
+func (coll *Collection) insert(
+ ctx context.Context,
+ documents []any,
+ opts ...options.Lister[options.InsertManyOptions],
+) ([]any, error) {
if ctx == nil {
ctx = context.Background()
}
- result := make([]interface{}, len(documents))
+ result := make([]any, len(documents))
docs := make([]bsoncore.Document, len(documents))
for i, doc := range documents {
@@ -257,7 +275,7 @@ func (coll *Collection) insert(ctx context.Context, documents []interface{},
if err != nil {
return nil, err
}
- bsoncoreDoc, id, err := ensureID(bsoncoreDoc, primitive.NilObjectID, coll.bsonOpts, coll.registry)
+ bsoncoreDoc, id, err := ensureID(bsoncoreDoc, bson.NilObjectID, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
@@ -281,41 +299,63 @@ func (coll *Collection) insert(ctx context.Context, documents []interface{},
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryWrites)
+
selector := makePinnedSelector(sess, coll.writeSelector)
- op := operation.NewInsert(docs...).
- Session(sess).WriteConcern(wc).CommandMonitor(coll.client.monitor).
- ServerSelector(selector).ClusterClock(coll.client.clock).
- Database(coll.db.name).Collection(coll.name).
- Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).Ordered(true).
- ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Logger(coll.client.logger).
- Authenticator(coll.client.authenticator)
- imo := options.MergeInsertManyOptions(opts...)
- if imo.BypassDocumentValidation != nil && *imo.BypassDocumentValidation {
- op = op.BypassDocumentValidation(*imo.BypassDocumentValidation)
+ op := insert{
+ documents: docs,
+ session: sess,
+ writeConcern: wc,
+ monitor: coll.client.monitor,
+ maxAdaptiveRetries: maxAdaptiveRetries,
+ enableOverloadRetargeting: coll.client.enableOverloadRetargeting,
+ selector: selector,
+ clock: coll.client.clock,
+ database: coll.db.name,
+ collection: coll.name,
+ deployment: coll.client.deployment,
+ crypt: coll.client.cryptFLE,
+ ordered: ptrutil.Ptr(true),
+ serverAPI: coll.client.serverAPI,
+ timeout: coll.client.timeout,
+ logger: coll.client.logger,
+ authenticator: coll.client.authenticator,
+ }
+
+ args, err := mongoutil.NewOptions[options.InsertManyOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ op.bypassDocumentValidation = args.BypassDocumentValidation
}
- if imo.Comment != nil {
- comment, err := marshalValue(imo.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
- op = op.Comment(comment)
+ op.comment = comment
+ }
+ if args.Ordered != nil {
+ op.ordered = args.Ordered
}
- if imo.Ordered != nil {
- op = op.Ordered(*imo.Ordered)
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op.rawData = &rawData
}
- if imo.BypassEmptyTsReplacement != nil {
- op = op.BypassEmptyTsReplacement(*imo.BypassEmptyTsReplacement)
+ if additionalCmd, ok := optionsutil.Value(args.Internal, "addCommandFields").(bson.D); ok {
+ op.additionalCmd = additionalCmd
}
retry := driver.RetryNone
if coll.client.retryWrites {
retry = driver.RetryOncePerCommand
}
- op = op.Retry(retry)
+ op.retry = &retry
err = op.Execute(ctx)
var wce driver.WriteCommandError
@@ -328,7 +368,7 @@ func (coll *Collection) insert(ctx context.Context, documents []interface{},
// i indexes have been removed before the current error, so the index is we.Index-i
idIndex := int(we.Index) - i
// if the insert is ordered, nothing after the error was inserted
- if imo.Ordered == nil || *imo.Ordered {
+ if args.Ordered == nil || *args.Ordered {
result = result[:idIndex]
break
}
@@ -347,28 +387,46 @@ func (coll *Collection) insert(ctx context.Context, documents []interface{},
// The opts parameter can be used to specify options for the operation (see the options.InsertOneOptions documentation.)
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/insert/.
-func (coll *Collection) InsertOne(ctx context.Context, document interface{},
- opts ...*options.InsertOneOptions) (*InsertOneResult, error) {
-
- ioOpts := options.MergeInsertOneOptions(opts...)
+func (coll *Collection) InsertOne(ctx context.Context, document any,
+ opts ...options.Lister[options.InsertOneOptions],
+) (*InsertOneResult, error) {
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
imOpts := options.InsertMany()
- if ioOpts.BypassDocumentValidation != nil && *ioOpts.BypassDocumentValidation {
- imOpts.SetBypassDocumentValidation(*ioOpts.BypassDocumentValidation)
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ imOpts.SetBypassDocumentValidation(*args.BypassDocumentValidation)
}
- if ioOpts.Comment != nil {
- imOpts.SetComment(ioOpts.Comment)
+ if args.Comment != nil {
+ imOpts.SetComment(args.Comment)
+ }
+ if rawDataOpt := optionsutil.Value(args.Internal, "rawData"); rawDataOpt != nil {
+ imOpts.Opts = append(imOpts.Opts, func(opts *options.InsertManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, "rawData", rawDataOpt)
+
+ return nil
+ })
}
- if ioOpts.BypassEmptyTsReplacement != nil {
- imOpts.BypassEmptyTsReplacement = ioOpts.BypassEmptyTsReplacement
+ if additionalCmd := optionsutil.Value(args.Internal, "addCommandFields"); additionalCmd != nil {
+ imOpts.Opts = append(imOpts.Opts, func(opts *options.InsertManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, "addCommandFields", additionalCmd)
+
+ return nil
+ })
}
- res, err := coll.insert(ctx, []interface{}{document}, imOpts)
+ res, err := coll.insert(ctx, []any{document}, imOpts)
rr, err := processWriteError(err)
- if rr&rrOne == 0 {
+ if rr&rrOne == 0 && rr.isAcknowledged() {
return nil, err
}
- return &InsertOneResult{InsertedID: res[0]}, err
+
+ return &InsertOneResult{
+ InsertedID: res[0],
+ Acknowledged: rr.isAcknowledged(),
+ }, err
}
// InsertMany executes an insert command to insert multiple documents into the collection. If write errors occur
@@ -382,20 +440,34 @@ func (coll *Collection) InsertOne(ctx context.Context, document interface{},
// The opts parameter can be used to specify options for the operation (see the options.InsertManyOptions documentation.)
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/insert/.
-func (coll *Collection) InsertMany(ctx context.Context, documents []interface{},
- opts ...*options.InsertManyOptions) (*InsertManyResult, error) {
+func (coll *Collection) InsertMany(
+ ctx context.Context,
+ documents any,
+ opts ...options.Lister[options.InsertManyOptions],
+) (*InsertManyResult, error) {
+ dv := reflect.ValueOf(documents)
+ if dv.Kind() != reflect.Slice {
+ return nil, fmt.Errorf("invalid documents: %w", ErrNotSlice)
+ }
+ if dv.Len() == 0 {
+ return nil, fmt.Errorf("invalid documents: %w", ErrEmptySlice)
+ }
- if len(documents) == 0 {
- return nil, ErrEmptySlice
+ docSlice := make([]any, 0, dv.Len())
+ for i := 0; i < dv.Len(); i++ {
+ docSlice = append(docSlice, dv.Index(i).Interface())
}
- result, err := coll.insert(ctx, documents, opts...)
+ result, err := coll.insert(ctx, docSlice, opts...)
rr, err := processWriteError(err)
if rr&rrMany == 0 {
return nil, err
}
- imResult := &InsertManyResult{InsertedIDs: result}
+ imResult := &InsertManyResult{
+ InsertedIDs: result,
+ Acknowledged: rr.isAcknowledged(),
+ }
var writeException WriteException
if !errors.As(err, &writeException) {
return imResult, err
@@ -417,9 +489,13 @@ func (coll *Collection) InsertMany(ctx context.Context, documents []interface{},
}
}
-func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOne bool, expectedRr returnResult,
- opts ...*options.DeleteOptions) (*DeleteResult, error) {
-
+func (coll *Collection) delete(
+ ctx context.Context,
+ filter any,
+ deleteOne bool,
+ expectedRr returnResult,
+ args *options.DeleteManyOptions,
+) (*DeleteResult, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -444,28 +520,36 @@ func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOn
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
+ // deleteMany cannot be retried
+ retryMode := driver.RetryNone
+ if deleteOne && coll.client.retryWrites {
+ retryMode = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryWrites)
+
selector := makePinnedSelector(sess, coll.writeSelector)
var limit int32
if deleteOne {
limit = 1
}
- do := options.MergeDeleteOptions(opts...)
+
didx, doc := bsoncore.AppendDocumentStart(nil)
doc = bsoncore.AppendDocumentElement(doc, "q", f)
doc = bsoncore.AppendInt32Element(doc, "limit", limit)
- if do.Collation != nil {
- doc = bsoncore.AppendDocumentElement(doc, "collation", do.Collation.ToDocument())
+ if args.Collation != nil {
+ doc = bsoncore.AppendDocumentElement(doc, "collation", toDocument(args.Collation))
}
- if do.Hint != nil {
- if isUnorderedMap(do.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return nil, ErrMapForOrderedArgument{"hint"}
}
- hint, err := marshalValue(do.Hint, coll.bsonOpts, coll.registry)
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
@@ -476,40 +560,41 @@ func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOn
op := operation.NewDelete(doc).
Session(sess).WriteConcern(wc).CommandMonitor(coll.client.monitor).
+ Retry(retryMode).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
ServerSelector(selector).ClusterClock(coll.client.clock).
Database(coll.db.name).Collection(coll.name).
Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).Ordered(true).
- ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Logger(coll.client.logger).
- Authenticator(coll.client.authenticator)
- if do.Comment != nil {
- comment, err := marshalValue(do.Comment, coll.bsonOpts, coll.registry)
+ ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Logger(coll.client.logger).Authenticator(coll.client.authenticator)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op = op.Comment(comment)
}
- if do.Hint != nil {
+ if args.Hint != nil {
op = op.Hint(true)
}
- if do.Let != nil {
- let, err := marshal(do.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op = op.Let(let)
}
-
- // deleteMany cannot be retried
- retryMode := driver.RetryNone
- if deleteOne && coll.client.retryWrites {
- retryMode = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retryMode)
+
rr, err := processWriteError(op.Execute(ctx))
if rr&expectedRr == 0 {
return nil, err
}
- return &DeleteResult{DeletedCount: op.Result().N}, err
+ return &DeleteResult{
+ DeletedCount: op.Result().N,
+ Acknowledged: rr.isAcknowledged(),
+ }, err
}
// DeleteOne executes a delete command to delete at most one document from the collection.
@@ -522,10 +607,24 @@ func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOn
// The opts parameter can be used to specify options for the operation (see the options.DeleteOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/delete/.
-func (coll *Collection) DeleteOne(ctx context.Context, filter interface{},
- opts ...*options.DeleteOptions) (*DeleteResult, error) {
+func (coll *Collection) DeleteOne(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.DeleteOneOptions],
+) (*DeleteResult, error) {
+ args, err := mongoutil.NewOptions[options.DeleteOneOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+ deleteOptions := &options.DeleteManyOptions{
+ Collation: args.Collation,
+ Comment: args.Comment,
+ Hint: args.Hint,
+ Let: args.Let,
+ Internal: args.Internal,
+ }
- return coll.delete(ctx, filter, true, rrOne, opts...)
+ return coll.delete(ctx, filter, true, rrOne, deleteOptions)
}
// DeleteMany executes a delete command to delete documents from the collection.
@@ -538,34 +637,46 @@ func (coll *Collection) DeleteOne(ctx context.Context, filter interface{},
// The opts parameter can be used to specify options for the operation (see the options.DeleteOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/delete/.
-func (coll *Collection) DeleteMany(ctx context.Context, filter interface{},
- opts ...*options.DeleteOptions) (*DeleteResult, error) {
+func (coll *Collection) DeleteMany(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.DeleteManyOptions],
+) (*DeleteResult, error) {
+ args, err := mongoutil.NewOptions[options.DeleteManyOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
- return coll.delete(ctx, filter, false, rrMany, opts...)
+ return coll.delete(ctx, filter, false, rrMany, args)
}
-func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Document, update interface{}, multi bool,
- expectedRr returnResult, checkDollarKey bool, opts ...*options.UpdateOptions) (*UpdateResult, error) {
-
+func (coll *Collection) updateOrReplace(
+ ctx context.Context,
+ filter bsoncore.Document,
+ update any,
+ multi bool,
+ expectedRr returnResult,
+ checkDollarKey bool,
+ sort any,
+ args *options.UpdateManyOptions,
+) (*UpdateResult, error) {
if ctx == nil {
ctx = context.Background()
}
- uo := options.MergeUpdateOptions(opts...)
-
// collation, arrayFilters, upsert, and hint are included on the individual update documents rather than as part of the
// command
- updateDoc, err := createUpdateDoc(
- filter,
- update,
- uo.Hint,
- uo.ArrayFilters,
- uo.Collation,
- uo.Upsert,
- multi,
- checkDollarKey,
- coll.bsonOpts,
- coll.registry)
+ updateDoc, err := updateDoc{
+ filter: filter,
+ update: update,
+ hint: args.Hint,
+ sort: sort,
+ arrayFilters: args.ArrayFilters,
+ collation: args.Collation,
+ upsert: args.Upsert,
+ multi: multi,
+ checkDollarKey: checkDollarKey,
+ }.marshal(coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
@@ -585,46 +696,53 @@ func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Doc
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
+ retry := driver.RetryNone
+ // retryable writes are only enabled updateOne/replaceOne operations
+ if !multi && coll.client.retryWrites {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryWrites)
+
selector := makePinnedSelector(sess, coll.writeSelector)
op := operation.NewUpdate(updateDoc).
Session(sess).WriteConcern(wc).CommandMonitor(coll.client.monitor).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
ServerSelector(selector).ClusterClock(coll.client.clock).
Database(coll.db.name).Collection(coll.name).
- Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).Hint(uo.Hint != nil).
- ArrayFilters(uo.ArrayFilters != nil).Ordered(true).ServerAPI(coll.client.serverAPI).
+ Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).Hint(args.Hint != nil).
+ ArrayFilters(args.ArrayFilters != nil).Ordered(true).ServerAPI(coll.client.serverAPI).
Timeout(coll.client.timeout).Logger(coll.client.logger).Authenticator(coll.client.authenticator)
- if uo.Let != nil {
- let, err := marshal(uo.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op = op.Let(let)
}
- if uo.BypassDocumentValidation != nil && *uo.BypassDocumentValidation {
- op = op.BypassDocumentValidation(*uo.BypassDocumentValidation)
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ op = op.BypassDocumentValidation(*args.BypassDocumentValidation)
}
- if uo.Comment != nil {
- comment, err := marshalValue(uo.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op = op.Comment(comment)
}
- if uo.BypassEmptyTsReplacement != nil {
- op.BypassEmptyTsReplacement(*uo.BypassEmptyTsReplacement)
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- retry := driver.RetryNone
- // retryable writes are only enabled updateOne/replaceOne operations
- if !multi && coll.client.retryWrites {
- retry = driver.RetryOncePerCommand
+ if additionalCmd, ok := optionsutil.Value(args.Internal, "addCommandFields").(bson.D); ok {
+ op = op.AdditionalCmd(additionalCmd)
}
- op = op.Retry(retry)
err = op.Execute(ctx)
rr, err := processWriteError(err)
@@ -637,6 +755,7 @@ func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Doc
MatchedCount: opRes.N,
ModifiedCount: opRes.NModified,
UpsertedCount: int64(len(opRes.Upserted)),
+ Acknowledged: rr.isAcknowledged(),
}
if len(opRes.Upserted) > 0 {
res.UpsertedID = opRes.Upserted[0].ID
@@ -659,10 +778,14 @@ func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Doc
// The opts parameter can be used to specify options for the operation (see the options.UpdateOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/update/.
-func (coll *Collection) UpdateByID(ctx context.Context, id interface{}, update interface{},
- opts ...*options.UpdateOptions) (*UpdateResult, error) {
+func (coll *Collection) UpdateByID(
+ ctx context.Context,
+ id any,
+ update any,
+ opts ...options.Lister[options.UpdateOneOptions],
+) (*UpdateResult, error) {
if id == nil {
- return nil, ErrNilValue
+ return nil, fmt.Errorf("invalid id: %w", ErrNilValue)
}
return coll.UpdateOne(ctx, bson.D{{"_id", id}}, update, opts...)
}
@@ -681,9 +804,12 @@ func (coll *Collection) UpdateByID(ctx context.Context, id interface{}, update i
// The opts parameter can be used to specify options for the operation (see the options.UpdateOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/update/.
-func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{},
- opts ...*options.UpdateOptions) (*UpdateResult, error) {
-
+func (coll *Collection) UpdateOne(
+ ctx context.Context,
+ filter any,
+ update any,
+ opts ...options.Lister[options.UpdateOneOptions],
+) (*UpdateResult, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -693,7 +819,22 @@ func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, updat
return nil, err
}
- return coll.updateOrReplace(ctx, f, update, false, rrOne, true, opts...)
+ args, err := mongoutil.NewOptions[options.UpdateOneOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+ updateOptions := &options.UpdateManyOptions{
+ ArrayFilters: args.ArrayFilters,
+ BypassDocumentValidation: args.BypassDocumentValidation,
+ Collation: args.Collation,
+ Comment: args.Comment,
+ Hint: args.Hint,
+ Upsert: args.Upsert,
+ Let: args.Let,
+ Internal: args.Internal,
+ }
+
+ return coll.updateOrReplace(ctx, f, update, false, rrOne, true, args.Sort, updateOptions)
}
// UpdateMany executes an update command to update documents in the collection.
@@ -709,9 +850,12 @@ func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, updat
// The opts parameter can be used to specify options for the operation (see the options.UpdateOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/update/.
-func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, update interface{},
- opts ...*options.UpdateOptions) (*UpdateResult, error) {
-
+func (coll *Collection) UpdateMany(
+ ctx context.Context,
+ filter any,
+ update any,
+ opts ...options.Lister[options.UpdateManyOptions],
+) (*UpdateResult, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -721,7 +865,12 @@ func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, upda
return nil, err
}
- return coll.updateOrReplace(ctx, f, update, true, rrMany, true, opts...)
+ args, err := mongoutil.NewOptions[options.UpdateManyOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ return coll.updateOrReplace(ctx, f, update, true, rrMany, true, nil, args)
}
// ReplaceOne executes an update command to replace at most one document in the collection.
@@ -737,13 +886,21 @@ func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, upda
// The opts parameter can be used to specify options for the operation (see the options.ReplaceOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/update/.
-func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{},
- replacement interface{}, opts ...*options.ReplaceOptions) (*UpdateResult, error) {
-
+func (coll *Collection) ReplaceOne(
+ ctx context.Context,
+ filter any,
+ replacement any,
+ opts ...options.Lister[options.ReplaceOptions],
+) (*UpdateResult, error) {
if ctx == nil {
ctx = context.Background()
}
+ args, err := mongoutil.NewOptions[options.ReplaceOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
f, err := marshal(filter, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
@@ -758,23 +915,17 @@ func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{},
return nil, err
}
- updateOptions := make([]*options.UpdateOptions, 0, len(opts))
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- uOpts := options.Update()
- uOpts.BypassDocumentValidation = opt.BypassDocumentValidation
- uOpts.Collation = opt.Collation
- uOpts.Upsert = opt.Upsert
- uOpts.Hint = opt.Hint
- uOpts.Let = opt.Let
- uOpts.Comment = opt.Comment
- uOpts.BypassEmptyTsReplacement = opt.BypassEmptyTsReplacement
- updateOptions = append(updateOptions, uOpts)
- }
-
- return coll.updateOrReplace(ctx, f, r, false, rrOne, false, updateOptions...)
+ updateOptions := &options.UpdateManyOptions{
+ BypassDocumentValidation: args.BypassDocumentValidation,
+ Collation: args.Collation,
+ Upsert: args.Upsert,
+ Hint: args.Hint,
+ Let: args.Let,
+ Comment: args.Comment,
+ Internal: args.Internal,
+ }
+
+ return coll.updateOrReplace(ctx, f, r, false, rrOne, false, args.Sort, updateOptions)
}
// Aggregate executes an aggregate command against the collection and returns a cursor over the resulting documents.
@@ -788,8 +939,11 @@ func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{},
// The opts parameter can be used to specify options for the operation (see the options.AggregateOptions documentation.)
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/aggregate/.
-func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{},
- opts ...*options.AggregateOptions) (*Cursor, error) {
+func (coll *Collection) Aggregate(
+ ctx context.Context,
+ pipeline any,
+ opts ...options.Lister[options.AggregateOptions],
+) (*Cursor, error) {
a := aggregateParams{
ctx: ctx,
pipeline: pipeline,
@@ -798,19 +952,18 @@ func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{},
readConcern: coll.readConcern,
writeConcern: coll.writeConcern,
bsonOpts: coll.bsonOpts,
- retryRead: coll.client.retryReads,
db: coll.db.name,
col: coll.name,
readSelector: coll.readSelector,
writeSelector: coll.writeSelector,
readPreference: coll.readPreference,
- opts: opts,
}
- return aggregate(a)
+
+ return aggregate(a, opts...)
}
// aggregate is the helper method for Aggregate
-func aggregate(a aggregateParams) (cur *Cursor, err error) {
+func aggregate(a aggregateParams, opts ...options.Lister[options.AggregateOptions]) (cur *Cursor, err error) {
if a.ctx == nil {
a.ctx = context.Background()
}
@@ -830,6 +983,7 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) {
if sess == nil && a.client.sessionPool != nil {
sess = session.NewImplicitClientSession(a.client.sessionPool, a.client.id)
}
+
if err = a.client.validSession(sess); err != nil {
return nil, err
}
@@ -843,19 +997,30 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) {
wc = nil
rc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
closeImplicitSession(sess)
sess = nil
}
+ retryReads := a.client.retryReads && !hasOutputStage
+ retryWrites := a.client.retryWrites && hasOutputStage
+
+ retry := driver.RetryNone
+ if retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
selector := makeReadPrefSelector(sess, a.readSelector, a.client.localThreshold)
if hasOutputStage {
selector = makeOutputAggregateSelector(sess, a.readPreference, a.client.localThreshold)
}
- ao := options.MergeAggregateOptions(a.opts...)
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
- cursorOpts := a.client.createBaseCursorOptions()
+ cursorOpts := a.client.createBaseCursorOptions(retryReads || retryWrites)
cursorOpts.MarshalValueEncoderFn = newEncoderFn(a.bsonOpts, a.registry)
@@ -865,6 +1030,9 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) {
ReadConcern(rc).
ReadPreference(a.readPreference).
CommandMonitor(a.client.monitor).
+ Retry(retry).
+ MaxAdaptiveRetries(cursorOpts.MaxAdaptiveRetries).
+ EnableOverloadRetargeting(cursorOpts.EnableOverloadRetargeting).
ServerSelector(selector).
ClusterClock(a.client.clock).
Database(a.db).
@@ -874,96 +1042,94 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) {
ServerAPI(a.client.serverAPI).
HasOutputStage(hasOutputStage).
Timeout(a.client.timeout).
- MaxTime(ao.MaxTime).
- Authenticator(a.client.authenticator)
-
- // Omit "maxTimeMS" from operations that return a user-managed cursor to
- // prevent confusing "cursor not found" errors. To maintain existing
- // behavior for users who set "timeoutMS" with no context deadline, only
- // omit "maxTimeMS" when a context deadline is set.
- //
- // See DRIVERS-2722 for more detail.
- _, deadlineSet := a.ctx.Deadline()
- op.OmitCSOTMaxTimeMS(deadlineSet)
+ Authenticator(a.client.authenticator).
+ // Omit "maxTimeMS" from operations that return a user-managed cursor to
+ // prevent confusing "cursor not found" errors.
+ //
+ // See DRIVERS-2722 for more detail.
+ OmitMaxTimeMS(true)
- if ao.AllowDiskUse != nil {
- op.AllowDiskUse(*ao.AllowDiskUse)
+ if args.AllowDiskUse != nil {
+ op.AllowDiskUse(*args.AllowDiskUse)
}
// ignore batchSize of 0 with $out
- if ao.BatchSize != nil && !(*ao.BatchSize == 0 && hasOutputStage) {
- op.BatchSize(*ao.BatchSize)
- cursorOpts.BatchSize = *ao.BatchSize
+ if args.BatchSize != nil && (*args.BatchSize != 0 || !hasOutputStage) {
+ op.BatchSize(*args.BatchSize)
+ cursorOpts.BatchSize = *args.BatchSize
}
- if ao.BypassDocumentValidation != nil && *ao.BypassDocumentValidation {
- op.BypassDocumentValidation(*ao.BypassDocumentValidation)
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ op.BypassDocumentValidation(*args.BypassDocumentValidation)
}
- if ao.Collation != nil {
- op.Collation(bsoncore.Document(ao.Collation.ToDocument()))
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if ao.MaxAwaitTime != nil {
- cursorOpts.MaxTimeMS = int64(*ao.MaxAwaitTime / time.Millisecond)
+ if args.MaxAwaitTime != nil {
+ cursorOpts.SetMaxAwaitTime(*args.MaxAwaitTime)
}
- if ao.Comment != nil {
- op.Comment(*ao.Comment)
-
- commentVal, err := marshalValue(ao.Comment, a.bsonOpts, a.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, a.bsonOpts, a.registry)
if err != nil {
return nil, err
}
- cursorOpts.Comment = commentVal
+
+ op.Comment(comment)
+ cursorOpts.Comment = comment
}
- if ao.Hint != nil {
- if isUnorderedMap(ao.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return nil, ErrMapForOrderedArgument{"hint"}
}
- hintVal, err := marshalValue(ao.Hint, a.bsonOpts, a.registry)
+ hintVal, err := marshalValue(args.Hint, a.bsonOpts, a.registry)
if err != nil {
return nil, err
}
op.Hint(hintVal)
}
- if ao.Let != nil {
- let, err := marshal(ao.Let, a.bsonOpts, a.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, a.bsonOpts, a.registry)
if err != nil {
return nil, err
}
op.Let(let)
}
- if ao.Custom != nil {
+ if args.Custom != nil {
// Marshal all custom options before passing to the aggregate operation. Return
// any errors from Marshaling.
customOptions := make(map[string]bsoncore.Value)
- for optionName, optionValue := range ao.Custom {
- bsonType, bsonData, err := bson.MarshalValueWithRegistry(a.registry, optionValue)
+ for optionName, optionValue := range args.Custom {
+ optionValueBSON, err := marshalValue(optionValue, nil, a.registry)
if err != nil {
return nil, err
}
- optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData}
customOptions[optionName] = optionValueBSON
}
op.CustomOptions(customOptions)
}
-
- retry := driver.RetryNone
- if a.retryRead && !hasOutputStage {
- retry = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retry)
err = op.Execute(a.ctx)
if err != nil {
- if wce, ok := err.(driver.WriteCommandError); ok && wce.WriteConcernError != nil {
+ var wce driver.WriteCommandError
+ if errors.As(err, &wce) && wce.WriteConcernError != nil {
return nil, *convertDriverWriteConcernError(wce.WriteConcernError)
}
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
bc, err := op.Result(cursorOpts)
if err != nil {
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- cursor, err := newCursorWithSession(bc, a.client.bsonOpts, a.registry, sess)
- return cursor, replaceErrors(err)
+ cursor, err := newCursorWithSession(bc, a.client.bsonOpts, a.registry, sess,
+
+ // The only way the server will return a tailable/awaitData cursor for an
+ // aggregate operation is for the first stage in the pipeline to
+ // be $changeStream, this is the only time maxAwaitTimeMS should be applied.
+ // For this reason, we pass the client timeout to the cursor.
+ withCursorOptionClientTimeout(a.client.timeout))
+ return cursor, wrapErrors(err)
}
// CountDocuments returns the number of documents in the collection. For a fast count of the documents in the
@@ -974,16 +1140,19 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) {
// result in a full collection scan.
//
// The opts parameter can be used to specify options for the operation (see the options.CountOptions documentation).
-func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
- opts ...*options.CountOptions) (int64, error) {
-
+func (coll *Collection) CountDocuments(ctx context.Context, filter any,
+ opts ...options.Lister[options.CountOptions],
+) (int64, error) {
if ctx == nil {
ctx = context.Background()
}
- countOpts := options.MergeCountOptions(opts...)
+ args, err := mongoutil.NewOptions[options.CountOptions](opts...)
+ if err != nil {
+ return 0, err
+ }
- pipelineArr, err := countDocumentsAggregatePipeline(filter, coll.bsonOpts, coll.registry, countOpts)
+ pipelineArr, err := countDocumentsAggregatePipeline(filter, coll.bsonOpts, coll.registry, args)
if err != nil {
return 0, err
}
@@ -1002,36 +1171,48 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
rc = nil
}
+ retry := driver.RetryNone
+ if coll.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryReads)
+
selector := makeReadPrefSelector(sess, coll.readSelector, coll.client.localThreshold)
op := operation.NewAggregate(pipelineArr).Session(sess).ReadConcern(rc).ReadPreference(coll.readPreference).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
CommandMonitor(coll.client.monitor).ServerSelector(selector).ClusterClock(coll.client.clock).Database(coll.db.name).
Collection(coll.name).Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).ServerAPI(coll.client.serverAPI).
- Timeout(coll.client.timeout).MaxTime(countOpts.MaxTime).Authenticator(coll.client.authenticator)
- if countOpts.Collation != nil {
- op.Collation(bsoncore.Document(countOpts.Collation.ToDocument()))
+ Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if countOpts.Comment != nil {
- op.Comment(*countOpts.Comment)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
+ if err != nil {
+ return 0, err
+ }
+
+ op.Comment(comment)
}
- if countOpts.Hint != nil {
- if isUnorderedMap(countOpts.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return 0, ErrMapForOrderedArgument{"hint"}
}
- hintVal, err := marshalValue(countOpts.Hint, coll.bsonOpts, coll.registry)
+ hintVal, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return 0, err
}
op.Hint(hintVal)
}
- retry := driver.RetryNone
- if coll.client.retryReads {
- retry = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retry)
err = op.Execute(ctx)
if err != nil {
- return 0, replaceErrors(err)
+ return 0, wrapErrors(err)
}
batch := op.ResultCursorResponse().FirstBatch
@@ -1059,9 +1240,10 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/count/.
-func (coll *Collection) EstimatedDocumentCount(ctx context.Context,
- opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
-
+func (coll *Collection) EstimatedDocumentCount(
+ ctx context.Context,
+ opts ...options.Lister[options.EstimatedDocumentCountOptions],
+) (int64, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -1084,31 +1266,40 @@ func (coll *Collection) EstimatedDocumentCount(ctx context.Context,
rc = nil
}
- co := options.MergeEstimatedDocumentCountOptions(opts...)
+ args, err := mongoutil.NewOptions[options.EstimatedDocumentCountOptions](opts...)
+ if err != nil {
+ return 0, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ retry := driver.RetryNone
+ if coll.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryReads)
selector := makeReadPrefSelector(sess, coll.readSelector, coll.client.localThreshold)
op := operation.NewCount().Session(sess).ClusterClock(coll.client.clock).
Database(coll.db.name).Collection(coll.name).CommandMonitor(coll.client.monitor).
Deployment(coll.client.deployment).ReadConcern(rc).ReadPreference(coll.readPreference).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
ServerSelector(selector).Crypt(coll.client.cryptFLE).ServerAPI(coll.client.serverAPI).
- Timeout(coll.client.timeout).MaxTime(co.MaxTime).Authenticator(coll.client.authenticator)
+ Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
- if co.Comment != nil {
- comment, err := marshalValue(co.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return 0, err
}
op = op.Comment(comment)
}
-
- retry := driver.RetryNone
- if coll.client.retryReads {
- retry = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op.Retry(retry)
err = op.Execute(ctx)
- return op.Result().N, replaceErrors(err)
+ return op.Result().N, wrapErrors(err)
}
// Distinct executes a distinct command to find the unique values for a specified field in the collection.
@@ -1121,16 +1312,19 @@ func (coll *Collection) EstimatedDocumentCount(ctx context.Context,
// The opts parameter can be used to specify options for the operation (see the options.DistinctOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/distinct/.
-func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{},
- opts ...*options.DistinctOptions) ([]interface{}, error) {
-
+func (coll *Collection) Distinct(
+ ctx context.Context,
+ fieldName string,
+ filter any,
+ opts ...options.Lister[options.DistinctOptions],
+) *DistinctResult {
if ctx == nil {
ctx = context.Background()
}
f, err := marshal(filter, coll.bsonOpts, coll.registry)
if err != nil {
- return nil, err
+ return &DistinctResult{err: err}
}
sess := sessionFromContext(ctx)
@@ -1142,7 +1336,7 @@ func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter i
err = coll.client.validSession(sess)
if err != nil {
- return nil, err
+ return &DistinctResult{err: err}
}
rc := coll.readConcern
@@ -1150,58 +1344,72 @@ func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter i
rc = nil
}
+ retry := driver.RetryNone
+ if coll.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryReads)
+
selector := makeReadPrefSelector(sess, coll.readSelector, coll.client.localThreshold)
- option := options.MergeDistinctOptions(opts...)
+
+ args, err := mongoutil.NewOptions[options.DistinctOptions](opts...)
+ if err != nil {
+ err = fmt.Errorf("failed to construct options from builder: %w", err)
+
+ return &DistinctResult{err: err}
+ }
op := operation.NewDistinct(fieldName, f).
Session(sess).ClusterClock(coll.client.clock).
Database(coll.db.name).Collection(coll.name).CommandMonitor(coll.client.monitor).
Deployment(coll.client.deployment).ReadConcern(rc).ReadPreference(coll.readPreference).
+ Retry(retry).MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
ServerSelector(selector).Crypt(coll.client.cryptFLE).ServerAPI(coll.client.serverAPI).
- Timeout(coll.client.timeout).MaxTime(option.MaxTime).Authenticator(coll.client.authenticator)
+ Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
- if option.Collation != nil {
- op.Collation(bsoncore.Document(option.Collation.ToDocument()))
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if option.Comment != nil {
- comment, err := marshalValue(option.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
- return nil, err
+ return &DistinctResult{err: err}
}
op.Comment(comment)
}
- retry := driver.RetryNone
- if coll.client.retryReads {
- retry = driver.RetryOncePerCommand
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
+ return &DistinctResult{err: ErrMapForOrderedArgument{"hint"}}
+ }
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
+ if err != nil {
+ return &DistinctResult{err: err}
+ }
+ op.Hint(hint)
+ }
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retry)
err = op.Execute(ctx)
if err != nil {
- return nil, replaceErrors(err)
+ return &DistinctResult{err: wrapErrors(err)}
}
arr, ok := op.Result().Values.ArrayOK()
if !ok {
- return nil, fmt.Errorf("response field 'values' is type array, but received BSON type %s", op.Result().Values.Type)
- }
+ err := fmt.Errorf("response field 'values' is type array, but received BSON type %s", op.Result().Values.Type)
- values, err := arr.Values()
- if err != nil {
- return nil, err
+ return &DistinctResult{err: err}
}
- retArray := make([]interface{}, len(values))
-
- for i, val := range values {
- raw := bson.RawValue{Type: val.Type, Value: val.Data}
- err = raw.Unmarshal(&retArray[i])
- if err != nil {
- return nil, err
- }
+ return &DistinctResult{
+ reg: coll.registry,
+ arr: bson.RawArray(arr),
+ bsonOpts: coll.bsonOpts,
}
-
- return retArray, replaceErrors(err)
}
// Find executes a find command and returns a Cursor over the matching documents in the collection.
@@ -1212,29 +1420,30 @@ func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter i
// The opts parameter can be used to specify options for the operation (see the options.FindOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/find/.
-func (coll *Collection) Find(ctx context.Context, filter interface{},
- opts ...*options.FindOptions) (cur *Cursor, err error) {
-
- if ctx == nil {
- ctx = context.Background()
+func (coll *Collection) Find(ctx context.Context, filter any,
+ opts ...options.Lister[options.FindOptions],
+) (*Cursor, error) {
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return nil, err
}
// Omit "maxTimeMS" from operations that return a user-managed cursor to
- // prevent confusing "cursor not found" errors. To maintain existing
- // behavior for users who set "timeoutMS" with no context deadline, only
- // omit "maxTimeMS" when a context deadline is set.
+ // prevent confusing "cursor not found" errors.
//
// See DRIVERS-2722 for more detail.
- _, deadlineSet := ctx.Deadline()
- return coll.find(ctx, filter, deadlineSet, opts...)
+ return coll.find(ctx, filter, true, args)
}
func (coll *Collection) find(
ctx context.Context,
- filter interface{},
- omitCSOTMaxTimeMS bool,
- opts ...*options.FindOptions,
+ filter any,
+ omitMaxTimeMS bool,
+ args *options.FindOptions,
) (cur *Cursor, err error) {
+ if ctx == nil {
+ ctx = context.Background()
+ }
f, err := marshal(filter, coll.bsonOpts, coll.registry)
if err != nil {
@@ -1262,45 +1471,50 @@ func (coll *Collection) find(
rc = nil
}
- fo := options.MergeFindOptions(opts...)
+ retry := driver.RetryNone
+ if coll.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ cursorOpts := coll.client.createBaseCursorOptions(coll.client.retryReads)
selector := makeReadPrefSelector(sess, coll.readSelector, coll.client.localThreshold)
op := operation.NewFind(f).
Session(sess).ReadConcern(rc).ReadPreference(coll.readPreference).
CommandMonitor(coll.client.monitor).ServerSelector(selector).
+ Retry(retry).MaxAdaptiveRetries(cursorOpts.MaxAdaptiveRetries).
+ EnableOverloadRetargeting(cursorOpts.EnableOverloadRetargeting).
ClusterClock(coll.client.clock).Database(coll.db.name).Collection(coll.name).
Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).ServerAPI(coll.client.serverAPI).
- Timeout(coll.client.timeout).MaxTime(fo.MaxTime).Logger(coll.client.logger).
- OmitCSOTMaxTimeMS(omitCSOTMaxTimeMS).Authenticator(coll.client.authenticator)
-
- cursorOpts := coll.client.createBaseCursorOptions()
+ Timeout(coll.client.timeout).Logger(coll.client.logger).Authenticator(coll.client.authenticator).
+ OmitMaxTimeMS(omitMaxTimeMS)
cursorOpts.MarshalValueEncoderFn = newEncoderFn(coll.bsonOpts, coll.registry)
- if fo.AllowDiskUse != nil {
- op.AllowDiskUse(*fo.AllowDiskUse)
+ if args.AllowDiskUse != nil {
+ op.AllowDiskUse(*args.AllowDiskUse)
}
- if fo.AllowPartialResults != nil {
- op.AllowPartialResults(*fo.AllowPartialResults)
+ if args.AllowPartialResults != nil {
+ op.AllowPartialResults(*args.AllowPartialResults)
}
- if fo.BatchSize != nil {
- cursorOpts.BatchSize = *fo.BatchSize
- op.BatchSize(*fo.BatchSize)
+ if args.BatchSize != nil {
+ cursorOpts.BatchSize = *args.BatchSize
+ op.BatchSize(*args.BatchSize)
}
- if fo.Collation != nil {
- op.Collation(bsoncore.Document(fo.Collation.ToDocument()))
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if fo.Comment != nil {
- op.Comment(*fo.Comment)
-
- commentVal, err := marshalValue(fo.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
- cursorOpts.Comment = commentVal
+
+ op.Comment(comment)
+ cursorOpts.Comment = comment
}
- if fo.CursorType != nil {
- switch *fo.CursorType {
+ if args.CursorType != nil {
+ switch *args.CursorType {
case options.Tailable:
op.Tailable(true)
case options.TailableAwait:
@@ -1308,25 +1522,25 @@ func (coll *Collection) find(
op.AwaitData(true)
}
}
- if fo.Hint != nil {
- if isUnorderedMap(fo.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return nil, ErrMapForOrderedArgument{"hint"}
}
- hint, err := marshalValue(fo.Hint, coll.bsonOpts, coll.registry)
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Hint(hint)
}
- if fo.Let != nil {
- let, err := marshal(fo.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Let(let)
}
- if fo.Limit != nil {
- limit := *fo.Limit
+ if args.Limit != nil {
+ limit := *args.Limit
if limit < 0 {
limit = -1 * limit
op.SingleBatch(true)
@@ -1334,73 +1548,91 @@ func (coll *Collection) find(
cursorOpts.Limit = int32(limit)
op.Limit(limit)
}
- if fo.Max != nil {
- max, err := marshal(fo.Max, coll.bsonOpts, coll.registry)
+ if args.Max != nil {
+ max, err := marshal(args.Max, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Max(max)
}
- if fo.MaxAwaitTime != nil {
- cursorOpts.MaxTimeMS = int64(*fo.MaxAwaitTime / time.Millisecond)
+ if args.MaxAwaitTime != nil {
+ cursorOpts.SetMaxAwaitTime(*args.MaxAwaitTime)
}
- if fo.Min != nil {
- min, err := marshal(fo.Min, coll.bsonOpts, coll.registry)
+ if args.Min != nil {
+ min, err := marshal(args.Min, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Min(min)
}
- if fo.NoCursorTimeout != nil {
- op.NoCursorTimeout(*fo.NoCursorTimeout)
+ if args.NoCursorTimeout != nil {
+ op.NoCursorTimeout(*args.NoCursorTimeout)
}
- if fo.OplogReplay != nil {
- op.OplogReplay(*fo.OplogReplay)
+ if args.OplogReplay != nil {
+ op.OplogReplay(*args.OplogReplay)
}
- if fo.Projection != nil {
- proj, err := marshal(fo.Projection, coll.bsonOpts, coll.registry)
+ if args.Projection != nil {
+ proj, err := marshal(args.Projection, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Projection(proj)
}
- if fo.ReturnKey != nil {
- op.ReturnKey(*fo.ReturnKey)
+ if args.ReturnKey != nil {
+ op.ReturnKey(*args.ReturnKey)
}
- if fo.ShowRecordID != nil {
- op.ShowRecordID(*fo.ShowRecordID)
+ if args.ShowRecordID != nil {
+ op.ShowRecordID(*args.ShowRecordID)
}
- if fo.Skip != nil {
- op.Skip(*fo.Skip)
+ if args.Skip != nil {
+ op.Skip(*args.Skip)
}
- if fo.Snapshot != nil {
- op.Snapshot(*fo.Snapshot)
- }
- if fo.Sort != nil {
- if isUnorderedMap(fo.Sort) {
+ if args.Sort != nil {
+ if isUnorderedMap(args.Sort) {
return nil, ErrMapForOrderedArgument{"sort"}
}
- sort, err := marshal(fo.Sort, coll.bsonOpts, coll.registry)
+ sort, err := marshal(args.Sort, coll.bsonOpts, coll.registry)
if err != nil {
return nil, err
}
op.Sort(sort)
}
- retry := driver.RetryNone
- if coll.client.retryReads {
- retry = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retry)
if err = op.Execute(ctx); err != nil {
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
bc, err := op.Result(cursorOpts)
if err != nil {
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- return newCursorWithSession(bc, coll.bsonOpts, coll.registry, sess)
+
+ return newCursorWithSession(bc, coll.bsonOpts, coll.registry, sess,
+ withCursorOptionClientTimeout(coll.client.timeout))
+}
+
+func newFindArgsFromFindOneArgs(args *options.FindOneOptions) *options.FindOptions {
+ var limit int64 = -1
+ v := &options.FindOptions{Limit: &limit}
+ if args != nil {
+ v.AllowPartialResults = args.AllowPartialResults
+ v.Collation = args.Collation
+ v.Comment = args.Comment
+ v.Hint = args.Hint
+ v.Max = args.Max
+ v.Min = args.Min
+ v.OplogReplay = args.OplogReplay
+ v.Projection = args.Projection
+ v.ReturnKey = args.ReturnKey
+ v.ShowRecordID = args.ShowRecordID
+ v.Skip = args.Skip
+ v.Sort = args.Sort
+ v.Internal = args.Internal
+ }
+ return v
}
// FindOne executes a find command and returns a SingleResult for one document in the collection.
@@ -1412,50 +1644,24 @@ func (coll *Collection) find(
// The opts parameter can be used to specify options for this operation (see the options.FindOneOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/find/.
-func (coll *Collection) FindOne(ctx context.Context, filter interface{},
- opts ...*options.FindOneOptions) *SingleResult {
-
+func (coll *Collection) FindOne(ctx context.Context, filter any,
+ opts ...options.Lister[options.FindOneOptions],
+) *SingleResult {
if ctx == nil {
ctx = context.Background()
}
- findOpts := make([]*options.FindOptions, 0, len(opts))
- for _, opt := range opts {
- if opt == nil {
- continue
- }
- findOpts = append(findOpts, &options.FindOptions{
- AllowPartialResults: opt.AllowPartialResults,
- BatchSize: opt.BatchSize,
- Collation: opt.Collation,
- Comment: opt.Comment,
- CursorType: opt.CursorType,
- Hint: opt.Hint,
- Max: opt.Max,
- MaxAwaitTime: opt.MaxAwaitTime,
- MaxTime: opt.MaxTime,
- Min: opt.Min,
- NoCursorTimeout: opt.NoCursorTimeout,
- OplogReplay: opt.OplogReplay,
- Projection: opt.Projection,
- ReturnKey: opt.ReturnKey,
- ShowRecordID: opt.ShowRecordID,
- Skip: opt.Skip,
- Snapshot: opt.Snapshot,
- Sort: opt.Sort,
- })
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return &SingleResult{err: err}
}
- // Unconditionally send a limit to make sure only one document is returned and the cursor is not kept open
- // by the server.
- findOpts = append(findOpts, options.Find().SetLimit(-1))
-
- cursor, err := coll.find(ctx, filter, false, findOpts...)
+ cursor, err := coll.find(ctx, filter, false, newFindArgsFromFindOneArgs(args))
return &SingleResult{
ctx: ctx,
cur: cursor,
bsonOpts: coll.bsonOpts,
reg: coll.registry,
- err: replaceErrors(err),
+ err: wrapErrors(err),
}
}
@@ -1480,7 +1686,7 @@ func (coll *Collection) findAndModify(ctx context.Context, op *operation.FindAnd
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
@@ -1491,6 +1697,8 @@ func (coll *Collection) findAndModify(ctx context.Context, op *operation.FindAnd
retry = driver.RetryOnce
}
+ maxAdaptiveRetries := coll.client.effectiveAdaptiveRetries(coll.client.retryWrites)
+
op = op.Session(sess).
WriteConcern(wc).
CommandMonitor(coll.client.monitor).
@@ -1500,18 +1708,21 @@ func (coll *Collection) findAndModify(ctx context.Context, op *operation.FindAnd
Collection(coll.name).
Deployment(coll.client.deployment).
Retry(retry).
+ MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(coll.client.enableOverloadRetargeting).
Crypt(coll.client.cryptFLE)
- _, err = processWriteError(op.Execute(ctx))
+ rr, err := processWriteError(op.Execute(ctx))
if err != nil {
return &SingleResult{err: err}
}
return &SingleResult{
- ctx: ctx,
- rdr: bson.Raw(op.Result().Value),
- bsonOpts: coll.bsonOpts,
- reg: coll.registry,
+ ctx: ctx,
+ rdr: bson.Raw(op.Result().Value),
+ bsonOpts: coll.bsonOpts,
+ reg: coll.registry,
+ Acknowledged: rr.isAcknowledged(),
}
}
@@ -1526,60 +1737,69 @@ func (coll *Collection) findAndModify(ctx context.Context, op *operation.FindAnd
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/.
-func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{},
- opts ...*options.FindOneAndDeleteOptions) *SingleResult {
-
+func (coll *Collection) FindOneAndDelete(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.FindOneAndDeleteOptions],
+) *SingleResult {
f, err := marshal(filter, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
- fod := options.MergeFindOneAndDeleteOptions(opts...)
- op := operation.NewFindAndModify(f).Remove(true).ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).
- MaxTime(fod.MaxTime).Authenticator(coll.client.authenticator)
- if fod.Collation != nil {
- op = op.Collation(bsoncore.Document(fod.Collation.ToDocument()))
+
+ args, err := mongoutil.NewOptions[options.FindOneAndDeleteOptions](opts...)
+ if err != nil {
+ return &SingleResult{err: fmt.Errorf("failed to construct options from builder: %w", err)}
+ }
+
+ op := operation.NewFindAndModify(f).Remove(true).ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
+ if args.Collation != nil {
+ op = op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if fod.Comment != nil {
- comment, err := marshalValue(fod.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Comment(comment)
}
- if fod.Projection != nil {
- proj, err := marshal(fod.Projection, coll.bsonOpts, coll.registry)
+ if args.Projection != nil {
+ proj, err := marshal(args.Projection, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Fields(proj)
}
- if fod.Sort != nil {
- if isUnorderedMap(fod.Sort) {
+ if args.Sort != nil {
+ if isUnorderedMap(args.Sort) {
return &SingleResult{err: ErrMapForOrderedArgument{"sort"}}
}
- sort, err := marshal(fod.Sort, coll.bsonOpts, coll.registry)
+ sort, err := marshal(args.Sort, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Sort(sort)
}
- if fod.Hint != nil {
- if isUnorderedMap(fod.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return &SingleResult{err: ErrMapForOrderedArgument{"hint"}}
}
- hint, err := marshalValue(fod.Hint, coll.bsonOpts, coll.registry)
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Hint(hint)
}
- if fod.Let != nil {
- let, err := marshal(fod.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Let(let)
}
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
+ }
return coll.findAndModify(ctx, op)
}
@@ -1598,9 +1818,12 @@ func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/.
-func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{},
- replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *SingleResult {
-
+func (coll *Collection) FindOneAndReplace(
+ ctx context.Context,
+ filter any,
+ replacement any,
+ opts ...options.Lister[options.FindOneAndReplaceOptions],
+) *SingleResult {
f, err := marshal(filter, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
@@ -1613,65 +1836,71 @@ func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{
return &SingleResult{err: errors.New("replacement document cannot contain keys beginning with '$'")}
}
- fo := options.MergeFindOneAndReplaceOptions(opts...)
- op := operation.NewFindAndModify(f).Update(bsoncore.Value{Type: bsontype.EmbeddedDocument, Data: r}).
- ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).MaxTime(fo.MaxTime).Authenticator(coll.client.authenticator)
+ args, err := mongoutil.NewOptions[options.FindOneAndReplaceOptions](opts...)
+ if err != nil {
+ return &SingleResult{err: fmt.Errorf("failed to construct options from builder: %w", err)}
+ }
- if fo.BypassDocumentValidation != nil && *fo.BypassDocumentValidation {
- op = op.BypassDocumentValidation(*fo.BypassDocumentValidation)
+ op := operation.NewFindAndModify(f).Update(bsoncore.Value{Type: bsoncore.TypeEmbeddedDocument, Data: r}).
+ ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ op = op.BypassDocumentValidation(*args.BypassDocumentValidation)
}
- if fo.Collation != nil {
- op = op.Collation(bsoncore.Document(fo.Collation.ToDocument()))
+ if args.Collation != nil {
+ op = op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if fo.Comment != nil {
- comment, err := marshalValue(fo.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Comment(comment)
}
- if fo.Projection != nil {
- proj, err := marshal(fo.Projection, coll.bsonOpts, coll.registry)
+ if args.Projection != nil {
+ proj, err := marshal(args.Projection, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Fields(proj)
}
- if fo.ReturnDocument != nil {
- op = op.NewDocument(*fo.ReturnDocument == options.After)
+ if args.ReturnDocument != nil {
+ op = op.NewDocument(*args.ReturnDocument == options.After)
}
- if fo.Sort != nil {
- if isUnorderedMap(fo.Sort) {
+ if args.Sort != nil {
+ if isUnorderedMap(args.Sort) {
return &SingleResult{err: ErrMapForOrderedArgument{"sort"}}
}
- sort, err := marshal(fo.Sort, coll.bsonOpts, coll.registry)
+ sort, err := marshal(args.Sort, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Sort(sort)
}
- if fo.Upsert != nil {
- op = op.Upsert(*fo.Upsert)
+ if args.Upsert != nil {
+ op = op.Upsert(*args.Upsert)
}
- if fo.Hint != nil {
- if isUnorderedMap(fo.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return &SingleResult{err: ErrMapForOrderedArgument{"hint"}}
}
- hint, err := marshalValue(fo.Hint, coll.bsonOpts, coll.registry)
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Hint(hint)
}
- if fo.Let != nil {
- let, err := marshal(fo.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Let(let)
}
- if fo.BypassEmptyTsReplacement != nil {
- op = op.BypassEmptyTsReplacement(*fo.BypassEmptyTsReplacement)
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
+ }
+ if additionalCmd, ok := optionsutil.Value(args.Internal, "addCommandFields").(bson.D); ok {
+ op = op.AdditionalCmd(additionalCmd)
}
return coll.findAndModify(ctx, op)
@@ -1692,9 +1921,12 @@ func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/.
-func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{},
- update interface{}, opts ...*options.FindOneAndUpdateOptions) *SingleResult {
-
+func (coll *Collection) FindOneAndUpdate(
+ ctx context.Context,
+ filter any,
+ update any,
+ opts ...options.Lister[options.FindOneAndUpdateOptions],
+) *SingleResult {
if ctx == nil {
ctx = context.Background()
}
@@ -1704,9 +1936,12 @@ func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}
return &SingleResult{err: err}
}
- fo := options.MergeFindOneAndUpdateOptions(opts...)
- op := operation.NewFindAndModify(f).ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).
- MaxTime(fo.MaxTime).Authenticator(coll.client.authenticator)
+ args, err := mongoutil.NewOptions[options.FindOneAndUpdateOptions](opts...)
+ if err != nil {
+ return &SingleResult{err: fmt.Errorf("failed to construct options from builder: %w", err)}
+ }
+
+ op := operation.NewFindAndModify(f).ServerAPI(coll.client.serverAPI).Timeout(coll.client.timeout).Authenticator(coll.client.authenticator)
u, err := marshalUpdateValue(update, coll.bsonOpts, coll.registry, true)
if err != nil {
@@ -1714,73 +1949,73 @@ func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}
}
op = op.Update(u)
- if fo.ArrayFilters != nil {
- af := fo.ArrayFilters
+ if args.ArrayFilters != nil {
+ af := args.ArrayFilters
reg := coll.registry
- if af.Registry != nil {
- reg = af.Registry
- }
- filtersDoc, err := marshalValue(af.Filters, coll.bsonOpts, reg)
+ filtersDoc, err := marshalValue(af, coll.bsonOpts, reg)
if err != nil {
return &SingleResult{err: err}
}
op = op.ArrayFilters(filtersDoc.Data)
}
- if fo.BypassDocumentValidation != nil && *fo.BypassDocumentValidation {
- op = op.BypassDocumentValidation(*fo.BypassDocumentValidation)
+ if args.BypassDocumentValidation != nil && *args.BypassDocumentValidation {
+ op = op.BypassDocumentValidation(*args.BypassDocumentValidation)
}
- if fo.Collation != nil {
- op = op.Collation(bsoncore.Document(fo.Collation.ToDocument()))
+ if args.Collation != nil {
+ op = op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if fo.Comment != nil {
- comment, err := marshalValue(fo.Comment, coll.bsonOpts, coll.registry)
+ if args.Comment != nil {
+ comment, err := marshalValue(args.Comment, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Comment(comment)
}
- if fo.Projection != nil {
- proj, err := marshal(fo.Projection, coll.bsonOpts, coll.registry)
+ if args.Projection != nil {
+ proj, err := marshal(args.Projection, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Fields(proj)
}
- if fo.ReturnDocument != nil {
- op = op.NewDocument(*fo.ReturnDocument == options.After)
+ if args.ReturnDocument != nil {
+ op = op.NewDocument(*args.ReturnDocument == options.After)
}
- if fo.Sort != nil {
- if isUnorderedMap(fo.Sort) {
+ if args.Sort != nil {
+ if isUnorderedMap(args.Sort) {
return &SingleResult{err: ErrMapForOrderedArgument{"sort"}}
}
- sort, err := marshal(fo.Sort, coll.bsonOpts, coll.registry)
+ sort, err := marshal(args.Sort, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Sort(sort)
}
- if fo.Upsert != nil {
- op = op.Upsert(*fo.Upsert)
+ if args.Upsert != nil {
+ op = op.Upsert(*args.Upsert)
}
- if fo.Hint != nil {
- if isUnorderedMap(fo.Hint) {
+ if args.Hint != nil {
+ if isUnorderedMap(args.Hint) {
return &SingleResult{err: ErrMapForOrderedArgument{"hint"}}
}
- hint, err := marshalValue(fo.Hint, coll.bsonOpts, coll.registry)
+ hint, err := marshalValue(args.Hint, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Hint(hint)
}
- if fo.Let != nil {
- let, err := marshal(fo.Let, coll.bsonOpts, coll.registry)
+ if args.Let != nil {
+ let, err := marshal(args.Let, coll.bsonOpts, coll.registry)
if err != nil {
return &SingleResult{err: err}
}
op = op.Let(let)
}
- if fo.BypassEmptyTsReplacement != nil {
- op = op.BypassEmptyTsReplacement(*fo.BypassEmptyTsReplacement)
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
+ }
+ if additionalCmd, ok := optionsutil.Value(args.Internal, "addCommandFields").(bson.D); ok {
+ op = op.AdditionalCmd(additionalCmd)
}
return coll.findAndModify(ctx, op)
@@ -1799,9 +2034,9 @@ func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}
//
// The opts parameter can be used to specify options for change stream creation (see the options.ChangeStreamOptions
// documentation).
-func (coll *Collection) Watch(ctx context.Context, pipeline interface{},
- opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
-
+func (coll *Collection) Watch(ctx context.Context, pipeline any,
+ opts ...options.Lister[options.ChangeStreamOptions],
+) (*ChangeStream, error) {
csConfig := changeStreamConfig{
readConcern: coll.readConcern,
readPreference: coll.readPreference,
@@ -1823,7 +2058,7 @@ func (coll *Collection) Indexes() IndexView {
// SearchIndexes returns a SearchIndexView instance that can be used to perform operations on the search indexes for the collection.
func (coll *Collection) SearchIndexes() SearchIndexView {
- c, _ := coll.Clone() // Clone() always return a nil error.
+ c := coll.Clone()
c.readConcern = nil
c.writeConcern = nil
return SearchIndexView{
@@ -1833,12 +2068,18 @@ func (coll *Collection) SearchIndexes() SearchIndexView {
// Drop drops the collection on the server. This method ignores "namespace not found" errors so it is safe to drop
// a collection that does not exist on the server.
-func (coll *Collection) Drop(ctx context.Context) error {
- // Follow Client-Side Encryption specification to check for encryptedFields.
- // Drop does not have an encryptedFields option. See: GODRIVER-2413.
- // Check for encryptedFields from the client EncryptedFieldsMap.
- // Check for encryptedFields from the server if EncryptedFieldsMap is set.
- ef := coll.db.getEncryptedFieldsFromMap(coll.name)
+func (coll *Collection) Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error {
+ args, err := mongoutil.NewOptions[options.DropCollectionOptions](opts...)
+ if err != nil {
+ return fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ ef := args.EncryptedFields
+
+ if ef == nil {
+ ef = coll.db.getEncryptedFieldsFromMap(coll.name)
+ }
+
if ef == nil && coll.db.client.encryptedFieldsMap != nil {
var err error
if ef, err = coll.db.getEncryptedFieldsFromServer(ctx, coll.name); err != nil {
@@ -1854,7 +2095,7 @@ func (coll *Collection) Drop(ctx context.Context) error {
}
// dropEncryptedCollection drops a collection with EncryptedFields.
-func (coll *Collection) dropEncryptedCollection(ctx context.Context, ef interface{}) error {
+func (coll *Collection) dropEncryptedCollection(ctx context.Context, ef any) error {
efBSON, err := marshal(ef, coll.bsonOpts, coll.registry)
if err != nil {
return fmt.Errorf("error transforming document: %w", err)
@@ -1904,7 +2145,7 @@ func (coll *Collection) drop(ctx context.Context) error {
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
@@ -1920,19 +2161,54 @@ func (coll *Collection) drop(ctx context.Context) error {
err = op.Execute(ctx)
// ignore namespace not found errors
- driverErr, ok := err.(driver.Error)
- if !ok || (ok && !driverErr.NamespaceNotFound()) {
- return replaceErrors(err)
+ var driverErr driver.Error
+ if !errors.As(err, &driverErr) || !driverErr.NamespaceNotFound() {
+ return wrapErrors(err)
}
return nil
}
+func toDocument(co *options.Collation) 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
+}
+
type pinnedServerSelector struct {
stringer fmt.Stringer
fallback description.ServerSelector
session *session.Client
}
+var _ description.ServerSelector = pinnedServerSelector{}
+
func (pss pinnedServerSelector) String() string {
if pss.stringer == nil {
return ""
@@ -1945,10 +2221,10 @@ func (pss pinnedServerSelector) SelectServer(
t description.Topology,
svrs []description.Server,
) ([]description.Server, error) {
- if pss.session != nil && pss.session.PinnedServer != nil {
+ if pss.session != nil && pss.session.PinnedServerAddr != nil {
// If there is a pinned server, try to find it in the list of candidates.
for _, candidate := range svrs {
- if candidate.Addr == pss.session.PinnedServer.Addr {
+ if candidate.Addr == *pss.session.PinnedServerAddr {
return []description.Server{candidate}, nil
}
}
@@ -1959,7 +2235,7 @@ func (pss pinnedServerSelector) SelectServer(
return pss.fallback.SelectServer(t, svrs)
}
-func makePinnedSelector(sess *session.Client, fallback description.ServerSelector) description.ServerSelector {
+func makePinnedSelector(sess *session.Client, fallback description.ServerSelector) pinnedServerSelector {
pss := pinnedServerSelector{
session: sess,
fallback: fallback,
@@ -1972,34 +2248,47 @@ func makePinnedSelector(sess *session.Client, fallback description.ServerSelecto
return pss
}
-func makeReadPrefSelector(sess *session.Client, selector description.ServerSelector, localThreshold time.Duration) description.ServerSelector {
+func makeReadPrefSelector(
+ sess *session.Client,
+ selector description.ServerSelector,
+ localThreshold time.Duration,
+) pinnedServerSelector {
if sess != nil && sess.TransactionRunning() {
- selector = description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(sess.CurrentRp),
- description.LatencySelector(localThreshold),
- })
+ selector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: sess.CurrentRp},
+ &serverselector.Latency{Latency: localThreshold},
+ },
+ }
}
return makePinnedSelector(sess, selector)
}
-func makeOutputAggregateSelector(sess *session.Client, rp *readpref.ReadPref, localThreshold time.Duration) description.ServerSelector {
+func makeOutputAggregateSelector(
+ sess *session.Client,
+ rp *readpref.ReadPref,
+ localThreshold time.Duration,
+) pinnedServerSelector {
if sess != nil && sess.TransactionRunning() {
// Use current transaction's read preference if available
rp = sess.CurrentRp
}
- selector := description.CompositeSelector([]description.ServerSelector{
- description.OutputAggregateSelector(rp),
- description.LatencySelector(localThreshold),
- })
+ selector := &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: rp, IsOutputAggregate: true},
+ &serverselector.Latency{Latency: localThreshold},
+ },
+ }
+
return makePinnedSelector(sess, selector)
}
// isUnorderedMap returns true if val is a map with more than 1 element. It is typically used to
// check for unordered Go values that are used in nested command documents where different field
// orders mean different things. Examples are the "sort" and "hint" fields.
-func isUnorderedMap(val interface{}) bool {
+func isUnorderedMap(val any) bool {
refValue := reflect.ValueOf(val)
return refValue.Kind() == reflect.Map && refValue.Len() > 1
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/crypt_retrievers.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/crypt_retrievers.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/mongo/crypt_retrievers.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/crypt_retrievers.go
index 5e96da731..2354328d1 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/crypt_retrievers.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/crypt_retrievers.go
@@ -9,7 +9,7 @@ package mongo
import (
"context"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// keyRetriever gets keys from the key vault collection.
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/cursor.go
similarity index 65%
rename from vendor/go.mongodb.org/mongo-driver/mongo/cursor.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/cursor.go
index 1e01e398d..f17565704 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/cursor.go
@@ -7,6 +7,7 @@
package mongo
import (
+ "bytes"
"context"
"errors"
"fmt"
@@ -14,13 +15,12 @@ import (
"reflect"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Cursor is used to iterate over a stream of documents. Each document can be decoded into a Go type via the Decode
@@ -31,49 +31,78 @@ type Cursor struct {
// to Next or TryNext. If continued access is required, a copy must be made.
Current bson.Raw
- bc batchCursor
- batch *bsoncore.DocumentSequence
- batchLength int
- bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
- clientSession *session.Client
+ bc batchCursor
+ batch *bsoncore.Iterator
+ batchLength int
+ bsonOpts *options.BSONOptions
+ registry *bson.Registry
+ clientSession *session.Client
+ clientTimeout time.Duration
+ hasClientTimeout bool
err error
}
+type cursorOptions struct {
+ clientTimeout time.Duration
+ hasClientTimeout bool
+}
+
+type cursorOption func(*cursorOptions)
+
+func withCursorOptionClientTimeout(dur *time.Duration) cursorOption {
+ return func(opts *cursorOptions) {
+ if dur != nil && *dur > 0 {
+ opts.clientTimeout = *dur
+ opts.hasClientTimeout = true
+ }
+ }
+}
+
func newCursor(
bc batchCursor,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
+ opts ...cursorOption,
) (*Cursor, error) {
- return newCursorWithSession(bc, bsonOpts, registry, nil)
+ return newCursorWithSession(bc, bsonOpts, registry, nil, opts...)
}
func newCursorWithSession(
bc batchCursor,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
clientSession *session.Client,
+ opts ...cursorOption,
) (*Cursor, error) {
if registry == nil {
- registry = bson.DefaultRegistry
+ registry = defaultRegistry
}
if bc == nil {
return nil, errors.New("batch cursor must not be nil")
}
+
+ cursorOpts := &cursorOptions{}
+ for _, opt := range opts {
+ opt(cursorOpts)
+ }
+
c := &Cursor{
- bc: bc,
- bsonOpts: bsonOpts,
- registry: registry,
- clientSession: clientSession,
+ bc: bc,
+ bsonOpts: bsonOpts,
+ registry: registry,
+ clientSession: clientSession,
+ clientTimeout: cursorOpts.clientTimeout,
+ hasClientTimeout: cursorOpts.hasClientTimeout,
}
if bc.ID() == 0 {
c.closeImplicitSession()
}
- // Initialize just the batchLength here so RemainingBatchLength will return an accurate result. The actual batch
- // will be pulled up by the first Next/TryNext call.
- c.batchLength = c.bc.Batch().DocumentCount()
+ // Initialize just the batchLength here so RemainingBatchLength will return an
+ // accurate result. The actual batch will be pulled up by the first
+ // Next/TryNext call.
+ c.batchLength = c.bc.Batch().Count()
return c, nil
}
@@ -82,52 +111,74 @@ func newEmptyCursor() *Cursor {
}
// NewCursorFromDocuments creates a new Cursor pre-loaded with the provided documents, error and registry. If no registry is provided,
-// bson.DefaultRegistry will be used.
+// bson.NewRegistry() will be used.
//
// The documents parameter must be a slice of documents. The slice may be nil or empty, but all elements must be non-nil.
-func NewCursorFromDocuments(documents []interface{}, err error, registry *bsoncodec.Registry) (*Cursor, error) {
+func NewCursorFromDocuments(documents []any, preloadedErr error, registry *bson.Registry) (*Cursor, error) {
if registry == nil {
- registry = bson.DefaultRegistry
+ registry = defaultRegistry
}
- // Convert documents slice to a sequence-style byte array.
- var docsBytes []byte
- for _, doc := range documents {
+ buf := new(bytes.Buffer)
+ enc := new(bson.Encoder)
+
+ values := make([]bsoncore.Value, len(documents))
+ for i, doc := range documents {
switch t := doc.(type) {
case nil:
- return nil, ErrNilDocument
+ return nil, fmt.Errorf("invalid document at index %d: %w", i, ErrNilDocument)
case []byte:
// Slight optimization so we'll just use MarshalBSON and not go through the codec machinery.
doc = bson.Raw(t)
}
- var marshalErr error
- docsBytes, marshalErr = bson.MarshalAppendWithRegistry(registry, docsBytes, doc)
- if marshalErr != nil {
- return nil, marshalErr
+
+ vw := bson.NewDocumentWriter(buf)
+ enc.Reset(vw)
+ enc.SetRegistry(registry)
+
+ if err := enc.Encode(doc); err != nil {
+ return nil, err
+ }
+
+ dup := make([]byte, len(buf.Bytes()))
+ copy(dup, buf.Bytes())
+
+ values[i] = bsoncore.Value{
+ Type: bsoncore.TypeEmbeddedDocument,
+ Data: dup,
}
+
+ buf.Reset()
}
c := &Cursor{
- bc: driver.NewBatchCursorFromDocuments(docsBytes),
+ bc: driver.NewBatchCursorFromList(bsoncore.BuildArray(nil, values...)),
registry: registry,
- err: err,
+ err: preloadedErr,
}
// Initialize batch and batchLength here. The underlying batch cursor will be preloaded with the
// provided contents, and thus already has a batch before calls to Next/TryNext.
c.batch = c.bc.Batch()
- c.batchLength = c.bc.Batch().DocumentCount()
+ c.batchLength = c.bc.Batch().Count()
+
return c, nil
}
// ID returns the ID of this cursor, or 0 if the cursor has been closed or exhausted.
func (c *Cursor) ID() int64 { return c.bc.ID() }
-// Next gets the next document for this cursor. It returns true if there were no errors and the cursor has not been
-// exhausted.
+// Next gets the next document for this cursor. It returns true if there were no
+// errors and the cursor has not been exhausted.
+//
+// Next blocks until a document is available or an error occurs. If the context
+// expires, the cursor's error will be set to ctx.Err(). In case of an error,
+// Next will return false.
//
-// Next blocks until a document is available or an error occurs. If the context expires, the cursor's error will
-// be set to ctx.Err(). In case of an error, Next will return false.
+// If MaxAwaitTime is set, the operation will be bound by the Context's
+// deadline. If the context does not have a deadline, the operation will be
+// bound by the client-level timeout, if one is set. If MaxAwaitTime is greater
+// than the user-provided timeout, Next will return false.
//
// If Next returns false, subsequent calls will also return false.
func (c *Cursor) Next(ctx context.Context) bool {
@@ -159,12 +210,47 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool {
if ctx == nil {
ctx = context.Background()
}
- doc, err := c.batch.Next()
+
+ // If the context does not have a deadline we defer to a client-level timeout,
+ // if one is set.
+ if _, ok := ctx.Deadline(); !ok && c.hasClientTimeout {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, c.clientTimeout)
+
+ defer cancel()
+ }
+
+ // To avoid unnecessary socket timeouts, we attempt to short-circuit tailable
+ // awaitData "getMore" operations by ensuring that the maxAwaitTimeMS is less
+ // than the operation timeout.
+ //
+ // The specifications assume that drivers iteratively apply the timeout
+ // provided at the constructor level (e.g., (*collection).Find) for tailable
+ // awaitData cursors:
+ //
+ // If set, drivers MUST apply the timeoutMS option to the initial aggregate
+ // operation. Drivers MUST also apply the original timeoutMS value to each
+ // next call on the change stream but MUST NOT use it to derive a maxTimeMS
+ // field for getMore commands.
+ //
+ // The Go Driver might decide to support the above behavior with DRIVERS-2722.
+ // The principal concern is that it would be unexpected for users to apply an
+ // operation-level timeout via contexts to a constructor and then that timeout
+ // later be applied while working with a resulting cursor. Instead, it is more
+ // idiomatic to apply the timeout to the context passed to Next or TryNext.
+ maxAwaitTime := c.bc.MaxAwaitTime() //
+ if maxAwaitTime != nil && !nonBlocking && !mongoutil.TimeoutWithinContext(ctx, *maxAwaitTime) {
+ c.err = fmt.Errorf("MaxAwaitTime must be less than the operation timeout")
+
+ return false
+ }
+
+ val, err := c.batch.Next()
switch {
case err == nil:
// Consume the next document in the current batch.
c.batchLength--
- c.Current = bson.Raw(doc)
+ c.Current = bson.Raw(val.Data)
return true
case errors.Is(err, io.EOF): // Need to do a getMore
default:
@@ -178,7 +264,7 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool {
// If we don't have a next batch
if !c.bc.Next(ctx) {
// Do we have an error? If so we return false.
- c.err = replaceErrors(c.bc.Err())
+ c.err = wrapErrors(c.bc.Err())
if c.err != nil {
return false
}
@@ -202,12 +288,12 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool {
// Use the new batch to update the batch and batchLength fields. Consume the first document in the batch.
c.batch = c.bc.Batch()
- c.batchLength = c.batch.DocumentCount()
- doc, err = c.batch.Next()
+ c.batchLength = c.batch.Count()
+ val, err = c.batch.Next()
switch {
case err == nil:
c.batchLength--
- c.Current = bson.Raw(doc)
+ c.Current = bson.Raw(val.Data)
return true
case errors.Is(err, io.EOF): // Empty batch so we continue
default:
@@ -220,12 +306,9 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool {
func getDecoder(
data []byte,
opts *options.BSONOptions,
- reg *bsoncodec.Registry,
-) (*bson.Decoder, error) {
- dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
- if err != nil {
- return nil, err
- }
+ reg *bson.Registry,
+) *bson.Decoder {
+ dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(data)))
if opts != nil {
if opts.AllowTruncatingDoubles {
@@ -234,12 +317,15 @@ func getDecoder(
if opts.BinaryAsSlice {
dec.BinaryAsSlice()
}
- if opts.DefaultDocumentD {
- dec.DefaultDocumentD()
- }
if opts.DefaultDocumentM {
dec.DefaultDocumentM()
}
+ if opts.DefaultDocumentMap {
+ dec.DefaultDocumentMap()
+ }
+ if opts.ObjectIDAsHexString {
+ dec.ObjectIDAsHexString()
+ }
if opts.UseJSONStructTags {
dec.UseJSONStructTags()
}
@@ -255,22 +341,16 @@ func getDecoder(
}
if reg != nil {
- // TODO:(GODRIVER-2719): Remove error handling.
- if err := dec.SetRegistry(reg); err != nil {
- return nil, err
- }
+ dec.SetRegistry(reg)
}
- return dec, nil
+ return dec
}
// Decode will unmarshal the current document into val and return any errors from the unmarshalling process without any
// modification. If val is nil or is a typed nil, an error will be returned.
-func (c *Cursor) Decode(val interface{}) error {
- dec, err := getDecoder(c.Current, c.bsonOpts, c.registry)
- if err != nil {
- return fmt.Errorf("error configuring BSON decoder: %w", err)
- }
+func (c *Cursor) Decode(val any) error {
+ dec := getDecoder(c.Current, c.bsonOpts, c.registry)
return dec.Decode(val)
}
@@ -282,7 +362,7 @@ func (c *Cursor) Err() error { return c.err }
// the first call, any subsequent calls will not change the state.
func (c *Cursor) Close(ctx context.Context) error {
defer c.closeImplicitSession()
- return replaceErrors(c.bc.Close(ctx))
+ return wrapErrors(c.bc.Close(ctx))
}
// All iterates the cursor and decodes each document into results. The results parameter must be a pointer to a slice.
@@ -291,7 +371,7 @@ func (c *Cursor) Close(ctx context.Context) error {
// cursor has been iterated, any previously iterated documents will not be included in results.
//
// This method requires driver version >= 1.1.0.
-func (c *Cursor) All(ctx context.Context, results interface{}) error {
+func (c *Cursor) All(ctx context.Context, results any) error {
resultsVal := reflect.ValueOf(results)
if resultsVal.Kind() != reflect.Ptr {
return fmt.Errorf("results argument must be a pointer to a slice, but was a %s", resultsVal.Kind())
@@ -329,7 +409,7 @@ func (c *Cursor) All(ctx context.Context, results interface{}) error {
batch = c.bc.Batch()
}
- if err = replaceErrors(c.bc.Err()); err != nil {
+ if err = wrapErrors(c.bc.Err()); err != nil {
return err
}
@@ -345,9 +425,9 @@ func (c *Cursor) RemainingBatchLength() int {
// addFromBatch adds all documents from batch to sliceVal starting at the given index. It returns the new slice value,
// the next empty index in the slice, and an error if one occurs.
-func (c *Cursor) addFromBatch(sliceVal reflect.Value, elemType reflect.Type, batch *bsoncore.DocumentSequence,
- index int) (reflect.Value, int, error) {
-
+func (c *Cursor) addFromBatch(sliceVal reflect.Value, elemType reflect.Type, batch *bsoncore.Iterator,
+ index int,
+) (reflect.Value, int, error) {
docs, err := batch.Documents()
if err != nil {
return sliceVal, index, err
@@ -362,10 +442,7 @@ func (c *Cursor) addFromBatch(sliceVal reflect.Value, elemType reflect.Type, bat
}
currElem := sliceVal.Index(index).Addr().Interface()
- dec, err := getDecoder(doc, c.bsonOpts, c.registry)
- if err != nil {
- return sliceVal, index, fmt.Errorf("error configuring BSON decoder: %w", err)
- }
+ dec := getDecoder(doc, c.bsonOpts, c.registry)
err = dec.Decode(currElem)
if err != nil {
return sliceVal, index, err
@@ -391,19 +468,19 @@ func (c *Cursor) SetBatchSize(batchSize int32) {
c.bc.SetBatchSize(batchSize)
}
-// SetMaxTime will set the maximum amount of time the server will allow the
+// SetMaxAwaitTime will set the maximum amount of time the server will allow the
// operations to execute. The server will error if this field is set but the
// cursor is not configured with awaitData=true.
//
// The time.Duration value passed by this setter will be converted and rounded
// down to the nearest millisecond.
-func (c *Cursor) SetMaxTime(dur time.Duration) {
- c.bc.SetMaxTime(dur)
+func (c *Cursor) SetMaxAwaitTime(dur time.Duration) {
+ c.bc.SetMaxAwaitTime(dur)
}
// SetComment will set a user-configurable comment that can be used to identify
// the operation in server logs.
-func (c *Cursor) SetComment(comment interface{}) {
+func (c *Cursor) SetComment(comment any) {
c.bc.SetComment(comment)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/database.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/database.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/mongo/database.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/database.go
index 5344c9641..c1d3474e9 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/database.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/database.go
@@ -12,23 +12,24 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/internal/csfle"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/csfle"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
-var (
- defaultRunCmdOpts = []*options.RunCmdOptions{options.RunCmd().SetReadPreference(readpref.Primary())}
-)
+var defaultRunCmdOpts = []options.Lister[options.RunCmdOptions]{options.RunCmd().SetReadPreference(readpref.Primary())}
// Database is a handle to a MongoDB database. It is safe for concurrent use by multiple goroutines.
type Database struct {
@@ -40,35 +41,35 @@ type Database struct {
readSelector description.ServerSelector
writeSelector description.ServerSelector
bsonOpts *options.BSONOptions
- registry *bsoncodec.Registry
+ registry *bson.Registry
}
-func newDatabase(client *Client, name string, opts ...*options.DatabaseOptions) *Database {
- dbOpt := options.MergeDatabaseOptions(opts...)
+func newDatabase(client *Client, name string, opts ...options.Lister[options.DatabaseOptions]) *Database {
+ args, _ := mongoutil.NewOptions[options.DatabaseOptions](opts...)
rc := client.readConcern
- if dbOpt.ReadConcern != nil {
- rc = dbOpt.ReadConcern
+ if args.ReadConcern != nil {
+ rc = args.ReadConcern
}
rp := client.readPreference
- if dbOpt.ReadPreference != nil {
- rp = dbOpt.ReadPreference
+ if args.ReadPreference != nil {
+ rp = args.ReadPreference
}
wc := client.writeConcern
- if dbOpt.WriteConcern != nil {
- wc = dbOpt.WriteConcern
+ if args.WriteConcern != nil {
+ wc = args.WriteConcern
}
bsonOpts := client.bsonOpts
- if dbOpt.BSONOptions != nil {
- bsonOpts = dbOpt.BSONOptions
+ if args.BSONOptions != nil {
+ bsonOpts = args.BSONOptions
}
reg := client.registry
- if dbOpt.Registry != nil {
- reg = dbOpt.Registry
+ if args.Registry != nil {
+ reg = args.Registry
}
db := &Database{
@@ -81,15 +82,19 @@ func newDatabase(client *Client, name string, opts ...*options.DatabaseOptions)
registry: reg,
}
- db.readSelector = description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(db.readPreference),
- description.LatencySelector(db.client.localThreshold),
- })
+ db.readSelector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: db.readPreference},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
- db.writeSelector = description.CompositeSelector([]description.ServerSelector{
- description.WriteSelector(),
- description.LatencySelector(db.client.localThreshold),
- })
+ db.writeSelector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.Write{},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
return db
}
@@ -104,13 +109,15 @@ func (db *Database) Name() string {
return db.name
}
-// Collection gets a handle for a collection with the given name configured with the given CollectionOptions.
-func (db *Database) Collection(name string, opts ...*options.CollectionOptions) *Collection {
+// Collection returns a handle for a collection with the given name and options.
+//
+// If the collection does not exist on the server, it will be created when a
+// write operation is performed.
+func (db *Database) Collection(name string, opts ...options.Lister[options.CollectionOptions]) *Collection {
return newCollection(db, name, opts...)
}
-// Aggregate executes an aggregate command the database. This requires MongoDB version >= 3.6 and driver version >=
-// 1.1.0.
+// Aggregate executes an aggregate command the database.
//
// The pipeline parameter must be a slice of documents, each representing an aggregation stage. The pipeline
// cannot be nil but can be empty. The stage documents must all be non-nil. For a pipeline of bson.D documents, the
@@ -121,8 +128,11 @@ func (db *Database) Collection(name string, opts ...*options.CollectionOptions)
// The opts parameter can be used to specify options for this operation (see the options.AggregateOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/aggregate/.
-func (db *Database) Aggregate(ctx context.Context, pipeline interface{},
- opts ...*options.AggregateOptions) (*Cursor, error) {
+func (db *Database) Aggregate(
+ ctx context.Context,
+ pipeline any,
+ opts ...options.Lister[options.AggregateOptions],
+) (*Cursor, error) {
a := aggregateParams{
ctx: ctx,
pipeline: pipeline,
@@ -130,30 +140,36 @@ func (db *Database) Aggregate(ctx context.Context, pipeline interface{},
registry: db.registry,
readConcern: db.readConcern,
writeConcern: db.writeConcern,
- retryRead: db.client.retryReads,
db: db.name,
readSelector: db.readSelector,
writeSelector: db.writeSelector,
readPreference: db.readPreference,
- opts: opts,
}
- return aggregate(a)
+
+ return aggregate(a, opts...)
}
-func (db *Database) processRunCommand(ctx context.Context, cmd interface{},
- cursorCommand bool, opts ...*options.RunCmdOptions) (*operation.Command, *session.Client, error) {
+func (db *Database) processRunCommand(
+ ctx context.Context,
+ cmd any,
+ cursorCommand bool,
+ opts ...options.Lister[options.RunCmdOptions],
+) (*operation.Command, *session.Client, error) {
+ args, err := mongoutil.NewOptions[options.RunCmdOptions](append(defaultRunCmdOpts, opts...)...)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
sess := sessionFromContext(ctx)
if sess == nil && db.client.sessionPool != nil {
sess = session.NewImplicitClientSession(db.client.sessionPool, db.client.id)
}
- err := db.client.validSession(sess)
- if err != nil {
+ if err := db.client.validSession(sess); err != nil {
return nil, sess, err
}
- ro := options.MergeRunCmdOptions(append(defaultRunCmdOpts, opts...)...)
- if sess != nil && sess.TransactionRunning() && ro.ReadPreference != nil && ro.ReadPreference.Mode() != readpref.PrimaryMode {
+ if sess != nil && sess.TransactionRunning() && args.ReadPreference != nil && args.ReadPreference.Mode() != readpref.PrimaryMode {
return nil, sess, errors.New("read preference in a transaction must be primary")
}
@@ -165,30 +181,39 @@ func (db *Database) processRunCommand(ctx context.Context, cmd interface{},
if err != nil {
return nil, sess, err
}
- readSelect := description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(ro.ReadPreference),
- description.LatencySelector(db.client.localThreshold),
- })
- if sess != nil && sess.PinnedServer != nil {
+
+ var readSelect description.ServerSelector
+
+ readSelect = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: args.ReadPreference},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
+
+ if sess != nil && sess.PinnedServerAddr != nil {
readSelect = makePinnedSelector(sess, readSelect)
}
var op *operation.Command
- switch cursorCommand {
+ switch retryOverload := db.client.retryReads && db.client.retryWrites; cursorCommand {
case true:
- cursorOpts := db.client.createBaseCursorOptions()
+ cursorOpts := db.client.createBaseCursorOptions(retryOverload)
cursorOpts.MarshalValueEncoderFn = newEncoderFn(db.bsonOpts, db.registry)
op = operation.NewCursorCommand(runCmdDoc, cursorOpts)
default:
op = operation.NewCommand(runCmdDoc)
+ maxAdaptiveRetries := db.client.effectiveAdaptiveRetries(retryOverload)
+ op = op.MaxAdaptiveRetries(maxAdaptiveRetries).
+ EnableOverloadRetargeting(db.client.enableOverloadRetargeting)
}
return op.Session(sess).CommandMonitor(db.client.monitor).
ServerSelector(readSelect).ClusterClock(db.client.clock).
Database(db.name).Deployment(db.client.deployment).
- Crypt(db.client.cryptFLE).ReadPreference(ro.ReadPreference).ServerAPI(db.client.serverAPI).
+ Crypt(db.client.cryptFLE).ReadPreference(args.ReadPreference).ServerAPI(db.client.serverAPI).
Timeout(db.client.timeout).Logger(db.client.logger).Authenticator(db.client.authenticator), sess, nil
}
@@ -210,7 +235,11 @@ func (db *Database) processRunCommand(ctx context.Context, cmd interface{},
// - A session ID or any transaction-specific fields
// - API versioning options when an API version is already declared on the Client
// - maxTimeMS when Timeout is set on the Client
-func (db *Database) RunCommand(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) *SingleResult {
+func (db *Database) RunCommand(
+ ctx context.Context,
+ runCommand any,
+ opts ...options.Lister[options.RunCmdOptions],
+) *SingleResult {
if ctx == nil {
ctx = context.Background()
}
@@ -223,13 +252,14 @@ func (db *Database) RunCommand(ctx context.Context, runCommand interface{}, opts
err = op.Execute(ctx)
// RunCommand can be used to run a write, thus execute may return a write error
- _, convErr := processWriteError(err)
+ rr, convErr := processWriteError(err)
return &SingleResult{
- ctx: ctx,
- err: convErr,
- rdr: bson.Raw(op.Result()),
- bsonOpts: db.bsonOpts,
- reg: db.registry,
+ ctx: ctx,
+ err: convErr,
+ rdr: bson.Raw(op.Result()),
+ bsonOpts: db.bsonOpts,
+ reg: db.registry,
+ Acknowledged: rr.isAcknowledged(),
}
}
@@ -247,7 +277,11 @@ func (db *Database) RunCommand(ctx context.Context, runCommand interface{}, opts
// - A session ID or any transaction-specific fields
// - API versioning options when an API version is already declared on the Client
// - maxTimeMS when Timeout is set on the Client
-func (db *Database) RunCommandCursor(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) (*Cursor, error) {
+func (db *Database) RunCommandCursor(
+ ctx context.Context,
+ runCommand any,
+ opts ...options.Lister[options.RunCmdOptions],
+) (*Cursor, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -255,7 +289,7 @@ func (db *Database) RunCommandCursor(ctx context.Context, runCommand interface{}
op, sess, err := db.processRunCommand(ctx, runCommand, true, opts...)
if err != nil {
closeImplicitSession(sess)
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
if err = op.Execute(ctx); err != nil {
@@ -264,16 +298,17 @@ func (db *Database) RunCommandCursor(ctx context.Context, runCommand interface{}
return nil, errors.New(
"database response does not contain a cursor; try using RunCommand instead")
}
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
bc, err := op.ResultCursor()
if err != nil {
closeImplicitSession(sess)
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- cursor, err := newCursorWithSession(bc, db.bsonOpts, db.registry, sess)
- return cursor, replaceErrors(err)
+ cursor, err := newCursorWithSession(bc, db.bsonOpts, db.registry, sess,
+ withCursorOptionClientTimeout(db.client.timeout))
+ return cursor, wrapErrors(err)
}
// Drop drops the database on the server. This method ignores "namespace not found" errors so it is safe to drop
@@ -298,7 +333,7 @@ func (db *Database) Drop(ctx context.Context) error {
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
@@ -312,9 +347,9 @@ func (db *Database) Drop(ctx context.Context) error {
err = op.Execute(ctx)
- driverErr, ok := err.(driver.Error)
- if err != nil && (!ok || !driverErr.NamespaceNotFound()) {
- return replaceErrors(err)
+ var driverErr driver.Error
+ if err != nil && (!errors.As(err, &driverErr) || !driverErr.NamespaceNotFound()) {
+ return wrapErrors(err)
}
return nil
}
@@ -330,30 +365,53 @@ func (db *Database) Drop(ctx context.Context) error {
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/listCollections/.
-//
-// BUG(benjirewis): ListCollectionSpecifications prevents listing more than 100 collections per database when running
-// against MongoDB version 2.6.
-func (db *Database) ListCollectionSpecifications(ctx context.Context, filter interface{},
- opts ...*options.ListCollectionsOptions) ([]*CollectionSpecification, error) {
-
+func (db *Database) ListCollectionSpecifications(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.ListCollectionsOptions],
+) ([]CollectionSpecification, error) {
cursor, err := db.ListCollections(ctx, filter, opts...)
if err != nil {
return nil, err
}
- var specs []*CollectionSpecification
- err = cursor.All(ctx, &specs)
+ var resp []struct {
+ Name string `bson:"name"`
+ Type string `bson:"type"`
+ Info *struct {
+ ReadOnly bool `bson:"readOnly"`
+ UUID *bson.Binary `bson:"uuid"`
+ } `bson:"info"`
+ Options bson.Raw `bson:"options"`
+ IDIndex indexListSpecificationResponse `bson:"idIndex"`
+ }
+
+ err = cursor.All(ctx, &resp)
if err != nil {
return nil, err
}
- for _, spec := range specs {
+ specs := make([]CollectionSpecification, len(resp))
+ for idx, spec := range resp {
+ specs[idx] = CollectionSpecification{
+ Name: spec.Name,
+ Type: spec.Type,
+ Options: spec.Options,
+ IDIndex: IndexSpecification(spec.IDIndex),
+ }
+
+ if spec.Info != nil {
+ specs[idx].ReadOnly = spec.Info.ReadOnly
+ specs[idx].UUID = spec.Info.UUID
+ }
+
// Pre-4.4 servers report a namespace in their responses, so we only set Namespace manually if it was not in
// the response.
- if spec.IDIndex != nil && spec.IDIndex.Namespace == "" {
- spec.IDIndex.Namespace = db.name + "." + spec.Name
+ if specs[idx].IDIndex.Namespace == "" {
+ specs[idx].IDIndex.Namespace = db.name + "." + specs[idx].Name
}
}
+
return specs, nil
}
@@ -370,11 +428,20 @@ func (db *Database) ListCollectionSpecifications(ctx context.Context, filter int
//
// BUG(benjirewis): ListCollections prevents listing more than 100 collections per database when running against
// MongoDB version 2.6.
-func (db *Database) ListCollections(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) (*Cursor, error) {
+func (db *Database) ListCollections(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.ListCollectionsOptions],
+) (*Cursor, error) {
if ctx == nil {
ctx = context.Background()
}
+ args, err := mongoutil.NewOptions[options.ListCollectionsOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
filterDoc, err := marshal(filter, db.bsonOpts, db.registry)
if err != nil {
return nil, err
@@ -391,53 +458,62 @@ func (db *Database) ListCollections(ctx context.Context, filter interface{}, opt
return nil, err
}
- selector := description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(readpref.Primary()),
- description.LatencySelector(db.client.localThreshold),
- })
+ retry := driver.RetryNone
+ if db.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ cursorOpts := db.client.createBaseCursorOptions(db.client.retryReads)
+
+ var selector description.ServerSelector
+
+ selector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: readpref.Primary()},
+ &serverselector.Latency{Latency: db.client.localThreshold},
+ },
+ }
+
selector = makeReadPrefSelector(sess, selector, db.client.localThreshold)
- lco := options.MergeListCollectionsOptions(opts...)
op := operation.NewListCollections(filterDoc).
Session(sess).ReadPreference(db.readPreference).CommandMonitor(db.client.monitor).
+ Retry(retry).MaxAdaptiveRetries(cursorOpts.MaxAdaptiveRetries).
+ EnableOverloadRetargeting(cursorOpts.EnableOverloadRetargeting).
ServerSelector(selector).ClusterClock(db.client.clock).
Database(db.name).Deployment(db.client.deployment).Crypt(db.client.cryptFLE).
ServerAPI(db.client.serverAPI).Timeout(db.client.timeout).Authenticator(db.client.authenticator)
- cursorOpts := db.client.createBaseCursorOptions()
-
cursorOpts.MarshalValueEncoderFn = newEncoderFn(db.bsonOpts, db.registry)
- if lco.NameOnly != nil {
- op = op.NameOnly(*lco.NameOnly)
+ if args.NameOnly != nil {
+ op = op.NameOnly(*args.NameOnly)
}
- if lco.BatchSize != nil {
- cursorOpts.BatchSize = *lco.BatchSize
- op = op.BatchSize(*lco.BatchSize)
+ if args.BatchSize != nil {
+ cursorOpts.BatchSize = *args.BatchSize
+ op = op.BatchSize(*args.BatchSize)
}
- if lco.AuthorizedCollections != nil {
- op = op.AuthorizedCollections(*lco.AuthorizedCollections)
+ if args.AuthorizedCollections != nil {
+ op = op.AuthorizedCollections(*args.AuthorizedCollections)
}
-
- retry := driver.RetryNone
- if db.client.retryReads {
- retry = driver.RetryOncePerCommand
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op = op.Retry(retry)
err = op.Execute(ctx)
if err != nil {
closeImplicitSession(sess)
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
bc, err := op.Result(cursorOpts)
if err != nil {
closeImplicitSession(sess)
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- cursor, err := newCursorWithSession(bc, db.bsonOpts, db.registry, sess)
- return cursor, replaceErrors(err)
+ cursor, err := newCursorWithSession(bc, db.bsonOpts, db.registry, sess,
+ withCursorOptionClientTimeout(db.client.timeout))
+ return cursor, wrapErrors(err)
}
// ListCollectionNames executes a listCollections command and returns a slice containing the names of the collections
@@ -454,7 +530,11 @@ func (db *Database) ListCollections(ctx context.Context, filter interface{}, opt
//
// BUG(benjirewis): ListCollectionNames prevents listing more than 100 collections per database when running against
// MongoDB version 2.6.
-func (db *Database) ListCollectionNames(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) ([]string, error) {
+func (db *Database) ListCollectionNames(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.ListCollectionsOptions],
+) ([]string, error) {
opts = append(opts, options.ListCollections().SetNameOnly(true))
res, err := db.ListCollections(ctx, filter, opts...)
@@ -483,21 +563,6 @@ func (db *Database) ListCollectionNames(ctx context.Context, filter interface{},
return names, nil
}
-// ReadConcern returns the read concern used to configure the Database object.
-func (db *Database) ReadConcern() *readconcern.ReadConcern {
- return db.readConcern
-}
-
-// ReadPreference returns the read preference used to configure the Database object.
-func (db *Database) ReadPreference() *readpref.ReadPref {
- return db.readPreference
-}
-
-// WriteConcern returns the write concern used to configure the Database object.
-func (db *Database) WriteConcern() *writeconcern.WriteConcern {
- return db.writeConcern
-}
-
// Watch returns a change stream for all changes to the corresponding database. See
// https://www.mongodb.com/docs/manual/changeStreams/ for more information about change streams.
//
@@ -511,13 +576,14 @@ func (db *Database) WriteConcern() *writeconcern.WriteConcern {
//
// The opts parameter can be used to specify options for change stream creation (see the options.ChangeStreamOptions
// documentation).
-func (db *Database) Watch(ctx context.Context, pipeline interface{},
- opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
-
+func (db *Database) Watch(ctx context.Context, pipeline any,
+ opts ...options.Lister[options.ChangeStreamOptions],
+) (*ChangeStream, error) {
csConfig := changeStreamConfig{
readConcern: db.readConcern,
readPreference: db.readPreference,
client: db.client,
+ bsonOpts: db.bsonOpts,
registry: db.registry,
streamType: DatabaseStream,
databaseName: db.Name(),
@@ -526,19 +592,24 @@ func (db *Database) Watch(ctx context.Context, pipeline interface{},
return newChangeStream(ctx, csConfig, pipeline, opts...)
}
-// CreateCollection executes a create command to explicitly create a new collection with the specified name on the
-// server. If the collection being created already exists, this method will return a mongo.CommandError. This method
-// requires driver version 1.4.0 or higher.
+// CreateCollection creates a new collection on the server with the specified
+// name and options.
//
-// The opts parameter can be used to specify options for the operation (see the options.CreateCollectionOptions
-// documentation).
+// MongoDB versions < 7.0 will return an error if the collection already exists.
+// MongoDB versions >= 7.0 will not return an error if an existing collection
+// created with the same name and options already exists.
//
-// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/create/.
-func (db *Database) CreateCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error {
- cco := options.MergeCreateCollectionOptions(opts...)
- // Follow Client-Side Encryption specification to check for encryptedFields.
+// For more information about the command, see
+// https://www.mongodb.com/docs/manual/reference/command/create/.
+func (db *Database) CreateCollection(ctx context.Context, name string, opts ...options.Lister[options.CreateCollectionOptions]) error {
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ // Follow In-Use Encryption specification to check for encryptedFields.
// Check for encryptedFields from create options.
- ef := cco.EncryptedFields
+ ef := args.EncryptedFields
// Check for encryptedFields from the client EncryptedFieldsMap.
if ef == nil {
ef = db.getEncryptedFieldsFromMap(name)
@@ -552,7 +623,7 @@ func (db *Database) CreateCollection(ctx context.Context, name string, opts ...*
// getEncryptedFieldsFromServer tries to get an "encryptedFields" document associated with collectionName by running the "listCollections" command.
// Returns nil and no error if the listCollections command succeeds, but "encryptedFields" is not present.
-func (db *Database) getEncryptedFieldsFromServer(ctx context.Context, collectionName string) (interface{}, error) {
+func (db *Database) getEncryptedFieldsFromServer(ctx context.Context, collectionName string) (any, error) {
// Check if collection has an EncryptedFields configured server-side.
collSpecs, err := db.ListCollectionSpecifications(ctx, bson.D{{"name", collectionName}})
if err != nil {
@@ -582,7 +653,7 @@ func (db *Database) getEncryptedFieldsFromServer(ctx context.Context, collection
// getEncryptedFieldsFromMap tries to get an "encryptedFields" document associated with collectionName by checking the client EncryptedFieldsMap.
// Returns nil and no error if an EncryptedFieldsMap is not configured, or does not contain an entry for collectionName.
-func (db *Database) getEncryptedFieldsFromMap(collectionName string) interface{} {
+func (db *Database) getEncryptedFieldsFromMap(collectionName string) any {
// Check the EncryptedFieldsMap
efMap := db.client.encryptedFieldsMap
if efMap == nil {
@@ -599,7 +670,12 @@ func (db *Database) getEncryptedFieldsFromMap(collectionName string) interface{}
}
// createCollectionWithEncryptedFields creates a collection with an EncryptedFields.
-func (db *Database) createCollectionWithEncryptedFields(ctx context.Context, name string, ef interface{}, opts ...*options.CreateCollectionOptions) error {
+func (db *Database) createCollectionWithEncryptedFields(
+ ctx context.Context,
+ name string,
+ ef any,
+ opts ...options.Lister[options.CreateCollectionOptions],
+) error {
efBSON, err := marshal(ef, db.bsonOpts, db.registry)
if err != nil {
return fmt.Errorf("error transforming document: %w", err)
@@ -610,10 +686,14 @@ func (db *Database) createCollectionWithEncryptedFields(ctx context.Context, nam
// That is OK. This wire version check is a best effort to inform users earlier if using a QEv2 driver with a QEv1 server.
{
const QEv2WireVersion = 21
- server, err := db.client.deployment.SelectServer(ctx, description.WriteSelector())
+ ctx, cancel := csot.WithServerSelectionTimeout(ctx, db.client.deployment.GetServerSelectionTimeout())
+ defer cancel()
+
+ server, err := db.client.deployment.SelectServer(ctx, &serverselector.Write{})
if err != nil {
return fmt.Errorf("error selecting server to check maxWireVersion: %w", err)
}
+
conn, err := server.Connection(ctx)
if err != nil {
return fmt.Errorf("error getting connection to check maxWireVersion: %w", err)
@@ -621,7 +701,7 @@ func (db *Database) createCollectionWithEncryptedFields(ctx context.Context, nam
defer conn.Close()
wireVersionRange := conn.Description().WireVersion
if wireVersionRange.Max < QEv2WireVersion {
- return fmt.Errorf("Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption. Got maxWireVersion %v but need maxWireVersion >= %v", wireVersionRange.Max, QEv2WireVersion)
+ return fmt.Errorf("driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption. Got maxWireVersion %v but need maxWireVersion >= %v", wireVersionRange.Max, QEv2WireVersion)
}
}
@@ -669,7 +749,11 @@ func (db *Database) createCollectionWithEncryptedFields(ctx context.Context, nam
}
// createCollection creates a collection without EncryptedFields.
-func (db *Database) createCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error {
+func (db *Database) createCollection(
+ ctx context.Context,
+ name string,
+ opts ...options.Lister[options.CreateCollectionOptions],
+) error {
op, err := db.createCollectionOperation(name, opts...)
if err != nil {
return err
@@ -677,101 +761,119 @@ func (db *Database) createCollection(ctx context.Context, name string, opts ...*
return db.executeCreateOperation(ctx, op)
}
-func (db *Database) createCollectionOperation(name string, opts ...*options.CreateCollectionOptions) (*operation.Create, error) {
- cco := options.MergeCreateCollectionOptions(opts...)
+func (db *Database) createCollectionOperation(
+ name string,
+ opts ...options.Lister[options.CreateCollectionOptions],
+) (*operation.Create, error) {
+ args, err := mongoutil.NewOptions[options.CreateCollectionOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
op := operation.NewCreate(name).ServerAPI(db.client.serverAPI).Authenticator(db.client.authenticator)
- if cco.Capped != nil {
- op.Capped(*cco.Capped)
+ if args.Capped != nil {
+ op.Capped(*args.Capped)
}
- if cco.Collation != nil {
- op.Collation(bsoncore.Document(cco.Collation.ToDocument()))
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
- if cco.ChangeStreamPreAndPostImages != nil {
- csppi, err := marshal(cco.ChangeStreamPreAndPostImages, db.bsonOpts, db.registry)
+ if args.ChangeStreamPreAndPostImages != nil {
+ csppi, err := marshal(args.ChangeStreamPreAndPostImages, db.bsonOpts, db.registry)
if err != nil {
return nil, err
}
op.ChangeStreamPreAndPostImages(csppi)
}
- if cco.DefaultIndexOptions != nil {
+ if args.DefaultIndexOptions != nil {
+ defaultIndexArgs, err := mongoutil.NewOptions[options.DefaultIndexOptions](args.DefaultIndexOptions)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct DefaultIndexArgs from options: %w", err)
+ }
+
idx, doc := bsoncore.AppendDocumentStart(nil)
- if cco.DefaultIndexOptions.StorageEngine != nil {
- storageEngine, err := marshal(cco.DefaultIndexOptions.StorageEngine, db.bsonOpts, db.registry)
+ if defaultIndexArgs.StorageEngine != nil {
+ storageEngine, err := marshal(defaultIndexArgs.StorageEngine, db.bsonOpts, db.registry)
if err != nil {
return nil, err
}
doc = bsoncore.AppendDocumentElement(doc, "storageEngine", storageEngine)
}
- doc, err := bsoncore.AppendDocumentEnd(doc, idx)
+
+ doc, err = bsoncore.AppendDocumentEnd(doc, idx)
if err != nil {
return nil, err
}
op.IndexOptionDefaults(doc)
}
- if cco.MaxDocuments != nil {
- op.Max(*cco.MaxDocuments)
+ if args.MaxDocuments != nil {
+ op.Max(*args.MaxDocuments)
}
- if cco.SizeInBytes != nil {
- op.Size(*cco.SizeInBytes)
+ if args.SizeInBytes != nil {
+ op.Size(*args.SizeInBytes)
}
- if cco.StorageEngine != nil {
- storageEngine, err := marshal(cco.StorageEngine, db.bsonOpts, db.registry)
+ if args.StorageEngine != nil {
+ storageEngine, err := marshal(args.StorageEngine, db.bsonOpts, db.registry)
if err != nil {
return nil, err
}
op.StorageEngine(storageEngine)
}
- if cco.ValidationAction != nil {
- op.ValidationAction(*cco.ValidationAction)
+ if args.ValidationAction != nil {
+ op.ValidationAction(*args.ValidationAction)
}
- if cco.ValidationLevel != nil {
- op.ValidationLevel(*cco.ValidationLevel)
+ if args.ValidationLevel != nil {
+ op.ValidationLevel(*args.ValidationLevel)
}
- if cco.Validator != nil {
- validator, err := marshal(cco.Validator, db.bsonOpts, db.registry)
+ if args.Validator != nil {
+ validator, err := marshal(args.Validator, db.bsonOpts, db.registry)
if err != nil {
return nil, err
}
op.Validator(validator)
}
- if cco.ExpireAfterSeconds != nil {
- op.ExpireAfterSeconds(*cco.ExpireAfterSeconds)
+ if args.ExpireAfterSeconds != nil {
+ op.ExpireAfterSeconds(*args.ExpireAfterSeconds)
}
- if cco.TimeSeriesOptions != nil {
+ if args.TimeSeriesOptions != nil {
+ timeSeriesArgs, err := mongoutil.NewOptions[options.TimeSeriesOptions](args.TimeSeriesOptions)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct DefaultIndexArgs from options: %w", err)
+ }
+
idx, doc := bsoncore.AppendDocumentStart(nil)
- doc = bsoncore.AppendStringElement(doc, "timeField", cco.TimeSeriesOptions.TimeField)
+ doc = bsoncore.AppendStringElement(doc, "timeField", timeSeriesArgs.TimeField)
- if cco.TimeSeriesOptions.MetaField != nil {
- doc = bsoncore.AppendStringElement(doc, "metaField", *cco.TimeSeriesOptions.MetaField)
+ if timeSeriesArgs.MetaField != nil {
+ doc = bsoncore.AppendStringElement(doc, "metaField", *timeSeriesArgs.MetaField)
}
- if cco.TimeSeriesOptions.Granularity != nil {
- doc = bsoncore.AppendStringElement(doc, "granularity", *cco.TimeSeriesOptions.Granularity)
+ if timeSeriesArgs.Granularity != nil {
+ doc = bsoncore.AppendStringElement(doc, "granularity", *timeSeriesArgs.Granularity)
}
- if cco.TimeSeriesOptions.BucketMaxSpan != nil {
- bmss := int64(*cco.TimeSeriesOptions.BucketMaxSpan / time.Second)
+ if timeSeriesArgs.BucketMaxSpan != nil {
+ bmss := int64(*timeSeriesArgs.BucketMaxSpan / time.Second)
doc = bsoncore.AppendInt64Element(doc, "bucketMaxSpanSeconds", bmss)
}
- if cco.TimeSeriesOptions.BucketRounding != nil {
- brs := int64(*cco.TimeSeriesOptions.BucketRounding / time.Second)
+ if timeSeriesArgs.BucketRounding != nil {
+ brs := int64(*timeSeriesArgs.BucketRounding / time.Second)
doc = bsoncore.AppendInt64Element(doc, "bucketRoundingSeconds", brs)
}
- doc, err := bsoncore.AppendDocumentEnd(doc, idx)
+ doc, err = bsoncore.AppendDocumentEnd(doc, idx)
if err != nil {
return nil, err
}
op.TimeSeries(doc)
}
- if cco.ClusteredIndex != nil {
- clusteredIndex, err := marshal(cco.ClusteredIndex, db.bsonOpts, db.registry)
+ if args.ClusteredIndex != nil {
+ clusteredIndex, err := marshal(args.ClusteredIndex, db.bsonOpts, db.registry)
if err != nil {
return nil, err
}
@@ -781,22 +883,23 @@ func (db *Database) createCollectionOperation(name string, opts ...*options.Crea
return op, nil
}
-// CreateView executes a create command to explicitly create a view on the server. See
-// https://www.mongodb.com/docs/manual/core/views/ for more information about views. This method requires driver version >=
-// 1.4.0 and MongoDB version >= 3.4.
-//
-// The viewName parameter specifies the name of the view to create.
+// CreateView creates a view on the server.
//
-// # The viewOn parameter specifies the name of the collection or view on which this view will be created
+// The viewName parameter specifies the name of the view to create. The viewOn
+// parameter specifies the name of the collection or view on which this view
+// will be created. The pipeline parameter specifies an aggregation pipeline
+// that will be exececuted against the source collection or view to create this
+// view.
//
-// The pipeline parameter specifies an aggregation pipeline that will be exececuted against the source collection or
-// view to create this view.
+// MongoDB versions < 7.0 will return an error if the view already exists.
+// MongoDB versions >= 7.0 will not return an error if an existing view created
+// with the same name and options already exists.
//
-// The opts parameter can be used to specify options for the operation (see the options.CreateViewOptions
-// documentation).
-func (db *Database) CreateView(ctx context.Context, viewName, viewOn string, pipeline interface{},
- opts ...*options.CreateViewOptions) error {
-
+// See https://www.mongodb.com/docs/manual/core/views/ for more information
+// about views.
+func (db *Database) CreateView(ctx context.Context, viewName, viewOn string, pipeline any,
+ opts ...options.Lister[options.CreateViewOptions],
+) error {
pipelineArray, _, err := marshalAggregatePipeline(pipeline, db.bsonOpts, db.registry)
if err != nil {
return err
@@ -805,11 +908,14 @@ func (db *Database) CreateView(ctx context.Context, viewName, viewOn string, pip
op := operation.NewCreate(viewName).
ViewOn(viewOn).
Pipeline(pipelineArray).
- ServerAPI(db.client.serverAPI).
- Authenticator(db.client.authenticator)
- cvo := options.MergeCreateViewOptions(opts...)
- if cvo.Collation != nil {
- op.Collation(bsoncore.Document(cvo.Collation.ToDocument()))
+ ServerAPI(db.client.serverAPI).Authenticator(db.client.authenticator)
+ args, err := mongoutil.NewOptions(opts...)
+ if err != nil {
+ return fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ if args.Collation != nil {
+ op.Collation(bsoncore.Document(toDocument(args.Collation)))
}
return db.executeCreateOperation(ctx, op)
@@ -831,7 +937,7 @@ func (db *Database) executeCreateOperation(ctx context.Context, op *operation.Cr
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
@@ -845,5 +951,41 @@ func (db *Database) executeCreateOperation(ctx context.Context, op *operation.Cr
Deployment(db.client.deployment).
Crypt(db.client.cryptFLE)
- return replaceErrors(op.Execute(ctx))
+ return wrapErrors(op.Execute(ctx))
+}
+
+// GridFSBucket is used to construct a GridFS bucket which can be used as a
+// container for files.
+func (db *Database) GridFSBucket(opts ...options.Lister[options.BucketOptions]) *GridFSBucket {
+ b := &GridFSBucket{
+ name: "fs",
+ chunkSize: DefaultGridFSChunkSize,
+ db: db,
+ }
+
+ bo, _ := mongoutil.NewOptions[options.BucketOptions](opts...)
+ if bo.Name != nil {
+ b.name = *bo.Name
+ }
+ if bo.ChunkSizeBytes != nil {
+ b.chunkSize = *bo.ChunkSizeBytes
+ }
+ if bo.WriteConcern != nil {
+ b.wc = bo.WriteConcern
+ }
+ if bo.ReadConcern != nil {
+ b.rc = bo.ReadConcern
+ }
+ if bo.ReadPreference != nil {
+ b.rp = bo.ReadPreference
+ }
+
+ collOpts := options.Collection().SetWriteConcern(b.wc).SetReadConcern(b.rc).SetReadPreference(b.rp)
+
+ b.chunksColl = db.Collection(b.name+".chunks", collOpts)
+ b.filesColl = db.Collection(b.name+".files", collOpts)
+ b.readBuf = make([]byte, b.chunkSize)
+ b.writeBuf = make([]byte, b.chunkSize)
+
+ return b
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/doc.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/mongo/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/doc.go
index e0a5d66ac..3756d58f1 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/doc.go
@@ -13,7 +13,7 @@
//
// ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
// defer cancel()
-// client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://foo:bar@localhost:27017"))
+// client, err := mongo.Connect( options.Client().ApplyURI("mongodb://foo:bar@localhost:27017"))
// if err != nil { return err }
//
// This will create a new client and start monitoring the MongoDB server on localhost.
@@ -73,8 +73,8 @@
// if err != nil { return err }
// // do something with result...
//
-// All Client, Collection, and Database methods that take parameters of type interface{}
-// will return ErrNilDocument if nil is passed in for an interface{}.
+// All Client, Collection, and Database methods that take parameters of type any
+// will return ErrNilDocument if nil is passed in for an any.
//
// Additional examples can be found under the examples directory in the driver's repository and
// on the MongoDB website.
@@ -102,16 +102,23 @@
// using a different DNS server (8.8.8.8 is the common default), and, if that's not possible, avoiding the "mongodb+srv"
// scheme.
//
-// # Client Side Encryption
+// # In-Use Encryption
//
-// Client-side encryption is a new feature in MongoDB 4.2 that allows specific data fields to be encrypted. Using this
+// MongoDB provides two approaches to In-Use Encryption: Queryable Encryption (QE) and Client-Side Field Level Encryption (CSFLE).
+//
+// The Queryable Encryption and CSFLE features share much of the same API with some exceptions.
+//
+// - AutoEncryptionOptions.SetEncryptedFieldsMap only applies to Queryable Encryption.
+// - AutoEncryptionOptions.SetSchemaMap only applies to CSFLE.
+//
+// In-use encryption is a new feature in MongoDB 4.2 that allows specific data fields to be encrypted. Using this
// feature requires specifying the "cse" build tag during compilation:
//
// go build -tags cse
//
// Note: Auto encryption is an enterprise- and Atlas-only feature.
//
-// The libmongocrypt C library is required when using client-side encryption. Specific versions of libmongocrypt
+// The libmongocrypt C library is required when using in-use encryption. Specific versions of libmongocrypt
// are required for different versions of the Go Driver:
//
// - Go Driver v1.2.0 requires libmongocrypt v1.0.0 or higher
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/errors.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/errors.go
similarity index 59%
rename from vendor/go.mongodb.org/mongo-driver/mongo/errors.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/errors.go
index d92c9ca9b..28c298c5f 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/errors.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/errors.go
@@ -12,29 +12,48 @@ import (
"errors"
"fmt"
"net"
+ "reflect"
"strings"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/codecutil"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt"
- "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/codecutil"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology"
)
-// ErrUnacknowledgedWrite is returned by operations that have an unacknowledged write concern.
-var ErrUnacknowledgedWrite = errors.New("unacknowledged write")
-
// ErrClientDisconnected is returned when disconnected Client is used to run an operation.
var ErrClientDisconnected = errors.New("client is disconnected")
+// InvalidArgumentError wraps an invalid argument error.
+type InvalidArgumentError struct {
+ wrapped error
+}
+
+// Error implements the error interface.
+func (e InvalidArgumentError) Error() string {
+ return e.wrapped.Error()
+}
+
+// Unwrap returns the underlying error.
+func (e InvalidArgumentError) Unwrap() error {
+ return e.wrapped
+}
+
+// ErrMultipleIndexDrop is returned if multiple indexes would be dropped from a call to IndexView.DropOne.
+var ErrMultipleIndexDrop error = InvalidArgumentError{errors.New("multiple indexes would be dropped")}
+
// ErrNilDocument is returned when a nil document is passed to a CRUD method.
-var ErrNilDocument = errors.New("document is nil")
+var ErrNilDocument error = InvalidArgumentError{errors.New("document is nil")}
// ErrNilValue is returned when a nil value is passed to a CRUD method.
-var ErrNilValue = errors.New("value is nil")
+var ErrNilValue error = InvalidArgumentError{errors.New("value is nil")}
// ErrEmptySlice is returned when an empty slice is passed to a CRUD method that requires a non-empty slice.
-var ErrEmptySlice = errors.New("must provide at least one element in input slice")
+var ErrEmptySlice error = InvalidArgumentError{errors.New("must provide at least one element in input slice")}
+
+// ErrNotSlice is returned when a type other than slice is passed to InsertMany.
+var ErrNotSlice error = InvalidArgumentError{errors.New("must provide a non-empty slice")}
// ErrMapForOrderedArgument is returned when a map with multiple keys is passed to a CRUD method for an ordered parameter
type ErrMapForOrderedArgument struct {
@@ -46,31 +65,60 @@ func (e ErrMapForOrderedArgument) Error() string {
return fmt.Sprintf("multi-key map passed in for ordered parameter %v", e.ParamName)
}
-func replaceErrors(err error) error {
+// wrapErrors wraps error types and values that are defined in "internal" and
+// "x" packages with error types and values that are defined in this package.
+// That allows users to inspect the errors using errors.Is/errors.As without
+// relying on "internal" or "x" packages.
+func wrapErrors(err error) error {
// Return nil when err is nil to avoid costly reflection logic below.
if err == nil {
return nil
}
+ // Do not propagate the acknowledgement sentinel error. For DDL commands,
+ // (creating indexes, dropping collections, etc) acknowledgement should be
+ // ignored. For non-DDL write commands (insert, update, etc), acknowledgement
+ // should be be propagated at the result-level: e.g.,
+ // SingleResult.Acknowledged.
+ if errors.Is(err, driver.ErrUnacknowledgedWrite) {
+ return nil
+ }
if errors.Is(err, topology.ErrTopologyClosed) {
return ErrClientDisconnected
}
- if de, ok := err.(driver.Error); ok {
+
+ var de driver.Error
+ if errors.As(err, &de) {
return CommandError{
Code: de.Code,
Message: de.Message,
Labels: de.Labels,
Name: de.Name,
- Wrapped: de.Wrapped,
+ Wrapped: err,
Raw: bson.Raw(de.Raw),
+
+ // Set wrappedMsgOnly=true here so that the Code and Message are not
+ // repeated multiple times in the error string. We expect that the
+ // wrapped driver.Error already contains that info in the error
+ // string.
+ wrappedMsgOnly: true,
}
}
- if qe, ok := err.(driver.QueryFailureError); ok {
+
+ var qe driver.QueryFailureError
+ if errors.As(err, &qe) {
// qe.Message is "command failure"
ce := CommandError{
Name: qe.Message,
- Wrapped: qe.Wrapped,
+ Wrapped: err,
Raw: bson.Raw(qe.Response),
+
+ // Don't set wrappedMsgOnly=true here because the code below adds
+ // additional error context that is not provided by the
+ // driver.QueryFailureError. Additionally, driver.QueryFailureError
+ // is only returned when parsing OP_QUERY replies (OP_REPLY), so
+ // it's unlikely this block will ever be run now that MongoDB 3.6 is
+ // no longer supported.
}
dollarErr, err := qe.Response.LookupErr("$err")
@@ -84,25 +132,45 @@ func replaceErrors(err error) error {
return ce
}
- if me, ok := err.(mongocrypt.Error); ok {
- return MongocryptError{Code: me.Code, Message: me.Message}
+
+ var me mongocrypt.Error
+ if errors.As(err, &me) {
+ return MongocryptError{
+ Code: me.Code,
+ Message: me.Message,
+ wrapped: err,
+
+ // Set wrappedMsgOnly=true here so that the Code and Message are not
+ // repeated multiple times in the error string. We expect that the
+ // wrapped mongocrypt.Error already contains that info in the error
+ // string.
+ wrappedMsgOnly: true,
+ }
}
if errors.Is(err, codecutil.ErrNilValue) {
return ErrNilValue
}
- if marshalErr, ok := err.(codecutil.MarshalError); ok {
+ var marshalErr codecutil.MarshalError
+ if errors.As(err, &marshalErr) {
return MarshalError{
Value: marshalErr.Value,
- Err: marshalErr.Err,
+ Err: err,
+
+ // Set wrappedMsgOnly=true here so that the Value is not repeated
+ // multiple times in the error string. We expect that the wrapped
+ // codecutil.MarshalError already contains that info in the error
+ // string.
+ wrappedMsgOnly: true,
}
}
return err
}
-// IsDuplicateKeyError returns true if err is a duplicate key error.
+// IsDuplicateKeyError returns true if err is a duplicate key error. For BulkWriteExceptions,
+// IsDuplicateKeyError returns true if at least one of the errors is a duplicate key error.
func IsDuplicateKeyError(err error) bool {
if se := ServerError(nil); errors.As(err, &se) {
return se.HasErrorCode(11000) || // Duplicate key error.
@@ -120,7 +188,6 @@ func IsDuplicateKeyError(err error) bool {
var timeoutErrs = [...]error{
context.DeadlineExceeded,
driver.ErrDeadlineWouldBeExceeded,
- topology.ErrServerSelectionTimeout,
}
// IsTimeout returns true if err was caused by a timeout. For error chains,
@@ -138,6 +205,9 @@ func IsTimeout(err error) bool {
if errors.As(err, &topology.WaitQueueTimeoutError{}) {
return true
}
+ if errors.As(err, &timeoutError{}) {
+ return true
+ }
if ce := (CommandError{}); errors.As(err, &ce) && ce.IsMaxTimeMSExpiredError() {
return true
}
@@ -157,25 +227,10 @@ func IsTimeout(err error) bool {
return false
}
-// unwrap returns the inner error if err implements Unwrap(), otherwise it returns nil.
-func unwrap(err error) error {
- u, ok := err.(interface {
- Unwrap() error
- })
- if !ok {
- return nil
- }
- return u.Unwrap()
-}
-
// errorHasLabel returns true if err contains the specified label
func errorHasLabel(err error, label string) bool {
- for ; err != nil; err = unwrap(err) {
- if le, ok := err.(LabeledError); ok && le.HasErrorLabel(label) {
- return true
- }
- }
- return false
+ var le LabeledError
+ return errors.As(err, &le) && le.HasErrorLabel(label)
}
// IsNetworkError returns true if err is a network error
@@ -183,18 +238,68 @@ func IsNetworkError(err error) bool {
return errorHasLabel(err, "NetworkError")
}
-// MongocryptError represents an libmongocrypt error during client-side encryption.
+// MarshalError is returned when attempting to marshal a value into a document
+// results in an error.
+type MarshalError struct {
+ Value any
+ Err error
+
+ // If wrappedMsgOnly is true, Error() only returns the error message from
+ // the "Err" error.
+ //
+ // This is typically only set by the wrapErrors function, which uses
+ // MarshalError to wrap codecutil.MarshalError, allowing users to access the
+ // "Value" from the underlying error but preventing duplication in the error
+ // string.
+ wrappedMsgOnly bool
+}
+
+// Error implements the error interface.
+func (me MarshalError) Error() string {
+ // If the MarshalError was created with wrappedMsgOnly=true, only return the
+ // error from the wrapped error. See the MarshalError.wrappedMsgOnly docs
+ // for more info.
+ if me.wrappedMsgOnly {
+ return me.Err.Error()
+ }
+
+ return fmt.Sprintf("cannot marshal type %s to a BSON Document: %v", reflect.TypeOf(me.Value), me.Err)
+}
+
+func (me MarshalError) Unwrap() error { return me.Err }
+
+// MongocryptError represents an libmongocrypt error during in-use encryption.
type MongocryptError struct {
Code int32
Message string
+ wrapped error
+
+ // If wrappedMsgOnly is true, Error() only returns the error message from
+ // the "wrapped" error.
+ //
+ // This is typically only set by the wrapErrors function, which uses
+ // MarshalError to wrap mongocrypt.Error, allowing users to access the
+ // "Code" and "Message" from the underlying error but preventing duplication
+ // in the error string.
+ wrappedMsgOnly bool
}
// Error implements the error interface.
func (m MongocryptError) Error() string {
+ // If the MongocryptError was created with wrappedMsgOnly=true, only return
+ // the error from the wrapped error. See the MongocryptError.wrappedMsgOnly
+ // docs for more info.
+ if m.wrappedMsgOnly {
+ return m.wrapped.Error()
+ }
+
return fmt.Sprintf("mongocrypt error %d: %v", m.Code, m.Message)
}
-// EncryptionKeyVaultError represents an error while communicating with the key vault collection during client-side
+// Unwrap returns the underlying error.
+func (m MongocryptError) Unwrap() error { return m.wrapped }
+
+// EncryptionKeyVaultError represents an error while communicating with the key vault collection during in-use
// encryption.
type EncryptionKeyVaultError struct {
Wrapped error
@@ -210,7 +315,7 @@ func (ekve EncryptionKeyVaultError) Unwrap() error {
return ekve.Wrapped
}
-// MongocryptdError represents an error while communicating with mongocryptd during client-side encryption.
+// MongocryptdError represents an error while communicating with mongocryptd during in-use encryption.
type MongocryptdError struct {
Wrapped error
}
@@ -232,6 +337,12 @@ type LabeledError interface {
HasErrorLabel(string) bool
}
+type errorCoder interface {
+ ErrorCodes() []int
+}
+
+var _ errorCoder = ServerError(nil)
+
// ServerError is the interface implemented by errors returned from the server. Custom implementations of this
// interface should not be used in production.
type ServerError interface {
@@ -243,13 +354,33 @@ type ServerError interface {
// HasErrorCodeWithMessage returns true if any of the contained errors have the specified code and message.
HasErrorCodeWithMessage(int, string) bool
+ // ErrorCodes returns all error codes (unsorted) in the server’s response.
+ // This would include nested errors (e.g., write concern errors) for
+ // supporting implementations (e.g., BulkWriteException) as well as the
+ // top-level error code.
+ ErrorCodes() []int
+
serverError()
}
-var _ ServerError = CommandError{}
-var _ ServerError = WriteError{}
-var _ ServerError = WriteException{}
-var _ ServerError = BulkWriteException{}
+func hasErrorCode(srvErr ServerError, code int) bool {
+ for _, srvErrCode := range srvErr.ErrorCodes() {
+ if code == srvErrCode {
+ return true
+ }
+ }
+
+ return false
+}
+
+var (
+ _ ServerError = CommandError{}
+ _ ServerError = WriteError{}
+ _ ServerError = WriteException{}
+ _ ServerError = BulkWriteException{}
+)
+
+var _ error = ClientBulkWriteException{}
// CommandError represents a server error during execution of a command. This can be returned by any operation.
type CommandError struct {
@@ -259,14 +390,38 @@ type CommandError struct {
Name string // A human-readable name corresponding to the error code
Wrapped error // The underlying error, if one exists.
Raw bson.Raw // The original server response containing the error.
+
+ // If wrappedMsgOnly is true, Error() only returns the error message from
+ // the "Wrapped" error.
+ //
+ // This is typically only set by the wrapErrors function, which uses
+ // CommandError to wrap driver.Error, allowing users to access the "Code",
+ // "Message", "Labels", "Name", and "Raw" from the underlying error but
+ // preventing duplication in the error string.
+ wrappedMsgOnly bool
}
// Error implements the error interface.
func (e CommandError) Error() string {
+ // If the CommandError was created with wrappedMsgOnly=true, only return the
+ // error from the wrapped error. See the CommandError.wrappedMsgOnly docs
+ // for more info.
+ if e.wrappedMsgOnly {
+ return e.Wrapped.Error()
+ }
+
+ var msg string
if e.Name != "" {
- return fmt.Sprintf("(%v) %v", e.Name, e.Message)
+ msg += fmt.Sprintf("(%v)", e.Name)
+ }
+ if e.Message != "" {
+ msg += " " + e.Message
}
- return e.Message
+ if e.Wrapped != nil {
+ msg += ": " + e.Wrapped.Error()
+ }
+
+ return msg
}
// Unwrap returns the underlying error.
@@ -279,13 +434,16 @@ func (e CommandError) HasErrorCode(code int) bool {
return int(e.Code) == code
}
+// ErrorCodes returns a list of error codes returned by the server.
+func (e CommandError) ErrorCodes() []int {
+ return []int{int(e.Code)}
+}
+
// HasErrorLabel returns true if the error contains the specified label.
func (e CommandError) HasErrorLabel(label string) bool {
- if e.Labels != nil {
- for _, l := range e.Labels {
- if l == label {
- return true
- }
+ for _, l := range e.Labels {
+ if l == label {
+ return true
}
}
return false
@@ -336,6 +494,11 @@ func (we WriteError) HasErrorCode(code int) bool {
return we.Code == code
}
+// ErrorCodes returns a list of error codes returned by the server.
+func (we WriteError) ErrorCodes() []int {
+ return []int{we.Code}
+}
+
// HasErrorLabel returns true if the error contains the specified label. WriteErrors do not contain labels,
// so we always return false.
func (we WriteError) HasErrorLabel(string) bool {
@@ -442,24 +605,28 @@ func (mwe WriteException) Error() string {
// HasErrorCode returns true if the error has the specified code.
func (mwe WriteException) HasErrorCode(code int) bool {
- if mwe.WriteConcernError != nil && mwe.WriteConcernError.Code == code {
- return true
+ return hasErrorCode(mwe, code)
+}
+
+// ErrorCodes returns a list of error codes returned by the server.
+func (mwe WriteException) ErrorCodes() []int {
+ errorCodes := []int{}
+ for _, writeError := range mwe.WriteErrors {
+ errorCodes = append(errorCodes, writeError.Code)
}
- for _, we := range mwe.WriteErrors {
- if we.Code == code {
- return true
- }
+
+ if mwe.WriteConcernError != nil {
+ errorCodes = append(errorCodes, mwe.WriteConcernError.Code)
}
- return false
+
+ return errorCodes
}
// HasErrorLabel returns true if the error contains the specified label.
func (mwe WriteException) HasErrorLabel(label string) bool {
- if mwe.Labels != nil {
- for _, l := range mwe.Labels {
- if l == label {
- return true
- }
+ for _, l := range mwe.Labels {
+ if l == label {
+ return true
}
}
return false
@@ -556,24 +723,28 @@ func (bwe BulkWriteException) Error() string {
// HasErrorCode returns true if any of the errors have the specified code.
func (bwe BulkWriteException) HasErrorCode(code int) bool {
- if bwe.WriteConcernError != nil && bwe.WriteConcernError.Code == code {
- return true
+ return hasErrorCode(bwe, code)
+}
+
+// ErrorCodes returns a list of error codes returned by the server.
+func (bwe BulkWriteException) ErrorCodes() []int {
+ errorCodes := []int{}
+ for _, writeError := range bwe.WriteErrors {
+ errorCodes = append(errorCodes, writeError.Code)
}
- for _, we := range bwe.WriteErrors {
- if we.Code == code {
- return true
- }
+
+ if bwe.WriteConcernError != nil {
+ errorCodes = append(errorCodes, bwe.WriteConcernError.Code)
}
- return false
+
+ return errorCodes
}
// HasErrorLabel returns true if the error contains the specified label.
func (bwe BulkWriteException) HasErrorLabel(label string) bool {
- if bwe.Labels != nil {
- for _, l := range bwe.Labels {
- if l == label {
- return true
- }
+ for _, l := range bwe.Labels {
+ if l == label {
+ return true
}
}
return false
@@ -609,6 +780,85 @@ func (bwe BulkWriteException) HasErrorCodeWithMessage(code int, message string)
// serverError implements the ServerError interface.
func (bwe BulkWriteException) serverError() {}
+// ClientBulkWriteException is the error type returned by ClientBulkWrite operations.
+type ClientBulkWriteException struct {
+ // A top-level error that occurred when attempting to communicate with the server
+ // or execute the bulk write. This value may not be populated if the exception was
+ // thrown due to errors occurring on individual writes.
+ WriteError *WriteError
+
+ // The write concern errors that occurred.
+ WriteConcernErrors []WriteConcernError
+
+ // The write errors that occurred during individual operation execution.
+ // This map will contain at most one entry if the bulk write was ordered.
+ WriteErrors map[int]WriteError
+
+ // The results of any successful operations that were performed before the error
+ // was encountered.
+ PartialResult *ClientBulkWriteResult
+}
+
+// Error implements the error interface.
+func (bwe ClientBulkWriteException) Error() string {
+ causes := make([]string, 0, 4)
+ if bwe.WriteError != nil {
+ causes = append(causes, "top level error: "+bwe.WriteError.Error())
+ }
+ if len(bwe.WriteConcernErrors) > 0 {
+ errs := make([]error, len(bwe.WriteConcernErrors))
+ for i := 0; i < len(bwe.WriteConcernErrors); i++ {
+ errs[i] = bwe.WriteConcernErrors[i]
+ }
+ causes = append(causes, "write concern errors: "+joinBatchErrors(errs))
+ }
+ if len(bwe.WriteErrors) > 0 {
+ errs := make([]error, 0, len(bwe.WriteErrors))
+ for _, v := range bwe.WriteErrors {
+ errs = append(errs, v)
+ }
+ causes = append(causes, "write errors: "+joinBatchErrors(errs))
+ }
+ if bwe.PartialResult != nil {
+ causes = append(causes, fmt.Sprintf("result: %v", *bwe.PartialResult))
+ }
+
+ message := "bulk write exception: "
+ if len(causes) == 0 {
+ return message + "no causes"
+ }
+ return "bulk write exception: " + strings.Join(causes, ", ")
+}
+
+var _ LabeledError = timeoutError{}
+
+// timeoutError represents an error that occurred due to a timeout.
+type timeoutError struct {
+ Wrapped error
+}
+
+// Error implements the error interface.
+func (e timeoutError) Error() string {
+ const timeoutMsg = "operation timed out"
+ if e.Wrapped == nil {
+ return timeoutMsg
+ }
+ return fmt.Sprintf("%s: %v", timeoutMsg, e.Wrapped.Error())
+}
+
+// Unwrap returns the underlying error.
+func (e timeoutError) Unwrap() error {
+ return e.Wrapped
+}
+
+// HasErrorLabel returns true if the error contains the specified label.
+func (e timeoutError) HasErrorLabel(label string) bool {
+ if le := LabeledError(nil); errors.As(e.Wrapped, &le) {
+ return le.HasErrorLabel(label)
+ }
+ return false
+}
+
// returnResult is used to determine if a function calling processWriteError should return
// the result or return nil. Since the processWriteError function is used by many different
// methods, both *One and *Many, we need a way to differentiate if the method should return
@@ -619,34 +869,45 @@ const (
rrNone returnResult = 1 << iota // None means do not return the result ever.
rrOne // One means return the result if this was called by a *One method.
rrMany // Many means return the result is this was called by a *Many method.
+ rrUnacknowledged
- rrAll returnResult = rrOne | rrMany // All means always return the result.
+ rrAll returnResult = rrOne | rrMany // All means always return the result.
+ rrAllUnacknowledged returnResult = rrAll | rrUnacknowledged // All + unacknowledged write
)
+func (rr returnResult) isAcknowledged() bool {
+ return rr&rrUnacknowledged == 0
+}
+
// processWriteError handles processing the result of a write operation. If the retrunResult matches
// the calling method's type, it should return the result object in addition to the error.
// This function will wrap the errors from other packages and return them as errors from this package.
//
// WriteConcernError will be returned over WriteErrors if both are present.
func processWriteError(err error) (returnResult, error) {
- switch {
- case errors.Is(err, driver.ErrUnacknowledgedWrite):
- return rrAll, ErrUnacknowledgedWrite
- case err != nil:
- switch tt := err.(type) {
- case driver.WriteCommandError:
- return rrMany, WriteException{
- WriteConcernError: convertDriverWriteConcernError(tt.WriteConcernError),
- WriteErrors: writeErrorsFromDriverWriteErrors(tt.WriteErrors),
- Labels: tt.Labels,
- Raw: bson.Raw(tt.Raw),
- }
- default:
- return rrNone, replaceErrors(err)
- }
- default:
+ if err == nil {
return rrAll, nil
}
+ // Do not propagate the acknowledgement sentinel error. For DDL commands,
+ // (creating indexes, dropping collections, etc) acknowledgement should be
+ // ignored. For non-DDL write commands (insert, update, etc), acknowledgement
+ // should be be propagated at the result-level: e.g.,
+ // SingleResult.Acknowledged.
+ if errors.Is(err, driver.ErrUnacknowledgedWrite) {
+ return rrAllUnacknowledged, nil
+ }
+
+ var wce driver.WriteCommandError
+ if !errors.As(err, &wce) {
+ return rrNone, wrapErrors(err)
+ }
+
+ return rrMany, WriteException{
+ WriteConcernError: convertDriverWriteConcernError(wce.WriteConcernError),
+ WriteErrors: writeErrorsFromDriverWriteErrors(wce.WriteErrors),
+ Labels: wce.Labels,
+ Raw: bson.Raw(wce.Raw),
+ }
}
// batchErrorsTargetLength is the target length of error messages returned by batch operation
@@ -680,3 +941,23 @@ func joinBatchErrors(errs []error) string {
return buf.String()
}
+
+// ErrorCodes returns the list of server error codes contained in err.
+func ErrorCodes(err error) []int {
+ if err == nil {
+ return nil
+ }
+
+ var ec errorCoder
+ // First check if the error is already wrapped (common case)
+ if errors.As(err, &ec) {
+ return ec.ErrorCodes()
+ }
+
+ // Only wrap if necessary (for internal errors)
+ if errors.As(wrapErrors(err), &ec) {
+ return ec.ErrorCodes()
+ }
+
+ return []int{}
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_bucket.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_bucket.go
new file mode 100644
index 000000000..742307702
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_bucket.go
@@ -0,0 +1,585 @@
+// 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 mongo
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+// TODO: add sessions options
+
+// DefaultGridFSChunkSize is the default size of each file chunk.
+const DefaultGridFSChunkSize int32 = 255 * 1024 // 255 KiB
+
+// ErrFileNotFound occurs if a user asks to download a file with a file ID that isn't found in the files collection.
+var ErrFileNotFound = errors.New("file with given parameters not found")
+
+// ErrMissingGridFSChunkSize occurs when downloading a file if the files
+// collection document is missing the "chunkSize" field.
+var ErrMissingGridFSChunkSize = errors.New("files collection document does not contain a 'chunkSize' field")
+
+// GridFSBucket represents a GridFS bucket.
+type GridFSBucket struct {
+ db *Database
+ chunksColl *Collection // collection to store file chunks
+ filesColl *Collection // collection to store file metadata
+
+ name string
+ chunkSize int32
+ wc *writeconcern.WriteConcern
+ rc *readconcern.ReadConcern
+ rp *readpref.ReadPref
+
+ firstWriteDone bool
+ readBuf []byte
+ writeBuf []byte
+}
+
+// upload contains options to upload a file to a bucket.
+type upload struct {
+ chunkSize int32
+ metadata bson.D
+}
+
+// OpenUploadStream creates a file ID new upload stream for a file given the
+// filename.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) OpenUploadStream(
+ ctx context.Context,
+ filename string,
+ opts ...options.Lister[options.GridFSUploadOptions],
+) (*GridFSUploadStream, error) {
+ return b.OpenUploadStreamWithID(ctx, bson.NewObjectID(), filename, opts...)
+}
+
+// OpenUploadStreamWithID creates a new upload stream for a file given the file
+// ID and filename.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) OpenUploadStreamWithID(
+ ctx context.Context,
+ fileID any,
+ filename string,
+ opts ...options.Lister[options.GridFSUploadOptions],
+) (*GridFSUploadStream, error) {
+ ctx, cancel := csot.WithTimeout(ctx, b.db.client.timeout)
+
+ if err := b.checkFirstWrite(ctx); err != nil {
+ return nil, err
+ }
+
+ upload, err := b.parseGridFSUploadOptions(opts...)
+ if err != nil {
+ return nil, err
+ }
+
+ return newUploadStream(ctx, cancel, upload, fileID, filename, b.chunksColl, b.filesColl), nil
+}
+
+// UploadFromStream creates a fileID and uploads a file given a source stream.
+//
+// If this upload requires a custom write deadline to be set on the bucket, it
+// cannot be done concurrently with other write operations operations on this
+// bucket that also require a custom deadline.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) UploadFromStream(
+ ctx context.Context,
+ filename string,
+ source io.Reader,
+ opts ...options.Lister[options.GridFSUploadOptions],
+) (bson.ObjectID, error) {
+ fileID := bson.NewObjectID()
+ err := b.UploadFromStreamWithID(ctx, fileID, filename, source, opts...)
+ return fileID, err
+}
+
+// UploadFromStreamWithID uploads a file given a source stream.
+//
+// If this upload requires a custom write deadline to be set on the bucket, it
+// cannot be done concurrently with other write operations operations on this
+// bucket that also require a custom deadline.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) UploadFromStreamWithID(
+ ctx context.Context,
+ fileID any,
+ filename string,
+ source io.Reader,
+ opts ...options.Lister[options.GridFSUploadOptions],
+) error {
+ ctx, cancel := csot.WithTimeout(ctx, b.db.client.timeout)
+ defer cancel()
+
+ us, err := b.OpenUploadStreamWithID(ctx, fileID, filename, opts...)
+ if err != nil {
+ return err
+ }
+
+ for {
+ n, err := source.Read(b.readBuf)
+ if err != nil && err != io.EOF {
+ _ = us.Abort() // upload considered aborted if source stream returns an error
+ return err
+ }
+
+ if n > 0 {
+ _, err := us.Write(b.readBuf[:n])
+ if err != nil {
+ return err
+ }
+ }
+
+ if n == 0 || err == io.EOF {
+ break
+ }
+ }
+
+ return us.Close()
+}
+
+// OpenDownloadStream creates a stream from which the contents of the file can
+// be read.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) OpenDownloadStream(ctx context.Context, fileID any) (*GridFSDownloadStream, error) {
+ return b.openDownloadStream(ctx, bson.D{{"_id", fileID}})
+}
+
+// DownloadToStream downloads the file with the specified fileID and writes it
+// to the provided io.Writer. Returns the number of bytes written to the stream
+// and an error, or nil if there was no error.
+//
+// If this download requires a custom read deadline to be set on the bucket, it
+// cannot be done concurrently with other read operations operations on this
+// bucket that also require a custom deadline.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) DownloadToStream(ctx context.Context, fileID any, stream io.Writer) (int64, error) {
+ ds, err := b.OpenDownloadStream(ctx, fileID)
+ if err != nil {
+ return 0, err
+ }
+
+ return b.downloadToStream(ds, stream)
+}
+
+// OpenDownloadStreamByName opens a download stream for the file with the given
+// filename.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) OpenDownloadStreamByName(
+ ctx context.Context,
+ filename string,
+ opts ...options.Lister[options.GridFSNameOptions],
+) (*GridFSDownloadStream, error) {
+ args, err := mongoutil.NewOptions[options.GridFSNameOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ numSkip := options.DefaultRevision
+ if args.Revision != nil {
+ numSkip = *args.Revision
+ }
+
+ var sortOrder int32 = 1
+
+ if numSkip < 0 {
+ sortOrder = -1
+ numSkip = (-1 * numSkip) - 1
+ }
+
+ findOpts := options.FindOne().SetSkip(int64(numSkip)).SetSort(bson.D{{"uploadDate", sortOrder}})
+
+ return b.openDownloadStream(ctx, bson.D{{"filename", filename}}, findOpts)
+}
+
+// DownloadToStreamByName downloads the file with the given name to the given
+// io.Writer.
+//
+// If this download requires a custom read deadline to be set on the bucket, it
+// cannot be done concurrently with other read operations operations on this
+// bucket that also require a custom deadline.
+//
+// The context provided to this method controls the entire lifetime of an
+// upload stream io.Writer. If the context does set a deadline, then the
+// client-level timeout will be used to cap the lifetime of the stream.
+func (b *GridFSBucket) DownloadToStreamByName(
+ ctx context.Context,
+ filename string,
+ stream io.Writer,
+ opts ...options.Lister[options.GridFSNameOptions],
+) (int64, error) {
+ ds, err := b.OpenDownloadStreamByName(ctx, filename, opts...)
+ if err != nil {
+ return 0, err
+ }
+
+ return b.downloadToStream(ds, stream)
+}
+
+// Delete deletes all chunks and metadata associated with the file with the
+// given file ID and runs the underlying delete operations with the provided
+// context.
+func (b *GridFSBucket) Delete(ctx context.Context, fileID any) error {
+ ctx, cancel := csot.WithTimeout(ctx, b.db.client.timeout)
+ defer cancel()
+
+ res, err := b.filesColl.DeleteOne(ctx, bson.D{{"_id", fileID}})
+ if err == nil && res.DeletedCount == 0 {
+ err = ErrFileNotFound
+ }
+ if err != nil {
+ _ = b.deleteChunks(ctx, fileID) // Can attempt to delete chunks even if no docs in files collection matched.
+ return err
+ }
+
+ return b.deleteChunks(ctx, fileID)
+}
+
+// Find returns the files collection documents that match the given filter and
+// runs the underlying find query with the provided context.
+func (b *GridFSBucket) Find(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.GridFSFindOptions],
+) (*Cursor, error) {
+ args, err := mongoutil.NewOptions[options.GridFSFindOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ find := options.Find()
+ if args.AllowDiskUse != nil {
+ find.SetAllowDiskUse(*args.AllowDiskUse)
+ }
+ if args.BatchSize != nil {
+ find.SetBatchSize(*args.BatchSize)
+ }
+ if args.Limit != nil {
+ find.SetLimit(int64(*args.Limit))
+ }
+ if args.NoCursorTimeout != nil {
+ find.SetNoCursorTimeout(*args.NoCursorTimeout)
+ }
+ if args.Skip != nil {
+ find.SetSkip(int64(*args.Skip))
+ }
+ if args.Sort != nil {
+ find.SetSort(args.Sort)
+ }
+
+ return b.filesColl.Find(ctx, filter, find)
+}
+
+// Rename renames the stored file with the specified file ID.
+func (b *GridFSBucket) Rename(ctx context.Context, fileID any, newFilename string) error {
+ res, err := b.filesColl.UpdateOne(ctx,
+ bson.D{{"_id", fileID}},
+ bson.D{{"$set", bson.D{{"filename", newFilename}}}},
+ )
+ if err != nil {
+ return err
+ }
+
+ if res.MatchedCount == 0 {
+ return ErrFileNotFound
+ }
+
+ return nil
+}
+
+// Drop drops the files and chunks collections associated with this bucket and
+// runs the drop operations with the provided context.
+func (b *GridFSBucket) Drop(ctx context.Context) error {
+ ctx, cancel := csot.WithTimeout(ctx, b.db.client.timeout)
+ defer cancel()
+
+ err := b.filesColl.Drop(ctx)
+ if err != nil {
+ return err
+ }
+
+ return b.chunksColl.Drop(ctx)
+}
+
+// GetFilesCollection returns a handle to the collection that stores the file documents for this bucket.
+func (b *GridFSBucket) GetFilesCollection() *Collection {
+ return b.filesColl
+}
+
+// GetChunksCollection returns a handle to the collection that stores the file chunks for this bucket.
+func (b *GridFSBucket) GetChunksCollection() *Collection {
+ return b.chunksColl
+}
+
+func (b *GridFSBucket) openDownloadStream(
+ ctx context.Context,
+ filter any,
+ opts ...options.Lister[options.FindOneOptions],
+) (*GridFSDownloadStream, error) {
+ ctx, cancel := csot.WithTimeout(ctx, b.db.client.timeout)
+
+ result := b.filesColl.FindOne(ctx, filter, opts...)
+
+ // Unmarshal the data into a File instance, which can be passed to newGridFSDownloadStream. The _id value has to be
+ // parsed out separately because "_id" will not match the File.ID field and we want to avoid exposing BSON tags
+ // in the File type. After parsing it, use RawValue.Unmarshal to ensure File.ID is set to the appropriate value.
+ var resp findFileResponse
+ if err := result.Decode(&resp); err != nil {
+ if errors.Is(err, ErrNoDocuments) {
+ return nil, ErrFileNotFound
+ }
+
+ return nil, fmt.Errorf("error decoding files collection document: %w", err)
+ }
+
+ foundFile := newFileFromResponse(resp)
+
+ if foundFile.Length == 0 {
+ return newGridFSDownloadStream(ctx, cancel, nil, foundFile.ChunkSize, foundFile), nil
+ }
+
+ // For a file with non-zero length, chunkSize must exist so we know what size to expect when downloading chunks.
+ if foundFile.ChunkSize == 0 {
+ return nil, ErrMissingGridFSChunkSize
+ }
+
+ chunksCursor, err := b.findChunks(ctx, foundFile.ID)
+ if err != nil {
+ return nil, err
+ }
+
+ // The chunk size can be overridden for individual files, so the expected chunk size should be the "chunkSize"
+ // field from the files collection document, not the bucket's chunk size.
+ return newGridFSDownloadStream(ctx, cancel, chunksCursor, foundFile.ChunkSize, foundFile), nil
+}
+
+func (b *GridFSBucket) downloadToStream(ds *GridFSDownloadStream, stream io.Writer) (int64, error) {
+ copied, err := io.Copy(stream, ds)
+ if err != nil {
+ _ = ds.Close()
+ return 0, err
+ }
+
+ return copied, ds.Close()
+}
+
+func (b *GridFSBucket) deleteChunks(ctx context.Context, fileID any) error {
+ _, err := b.chunksColl.DeleteMany(ctx, bson.D{{"files_id", fileID}})
+ return err
+}
+
+func (b *GridFSBucket) findChunks(ctx context.Context, fileID any) (*Cursor, error) {
+ chunksCursor, err := b.chunksColl.Find(ctx,
+ bson.D{{"files_id", fileID}},
+ options.Find().SetSort(bson.D{{"n", 1}})) // sort by chunk index
+ if err != nil {
+ return nil, err
+ }
+
+ return chunksCursor, nil
+}
+
+// returns true if the 2 index documents are equal
+func numericalIndexDocsEqual(expected, actual bsoncore.Document) (bool, error) {
+ if bytes.Equal(expected, actual) {
+ return true, nil
+ }
+
+ actualElems, err := actual.Elements()
+ if err != nil {
+ return false, err
+ }
+ expectedElems, err := expected.Elements()
+ if err != nil {
+ return false, err
+ }
+
+ if len(actualElems) != len(expectedElems) {
+ return false, nil
+ }
+
+ for idx, expectedElem := range expectedElems {
+ actualElem := actualElems[idx]
+ if actualElem.Key() != expectedElem.Key() {
+ return false, nil
+ }
+
+ actualVal := actualElem.Value()
+ expectedVal := expectedElem.Value()
+ actualInt, actualOK := actualVal.AsInt64OK()
+ expectedInt, expectedOK := expectedVal.AsInt64OK()
+
+ // GridFS indexes always have numeric values
+ if !actualOK || !expectedOK {
+ return false, nil
+ }
+
+ if actualInt != expectedInt {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+// Create an index if it doesn't already exist
+func createNumericalIndexIfNotExists(ctx context.Context, iv IndexView, model IndexModel) error {
+ c, err := iv.List(ctx)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = c.Close(ctx)
+ }()
+
+ modelKeysBytes, err := bson.Marshal(model.Keys)
+ if err != nil {
+ return err
+ }
+ modelKeysDoc := bsoncore.Document(modelKeysBytes)
+
+ for c.Next(ctx) {
+ keyElem, err := c.Current.LookupErr("key")
+ if err != nil {
+ return err
+ }
+
+ keyElemDoc := keyElem.Document()
+
+ found, err := numericalIndexDocsEqual(modelKeysDoc, bsoncore.Document(keyElemDoc))
+ if err != nil {
+ return err
+ }
+ if found {
+ return nil
+ }
+ }
+
+ _, err = iv.CreateOne(ctx, model)
+ return err
+}
+
+// create indexes on the files and chunks collection if needed
+func (b *GridFSBucket) createIndexes(ctx context.Context) error {
+ // must use primary read pref mode to check if files coll empty
+ cloned := b.filesColl.Clone(options.Collection().SetReadPreference(readpref.Primary()))
+
+ docRes := cloned.FindOne(ctx, bson.D{}, options.FindOne().SetProjection(bson.D{{"_id", 1}}))
+
+ _, err := docRes.Raw()
+ if !errors.Is(err, ErrNoDocuments) {
+ // nil, or error that occurred during the FindOne operation
+ return err
+ }
+
+ filesIv := b.filesColl.Indexes()
+ chunksIv := b.chunksColl.Indexes()
+
+ filesModel := IndexModel{
+ Keys: bson.D{
+ {"filename", int32(1)},
+ {"uploadDate", int32(1)},
+ },
+ }
+
+ chunksModel := IndexModel{
+ Keys: bson.D{
+ {"files_id", int32(1)},
+ {"n", int32(1)},
+ },
+ Options: options.Index().SetUnique(true),
+ }
+
+ if err = createNumericalIndexIfNotExists(ctx, filesIv, filesModel); err != nil {
+ return err
+ }
+ return createNumericalIndexIfNotExists(ctx, chunksIv, chunksModel)
+}
+
+func (b *GridFSBucket) checkFirstWrite(ctx context.Context) error {
+ if !b.firstWriteDone {
+ // before the first write operation, must determine if files collection is empty
+ // if so, create indexes if they do not already exist
+
+ if err := b.createIndexes(ctx); err != nil {
+ return err
+ }
+ b.firstWriteDone = true
+ }
+
+ return nil
+}
+
+func (b *GridFSBucket) parseGridFSUploadOptions(opts ...options.Lister[options.GridFSUploadOptions]) (*upload, error) {
+ upload := &upload{
+ chunkSize: b.chunkSize, // upload chunk size defaults to bucket's value
+ }
+
+ args, err := mongoutil.NewOptions[options.GridFSUploadOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ if args.ChunkSizeBytes != nil {
+ upload.chunkSize = *args.ChunkSizeBytes
+ }
+ if args.Registry == nil {
+ args.Registry = defaultRegistry
+ }
+ if args.Metadata != nil {
+ // TODO(GODRIVER-2726): Replace with marshal() and unmarshal() once the
+ // TODO gridfs package is merged into the mongo package.
+ buf := new(bytes.Buffer)
+ vw := bson.NewDocumentWriter(buf)
+ enc := bson.NewEncoder(vw)
+ enc.SetRegistry(args.Registry)
+ err := enc.Encode(args.Metadata)
+ if err != nil {
+ return nil, err
+ }
+ var doc bson.D
+ dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(buf.Bytes())))
+ dec.SetRegistry(args.Registry)
+ unMarErr := dec.Decode(&doc)
+ if unMarErr != nil {
+ return nil, unMarErr
+ }
+ upload.metadata = doc
+ }
+
+ return upload, nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_download_stream.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_download_stream.go
new file mode 100644
index 000000000..c7967b748
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_download_stream.go
@@ -0,0 +1,299 @@
+// 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 mongo
+
+import (
+ "context"
+ "errors"
+ "io"
+ "math"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+)
+
+// ErrMissingChunk indicates that the number of chunks read from the server is
+// less than expected. This error is specific to GridFS operations.
+var ErrMissingChunk = errors.New("EOF missing one or more chunks")
+
+// ErrWrongSize is used when the chunk retrieved from the server does not have
+// the expected size. This error is specific to GridFS operations.
+var ErrWrongSize = errors.New("chunk size does not match expected size")
+
+var errNoMoreChunks = errors.New("no more chunks remaining")
+
+// GridFSDownloadStream is a io.Reader that can be used to download a file from a GridFS bucket.
+type GridFSDownloadStream struct {
+ numChunks int32
+ chunkSize int32
+ cursor *Cursor
+ done bool
+ closed bool
+ buffer []byte // store up to 1 chunk if the user provided buffer isn't big enough
+ bufferStart int
+ bufferEnd int
+ expectedChunk int32 // index of next expected chunk
+ fileLen int64
+ ctx context.Context
+ cancel context.CancelFunc
+
+ // The pointer returned by GetFile. This should not be used in the actual GridFSDownloadStream code outside of the
+ // newGridFSDownloadStream constructor because the values can be mutated by the user after calling GetFile. Instead,
+ // any values needed in the code should be stored separately and copied over in the constructor.
+ file *GridFSFile
+}
+
+// GridFSFile represents a file stored in GridFS. This type can be used to
+// access file information when downloading using the
+// GridFSDownloadStream.GetFile method.
+type GridFSFile struct {
+ // ID is the file's ID. This will match the file ID specified when uploading the file. If an upload helper that
+ // does not require a file ID was used, this field will be a bson.ObjectID.
+ ID any
+
+ // Length is the length of this file in bytes.
+ Length int64
+
+ // ChunkSize is the maximum number of bytes for each chunk in this file.
+ ChunkSize int32
+
+ // UploadDate is the time this file was added to GridFS in UTC. This field is set by the driver and is not configurable.
+ // The Metadata field can be used to store a custom date.
+ UploadDate time.Time
+
+ // Name is the name of this file.
+ Name string
+
+ // Metadata is additional data that was specified when creating this file. This field can be unmarshalled into a
+ // custom type using the bson.Unmarshal family of functions.
+ Metadata bson.Raw
+}
+
+var _ bson.Unmarshaler = &GridFSFile{}
+
+// findFileResponse is a temporary type used to unmarshal documents from the
+// files collection and can be transformed into a File instance. This type
+// exists to avoid adding BSON struct tags to the exported File type.
+type findFileResponse struct {
+ ID any `bson:"_id"`
+ Length int64 `bson:"length"`
+ ChunkSize int32 `bson:"chunkSize"`
+ UploadDate time.Time `bson:"uploadDate"`
+ Name string `bson:"filename"`
+ Metadata bson.Raw `bson:"metadata"`
+}
+
+func newFileFromResponse(resp findFileResponse) *GridFSFile {
+ return &GridFSFile{
+ ID: resp.ID,
+ Length: resp.Length,
+ ChunkSize: resp.ChunkSize,
+ UploadDate: resp.UploadDate,
+ Name: resp.Name,
+ Metadata: resp.Metadata,
+ }
+}
+
+// UnmarshalBSON implements the bson.Unmarshaler interface.
+func (f *GridFSFile) UnmarshalBSON(data []byte) error {
+ var temp findFileResponse
+ if err := bson.Unmarshal(data, &temp); err != nil {
+ return err
+ }
+
+ f.ID = temp.ID
+ f.Length = temp.Length
+ f.ChunkSize = temp.ChunkSize
+ f.UploadDate = temp.UploadDate
+ f.Name = temp.Name
+ f.Metadata = temp.Metadata
+
+ return nil
+}
+
+func newGridFSDownloadStream(
+ ctx context.Context,
+ cancel context.CancelFunc,
+ cursor *Cursor,
+ chunkSize int32,
+ file *GridFSFile,
+) *GridFSDownloadStream {
+ numChunks := int32(math.Ceil(float64(file.Length) / float64(chunkSize)))
+
+ return &GridFSDownloadStream{
+ numChunks: numChunks,
+ chunkSize: chunkSize,
+ cursor: cursor,
+ buffer: make([]byte, chunkSize),
+ done: cursor == nil,
+ fileLen: file.Length,
+ file: file,
+ ctx: ctx,
+ cancel: cancel,
+ }
+}
+
+// Close closes this download stream.
+func (ds *GridFSDownloadStream) Close() error {
+ defer func() {
+ if ds.cancel != nil {
+ ds.cancel()
+ }
+ }()
+
+ if ds.closed {
+ return ErrStreamClosed
+ }
+
+ ds.closed = true
+ if ds.cursor != nil {
+ return ds.cursor.Close(context.Background())
+ }
+ return nil
+}
+
+// Read reads the file from the server and writes it to a destination byte slice.
+func (ds *GridFSDownloadStream) Read(p []byte) (int, error) {
+ if ds.closed {
+ return 0, ErrStreamClosed
+ }
+
+ if ds.done {
+ return 0, io.EOF
+ }
+
+ bytesCopied := 0
+ var err error
+ for bytesCopied < len(p) {
+ if ds.bufferStart >= ds.bufferEnd {
+ // Buffer is empty and can load in data from new chunk.
+ err = ds.fillBuffer(ds.ctx)
+ if err != nil {
+ if errors.Is(err, errNoMoreChunks) {
+ if bytesCopied == 0 {
+ ds.done = true
+ return 0, io.EOF
+ }
+ return bytesCopied, nil
+ }
+ return bytesCopied, err
+ }
+ }
+
+ copied := copy(p[bytesCopied:], ds.buffer[ds.bufferStart:ds.bufferEnd])
+
+ bytesCopied += copied
+ ds.bufferStart += copied
+ }
+
+ return len(p), nil
+}
+
+// Skip skips a given number of bytes in the file.
+func (ds *GridFSDownloadStream) Skip(skip int64) (int64, error) {
+ if ds.closed {
+ return 0, ErrStreamClosed
+ }
+
+ if ds.done {
+ return 0, nil
+ }
+
+ var skipped int64
+ var err error
+
+ for skipped < skip {
+ if ds.bufferStart >= ds.bufferEnd {
+ // Buffer is empty and can load in data from new chunk.
+ err = ds.fillBuffer(ds.ctx)
+ if err != nil {
+ if errors.Is(err, errNoMoreChunks) {
+ return skipped, nil
+ }
+ return skipped, err
+ }
+ }
+
+ toSkip := skip - skipped
+ // Cap the amount to skip to the remaining bytes in the buffer to be consumed.
+ bufferRemaining := ds.bufferEnd - ds.bufferStart
+ if toSkip > int64(bufferRemaining) {
+ toSkip = int64(bufferRemaining)
+ }
+
+ skipped += toSkip
+ ds.bufferStart += int(toSkip)
+ }
+
+ return skip, nil
+}
+
+// GetFile returns a File object representing the file being downloaded.
+func (ds *GridFSDownloadStream) GetFile() *GridFSFile {
+ return ds.file
+}
+
+func (ds *GridFSDownloadStream) fillBuffer(ctx context.Context) error {
+ if !ds.cursor.Next(ctx) {
+ ds.done = true
+ // Check for cursor error, otherwise there are no more chunks.
+ if ds.cursor.Err() != nil {
+ _ = ds.cursor.Close(ctx)
+ return ds.cursor.Err()
+ }
+ // If there are no more chunks, but we didn't read the expected number of chunks, return an
+ // ErrMissingChunk error to indicate that we're missing chunks at the end of the file.
+ if ds.expectedChunk != ds.numChunks {
+ return ErrMissingChunk
+ }
+ return errNoMoreChunks
+ }
+
+ chunkIndex, err := ds.cursor.Current.LookupErr("n")
+ if err != nil {
+ return err
+ }
+
+ var chunkIndexInt32 int32
+ if chunkIndexInt64, ok := chunkIndex.Int64OK(); ok {
+ chunkIndexInt32 = int32(chunkIndexInt64)
+ } else {
+ chunkIndexInt32 = chunkIndex.Int32()
+ }
+
+ if chunkIndexInt32 != ds.expectedChunk {
+ return ErrMissingChunk
+ }
+
+ ds.expectedChunk++
+ data, err := ds.cursor.Current.LookupErr("data")
+ if err != nil {
+ return err
+ }
+
+ _, dataBytes := data.Binary()
+ copied := copy(ds.buffer, dataBytes)
+
+ bytesLen := int32(len(dataBytes))
+ if ds.expectedChunk == ds.numChunks {
+ // final chunk can be fewer than ds.chunkSize bytes
+ bytesDownloaded := int64(ds.chunkSize) * (int64(ds.expectedChunk) - int64(1))
+ bytesRemaining := ds.fileLen - bytesDownloaded
+
+ if int64(bytesLen) != bytesRemaining {
+ return ErrWrongSize
+ }
+ } else if bytesLen != ds.chunkSize {
+ // all intermediate chunks must have size ds.chunkSize
+ return ErrWrongSize
+ }
+
+ ds.bufferStart = 0
+ ds.bufferEnd = copied
+
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_upload_stream.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_upload_stream.go
new file mode 100644
index 000000000..890227099
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_upload_stream.go
@@ -0,0 +1,204 @@
+// 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 mongo
+
+import (
+ "context"
+ "errors"
+ "math"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+)
+
+// uploadBufferSize is the size in bytes of one stream batch. Chunks will be written to the db after the sum of chunk
+// lengths is equal to the batch size.
+const uploadBufferSize = 16 * 1024 * 1024 // 16 MiB
+
+// ErrStreamClosed is an error returned if an operation is attempted on a closed/aborted stream.
+var ErrStreamClosed = errors.New("stream is closed or aborted")
+
+// GridFSUploadStream is used to upload a file in chunks. This type implements the io.Writer interface and a file can be
+// uploaded using the Write method. After an upload is complete, the Close method must be called to write file
+// metadata.
+type GridFSUploadStream struct {
+ *upload // chunk size and metadata
+ FileID any
+
+ chunkIndex int
+ chunksColl *Collection // collection to store file chunks
+ filename string
+ filesColl *Collection // collection to store file metadata
+ closed bool
+ buffer []byte
+ bufferIndex int
+ fileLen int64
+ ctx context.Context
+ cancel context.CancelFunc
+}
+
+// NewUploadStream creates a new upload stream.
+func newUploadStream(
+ ctx context.Context,
+ cancel context.CancelFunc,
+ up *upload,
+ fileID any,
+ filename string,
+ chunks, files *Collection,
+) *GridFSUploadStream {
+ return &GridFSUploadStream{
+ upload: up,
+ FileID: fileID,
+
+ chunksColl: chunks,
+ filename: filename,
+ filesColl: files,
+ buffer: make([]byte, uploadBufferSize),
+ ctx: ctx,
+ cancel: cancel,
+ }
+}
+
+// Close writes file metadata to the files collection and cleans up any resources associated with the UploadStream.
+func (us *GridFSUploadStream) Close() error {
+ defer func() {
+ if us.cancel != nil {
+ us.cancel()
+ }
+ }()
+
+ if us.closed {
+ return ErrStreamClosed
+ }
+
+ if us.bufferIndex != 0 {
+ if err := us.uploadChunks(us.ctx, true); err != nil {
+ return err
+ }
+ }
+
+ if err := us.createFilesCollDoc(us.ctx); err != nil {
+ return err
+ }
+
+ us.closed = true
+ return nil
+}
+
+// Write transfers the contents of a byte slice into this upload stream. If the stream's underlying buffer fills up,
+// the buffer will be uploaded as chunks to the server. Implements the io.Writer interface.
+func (us *GridFSUploadStream) Write(p []byte) (int, error) {
+ if us.closed {
+ return 0, ErrStreamClosed
+ }
+
+ origLen := len(p)
+ for len(p) != 0 {
+
+ n := copy(us.buffer[us.bufferIndex:], p) // copy as much as possible
+ p = p[n:]
+ us.bufferIndex += n
+
+ if us.bufferIndex == uploadBufferSize {
+ err := us.uploadChunks(us.ctx, false)
+ if err != nil {
+ return 0, err
+ }
+ }
+ }
+ return origLen, nil
+}
+
+// Abort closes the stream and deletes all file chunks that have already been written.
+func (us *GridFSUploadStream) Abort() error {
+ defer func() {
+ if us.cancel != nil {
+ us.cancel()
+ }
+ }()
+
+ if us.closed {
+ return ErrStreamClosed
+ }
+
+ _, err := us.chunksColl.DeleteMany(us.ctx, bson.D{{"files_id", us.FileID}})
+ if err != nil {
+ return err
+ }
+
+ us.closed = true
+ return nil
+}
+
+// uploadChunks uploads the current buffer as a series of chunks to the bucket
+// if uploadPartial is true, any data at the end of the buffer that is smaller than a chunk will be uploaded as a partial
+// chunk. if it is false, the data will be moved to the front of the buffer.
+// uploadChunks sets us.bufferIndex to the next available index in the buffer after uploading
+func (us *GridFSUploadStream) uploadChunks(ctx context.Context, uploadPartial bool) error {
+ chunks := float64(us.bufferIndex) / float64(us.chunkSize)
+ numChunks := int(math.Ceil(chunks))
+ if !uploadPartial {
+ numChunks = int(math.Floor(chunks))
+ }
+
+ docs := make([]any, numChunks)
+
+ begChunkIndex := us.chunkIndex
+ for i := 0; i < us.bufferIndex; i += int(us.chunkSize) {
+ endIndex := i + int(us.chunkSize)
+ if us.bufferIndex-i < int(us.chunkSize) {
+ // partial chunk
+ if !uploadPartial {
+ break
+ }
+ endIndex = us.bufferIndex
+ }
+ chunkData := us.buffer[i:endIndex]
+ docs[us.chunkIndex-begChunkIndex] = bson.D{
+ {"_id", bson.NewObjectID()},
+ {"files_id", us.FileID},
+ {"n", int32(us.chunkIndex)},
+ {"data", bson.Binary{Subtype: 0x00, Data: chunkData}},
+ }
+ us.chunkIndex++
+ us.fileLen += int64(len(chunkData))
+ }
+
+ _, err := us.chunksColl.InsertMany(ctx, docs)
+ if err != nil {
+ return err
+ }
+
+ // copy any remaining bytes to beginning of buffer and set buffer index
+ bytesUploaded := numChunks * int(us.chunkSize)
+ if bytesUploaded != uploadBufferSize && !uploadPartial {
+ copy(us.buffer[0:], us.buffer[bytesUploaded:us.bufferIndex])
+ }
+ us.bufferIndex = uploadBufferSize - bytesUploaded
+ return nil
+}
+
+func (us *GridFSUploadStream) createFilesCollDoc(ctx context.Context) error {
+ doc := bson.D{
+ {"_id", us.FileID},
+ {"length", us.fileLen},
+ {"chunkSize", us.chunkSize},
+ {"uploadDate", bson.DateTime(time.Now().UnixNano() / int64(time.Millisecond))},
+ {"filename", us.filename},
+ }
+
+ if us.metadata != nil {
+ doc = append(doc, bson.E{"metadata", us.metadata})
+ }
+
+ _, err := us.filesColl.InsertOne(ctx, doc)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/index_view.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/index_view.go
similarity index 56%
rename from vendor/go.mongodb.org/mongo-driver/mongo/index_view.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/index_view.go
index db65f7507..921635851 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/index_view.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/index_view.go
@@ -13,16 +13,16 @@ import (
"fmt"
"strconv"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// ErrInvalidIndexValue is returned if an index is created with a keys document that has a value that is not a number
@@ -30,11 +30,10 @@ import (
var ErrInvalidIndexValue = errors.New("invalid index value")
// ErrNonStringIndexName is returned if an index is created with a name that is not a string.
+//
+// Deprecated: it will be removed in the next major release
var ErrNonStringIndexName = errors.New("index name must be a string")
-// ErrMultipleIndexDrop is returned if multiple indexes would be dropped from a call to IndexView.DropOne.
-var ErrMultipleIndexDrop = errors.New("multiple indexes would be dropped")
-
// IndexView is a type that can be used to create, drop, and list indexes on a collection. An IndexView for a collection
// can be created by a call to Collection.Indexes().
type IndexView struct {
@@ -46,17 +45,10 @@ type IndexModel struct {
// A document describing which keys should be used for the index. It cannot be nil. This must be an order-preserving
// type such as bson.D. Map types such as bson.M are not valid. See https://www.mongodb.com/docs/manual/indexes/#indexes
// for examples of valid documents.
- Keys interface{}
+ Keys any
// The options to use to create the index.
- Options *options.IndexOptions
-}
-
-func isNamespaceNotFoundError(err error) bool {
- if de, ok := err.(driver.Error); ok {
- return de.Code == 26
- }
- return false
+ Options *options.IndexOptionsBuilder
}
// List executes a listIndexes command and returns a cursor over the indexes in the collection.
@@ -65,7 +57,7 @@ func isNamespaceNotFoundError(err error) bool {
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/listIndexes/.
-func (iv IndexView) List(ctx context.Context, opts ...*options.ListIndexesOptions) (*Cursor, error) {
+func (iv IndexView) List(ctx context.Context, opts ...options.Lister[options.ListIndexesOptions]) (*Cursor, error) {
if ctx == nil {
ctx = context.Background()
}
@@ -80,84 +72,107 @@ func (iv IndexView) List(ctx context.Context, opts ...*options.ListIndexesOption
closeImplicitSession(sess)
return nil, err
}
+ var selector description.ServerSelector
- selector := description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(readpref.Primary()),
- description.LatencySelector(iv.coll.client.localThreshold),
- })
- selector = makeReadPrefSelector(sess, selector, iv.coll.client.localThreshold)
+ retry := driver.RetryNone
+ if iv.coll.client.retryReads {
+ retry = driver.RetryOncePerCommand
+ }
+
+ cursorOpts := iv.coll.client.createBaseCursorOptions(iv.coll.client.retryReads)
+
+ selector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: readpref.Primary()},
+ &serverselector.Latency{Latency: iv.coll.client.localThreshold},
+ },
+ }
- // TODO(GODRIVER-3038): This operation should pass CSE to the ListIndexes
- // Crypt setter to be applied to the operation.
+ selector = makeReadPrefSelector(sess, selector, iv.coll.client.localThreshold)
op := operation.NewListIndexes().
Session(sess).CommandMonitor(iv.coll.client.monitor).
ServerSelector(selector).ClusterClock(iv.coll.client.clock).
+ Retry(retry).MaxAdaptiveRetries(cursorOpts.MaxAdaptiveRetries).
+ EnableOverloadRetargeting(cursorOpts.EnableOverloadRetargeting).
Database(iv.coll.db.name).Collection(iv.coll.name).
Deployment(iv.coll.client.deployment).ServerAPI(iv.coll.client.serverAPI).
- Timeout(iv.coll.client.timeout).Authenticator(iv.coll.client.authenticator)
-
- cursorOpts := iv.coll.client.createBaseCursorOptions()
+ Timeout(iv.coll.client.timeout).Crypt(iv.coll.client.cryptFLE).Authenticator(iv.coll.client.authenticator)
cursorOpts.MarshalValueEncoderFn = newEncoderFn(iv.coll.bsonOpts, iv.coll.registry)
- lio := options.MergeListIndexesOptions(opts...)
- if lio.BatchSize != nil {
- op = op.BatchSize(*lio.BatchSize)
- cursorOpts.BatchSize = *lio.BatchSize
+ args, err := mongoutil.NewOptions[options.ListIndexesOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
}
- op = op.MaxTime(lio.MaxTime)
- retry := driver.RetryNone
- if iv.coll.client.retryReads {
- retry = driver.RetryOncePerCommand
+
+ if args.BatchSize != nil {
+ op = op.BatchSize(*args.BatchSize)
+ cursorOpts.BatchSize = *args.BatchSize
+ }
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
}
- op.Retry(retry)
err = op.Execute(ctx)
if err != nil {
// for namespaceNotFound errors, return an empty cursor and do not throw an error
closeImplicitSession(sess)
- if isNamespaceNotFoundError(err) {
+ var de driver.Error
+ if errors.As(err, &de) && de.NamespaceNotFound() {
return newEmptyCursor(), nil
}
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
bc, err := op.Result(cursorOpts)
if err != nil {
closeImplicitSession(sess)
- return nil, replaceErrors(err)
+ return nil, wrapErrors(err)
}
- cursor, err := newCursorWithSession(bc, iv.coll.bsonOpts, iv.coll.registry, sess)
- return cursor, replaceErrors(err)
+ cursor, err := newCursorWithSession(bc, iv.coll.bsonOpts, iv.coll.registry, sess,
+
+ // This value is included for completeness, but a server will never return
+ // a tailable awaitData cursor from a listIndexes operation.
+ withCursorOptionClientTimeout(iv.coll.client.timeout))
+
+ return cursor, wrapErrors(err)
}
// ListSpecifications executes a List command and returns a slice of returned IndexSpecifications
-func (iv IndexView) ListSpecifications(ctx context.Context, opts ...*options.ListIndexesOptions) ([]*IndexSpecification, error) {
+func (iv IndexView) ListSpecifications(
+ ctx context.Context,
+ opts ...options.Lister[options.ListIndexesOptions],
+) ([]IndexSpecification, error) {
cursor, err := iv.List(ctx, opts...)
if err != nil {
return nil, err
}
- var results []*IndexSpecification
- err = cursor.All(ctx, &results)
- if err != nil {
+ var resp []indexListSpecificationResponse
+
+ if err := cursor.All(ctx, &resp); err != nil {
return nil, err
}
- ns := iv.coll.db.Name() + "." + iv.coll.Name()
- for _, res := range results {
- // Pre-4.4 servers report a namespace in their responses, so we only set Namespace manually if it was not in
- // the response.
- res.Namespace = ns
+ namespace := iv.coll.db.Name() + "." + iv.coll.Name()
+
+ specs := make([]IndexSpecification, len(resp))
+ for idx, spec := range resp {
+ specs[idx] = IndexSpecification(spec)
+ specs[idx].Namespace = namespace
}
- return results, nil
+ return specs, nil
}
// CreateOne executes a createIndexes command to create an index on the collection and returns the name of the new
// index. See the IndexView.CreateMany documentation for more information and an example.
-func (iv IndexView) CreateOne(ctx context.Context, model IndexModel, opts ...*options.CreateIndexesOptions) (string, error) {
+func (iv IndexView) CreateOne(
+ ctx context.Context,
+ model IndexModel,
+ opts ...options.Lister[options.CreateIndexesOptions],
+) (string, error) {
names, err := iv.CreateMany(ctx, []IndexModel{model}, opts...)
if err != nil {
return "", err
@@ -176,7 +191,11 @@ func (iv IndexView) CreateOne(ctx context.Context, model IndexModel, opts ...*op
// documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/createIndexes/.
-func (iv IndexView) CreateMany(ctx context.Context, models []IndexModel, opts ...*options.CreateIndexesOptions) ([]string, error) {
+func (iv IndexView) CreateMany(
+ ctx context.Context,
+ models []IndexModel,
+ opts ...options.Lister[options.CreateIndexesOptions],
+) ([]string, error) {
names := make([]string, 0, len(models))
var indexes bsoncore.Document
@@ -246,128 +265,139 @@ func (iv IndexView) CreateMany(ctx context.Context, models []IndexModel, opts ..
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
+ maxAdaptiveRetries := iv.coll.client.effectiveAdaptiveRetries(iv.coll.client.retryWrites)
+
selector := makePinnedSelector(sess, iv.coll.writeSelector)
- option := options.MergeCreateIndexesOptions(opts...)
+ args, err := mongoutil.NewOptions[options.CreateIndexesOptions](opts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
- // TODO(GODRIVER-3038): This operation should pass CSE to the CreateIndexes
- // Crypt setter to be applied to the operation.
- //
- // This was added in GODRIVER-2413 for the 2.0 major release.
op := operation.NewCreateIndexes(indexes).
Session(sess).WriteConcern(wc).ClusterClock(iv.coll.client.clock).
+ MaxAdaptiveRetries(maxAdaptiveRetries).EnableOverloadRetargeting(iv.coll.client.enableOverloadRetargeting).
Database(iv.coll.db.name).Collection(iv.coll.name).CommandMonitor(iv.coll.client.monitor).
Deployment(iv.coll.client.deployment).ServerSelector(selector).ServerAPI(iv.coll.client.serverAPI).
- Timeout(iv.coll.client.timeout).MaxTime(option.MaxTime).Authenticator(iv.coll.client.authenticator)
- if option.CommitQuorum != nil {
- commitQuorum, err := marshalValue(option.CommitQuorum, iv.coll.bsonOpts, iv.coll.registry)
+ Timeout(iv.coll.client.timeout).Crypt(iv.coll.client.cryptFLE).Authenticator(iv.coll.client.authenticator)
+ if args.CommitQuorum != nil {
+ commitQuorum, err := marshalValue(args.CommitQuorum, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
return nil, err
}
op.CommitQuorum(commitQuorum)
}
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
+ }
- err = op.Execute(ctx)
+ _, err = processWriteError(op.Execute(ctx))
if err != nil {
- _, err = processWriteError(err)
return nil, err
}
return names, nil
}
-func (iv IndexView) createOptionsDoc(opts *options.IndexOptions) (bsoncore.Document, error) {
- optsDoc := bsoncore.Document{}
- if opts.Background != nil {
- optsDoc = bsoncore.AppendBooleanElement(optsDoc, "background", *opts.Background)
+func (iv IndexView) createOptionsDoc(opts options.Lister[options.IndexOptions]) (bsoncore.Document, error) {
+ args, err := mongoutil.NewOptions[options.IndexOptions](opts)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
}
- if opts.ExpireAfterSeconds != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "expireAfterSeconds", *opts.ExpireAfterSeconds)
+
+ optsDoc := bsoncore.Document{}
+ if args.ExpireAfterSeconds != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "expireAfterSeconds", *args.ExpireAfterSeconds)
}
- if opts.Name != nil {
- optsDoc = bsoncore.AppendStringElement(optsDoc, "name", *opts.Name)
+ if args.Name != nil {
+ optsDoc = bsoncore.AppendStringElement(optsDoc, "name", *args.Name)
}
- if opts.Sparse != nil {
- optsDoc = bsoncore.AppendBooleanElement(optsDoc, "sparse", *opts.Sparse)
+ if args.Sparse != nil {
+ optsDoc = bsoncore.AppendBooleanElement(optsDoc, "sparse", *args.Sparse)
}
- if opts.StorageEngine != nil {
- doc, err := marshal(opts.StorageEngine, iv.coll.bsonOpts, iv.coll.registry)
+ if args.StorageEngine != nil {
+ doc, err := marshal(args.StorageEngine, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
return nil, err
}
optsDoc = bsoncore.AppendDocumentElement(optsDoc, "storageEngine", doc)
}
- if opts.Unique != nil {
- optsDoc = bsoncore.AppendBooleanElement(optsDoc, "unique", *opts.Unique)
+ if args.Unique != nil {
+ optsDoc = bsoncore.AppendBooleanElement(optsDoc, "unique", *args.Unique)
}
- if opts.Version != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "v", *opts.Version)
+ if args.Version != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "v", *args.Version)
}
- if opts.DefaultLanguage != nil {
- optsDoc = bsoncore.AppendStringElement(optsDoc, "default_language", *opts.DefaultLanguage)
+ if args.DefaultLanguage != nil {
+ optsDoc = bsoncore.AppendStringElement(optsDoc, "default_language", *args.DefaultLanguage)
}
- if opts.LanguageOverride != nil {
- optsDoc = bsoncore.AppendStringElement(optsDoc, "language_override", *opts.LanguageOverride)
+ if args.LanguageOverride != nil {
+ optsDoc = bsoncore.AppendStringElement(optsDoc, "language_override", *args.LanguageOverride)
}
- if opts.TextVersion != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "textIndexVersion", *opts.TextVersion)
+ if args.TextVersion != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "textIndexVersion", *args.TextVersion)
}
- if opts.Weights != nil {
- doc, err := marshal(opts.Weights, iv.coll.bsonOpts, iv.coll.registry)
+ if args.Weights != nil {
+ doc, err := marshal(args.Weights, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
return nil, err
}
optsDoc = bsoncore.AppendDocumentElement(optsDoc, "weights", doc)
}
- if opts.SphereVersion != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "2dsphereIndexVersion", *opts.SphereVersion)
+ if args.SphereVersion != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "2dsphereIndexVersion", *args.SphereVersion)
}
- if opts.Bits != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "bits", *opts.Bits)
+ if args.Bits != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "bits", *args.Bits)
}
- if opts.Max != nil {
- optsDoc = bsoncore.AppendDoubleElement(optsDoc, "max", *opts.Max)
+ if args.Max != nil {
+ optsDoc = bsoncore.AppendDoubleElement(optsDoc, "max", *args.Max)
}
- if opts.Min != nil {
- optsDoc = bsoncore.AppendDoubleElement(optsDoc, "min", *opts.Min)
+ if args.Min != nil {
+ optsDoc = bsoncore.AppendDoubleElement(optsDoc, "min", *args.Min)
}
- if opts.BucketSize != nil {
- optsDoc = bsoncore.AppendInt32Element(optsDoc, "bucketSize", *opts.BucketSize)
+ if args.BucketSize != nil {
+ optsDoc = bsoncore.AppendInt32Element(optsDoc, "bucketSize", *args.BucketSize)
}
- if opts.PartialFilterExpression != nil {
- doc, err := marshal(opts.PartialFilterExpression, iv.coll.bsonOpts, iv.coll.registry)
+ if args.PartialFilterExpression != nil {
+ doc, err := marshal(args.PartialFilterExpression, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
return nil, err
}
optsDoc = bsoncore.AppendDocumentElement(optsDoc, "partialFilterExpression", doc)
}
- if opts.Collation != nil {
- optsDoc = bsoncore.AppendDocumentElement(optsDoc, "collation", bsoncore.Document(opts.Collation.ToDocument()))
+ if args.Collation != nil {
+ optsDoc = bsoncore.AppendDocumentElement(optsDoc, "collation", bsoncore.Document(toDocument(args.Collation)))
}
- if opts.WildcardProjection != nil {
- doc, err := marshal(opts.WildcardProjection, iv.coll.bsonOpts, iv.coll.registry)
+ if args.WildcardProjection != nil {
+ doc, err := marshal(args.WildcardProjection, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
return nil, err
}
optsDoc = bsoncore.AppendDocumentElement(optsDoc, "wildcardProjection", doc)
}
- if opts.Hidden != nil {
- optsDoc = bsoncore.AppendBooleanElement(optsDoc, "hidden", *opts.Hidden)
+ if args.Hidden != nil {
+ optsDoc = bsoncore.AppendBooleanElement(optsDoc, "hidden", *args.Hidden)
}
return optsDoc, nil
}
-func (iv IndexView) drop(ctx context.Context, index any, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+func (iv IndexView) drop(ctx context.Context, index any, opts ...options.Lister[options.DropIndexesOptions]) error {
+ args, err := mongoutil.NewOptions[options.DropIndexesOptions](opts...)
+ if err != nil {
+ return fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
if ctx == nil {
ctx = context.Background()
}
@@ -378,92 +408,100 @@ func (iv IndexView) drop(ctx context.Context, index any, opts ...*options.DropIn
defer sess.EndSession()
}
- err := iv.coll.client.validSession(sess)
+ err = iv.coll.client.validSession(sess)
if err != nil {
- return nil, err
+ return err
}
wc := iv.coll.writeConcern
if sess.TransactionRunning() {
wc = nil
}
- if !writeconcern.AckWrite(wc) {
+ if !wc.Acknowledged() {
sess = nil
}
- selector := makePinnedSelector(sess, iv.coll.writeSelector)
+ maxAdaptiveRetries := iv.coll.client.effectiveAdaptiveRetries(iv.coll.client.retryWrites)
- dio := options.MergeDropIndexesOptions(opts...)
+ selector := makePinnedSelector(sess, iv.coll.writeSelector)
- // TODO(GODRIVER-3038): This operation should pass CSE to the DropIndexes
- // Crypt setter to be applied to the operation.
op := operation.NewDropIndexes(index).Session(sess).WriteConcern(wc).CommandMonitor(iv.coll.client.monitor).
+ MaxAdaptiveRetries(maxAdaptiveRetries).EnableOverloadRetargeting(iv.coll.client.enableOverloadRetargeting).
ServerSelector(selector).ClusterClock(iv.coll.client.clock).
Database(iv.coll.db.name).Collection(iv.coll.name).
Deployment(iv.coll.client.deployment).ServerAPI(iv.coll.client.serverAPI).
- Timeout(iv.coll.client.timeout).MaxTime(dio.MaxTime).
- Authenticator(iv.coll.client.authenticator)
+ Timeout(iv.coll.client.timeout).Crypt(iv.coll.client.cryptFLE).Authenticator(iv.coll.client.authenticator)
+
+ if rawData, ok := optionsutil.Value(args.Internal, "rawData").(bool); ok {
+ op = op.RawData(rawData)
+ }
err = op.Execute(ctx)
if err != nil {
- return nil, replaceErrors(err)
+ return wrapErrors(err)
}
- // TODO: it's weird to return a bson.Raw here because we have to convert the result back to BSON
- ridx, res := bsoncore.AppendDocumentStart(nil)
- res = bsoncore.AppendInt32Element(res, "nIndexesWas", op.Result().NIndexesWas)
- res, _ = bsoncore.AppendDocumentEnd(res, ridx)
- return res, nil
+ return nil
}
-// DropOne executes a dropIndexes operation to drop an index on the collection. If the operation succeeds, this returns
-// a BSON document in the form {nIndexesWas: }. The "nIndexesWas" field in the response contains the number of
-// indexes that existed prior to the drop.
+// DropOne executes a dropIndexes operation to drop an index on the collection.
//
-// The name parameter should be the name of the index to drop. If the name is "*", ErrMultipleIndexDrop will be returned
-// without running the command because doing so would drop all indexes.
+// The name parameter should be the name of the index to drop. If the name is
+// "*", ErrMultipleIndexDrop will be returned without running the command
+// because doing so would drop all indexes.
//
-// The opts parameter can be used to specify options for this operation (see the options.DropIndexesOptions
-// documentation).
+// The opts parameter can be used to specify options for this operation (see the
+// options.DropIndexesOptions documentation).
//
// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/dropIndexes/.
-func (iv IndexView) DropOne(ctx context.Context, name string, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+func (iv IndexView) DropOne(
+ ctx context.Context,
+ name string,
+ opts ...options.Lister[options.DropIndexesOptions],
+) error {
+ // For more information about the command, see
+ // https://www.mongodb.com/docs/manual/reference/command/dropIndexes/.
if name == "*" {
- return nil, ErrMultipleIndexDrop
+ return ErrMultipleIndexDrop
}
return iv.drop(ctx, name, opts...)
}
-// DropOneWithKey drops a collection index by key using the dropIndexes operation. If the operation succeeds, this returns
-// a BSON document in the form {nIndexesWas: }. The "nIndexesWas" field in the response contains the number of
-// indexes that existed prior to the drop.
+// DropWithKey drops a collection index by key using the dropIndexes operation.
//
// This function is useful to drop an index using its key specification instead of its name.
-func (iv IndexView) DropOneWithKey(ctx context.Context, keySpecDocument interface{}, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+func (iv IndexView) DropWithKey(ctx context.Context, keySpecDocument any, opts ...options.Lister[options.DropIndexesOptions]) error {
doc, err := marshal(keySpecDocument, iv.coll.bsonOpts, iv.coll.registry)
if err != nil {
- return nil, err
+ return err
}
return iv.drop(ctx, doc, opts...)
}
-// DropAll executes a dropIndexes operation to drop all indexes on the collection. If the operation succeeds, this
-// returns a BSON document in the form {nIndexesWas: }. The "nIndexesWas" field in the response contains the
-// number of indexes that existed prior to the drop.
+// DropAll executes a dropIndexes operation to drop all indexes on the collection.
//
-// The opts parameter can be used to specify options for this operation (see the options.DropIndexesOptions
-// documentation).
+// The opts parameter can be used to specify options for this operation (see the
+// options.DropIndexesOptions documentation).
//
-// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/dropIndexes/.
-func (iv IndexView) DropAll(ctx context.Context, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+// For more information about the command, see
+// https://www.mongodb.com/docs/manual/reference/command/dropIndexes/.
+func (iv IndexView) DropAll(
+ ctx context.Context,
+ opts ...options.Lister[options.DropIndexesOptions],
+) error {
return iv.drop(ctx, "*", opts...)
}
func getOrGenerateIndexName(keySpecDocument bsoncore.Document, model IndexModel) (string, error) {
- if model.Options != nil && model.Options.Name != nil {
- return *model.Options.Name, nil
+ args, err := mongoutil.NewOptions[options.IndexOptions](model.Options)
+ if err != nil {
+ return "", fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ if args != nil && args.Name != nil {
+ return *args.Name, nil
}
name := bytes.NewBufferString("")
@@ -495,11 +533,11 @@ func getOrGenerateIndexName(keySpecDocument bsoncore.Document, model IndexModel)
bsonValue := elem.Value()
switch bsonValue.Type {
- case bsontype.Int32:
+ case bsoncore.TypeInt32:
value = fmt.Sprintf("%d", bsonValue.Int32())
- case bsontype.Int64:
+ case bsoncore.TypeInt64:
value = fmt.Sprintf("%d", bsonValue.Int64())
- case bsontype.String:
+ case bsoncore.TypeString:
value = bsonValue.StringValue()
default:
return "", ErrInvalidIndexValue
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/insert.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/insert.go
new file mode 100644
index 000000000..9b34d79cc
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/insert.go
@@ -0,0 +1,146 @@
+// Copyright (C) MongoDB, Inc. 2019-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 mongo
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
+)
+
+// insert performs an insert operation.
+type insert struct {
+ authenticator driver.Authenticator
+ bypassDocumentValidation *bool
+ comment bsoncore.Value
+ documents []bsoncore.Document
+ ordered *bool
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result insertResult
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
+ additionalCmd bson.D
+ logger *logger.Logger
+}
+
+// insertResult represents an insert result returned by the server.
+type insertResult struct {
+ // Number of documents successfully inserted.
+ N int64
+}
+
+func buildInsertResult(response bsoncore.Document) (insertResult, error) {
+ elements, err := response.Elements()
+ if err != nil {
+ return insertResult{}, err
+ }
+ ir := insertResult{}
+ for _, element := range elements {
+ if element.Key() == "n" {
+ var ok bool
+ ir.N, ok = element.Value().AsInt64OK()
+ if !ok {
+ return ir, fmt.Errorf("response field 'n' is type int32 or int64, but received BSON type %s", element.Value().Type)
+ }
+ }
+ }
+ return ir, nil
+}
+
+// Result returns the result of executing this operation.
+func (i *insert) Result() insertResult { return i.result }
+
+func (i *insert) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
+ ir, err := buildInsertResult(resp)
+ i.result.N += ir.N
+ return err
+}
+
+// Execute runs this operations and returns an error if the operation did not execute successfully.
+func (i *insert) Execute(ctx context.Context) error {
+ if i.deployment == nil {
+ return errors.New("the Insert operation must have a Deployment set before Execute can be called")
+ }
+ batches := &driver.Batches{
+ Identifier: "documents",
+ Documents: i.documents,
+ Ordered: i.ordered,
+ }
+
+ return driver.Operation{
+ CommandFn: i.command,
+ ProcessResponseFn: i.processResponse,
+ Batches: batches,
+ RetryMode: i.retry,
+ MaxAdaptiveRetries: i.maxAdaptiveRetries,
+ EnableOverloadRetargeting: i.enableOverloadRetargeting,
+ Type: driver.Write,
+ Client: i.session,
+ Clock: i.clock,
+ CommandMonitor: i.monitor,
+ Crypt: i.crypt,
+ Database: i.database,
+ Deployment: i.deployment,
+ Selector: i.selector,
+ WriteConcern: i.writeConcern,
+ ServerAPI: i.serverAPI,
+ Timeout: i.timeout,
+ Logger: i.logger,
+ Name: driverutil.InsertOp,
+ Authenticator: i.authenticator,
+ }.Execute(ctx)
+}
+
+func (i *insert) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
+ dst = bsoncore.AppendStringElement(dst, "insert", i.collection)
+ if i.bypassDocumentValidation != nil && (desc.WireVersion != nil &&
+ driverutil.VersionRangeIncludes(*desc.WireVersion, 4)) {
+
+ dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *i.bypassDocumentValidation)
+ }
+ if i.comment.Type != bsoncore.Type(0) {
+ dst = bsoncore.AppendValueElement(dst, "comment", i.comment)
+ }
+ if i.ordered != nil {
+ dst = bsoncore.AppendBooleanElement(dst, "ordered", *i.ordered)
+ }
+ // Set rawData for 8.2+ servers.
+ if i.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *i.rawData)
+ }
+ if len(i.additionalCmd) > 0 {
+ doc, err := bson.Marshal(i.additionalCmd)
+ if err != nil {
+ return nil, err
+ }
+ dst = append(dst, doc[4:len(doc)-1]...)
+ }
+ return dst, nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongo.go
similarity index 71%
rename from vendor/go.mongodb.org/mongo-driver/mongo/mongo.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/mongo.go
index ec8e817c7..703115fdc 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongo.go
@@ -4,7 +4,7 @@
// 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 mongo // import "go.mongodb.org/mongo-driver/mongo"
+package mongo
import (
"bytes"
@@ -17,58 +17,20 @@ import (
"strconv"
"strings"
- "go.mongodb.org/mongo-driver/internal/codecutil"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/internal/codecutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/v2/bson"
)
+var defaultRegistry = bson.NewRegistry()
+
// Dialer is used to make network connections.
type Dialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
-// BSONAppender is an interface implemented by types that can marshal a
-// provided type into BSON bytes and append those bytes to the provided []byte.
-// The AppendBSON can return a non-nil error and non-nil []byte. The AppendBSON
-// method may also write incomplete BSON to the []byte.
-//
-// Deprecated: BSONAppender is unused and will be removed in Go Driver 2.0.
-type BSONAppender interface {
- AppendBSON([]byte, interface{}) ([]byte, error)
-}
-
-// BSONAppenderFunc is an adapter function that allows any function that
-// satisfies the AppendBSON method signature to be used where a BSONAppender is
-// used.
-//
-// Deprecated: BSONAppenderFunc is unused and will be removed in Go Driver 2.0.
-type BSONAppenderFunc func([]byte, interface{}) ([]byte, error)
-
-// AppendBSON implements the BSONAppender interface
-//
-// Deprecated: BSONAppenderFunc is unused and will be removed in Go Driver 2.0.
-func (baf BSONAppenderFunc) AppendBSON(dst []byte, val interface{}) ([]byte, error) {
- return baf(dst, val)
-}
-
-// MarshalError is returned when attempting to marshal 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 marshal type %s to a BSON Document: %v", reflect.TypeOf(me.Value), me.Err)
-}
-
// Pipeline is a type that makes creating aggregation pipelines easier. It is a
// helper and is intended for serializing to BSON.
//
@@ -80,21 +42,15 @@ func (me MarshalError) Error() string {
// }
type Pipeline []bson.D
-// bvwPool is a pool of BSON value writers. BSON value writers
-var bvwPool = bsonrw.NewBSONValueWriterPool()
-
// getEncoder takes a writer, BSON options, and a BSON registry and returns a properly configured
// bson.Encoder that writes to the given writer.
func getEncoder(
w io.Writer,
opts *options.BSONOptions,
- reg *bsoncodec.Registry,
-) (*bson.Encoder, error) {
- vw := bvwPool.Get(w)
- enc, err := bson.NewEncoder(vw)
- if err != nil {
- return nil, err
- }
+ reg *bson.Registry,
+) *bson.Encoder {
+ vw := bson.NewDocumentWriter(w)
+ enc := bson.NewEncoder(vw)
if opts != nil {
if opts.ErrorOnInlineDuplicates {
@@ -115,6 +71,9 @@ func getEncoder(
if opts.OmitZeroStruct {
enc.OmitZeroStruct()
}
+ if opts.OmitEmpty {
+ enc.OmitEmpty()
+ }
if opts.StringifyMapKeysWithFmt {
enc.StringifyMapKeysWithFmt()
}
@@ -124,19 +83,16 @@ func getEncoder(
}
if reg != nil {
- // TODO:(GODRIVER-2719): Remove error handling.
- if err := enc.SetRegistry(reg); err != nil {
- return nil, err
- }
+ enc.SetRegistry(reg)
}
- return enc, nil
+ return enc
}
// newEncoderFn will return a function for constructing an encoder based on the
// provided codec options.
-func newEncoderFn(opts *options.BSONOptions, registry *bsoncodec.Registry) codecutil.EncoderFn {
- return func(w io.Writer) (*bson.Encoder, error) {
+func newEncoderFn(opts *options.BSONOptions, registry *bson.Registry) codecutil.EncoderFn {
+ return func(w io.Writer) *bson.Encoder {
return getEncoder(w, opts, registry)
}
}
@@ -147,12 +103,12 @@ func newEncoderFn(opts *options.BSONOptions, registry *bsoncodec.Registry) codec
// If bsonOpts and registry are specified, the encoder is configured with the requested behaviors.
// If they are nil, the default behaviors are used.
func marshal(
- val interface{},
+ val any,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
) (bsoncore.Document, error) {
if registry == nil {
- registry = bson.DefaultRegistry
+ registry = defaultRegistry
}
if val == nil {
return nil, ErrNilDocument
@@ -163,12 +119,8 @@ func marshal(
}
buf := new(bytes.Buffer)
- enc, err := getEncoder(buf, bsonOpts, registry)
- if err != nil {
- return nil, fmt.Errorf("error configuring BSON encoder: %w", err)
- }
-
- err = enc.Encode(val)
+ enc := getEncoder(buf, bsonOpts, registry)
+ err := enc.Encode(val)
if err != nil {
return nil, MarshalError{Value: val, Err: err}
}
@@ -178,32 +130,29 @@ func marshal(
// ensureID inserts the given ObjectID as an element named "_id" at the
// beginning of the given BSON document if there is not an "_id" already.
-// If the given ObjectID is primitive.NilObjectID, a new object ID will be
+// If the given ObjectID is bson.NilObjectID, a new object ID will be
// generated with time.Now().
//
// If there is already an element named "_id", the document is not modified. It
// returns the resulting document and the decoded Go value of the "_id" element.
func ensureID(
doc bsoncore.Document,
- oid primitive.ObjectID,
+ oid bson.ObjectID,
bsonOpts *options.BSONOptions,
- reg *bsoncodec.Registry,
-) (bsoncore.Document, interface{}, error) {
+ reg *bson.Registry,
+) (bsoncore.Document, any, error) {
if reg == nil {
- reg = bson.DefaultRegistry
+ reg = defaultRegistry
}
// Try to find the "_id" element. If it exists, try to unmarshal just the
- // "_id" field as an interface{} and return it along with the unmodified
+ // "_id" field as an any and return it along with the unmodified
// BSON document.
if _, err := doc.LookupErr("_id"); err == nil {
var id struct {
- ID interface{} `bson:"_id"`
- }
- dec, err := getDecoder(doc, bsonOpts, reg)
- if err != nil {
- return nil, nil, fmt.Errorf("error configuring BSON decoder: %w", err)
+ ID any `bson:"_id"`
}
+ dec := getDecoder(doc, bsonOpts, reg)
err = dec.Decode(&id)
if err != nil {
return nil, nil, fmt.Errorf("error unmarshaling BSON document: %w", err)
@@ -223,7 +172,7 @@ func ensureID(
doc = make(bsoncore.Document, 0, len(olddoc)+extraSpace)
_, doc = bsoncore.ReserveLength(doc)
if oid.IsZero() {
- oid = primitive.NewObjectID()
+ oid = bson.NewObjectID()
}
doc = bsoncore.AppendObjectIDElement(doc, "_id", oid)
@@ -256,18 +205,18 @@ func ensureNoDollarKey(doc bsoncore.Document) error {
}
func marshalAggregatePipeline(
- pipeline interface{},
+ pipeline any,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
) (bsoncore.Document, bool, error) {
switch t := pipeline.(type) {
- case bsoncodec.ValueMarshaler:
+ case bson.ValueMarshaler:
btype, val, err := t.MarshalBSONValue()
if err != nil {
return nil, false, err
}
- if btype != bsontype.Array {
- return nil, false, fmt.Errorf("ValueMarshaler returned a %v, but was expecting %v", btype, bsontype.Array)
+ if typ := bson.Type(btype); typ != bson.TypeArray {
+ return nil, false, fmt.Errorf("ValueMarshaler returned a %v, but was expecting %v", typ, bson.TypeArray)
}
var hasOutputStage bool
@@ -344,9 +293,9 @@ func marshalAggregatePipeline(
}
func marshalUpdateValue(
- update interface{},
+ update any,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
dollarKeysAllowed bool,
) (bsoncore.Value, error) {
documentCheckerFunc := ensureDollarKey
@@ -359,8 +308,8 @@ func marshalUpdateValue(
switch t := update.(type) {
case nil:
return u, ErrNilDocument
- case primitive.D:
- u.Type = bsontype.EmbeddedDocument
+ case bson.D:
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data, err = marshal(update, bsonOpts, registry)
if err != nil {
return u, err
@@ -368,32 +317,34 @@ func marshalUpdateValue(
return u, documentCheckerFunc(u.Data)
case bson.Raw:
- u.Type = bsontype.EmbeddedDocument
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data = t
return u, documentCheckerFunc(u.Data)
case bsoncore.Document:
- u.Type = bsontype.EmbeddedDocument
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data = t
return u, documentCheckerFunc(u.Data)
case []byte:
- u.Type = bsontype.EmbeddedDocument
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data = t
return u, documentCheckerFunc(u.Data)
- case bsoncodec.Marshaler:
- u.Type = bsontype.EmbeddedDocument
+ case bson.Marshaler:
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data, err = t.MarshalBSON()
if err != nil {
return u, err
}
return u, documentCheckerFunc(u.Data)
- case bsoncodec.ValueMarshaler:
- u.Type, u.Data, err = t.MarshalBSONValue()
+ case bson.ValueMarshaler:
+ tt, data, err := t.MarshalBSONValue()
+ u.Type = bsoncore.Type(tt)
+ u.Data = data
if err != nil {
return u, err
}
- if u.Type != bsontype.Array && u.Type != bsontype.EmbeddedDocument {
- return u, fmt.Errorf("ValueMarshaler returned a %v, but was expecting %v or %v", u.Type, bsontype.Array, bsontype.EmbeddedDocument)
+ if u.Type != bsoncore.TypeArray && u.Type != bsoncore.TypeEmbeddedDocument {
+ return u, fmt.Errorf("ValueMarshaler returned a %v, but was expecting %v or %v", u.Type, bsoncore.TypeArray, bsoncore.TypeEmbeddedDocument)
}
return u, err
default:
@@ -402,7 +353,7 @@ func marshalUpdateValue(
return u, fmt.Errorf("can only marshal slices and arrays into update pipelines, but got %v", val.Kind())
}
if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
- u.Type = bsontype.EmbeddedDocument
+ u.Type = bsoncore.TypeEmbeddedDocument
u.Data, err = marshal(update, bsonOpts, registry)
if err != nil {
return u, err
@@ -411,7 +362,7 @@ func marshalUpdateValue(
return u, documentCheckerFunc(u.Data)
}
- u.Type = bsontype.Array
+ u.Type = bsoncore.TypeArray
aidx, arr := bsoncore.AppendArrayStart(nil)
valLen := val.Len()
for idx := 0; idx < valLen; idx++ {
@@ -432,19 +383,19 @@ func marshalUpdateValue(
}
func marshalValue(
- val interface{},
+ val any,
bsonOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
+ registry *bson.Registry,
) (bsoncore.Value, error) {
return codecutil.MarshalValue(val, newEncoderFn(bsonOpts, registry))
}
// Build the aggregation pipeline for the CountDocument command.
func countDocumentsAggregatePipeline(
- filter interface{},
+ filter any,
encOpts *options.BSONOptions,
- registry *bsoncodec.Registry,
- opts *options.CountOptions,
+ registry *bson.Registry,
+ args *options.CountOptions,
) (bsoncore.Document, error) {
filterDoc, err := marshal(filter, encOpts, registry)
if err != nil {
@@ -457,16 +408,16 @@ func countDocumentsAggregatePipeline(
arr, _ = bsoncore.AppendDocumentEnd(arr, didx)
index := 1
- if opts != nil {
- if opts.Skip != nil {
+ if args != nil {
+ if args.Skip != nil {
didx, arr = bsoncore.AppendDocumentElementStart(arr, strconv.Itoa(index))
- arr = bsoncore.AppendInt64Element(arr, "$skip", *opts.Skip)
+ arr = bsoncore.AppendInt64Element(arr, "$skip", *args.Skip)
arr, _ = bsoncore.AppendDocumentEnd(arr, didx)
index++
}
- if opts.Limit != nil {
+ if args.Limit != nil {
didx, arr = bsoncore.AppendDocumentElementStart(arr, strconv.Itoa(index))
- arr = bsoncore.AppendInt64Element(arr, "$limit", *opts.Limit)
+ arr = bsoncore.AppendInt64Element(arr, "$limit", *args.Limit)
arr, _ = bsoncore.AppendDocumentEnd(arr, didx)
index++
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/mongocryptd.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongocryptd.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/mongo/mongocryptd.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/mongocryptd.go
index 2603a3918..4af950d75 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/mongocryptd.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongocryptd.go
@@ -12,10 +12,10 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
const (
@@ -25,8 +25,10 @@ const (
serverSelectionTimeoutStr = "server selection error"
)
-var defaultTimeoutArgs = []string{"--idleShutdownTimeoutSecs=60"}
-var databaseOpts = options.Database().SetReadConcern(readconcern.New()).SetReadPreference(readpref.Primary())
+var (
+ defaultTimeoutArgs = []string{"--idleShutdownTimeoutSecs=60"}
+ databaseOpts = options.Database().SetReadConcern(&readconcern.ReadConcern{}).SetReadPreference(readpref.Primary())
+)
type mongocryptdClient struct {
bypassSpawn bool
@@ -74,7 +76,7 @@ func newMongocryptdClient(opts *options.AutoEncryptionOptions) (*mongocryptdClie
}
// create client
- client, err := NewClient(options.Client().ApplyURI(uri).SetServerSelectionTimeout(defaultServerSelectionTimeout))
+ client, err := newClient(options.Client().ApplyURI(uri).SetServerSelectionTimeout(defaultServerSelectionTimeout))
if err != nil {
return nil, err
}
@@ -113,8 +115,8 @@ func (mc *mongocryptdClient) markCommand(ctx context.Context, dbName string, cmd
}
// connect connects the underlying Client instance. This must be called before performing any mark operations.
-func (mc *mongocryptdClient) connect(ctx context.Context) error {
- return mc.client.Connect(ctx)
+func (mc *mongocryptdClient) connect() error {
+ return mc.client.connect()
}
// disconnect disconnects the underlying Client instance. This should be called after all operations have completed.
@@ -132,7 +134,7 @@ func (mc *mongocryptdClient) spawnProcess() error {
}
// createSpawnArgs creates arguments to spawn mcryptClient. It returns the path and a slice of arguments.
-func createSpawnArgs(opts map[string]interface{}) (string, []string) {
+func createSpawnArgs(opts map[string]any) (string, []string) {
var spawnArgs []string
// get command path
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/mongointernal.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongointernal.go
similarity index 81%
rename from vendor/go.mongodb.org/mongo-driver/mongo/mongointernal.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/mongointernal.go
index 0148756fc..31195d37e 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/mongointernal.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/mongointernal.go
@@ -11,9 +11,9 @@ package mongo
import (
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// NewSessionWithLSID returns a Session with the given sessionID document. The
@@ -26,8 +26,8 @@ import (
//
// NewSessionWithLSID is intended only for internal use and may be changed or
// removed at any time.
-func NewSessionWithLSID(client *Client, sessionID bson.Raw) Session {
- return &sessionImpl{
+func NewSessionWithLSID(client *Client, sessionID bson.Raw) *Session {
+ return &Session{
clientSession: &session.Client{
Server: &session.Server{
SessionID: bsoncore.Document(sessionID),
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/aggregateoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/aggregateoptions.go
new file mode 100644
index 000000000..58ca97d6c
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/aggregateoptions.go
@@ -0,0 +1,170 @@
+// 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 (
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+)
+
+// AggregateOptions represents arguments that can be used to configure an
+// Aggregate operation.
+//
+// See corresponding setter methods for documentation.
+type AggregateOptions struct {
+ AllowDiskUse *bool
+ BatchSize *int32
+ BypassDocumentValidation *bool
+ Collation *Collation
+ MaxAwaitTime *time.Duration
+ Comment any
+ Hint any
+ Let any
+ Custom bson.M
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// AggregateOptionsBuilder contains options to configure aggregate operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type AggregateOptionsBuilder struct {
+ Opts []func(*AggregateOptions) error
+}
+
+// Aggregate creates a new AggregateOptions instance.
+func Aggregate() *AggregateOptionsBuilder {
+ return &AggregateOptionsBuilder{}
+}
+
+// List returns a list of AggergateOptions setter functions.
+func (ao *AggregateOptionsBuilder) List() []func(*AggregateOptions) error {
+ return ao.Opts
+}
+
+// SetAllowDiskUse sets the value for the AllowDiskUse field. If true, the operation can write to temporary
+// files in the _tmp subdirectory of the database directory path on the server. The default value is false.
+func (ao *AggregateOptionsBuilder) SetAllowDiskUse(b bool) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.AllowDiskUse = &b
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetBatchSize sets the value for the BatchSize field. Specifies the maximum number of documents
+// to be included in each batch returned by the server.
+func (ao *AggregateOptionsBuilder) SetBatchSize(i int32) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.BatchSize = &i
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true, writes
+// executed as part of the operation will opt out of document-level validation on the server. The default value
+// is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about
+// document validation.
+func (ao *AggregateOptionsBuilder) SetBypassDocumentValidation(b bool) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (ao *AggregateOptionsBuilder) SetCollation(c *Collation) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetMaxAwaitTime sets the value for the MaxAwaitTime field. Specifies maximum amount of time
+// that the server should wait for new documents to satisfy a tailable cursor query.
+func (ao *AggregateOptionsBuilder) SetMaxAwaitTime(d time.Duration) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.MaxAwaitTime = &d
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included in
+// server logs, profiling logs, and currentOp queries to help trace the operation. The default is nil,
+// which means that no comment will be included in the logs.
+func (ao *AggregateOptionsBuilder) SetComment(comment any) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the aggregation. This should
+// either be the index name as a string or the index specification as a document. The hint does not apply to
+// $lookup and $graphLookup aggregation stages. The driver will return an error if the hint parameter
+// is a multi-key map. The default value is nil, which means that no hint will be sent.
+func (ao *AggregateOptionsBuilder) SetHint(h any) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.Hint = h
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the aggregate expression. This
+// option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using this
+// option. This must be a document mapping parameter names to values. Values must be constant or closed
+// expressions that do not reference document fields. Parameters can then be accessed as variables in
+// an aggregate expression context (e.g. "$$var").
+func (ao *AggregateOptionsBuilder) SetLet(let any) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return ao
+}
+
+// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate
+// with desired option names and values. Values must be Marshalable. Custom options may conflict
+// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom
+// options where possible.
+func (ao *AggregateOptionsBuilder) SetCustom(c bson.M) *AggregateOptionsBuilder {
+ ao.Opts = append(ao.Opts, func(opts *AggregateOptions) error {
+ opts.Custom = c
+
+ return nil
+ })
+
+ return ao
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/autoencryptionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/autoencryptionoptions.go
similarity index 72%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/autoencryptionoptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/autoencryptionoptions.go
index 15d513862..db3508fb4 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/autoencryptionoptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/autoencryptionoptions.go
@@ -9,11 +9,12 @@ package options
import (
"crypto/tls"
"net/http"
+ "time"
- "go.mongodb.org/mongo-driver/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
)
-// AutoEncryptionOptions represents options used to configure auto encryption/decryption behavior for a mongo.Client
+// AutoEncryptionOptions represents arguments used to configure auto encryption/decryption behavior for a mongo.Client
// instance.
//
// Automatic encryption is an enterprise only feature that only applies to operations on a collection. Automatic
@@ -25,19 +26,22 @@ import (
// If automatic encryption fails on an operation, use a MongoClient configured with bypassAutoEncryption=true and use
// ClientEncryption.encrypt() to manually encrypt values.
//
-// Enabling Client Side Encryption reduces the maximum document and message size (using a maxBsonObjectSize of 2MiB and
+// Enabling In-Use Encryption reduces the maximum document and message size (using a maxBsonObjectSize of 2MiB and
// maxMessageSizeBytes of 6MB) and may have a negative performance impact.
+//
+// See corresponding setter methods for documentation.
type AutoEncryptionOptions struct {
KeyVaultClientOptions *ClientOptions
KeyVaultNamespace string
- KmsProviders map[string]map[string]interface{}
- SchemaMap map[string]interface{}
+ KmsProviders map[string]map[string]any
+ SchemaMap map[string]any
BypassAutoEncryption *bool
- ExtraOptions map[string]interface{}
+ ExtraOptions map[string]any
TLSConfig map[string]*tls.Config
HTTPClient *http.Client
- EncryptedFieldsMap map[string]interface{}
+ EncryptedFieldsMap map[string]any
BypassQueryAnalysis *bool
+ KeyExpiration *time.Duration
}
// AutoEncryption creates a new AutoEncryptionOptions configured with default values.
@@ -58,30 +62,34 @@ func AutoEncryption() *AutoEncryptionOptions {
// mongo.Client except minPoolSize is set to 0 and AutoEncryptionOptions is omitted.
func (a *AutoEncryptionOptions) SetKeyVaultClientOptions(opts *ClientOptions) *AutoEncryptionOptions {
a.KeyVaultClientOptions = opts
+
return a
}
// SetKeyVaultNamespace specifies the namespace of the key vault collection. This is required.
func (a *AutoEncryptionOptions) SetKeyVaultNamespace(ns string) *AutoEncryptionOptions {
a.KeyVaultNamespace = ns
+
return a
}
// SetKmsProviders specifies options for KMS providers. This is required.
-func (a *AutoEncryptionOptions) SetKmsProviders(providers map[string]map[string]interface{}) *AutoEncryptionOptions {
+func (a *AutoEncryptionOptions) SetKmsProviders(providers map[string]map[string]any) *AutoEncryptionOptions {
a.KmsProviders = providers
+
return a
}
// SetSchemaMap specifies a map from namespace to local schema document. Schemas supplied in the schemaMap only apply
-// to configuring automatic encryption for client side encryption. Other validation rules in the JSON schema will not
-// be enforced by the driver and will result in an error.
+// to configuring automatic encryption for Client-Side Field Level Encryption. Other validation rules in the JSON schema
+// will not be enforced by the driver and will result in an error.
//
// Supplying a schemaMap provides more security than relying on JSON Schemas obtained from the server. It protects
// against a malicious server advertising a false JSON Schema, which could trick the client into sending unencrypted
// data that should be encrypted.
-func (a *AutoEncryptionOptions) SetSchemaMap(schemaMap map[string]interface{}) *AutoEncryptionOptions {
+func (a *AutoEncryptionOptions) SetSchemaMap(schemaMap map[string]any) *AutoEncryptionOptions {
a.SchemaMap = schemaMap
+
return a
}
@@ -95,6 +103,7 @@ func (a *AutoEncryptionOptions) SetSchemaMap(schemaMap map[string]interface{}) *
// is set to 0 and AutoEncryptionOptions is omitted.
func (a *AutoEncryptionOptions) SetBypassAutoEncryption(bypass bool) *AutoEncryptionOptions {
a.BypassAutoEncryption = &bypass
+
return a
}
@@ -127,32 +136,26 @@ func (a *AutoEncryptionOptions) SetBypassAutoEncryption(bypass bool) *AutoEncryp
// absolute path to the directory containing the linked libmongocrypt library. Setting an override
// path disables the default system library search path. If an override path is specified but the
// crypt_shared library cannot be loaded, Client creation will return an error. Must be a string.
-func (a *AutoEncryptionOptions) SetExtraOptions(extraOpts map[string]interface{}) *AutoEncryptionOptions {
+func (a *AutoEncryptionOptions) SetExtraOptions(extraOpts map[string]any) *AutoEncryptionOptions {
a.ExtraOptions = extraOpts
+
return a
}
// SetTLSConfig specifies tls.Config instances for each KMS provider to use to configure TLS on all connections created
// to the KMS provider.
-//
-// This should only be used to set custom TLS configurations. By default, the connection will use an empty tls.Config{} with MinVersion set to tls.VersionTLS12.
-func (a *AutoEncryptionOptions) SetTLSConfig(tlsOpts map[string]*tls.Config) *AutoEncryptionOptions {
- tlsConfigs := make(map[string]*tls.Config)
- for provider, config := range tlsOpts {
- // use TLS min version 1.2 to enforce more secure hash algorithms and advanced cipher suites
- if config.MinVersion == 0 {
- config.MinVersion = tls.VersionTLS12
- }
- tlsConfigs[provider] = config
- }
- a.TLSConfig = tlsConfigs
+func (a *AutoEncryptionOptions) SetTLSConfig(cfg map[string]*tls.Config) *AutoEncryptionOptions {
+ // This should only be used to set custom TLS configurations. By default, the connection will use an empty tls.Config{} with MinVersion set to tls.VersionTLS12.
+ a.TLSConfig = cfg
+
return a
}
// SetEncryptedFieldsMap specifies a map from namespace to local EncryptedFieldsMap document.
// EncryptedFieldsMap is used for Queryable Encryption.
-func (a *AutoEncryptionOptions) SetEncryptedFieldsMap(ef map[string]interface{}) *AutoEncryptionOptions {
+func (a *AutoEncryptionOptions) SetEncryptedFieldsMap(ef map[string]any) *AutoEncryptionOptions {
a.EncryptedFieldsMap = ef
+
return a
}
@@ -160,51 +163,14 @@ func (a *AutoEncryptionOptions) SetEncryptedFieldsMap(ef map[string]interface{})
// Use this option when using explicit encryption with Queryable Encryption.
func (a *AutoEncryptionOptions) SetBypassQueryAnalysis(bypass bool) *AutoEncryptionOptions {
a.BypassQueryAnalysis = &bypass
+
return a
}
-// MergeAutoEncryptionOptions combines the argued AutoEncryptionOptions in a last-one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeAutoEncryptionOptions(opts ...*AutoEncryptionOptions) *AutoEncryptionOptions {
- aeo := AutoEncryption()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.KeyVaultClientOptions != nil {
- aeo.KeyVaultClientOptions = opt.KeyVaultClientOptions
- }
- if opt.KeyVaultNamespace != "" {
- aeo.KeyVaultNamespace = opt.KeyVaultNamespace
- }
- if opt.KmsProviders != nil {
- aeo.KmsProviders = opt.KmsProviders
- }
- if opt.SchemaMap != nil {
- aeo.SchemaMap = opt.SchemaMap
- }
- if opt.BypassAutoEncryption != nil {
- aeo.BypassAutoEncryption = opt.BypassAutoEncryption
- }
- if opt.ExtraOptions != nil {
- aeo.ExtraOptions = opt.ExtraOptions
- }
- if opt.TLSConfig != nil {
- aeo.TLSConfig = opt.TLSConfig
- }
- if opt.EncryptedFieldsMap != nil {
- aeo.EncryptedFieldsMap = opt.EncryptedFieldsMap
- }
- if opt.BypassQueryAnalysis != nil {
- aeo.BypassQueryAnalysis = opt.BypassQueryAnalysis
- }
- if opt.HTTPClient != nil {
- aeo.HTTPClient = opt.HTTPClient
- }
- }
+// SetKeyExpiration specifies duration for the key expiration. 0 or negative value means "never expire".
+// The granularity is in milliseconds. Any sub-millisecond fraction will be rounded up.
+func (a *AutoEncryptionOptions) SetKeyExpiration(expiration time.Duration) *AutoEncryptionOptions {
+ a.KeyExpiration = &expiration
- return aeo
+ return a
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/bulkwriteoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/bulkwriteoptions.go
new file mode 100644
index 000000000..cbdc7f48f
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/bulkwriteoptions.go
@@ -0,0 +1,100 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// DefaultOrdered is the default value for the Ordered option in BulkWriteOptions.
+var DefaultOrdered = true
+
+// BulkWriteOptions represents arguments that can be used to configure a
+// BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type BulkWriteOptions struct {
+ BypassDocumentValidation *bool
+ Comment any
+ Ordered *bool
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// BulkWriteOptionsBuilder contains options to configure bulk write operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type BulkWriteOptionsBuilder struct {
+ Opts []func(*BulkWriteOptions) error
+}
+
+// BulkWrite creates a new *BulkWriteOptions instance.
+func BulkWrite() *BulkWriteOptionsBuilder {
+ opts := &BulkWriteOptionsBuilder{}
+ opts = opts.SetOrdered(DefaultOrdered)
+
+ return opts
+}
+
+// List returns a list of BulkWriteOptions setter functions.
+func (b *BulkWriteOptionsBuilder) List() []func(*BulkWriteOptions) error {
+ return b.Opts
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included in
+// server logs, profiling logs, and currentOp queries to help tracethe operation. The default value is nil,
+// which means that no comment will be included in the logs.
+func (b *BulkWriteOptionsBuilder) SetComment(comment any) *BulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BulkWriteOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return b
+}
+
+// SetOrdered sets the value for the Ordered field. If true, no writes will be executed after one fails.
+// The default value is true.
+func (b *BulkWriteOptionsBuilder) SetOrdered(ordered bool) *BulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BulkWriteOptions) error {
+ opts.Ordered = &ordered
+
+ return nil
+ })
+
+ return b
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true, writes
+// executed as part of the operation will opt out of document-level validation on the server. The default value is
+// false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document
+// validation.
+func (b *BulkWriteOptionsBuilder) SetBypassDocumentValidation(bypass bool) *BulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BulkWriteOptions) error {
+ opts.BypassDocumentValidation = &bypass
+
+ return nil
+ })
+
+ return b
+}
+
+// SetLet sets the value for the Let field. Let specifies parameters for all update and delete commands in the BulkWrite.
+// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using this option.
+// This must be a document mapping parameter names to values. Values must be constant or closed expressions that do not
+// reference document fields. Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (b *BulkWriteOptionsBuilder) SetLet(let any) *BulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BulkWriteOptions) error {
+ opts.Let = &let
+
+ return nil
+ })
+
+ return b
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/changestreamoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/changestreamoptions.go
new file mode 100644
index 000000000..92f19638c
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/changestreamoptions.go
@@ -0,0 +1,183 @@
+// 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 (
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+)
+
+// ChangeStreamOptions represents arguments that can be used to configure a Watch operation.
+//
+// See corresponding setter methods for documentation.
+type ChangeStreamOptions struct {
+ BatchSize *int32
+ Collation *Collation
+ Comment any
+ FullDocument *FullDocument
+ FullDocumentBeforeChange *FullDocument
+ MaxAwaitTime *time.Duration
+ ResumeAfter any
+ ShowExpandedEvents *bool
+ StartAtOperationTime *bson.Timestamp
+ StartAfter any
+ Custom bson.M
+ CustomPipeline bson.M
+}
+
+// ChangeStreamOptionsBuilder contains options to configure change stream
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type ChangeStreamOptionsBuilder struct {
+ Opts []func(*ChangeStreamOptions) error
+}
+
+// ChangeStream creates a new ChangeStreamOptions instance.
+func ChangeStream() *ChangeStreamOptionsBuilder {
+ return &ChangeStreamOptionsBuilder{}
+}
+
+// List returns a list of ChangeStreamOptions setter functions.
+func (cso *ChangeStreamOptionsBuilder) List() []func(*ChangeStreamOptions) error {
+ return cso.Opts
+}
+
+// SetBatchSize sets the value for the BatchSize field. Specifies the maximum number of documents to
+// be included in each batch returned by the server.
+func (cso *ChangeStreamOptionsBuilder) SetBatchSize(i int32) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.BatchSize = &i
+ return nil
+ })
+ return cso
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (cso *ChangeStreamOptionsBuilder) SetCollation(c Collation) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.Collation = &c
+ return nil
+ })
+ return cso
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included in
+// server logs, profiling logs, and currentOp queries to help trace the operation. The default is nil,
+// which means that no comment will be included in the logs.
+func (cso *ChangeStreamOptionsBuilder) SetComment(comment any) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.Comment = comment
+ return nil
+ })
+ return cso
+}
+
+// SetFullDocument sets the value for the FullDocument field. Specifies how the updated document should be
+// returned in change notifications for update operations. The default is options.Default, which means that
+// only partial update deltas will be included in the change notification.
+func (cso *ChangeStreamOptionsBuilder) SetFullDocument(fd FullDocument) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.FullDocument = &fd
+ return nil
+ })
+ return cso
+}
+
+// SetFullDocumentBeforeChange sets the value for the FullDocumentBeforeChange field. Specifies how the
+// pre-update document should be returned in change notifications for update operations. The default
+// is options.Off, which means that the pre-update document will not be included in the change notification.
+func (cso *ChangeStreamOptionsBuilder) SetFullDocumentBeforeChange(fdbc FullDocument) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.FullDocumentBeforeChange = &fdbc
+ return nil
+ })
+ return cso
+}
+
+// SetMaxAwaitTime sets the value for the MaxAwaitTime field. The maximum amount of time that the server should
+// wait for new documents to satisfy a tailable cursor query.
+func (cso *ChangeStreamOptionsBuilder) SetMaxAwaitTime(d time.Duration) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.MaxAwaitTime = &d
+ return nil
+ })
+ return cso
+}
+
+// SetResumeAfter sets the value for the ResumeAfter field. Specifies a document specifying the logical starting
+// point for the change stream. Only changes corresponding to an oplog entry immediately after the resume token
+// will be returned. If this is specified, StartAtOperationTime and StartAfter must not be set.
+func (cso *ChangeStreamOptionsBuilder) SetResumeAfter(rt any) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.ResumeAfter = rt
+ return nil
+ })
+ return cso
+}
+
+// SetShowExpandedEvents sets the value for the ShowExpandedEvents field. ShowExpandedEvents specifies whether
+// the server will return an expanded list of change stream events. Additional events include: createIndexes,
+// dropIndexes, modify, create, shardCollection, reshardCollection and refineCollectionShardKey. This option
+// is only valid for MongoDB versions >= 6.0.
+func (cso *ChangeStreamOptionsBuilder) SetShowExpandedEvents(see bool) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.ShowExpandedEvents = &see
+ return nil
+ })
+ return cso
+}
+
+// SetStartAtOperationTime sets the value for the StartAtOperationTime field. If specified, the change stream
+// will only return changes that occurred at or after the given timestamp.
+// If this is specified, ResumeAfter and StartAfter must not be set.
+func (cso *ChangeStreamOptionsBuilder) SetStartAtOperationTime(t *bson.Timestamp) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.StartAtOperationTime = t
+ return nil
+ })
+ return cso
+}
+
+// SetStartAfter sets the value for the StartAfter field. Sets a document specifying the logical starting
+// point for the change stream. This is similar to the ResumeAfter option, but allows a resume token from
+// an "invalidate" notification to be used. This allows a change stream on a collection to be resumed after
+// the collection has been dropped and recreated or renamed. Only changes corresponding to an oplog entry
+// immediately after the specified token will be returned. If this is specified, ResumeAfter and
+// StartAtOperationTime must not be set. This option is only valid for MongoDB versions >= 4.1.1.
+func (cso *ChangeStreamOptionsBuilder) SetStartAfter(sa any) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.StartAfter = sa
+ return nil
+ })
+ return cso
+}
+
+// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate
+// with desired option names and values. Values must be Marshalable. Custom options may conflict
+// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom
+// options where possible.
+func (cso *ChangeStreamOptionsBuilder) SetCustom(c bson.M) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.Custom = c
+ return nil
+ })
+ return cso
+}
+
+// SetCustomPipeline sets the value for the CustomPipeline field. Key-value pairs of the BSON map
+// should correlate with desired option names and values. Values must be Marshalable. Custom pipeline
+// options bypass client-side validation. Prefer using non-custom options where possible.
+func (cso *ChangeStreamOptionsBuilder) SetCustomPipeline(cp bson.M) *ChangeStreamOptionsBuilder {
+ cso.Opts = append(cso.Opts, func(opts *ChangeStreamOptions) error {
+ opts.CustomPipeline = cp
+ return nil
+ })
+ return cso
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientbulkwriteoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientbulkwriteoptions.go
new file mode 100644
index 000000000..90d6c2414
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientbulkwriteoptions.go
@@ -0,0 +1,127 @@
+// Copyright (C) MongoDB, Inc. 2024-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 (
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+)
+
+// ClientBulkWriteOptions represents options that can be used to configure a client-level BulkWrite operation.
+//
+// See corresponding setter methods for documentation.
+type ClientBulkWriteOptions struct {
+ BypassDocumentValidation *bool
+ Comment any
+ Ordered *bool
+ Let any
+ WriteConcern *writeconcern.WriteConcern
+ VerboseResults *bool
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// ClientBulkWriteOptionsBuilder contains options to configure client-level bulk
+// write operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type ClientBulkWriteOptionsBuilder struct {
+ Opts []func(*ClientBulkWriteOptions) error
+}
+
+// ClientBulkWrite creates a new *ClientBulkWriteOptions instance.
+func ClientBulkWrite() *ClientBulkWriteOptionsBuilder {
+ opts := &ClientBulkWriteOptionsBuilder{}
+ opts = opts.SetOrdered(DefaultOrdered)
+
+ return opts
+}
+
+// List returns a list of ClientBulkWriteOptions setter functions.
+func (b *ClientBulkWriteOptionsBuilder) List() []func(*ClientBulkWriteOptions) error {
+ return b.Opts
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included in
+// server logs, profiling logs, and currentOp queries to help tracethe operation. The default value is nil,
+// which means that no comment will be included in the logs.
+func (b *ClientBulkWriteOptionsBuilder) SetComment(comment any) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return b
+}
+
+// SetOrdered sets the value for the Ordered field. If true, no writes will be executed after one fails.
+// The default value is true.
+func (b *ClientBulkWriteOptionsBuilder) SetOrdered(ordered bool) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.Ordered = &ordered
+
+ return nil
+ })
+
+ return b
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true, writes
+// executed as part of the operation will opt out of document-level validation on the server. The default
+// value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information
+// about document validation.
+func (b *ClientBulkWriteOptionsBuilder) SetBypassDocumentValidation(bypass bool) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.BypassDocumentValidation = &bypass
+
+ return nil
+ })
+
+ return b
+}
+
+// SetLet sets the value for the Let field. Let specifies parameters for all update and delete commands in the BulkWrite.
+// This must be a document mapping parameter names to values. Values must be constant or closed expressions that do not
+// reference document fields. Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (b *ClientBulkWriteOptionsBuilder) SetLet(let any) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.Let = &let
+
+ return nil
+ })
+
+ return b
+}
+
+// SetWriteConcern sets the value for the WriteConcern field. Specifies the write concern for
+// operations in the transaction. The default value is nil, which means that the default
+// write concern of the session used to start the transaction will be used.
+func (b *ClientBulkWriteOptionsBuilder) SetWriteConcern(wc *writeconcern.WriteConcern) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.WriteConcern = wc
+
+ return nil
+ })
+
+ return b
+}
+
+// SetVerboseResults sets the value for the VerboseResults field. Specifies whether detailed
+// results for each successful operation should be included in the returned BulkWriteResult.
+// The defaults value is false.
+func (b *ClientBulkWriteOptionsBuilder) SetVerboseResults(verboseResults bool) *ClientBulkWriteOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *ClientBulkWriteOptions) error {
+ opts.VerboseResults = &verboseResults
+
+ return nil
+ })
+
+ return b
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientencryptionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientencryptionoptions.go
similarity index 61%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/clientencryptionoptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientencryptionoptions.go
index 2457f682b..a6c477a7a 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientencryptionoptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientencryptionoptions.go
@@ -10,34 +10,61 @@ import (
"crypto/tls"
"fmt"
"net/http"
+ "time"
- "go.mongodb.org/mongo-driver/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
)
-// ClientEncryptionOptions represents all possible options used to configure a ClientEncryption instance.
+// ClientEncryptionOptions represents all possible arguments used to configure a ClientEncryption instance.
+//
+// See corresponding setter methods for documentation.
type ClientEncryptionOptions struct {
KeyVaultNamespace string
- KmsProviders map[string]map[string]interface{}
+ KmsProviders map[string]map[string]any
TLSConfig map[string]*tls.Config
HTTPClient *http.Client
+ KeyExpiration *time.Duration
+}
+
+// ClientEncryptionOptionsBuilder contains options to configure client
+// encryption operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type ClientEncryptionOptionsBuilder struct {
+ Opts []func(*ClientEncryptionOptions) error
}
// ClientEncryption creates a new ClientEncryptionOptions instance.
-func ClientEncryption() *ClientEncryptionOptions {
- return &ClientEncryptionOptions{
- HTTPClient: httputil.DefaultHTTPClient,
+func ClientEncryption() *ClientEncryptionOptionsBuilder {
+ return &ClientEncryptionOptionsBuilder{
+ Opts: []func(*ClientEncryptionOptions) error{
+ func(arg *ClientEncryptionOptions) error {
+ arg.HTTPClient = httputil.DefaultHTTPClient
+ return nil
+ },
+ },
}
}
+// List returns a list of ClientEncryptionOptions setter functions.
+func (c *ClientEncryptionOptionsBuilder) List() []func(*ClientEncryptionOptions) error {
+ return c.Opts
+}
+
// SetKeyVaultNamespace specifies the namespace of the key vault collection. This is required.
-func (c *ClientEncryptionOptions) SetKeyVaultNamespace(ns string) *ClientEncryptionOptions {
- c.KeyVaultNamespace = ns
+func (c *ClientEncryptionOptionsBuilder) SetKeyVaultNamespace(ns string) *ClientEncryptionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *ClientEncryptionOptions) error {
+ opts.KeyVaultNamespace = ns
+ return nil
+ })
return c
}
// SetKmsProviders specifies options for KMS providers. This is required.
-func (c *ClientEncryptionOptions) SetKmsProviders(providers map[string]map[string]interface{}) *ClientEncryptionOptions {
- c.KmsProviders = providers
+func (c *ClientEncryptionOptionsBuilder) SetKmsProviders(providers map[string]map[string]any) *ClientEncryptionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *ClientEncryptionOptions) error {
+ opts.KmsProviders = providers
+ return nil
+ })
return c
}
@@ -45,16 +72,25 @@ func (c *ClientEncryptionOptions) SetKmsProviders(providers map[string]map[strin
// to the KMS provider.
//
// This should only be used to set custom TLS configurations. By default, the connection will use an empty tls.Config{} with MinVersion set to tls.VersionTLS12.
-func (c *ClientEncryptionOptions) SetTLSConfig(tlsOpts map[string]*tls.Config) *ClientEncryptionOptions {
- tlsConfigs := make(map[string]*tls.Config)
- for provider, config := range tlsOpts {
- // use TLS min version 1.2 to enforce more secure hash algorithms and advanced cipher suites
- if config.MinVersion == 0 {
- config.MinVersion = tls.VersionTLS12
- }
- tlsConfigs[provider] = config
- }
- c.TLSConfig = tlsConfigs
+func (c *ClientEncryptionOptionsBuilder) SetTLSConfig(cfg map[string]*tls.Config) *ClientEncryptionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *ClientEncryptionOptions) error {
+ opts.TLSConfig = cfg
+
+ return nil
+ })
+
+ return c
+}
+
+// SetKeyExpiration specifies duration for the key expiration. 0 or negative value means "never expire".
+// The granularity is in milliseconds. Any sub-millisecond fraction will be rounded up.
+func (c *ClientEncryptionOptionsBuilder) SetKeyExpiration(expiration time.Duration) *ClientEncryptionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *ClientEncryptionOptions) error {
+ opts.KeyExpiration = &expiration
+
+ return nil
+ })
+
return c
}
@@ -81,7 +117,7 @@ func (c *ClientEncryptionOptions) SetTLSConfig(tlsOpts map[string]*tls.Config) *
// to be considered trusted when making a TLS connection (e.g. "tlsCaFile=/path/to/caFile").
//
// This should only be used to set custom TLS options. By default, the connection will use an empty tls.Config{} with MinVersion set to tls.VersionTLS12.
-func BuildTLSConfig(tlsOpts map[string]interface{}) (*tls.Config, error) {
+func BuildTLSConfig(tlsOpts map[string]any) (*tls.Config, error) {
// use TLS min version 1.2 to enforce more secure hash algorithms and advanced cipher suites
cfg := &tls.Config{MinVersion: tls.VersionTLS12}
@@ -120,31 +156,3 @@ func BuildTLSConfig(tlsOpts map[string]interface{}) (*tls.Config, error) {
return cfg, nil
}
-
-// MergeClientEncryptionOptions combines the argued ClientEncryptionOptions in a last-one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeClientEncryptionOptions(opts ...*ClientEncryptionOptions) *ClientEncryptionOptions {
- ceo := ClientEncryption()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.KeyVaultNamespace != "" {
- ceo.KeyVaultNamespace = opt.KeyVaultNamespace
- }
- if opt.KmsProviders != nil {
- ceo.KmsProviders = opt.KmsProviders
- }
- if opt.TLSConfig != nil {
- ceo.TLSConfig = opt.TLSConfig
- }
- if opt.HTTPClient != nil {
- ceo.HTTPClient = opt.HTTPClient
- }
- }
-
- return ceo
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientoptions.go
similarity index 75%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientoptions.go
index b1dc0b6a7..6a69b2e95 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientoptions.go
@@ -4,7 +4,7 @@
// 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 "go.mongodb.org/mongo-driver/mongo/options"
+package options
import (
"bytes"
@@ -18,21 +18,23 @@ import (
"math"
"net"
"net/http"
+ "reflect"
"strings"
"time"
"github.com/youmark/pkcs8"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/httputil"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/tag"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/tag"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)
const (
@@ -66,7 +68,7 @@ type ContextDialer interface {
// Credential can be used to provide authentication options when configuring a Client.
//
// AuthMechanism: the mechanism to use for authentication. Supported values include "SCRAM-SHA-256", "SCRAM-SHA-1",
-// "MONGODB-CR", "PLAIN", "GSSAPI", "MONGODB-X509", and "MONGODB-AWS". This can also be set through the "authMechanism"
+// "PLAIN", "GSSAPI", "MONGODB-X509", and "MONGODB-AWS". This can also be set through the "authMechanism"
// URI option. (e.g. "authMechanism=PLAIN"). For more information, see
// https://www.mongodb.com/docs/manual/core/authentication-mechanisms/.
//
@@ -181,9 +183,12 @@ type BSONOptions struct {
// OmitZeroStruct causes the driver to consider the zero value for a struct
// (e.g. MyStruct{}) as empty and omit it from the marshaled BSON when the
- // "omitempty" struct tag option is set.
+ // "omitempty" struct tag option or the "OmitEmpty" field is set.
OmitZeroStruct bool
+ // OmitEmpty causes the driver to omit empty values from the marshaled BSON.
+ OmitEmpty bool
+
// StringifyMapKeysWithFmt causes the driver to convert Go map keys to BSON
// document field name strings using fmt.Sprint instead of the default
// string conversion logic.
@@ -197,19 +202,23 @@ type BSONOptions struct {
// BinaryAsSlice causes the driver to unmarshal BSON binary field values
// that are the "Generic" or "Old" BSON binary subtype as a Go byte slice
- // instead of a primitive.Binary.
+ // instead of a bson.Binary.
BinaryAsSlice bool
- // DefaultDocumentD causes the driver to always unmarshal documents into the
- // primitive.D type. This behavior is restricted to data typed as
- // "interface{}" or "map[string]interface{}".
- DefaultDocumentD bool
-
// DefaultDocumentM causes the driver to always unmarshal documents into the
- // primitive.M type. This behavior is restricted to data typed as
- // "interface{}" or "map[string]interface{}".
+ // bson.M type. This behavior is restricted to data typed as
+ // "any" or "map[string]any".
DefaultDocumentM bool
+ // DefaultDocumentMap causes the driver to always unmarshal documents into the
+ // map[string]any type. This behavior is restricted to data typed as "any" or
+ // "map[string]any".
+ DefaultDocumentMap bool
+
+ // ObjectIDAsHexString causes the Decoder to decode object IDs to their hex
+ // representation.
+ ObjectIDAsHexString bool
+
// UseLocalTimeZone causes the driver to unmarshal time.Time values in the
// local timezone instead of the UTC timezone.
UseLocalTimeZone bool
@@ -224,8 +233,20 @@ type BSONOptions struct {
ZeroStructs bool
}
-// ClientOptions contains options to configure a Client instance. Each option can be set through setter functions. See
-// documentation for each setter function for an explanation of the option.
+// DriverInfo appends the client metadata generated by the driver when
+// handshaking the server. These options do not replace the values used
+// during the handshake, rather they are deliminated with a | with the
+// driver-generated data. This should be used by libraries wrapping the driver,
+// e.g. ODMs.
+type DriverInfo struct {
+ Name string // Name of the library wrapping the driver.
+ Version string // Version of the library wrapping the driver.
+ Platform string // Platform information for the wrapping driver.
+}
+
+// ClientOptions contains arguments to configure a Client instance. Arguments
+// can be set through the ClientOptions setter functions. See each function for
+// documentation.
type ClientOptions struct {
AppName *string
Auth *Credential
@@ -235,6 +256,7 @@ type ClientOptions struct {
Dialer ContextDialer
Direct *bool
DisableOCSPEndpointCheck *bool
+ DriverInfo *DriverInfo
HeartbeatInterval *time.Duration
Hosts []string
HTTPClient *http.Client
@@ -251,7 +273,7 @@ type ClientOptions struct {
ReadConcern *readconcern.ReadConcern
ReadPreference *readpref.ReadPref
BSONOptions *BSONOptions
- Registry *bsoncodec.Registry
+ Registry *bson.Registry
ReplicaSet *string
RetryReads *bool
RetryWrites *bool
@@ -266,372 +288,405 @@ type ClientOptions struct {
ZlibLevel *int
ZstdLevel *int
- err error
- cs *connstring.ConnString
-
- // AuthenticateToAnything skips server type checks when deciding if authentication is possible.
- //
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
- AuthenticateToAnything *bool
+ MaxAdaptiveRetries *uint
+ EnableOverloadRetargeting *bool
// Crypt specifies a custom driver.Crypt to be used to encrypt and decrypt documents. The default is no
// encryption.
//
// Deprecated: This option is for internal use only and should not be set (see GODRIVER-2149). It may be
- // changed or removed in any release.
+ // changed in any release. This option will be removed in 3.0 and replaced with the Custom options.Options
+ // pattern: SetInternalClientOptions(clientOptions, "crypt", myCrypt)
Crypt driver.Crypt
// Deployment specifies a custom deployment to use for the new Client.
//
- // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
- // release.
+ // Deprecated: This option is for internal use only and should not be set. It may be changed in any release.
+ // This option will be removed in 3.0 and replaced with the Custom options.Options pattern:
+ // SetInternalClientOptions(clientOptions, "deployment", myDeployment)
Deployment driver.Deployment
- // SocketTimeout specifies the timeout to be used for the Client's socket reads and writes.
+ // Custom specifies internal options for the new Client.
//
- // NOTE(benjirewis): SocketTimeout will be deprecated in a future release. The more general Timeout option
- // may be used in its place to control the amount of time that a single operation can run before returning
- // an error. Setting SocketTimeout and Timeout on a single client will result in undefined behavior.
- SocketTimeout *time.Duration
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Custom optionsutil.Options
+
+ connString *connstring.ConnString
+ err error
}
// Client creates a new ClientOptions instance.
func Client() *ClientOptions {
- return &ClientOptions{
- HTTPClient: httputil.DefaultHTTPClient,
- }
-}
+ opts := &ClientOptions{}
+ opts = opts.SetHTTPClient(httputil.NewHTTPClient())
-// Validate validates the client options. This method will return the first error found.
-func (c *ClientOptions) Validate() error {
- if c.err != nil {
- return c.err
- }
- c.err = c.validate()
- return c.err
+ return opts
}
-func (c *ClientOptions) validate() error {
- // Direct connections cannot be made if multiple hosts are specified or an SRV URI is used.
- if c.Direct != nil && *c.Direct {
- if len(c.Hosts) > 1 {
- return errors.New("a direct connection cannot be made if multiple hosts are specified")
- }
- if c.cs != nil && c.cs.Scheme == connstring.SchemeMongoDBSRV {
- return errors.New("a direct connection cannot be made if an SRV URI is used")
- }
+func setURIOpts(uri string, opts *ClientOptions) error {
+ connString, err := connstring.ParseAndValidate(uri)
+ if err != nil {
+ return err
}
- if c.MaxPoolSize != nil && c.MinPoolSize != nil && *c.MaxPoolSize != 0 && *c.MinPoolSize > *c.MaxPoolSize {
- return fmt.Errorf("minPoolSize must be less than or equal to maxPoolSize, got minPoolSize=%d maxPoolSize=%d", *c.MinPoolSize, *c.MaxPoolSize)
+ opts.connString = connString
+
+ if connString.AppName != "" {
+ opts.AppName = &connString.AppName
}
- // verify server API version if ServerAPIOptions are passed in.
- if c.ServerAPIOptions != nil {
- if err := c.ServerAPIOptions.ServerAPIVersion.Validate(); err != nil {
- return err
+ // Only create a Credential if there is a request for authentication via
+ // non-empty credentials in the URI.
+ if connString.HasAuthParameters() {
+ opts.Auth = &Credential{
+ AuthMechanism: connString.AuthMechanism,
+ AuthMechanismProperties: connString.AuthMechanismProperties,
+ AuthSource: connString.AuthSource,
+ Username: connString.Username,
+ Password: connString.Password,
+ PasswordSet: connString.PasswordSet,
}
}
- // Validation for load-balanced mode.
- if c.LoadBalanced != nil && *c.LoadBalanced {
- if len(c.Hosts) > 1 {
- return connstring.ErrLoadBalancedWithMultipleHosts
- }
- if c.ReplicaSet != nil {
- return connstring.ErrLoadBalancedWithReplicaSet
- }
- if c.Direct != nil && *c.Direct {
- return connstring.ErrLoadBalancedWithDirectConnection
- }
+ if connString.ConnectSet {
+ direct := connString.Connect == connstring.SingleConnect
+ opts.Direct = &direct
}
- // Validation for srvMaxHosts.
- if c.SRVMaxHosts != nil && *c.SRVMaxHosts > 0 {
- if c.ReplicaSet != nil {
- return connstring.ErrSRVMaxHostsWithReplicaSet
- }
- if c.LoadBalanced != nil && *c.LoadBalanced {
- return connstring.ErrSRVMaxHostsWithLoadBalanced
- }
+ if connString.DirectConnectionSet {
+ opts.Direct = &connString.DirectConnection
}
- if mode := c.ServerMonitoringMode; mode != nil && !connstring.IsValidServerMonitoringMode(*mode) {
- return fmt.Errorf("invalid server monitoring mode: %q", *mode)
+ if connString.ConnectTimeoutSet {
+ opts.ConnectTimeout = &connString.ConnectTimeout
}
- // OIDC Validation
- if c.Auth != nil && c.Auth.AuthMechanism == auth.MongoDBOIDC {
- if c.Auth.Password != "" {
- return fmt.Errorf("password must not be set for the %s auth mechanism", auth.MongoDBOIDC)
- }
- if c.Auth.OIDCMachineCallback != nil && c.Auth.OIDCHumanCallback != nil {
- return fmt.Errorf("cannot set both OIDCMachineCallback and OIDCHumanCallback, only one may be specified")
- }
- if c.Auth.OIDCHumanCallback == nil && c.Auth.AuthMechanismProperties[auth.AllowedHostsProp] != "" {
- return fmt.Errorf("Cannot specify ALLOWED_HOSTS without an OIDCHumanCallback")
+ if len(connString.Compressors) > 0 {
+ opts.Compressors = connString.Compressors
+ if stringSliceContains(opts.Compressors, "zlib") {
+ defaultLevel := wiremessage.DefaultZlibLevel
+ opts.ZlibLevel = &defaultLevel
}
- if env, ok := c.Auth.AuthMechanismProperties[auth.EnvironmentProp]; ok {
- switch env {
- case auth.GCPEnvironmentValue, auth.AzureEnvironmentValue:
- if c.Auth.OIDCMachineCallback != nil {
- return fmt.Errorf("OIDCMachineCallback cannot be specified with the %s %q", env, auth.EnvironmentProp)
- }
- if c.Auth.OIDCHumanCallback != nil {
- return fmt.Errorf("OIDCHumanCallback cannot be specified with the %s %q", env, auth.EnvironmentProp)
- }
- if c.Auth.AuthMechanismProperties[auth.ResourceProp] == "" {
- return fmt.Errorf("%q must be set for the %s %q", auth.ResourceProp, env, auth.EnvironmentProp)
- }
- default:
- if c.Auth.AuthMechanismProperties[auth.ResourceProp] != "" {
- return fmt.Errorf("%q must not be set for the %s %q", auth.ResourceProp, env, auth.EnvironmentProp)
- }
- }
+ if stringSliceContains(opts.Compressors, "zstd") {
+ defaultLevel := wiremessage.DefaultZstdLevel
+ opts.ZstdLevel = &defaultLevel
}
}
- return nil
-}
-
-// GetURI returns the original URI used to configure the ClientOptions instance. If ApplyURI was not called during
-// construction, this returns "".
-func (c *ClientOptions) GetURI() string {
- if c.cs == nil {
- return ""
+ if connString.HeartbeatIntervalSet {
+ opts.HeartbeatInterval = &connString.HeartbeatInterval
}
- return c.cs.Original
-}
-// ApplyURI parses the given URI and sets options accordingly. The URI can contain host names, IPv4/IPv6 literals, or
-// an SRV record that will be resolved when the Client is created. When using an SRV record, TLS support is
-// implicitly enabled. Specify the "tls=false" URI option to override this.
-//
-// If the connection string contains any options that have previously been set, it will overwrite them. Options that
-// correspond to multiple URI parameters, such as WriteConcern, will be completely overwritten if any of the query
-// parameters are specified. If an option is set on ClientOptions after this method is called, that option will override
-// any option applied via the connection string.
-//
-// If the URI format is incorrect or there are conflicting options specified in the URI an error will be recorded and
-// can be retrieved by calling Validate.
-//
-// For more information about the URI format, see https://www.mongodb.com/docs/manual/reference/connection-string/. See
-// mongo.Connect documentation for examples of using URIs for different Client configurations.
-func (c *ClientOptions) ApplyURI(uri string) *ClientOptions {
- if c.err != nil {
- return c
+ opts.Hosts = connString.Hosts
+
+ if connString.LoadBalancedSet {
+ opts.LoadBalanced = &connString.LoadBalanced
}
- cs, err := connstring.ParseAndValidate(uri)
- if err != nil {
- c.err = err
- return c
+ if connString.LocalThresholdSet {
+ opts.LocalThreshold = &connString.LocalThreshold
}
- c.cs = cs
- if cs.AppName != "" {
- c.AppName = &cs.AppName
+ if connString.MaxConnIdleTimeSet {
+ opts.MaxConnIdleTime = &connString.MaxConnIdleTime
}
- // Only create a Credential if there is a request for authentication via non-empty credentials in the URI.
- if cs.HasAuthParameters() {
- c.Auth = &Credential{
- AuthMechanism: cs.AuthMechanism,
- AuthMechanismProperties: cs.AuthMechanismProperties,
- AuthSource: cs.AuthSource,
- Username: cs.Username,
- Password: cs.Password,
- PasswordSet: cs.PasswordSet,
- }
+ if connString.MaxPoolSizeSet {
+ opts.MaxPoolSize = &connString.MaxPoolSize
}
- if cs.ConnectSet {
- direct := cs.Connect == connstring.SingleConnect
- c.Direct = &direct
+ if connString.MinPoolSizeSet {
+ opts.MinPoolSize = &connString.MinPoolSize
}
- if cs.DirectConnectionSet {
- c.Direct = &cs.DirectConnection
+ if connString.MaxConnectingSet {
+ opts.MaxConnecting = &connString.MaxConnecting
}
- if cs.ConnectTimeoutSet {
- c.ConnectTimeout = &cs.ConnectTimeout
+ if connString.ReadConcernLevel != "" {
+ opts.ReadConcern = &readconcern.ReadConcern{Level: connString.ReadConcernLevel}
}
- if len(cs.Compressors) > 0 {
- c.Compressors = cs.Compressors
- if stringSliceContains(c.Compressors, "zlib") {
- defaultLevel := wiremessage.DefaultZlibLevel
- c.ZlibLevel = &defaultLevel
+ if connString.ReadPreference != "" || len(connString.ReadPreferenceTagSets) > 0 || connString.MaxStalenessSet {
+ readPrefOpts := make([]readpref.Option, 0, 1)
+
+ tagSets := tag.NewTagSetsFromMaps(connString.ReadPreferenceTagSets)
+ if len(tagSets) > 0 {
+ readPrefOpts = append(readPrefOpts, readpref.WithTagSets(tagSets...))
}
- if stringSliceContains(c.Compressors, "zstd") {
- defaultLevel := wiremessage.DefaultZstdLevel
- c.ZstdLevel = &defaultLevel
+
+ if connString.MaxStaleness != 0 {
+ readPrefOpts = append(readPrefOpts, readpref.WithMaxStaleness(connString.MaxStaleness))
}
- }
- if cs.HeartbeatIntervalSet {
- c.HeartbeatInterval = &cs.HeartbeatInterval
+ mode, err := readpref.ModeFromString(connString.ReadPreference)
+ if err != nil {
+ return err
+ }
+
+ opts.ReadPreference, err = readpref.New(mode, readPrefOpts...)
+ if err != nil {
+ return err
+ }
}
- c.Hosts = cs.Hosts
+ if connString.RetryWritesSet {
+ opts.RetryWrites = &connString.RetryWrites
+ }
- if cs.LoadBalancedSet {
- c.LoadBalanced = &cs.LoadBalanced
+ if connString.RetryReadsSet {
+ opts.RetryReads = &connString.RetryReads
}
- if cs.LocalThresholdSet {
- c.LocalThreshold = &cs.LocalThreshold
+ if connString.MaxAdaptiveRetriesSet {
+ opts.MaxAdaptiveRetries = &connString.MaxAdaptiveRetries
}
- if cs.MaxConnIdleTimeSet {
- c.MaxConnIdleTime = &cs.MaxConnIdleTime
+ if connString.EnableOverloadRetargetingSet {
+ opts.EnableOverloadRetargeting = &connString.EnableOverloadRetargeting
}
- if cs.MaxPoolSizeSet {
- c.MaxPoolSize = &cs.MaxPoolSize
+ if connString.ReplicaSet != "" {
+ opts.ReplicaSet = &connString.ReplicaSet
}
- if cs.MinPoolSizeSet {
- c.MinPoolSize = &cs.MinPoolSize
+ if connString.ServerSelectionTimeoutSet {
+ opts.ServerSelectionTimeout = &connString.ServerSelectionTimeout
}
- if cs.MaxConnectingSet {
- c.MaxConnecting = &cs.MaxConnecting
+ if connString.SRVMaxHosts != 0 {
+ opts.SRVMaxHosts = &connString.SRVMaxHosts
}
- if cs.ReadConcernLevel != "" {
- c.ReadConcern = readconcern.New(readconcern.Level(cs.ReadConcernLevel))
+ if connString.SRVServiceName != "" {
+ opts.SRVServiceName = &connString.SRVServiceName
}
- if cs.ReadPreference != "" || len(cs.ReadPreferenceTagSets) > 0 || cs.MaxStalenessSet {
- opts := make([]readpref.Option, 0, 1)
+ if connString.SSL {
+ tlsConfig := new(tls.Config)
- tagSets := tag.NewTagSetsFromMaps(cs.ReadPreferenceTagSets)
- if len(tagSets) > 0 {
- opts = append(opts, readpref.WithTagSets(tagSets...))
+ if connString.SSLCaFileSet {
+ if err := addCACertFromFile(tlsConfig, connString.SSLCaFile); err != nil {
+ return err
+ }
}
- if cs.MaxStaleness != 0 {
- opts = append(opts, readpref.WithMaxStaleness(cs.MaxStaleness))
+ if connString.SSLInsecure {
+ tlsConfig.InsecureSkipVerify = true
+ }
+
+ var x509Subject string
+ var keyPasswd string
+ if connString.SSLClientCertificateKeyPasswordSet && connString.SSLClientCertificateKeyPassword != nil {
+ keyPasswd = connString.SSLClientCertificateKeyPassword()
+ }
+
+ var err error
+ if connString.SSLClientCertificateKeyFileSet {
+ x509Subject, err = addClientCertFromConcatenatedFile(tlsConfig, connString.SSLClientCertificateKeyFile, keyPasswd)
+ } else if connString.SSLCertificateFileSet || connString.SSLPrivateKeyFileSet {
+ x509Subject, err = addClientCertFromSeparateFiles(tlsConfig, connString.SSLCertificateFile,
+ connString.SSLPrivateKeyFile, keyPasswd)
}
- mode, err := readpref.ModeFromString(cs.ReadPreference)
if err != nil {
- c.err = err
- return c
+ return err
}
- c.ReadPreference, c.err = readpref.New(mode, opts...)
- if c.err != nil {
- return c
+ // If a username wasn't specified fork x509, add one from the certificate.
+ if opts.Auth != nil && strings.ToLower(opts.Auth.AuthMechanism) == "mongodb-x509" && opts.Auth.Username == "" {
+ // The Go x509 package gives the subject with the pairs in reverse order that we want.
+ opts.Auth.Username = extractX509UsernameFromSubject(x509Subject)
}
+
+ opts.TLSConfig = tlsConfig
}
- if cs.RetryWritesSet {
- c.RetryWrites = &cs.RetryWrites
+ if connString.JSet || connString.WString != "" || connString.WNumberSet {
+ opts.WriteConcern = &writeconcern.WriteConcern{}
+
+ if len(connString.WString) > 0 {
+ opts.WriteConcern.W = connString.WString
+ } else if connString.WNumberSet {
+ opts.WriteConcern.W = connString.WNumber
+ }
+
+ if connString.JSet {
+ opts.WriteConcern.Journal = &connString.J
+ }
}
- if cs.RetryReadsSet {
- c.RetryReads = &cs.RetryReads
+ if connString.ZlibLevelSet {
+ opts.ZlibLevel = &connString.ZlibLevel
+ }
+ if connString.ZstdLevelSet {
+ opts.ZstdLevel = &connString.ZstdLevel
}
- if cs.ReplicaSet != "" {
- c.ReplicaSet = &cs.ReplicaSet
+ if connString.SSLDisableOCSPEndpointCheckSet {
+ opts.DisableOCSPEndpointCheck = &connString.SSLDisableOCSPEndpointCheck
}
- if cs.ServerSelectionTimeoutSet {
- c.ServerSelectionTimeout = &cs.ServerSelectionTimeout
+ if connString.TimeoutSet {
+ opts.Timeout = &connString.Timeout
}
- if cs.SocketTimeoutSet {
- c.SocketTimeout = &cs.SocketTimeout
+ return nil
+}
+
+// GetURI returns the original URI used to configure the ClientOptions instance.
+// If ApplyURI was not called during construction, this returns "".
+func (c *ClientOptions) GetURI() string {
+ if c != nil && c.connString != nil {
+ return c.connString.Original
}
- if cs.SRVMaxHosts != 0 {
- c.SRVMaxHosts = &cs.SRVMaxHosts
+ return ""
+}
+
+// Validate validates the client options. This method will return the first
+// error found.
+func (c *ClientOptions) Validate() error {
+ if c.err != nil {
+ return c.err
}
- if cs.SRVServiceName != "" {
- c.SRVServiceName = &cs.SRVServiceName
+ // Direct connections cannot be made if multiple hosts are specified or an SRV
+ // URI is used.
+ if c.Direct != nil && *c.Direct {
+ if len(c.Hosts) > 1 {
+ return errors.New("a direct connection cannot be made if multiple hosts are specified")
+ }
+ if c.connString != nil && c.connString.Scheme == connstring.SchemeMongoDBSRV {
+ return errors.New("a direct connection cannot be made if an SRV URI is used")
+ }
}
- if cs.SSL {
- tlsConfig := new(tls.Config)
+ if c.HeartbeatInterval != nil && *c.HeartbeatInterval < (500*time.Millisecond) {
+ return fmt.Errorf("heartbeatFrequencyMS must exceed the minimum heartbeat interval of 500ms, got heartbeatFrequencyMS=%q",
+ *c.HeartbeatInterval)
+ }
- if cs.SSLCaFileSet {
- c.err = addCACertFromFile(tlsConfig, cs.SSLCaFile)
- if c.err != nil {
- return c
- }
- }
+ if c.MaxPoolSize != nil && c.MinPoolSize != nil && *c.MaxPoolSize != 0 &&
+ *c.MinPoolSize > *c.MaxPoolSize {
+ return fmt.Errorf("minPoolSize must be less than or equal to maxPoolSize, got minPoolSize=%d maxPoolSize=%d",
+ *c.MinPoolSize, *c.MaxPoolSize)
+ }
- if cs.SSLInsecure {
- tlsConfig.InsecureSkipVerify = true
+ // verify server API version if ServerAPIOptions are passed in.
+ if c.ServerAPIOptions != nil {
+ if err := c.ServerAPIOptions.ServerAPIVersion.Validate(); err != nil {
+ return err
}
+ }
- var x509Subject string
- var keyPasswd string
- if cs.SSLClientCertificateKeyPasswordSet && cs.SSLClientCertificateKeyPassword != nil {
- keyPasswd = cs.SSLClientCertificateKeyPassword()
+ // Validation for load-balanced mode.
+ if c.LoadBalanced != nil && *c.LoadBalanced {
+ if len(c.Hosts) > 1 {
+ return connstring.ErrLoadBalancedWithMultipleHosts
}
- if cs.SSLClientCertificateKeyFileSet {
- x509Subject, err = addClientCertFromConcatenatedFile(tlsConfig, cs.SSLClientCertificateKeyFile, keyPasswd)
- } else if cs.SSLCertificateFileSet || cs.SSLPrivateKeyFileSet {
- x509Subject, err = addClientCertFromSeparateFiles(tlsConfig, cs.SSLCertificateFile,
- cs.SSLPrivateKeyFile, keyPasswd)
+ if c.ReplicaSet != nil {
+ return connstring.ErrLoadBalancedWithReplicaSet
}
- if err != nil {
- c.err = err
- return c
+ if c.Direct != nil && *c.Direct {
+ return connstring.ErrLoadBalancedWithDirectConnection
}
+ }
- // If a username wasn't specified fork x509, add one from the certificate.
- if c.Auth != nil && strings.ToLower(c.Auth.AuthMechanism) == "mongodb-x509" &&
- c.Auth.Username == "" {
-
- // The Go x509 package gives the subject with the pairs in reverse order that we want.
- c.Auth.Username = extractX509UsernameFromSubject(x509Subject)
+ // Validation for srvMaxHosts.
+ if c.SRVMaxHosts != nil && *c.SRVMaxHosts > 0 {
+ if c.ReplicaSet != nil {
+ return connstring.ErrSRVMaxHostsWithReplicaSet
+ }
+ if c.LoadBalanced != nil && *c.LoadBalanced {
+ return connstring.ErrSRVMaxHostsWithLoadBalanced
}
+ }
- c.TLSConfig = tlsConfig
+ if mode := c.ServerMonitoringMode; mode != nil && !connstring.IsValidServerMonitoringMode(*mode) {
+ return fmt.Errorf("invalid server monitoring mode: %q", *mode)
}
- if cs.JSet || cs.WString != "" || cs.WNumberSet || cs.WTimeoutSet {
- opts := make([]writeconcern.Option, 0, 1)
+ if to := c.Timeout; to != nil && *to < 0 {
+ return fmt.Errorf(`invalid value %q for "Timeout": value must be positive`, *to)
+ }
- if len(cs.WString) > 0 {
- opts = append(opts, writeconcern.WTagSet(cs.WString))
- } else if cs.WNumberSet {
- opts = append(opts, writeconcern.W(cs.WNumber))
+ // OIDC Validation
+ if c.Auth != nil && c.Auth.AuthMechanism == auth.MongoDBOIDC {
+ if c.Auth.Password != "" {
+ return fmt.Errorf("password must not be set for the %s auth mechanism", auth.MongoDBOIDC)
}
-
- if cs.JSet {
- opts = append(opts, writeconcern.J(cs.J))
+ if c.Auth.OIDCMachineCallback != nil && c.Auth.OIDCHumanCallback != nil {
+ return fmt.Errorf("cannot set both OIDCMachineCallback and OIDCHumanCallback, only one may be specified")
+ }
+ if c.Auth.OIDCHumanCallback == nil && c.Auth.AuthMechanismProperties[auth.AllowedHostsProp] != "" {
+ return fmt.Errorf("cannot specify ALLOWED_HOSTS without an OIDCHumanCallback")
+ }
+ if c.Auth.OIDCMachineCallback == nil && c.Auth.OIDCHumanCallback == nil && c.Auth.AuthMechanismProperties[auth.EnvironmentProp] == "" {
+ return errors.New("must specify at least one of OIDCMachineCallback, OIDCHumanCallback, or ENVIRONMENT authMechanismProperty")
}
- if cs.WTimeoutSet {
- opts = append(opts, writeconcern.WTimeout(cs.WTimeout))
+ // Return an error if an unsupported authMechanismProperty is specified
+ // for MONGODB-OIDC.
+ for prop := range c.Auth.AuthMechanismProperties {
+ switch prop {
+ case auth.AllowedHostsProp, auth.EnvironmentProp, auth.ResourceProp:
+ default:
+ return fmt.Errorf("auth mechanism property %q is not valid for MONGODB-OIDC", prop)
+ }
}
- c.WriteConcern = writeconcern.New(opts...)
+ if env, ok := c.Auth.AuthMechanismProperties[auth.EnvironmentProp]; ok {
+ switch env {
+ case auth.GCPEnvironmentValue, auth.AzureEnvironmentValue:
+ if c.Auth.AuthMechanismProperties[auth.ResourceProp] == "" {
+ return fmt.Errorf("%q must be set for the %s %q", auth.ResourceProp, env, auth.EnvironmentProp)
+ }
+ fallthrough
+ case auth.K8SEnvironmentValue:
+ if c.Auth.OIDCMachineCallback != nil {
+ return fmt.Errorf("OIDCMachineCallback cannot be specified with the %s %q", env, auth.EnvironmentProp)
+ }
+ if c.Auth.OIDCHumanCallback != nil {
+ return fmt.Errorf("OIDCHumanCallback cannot be specified with the %s %q", env, auth.EnvironmentProp)
+ }
+ case auth.TestEnvironmentValue:
+ if c.Auth.AuthMechanismProperties[auth.ResourceProp] != "" {
+ return fmt.Errorf("%q must not be set for the %s %q", auth.ResourceProp, env, auth.EnvironmentProp)
+ }
+ if c.Auth.Username != "" {
+ return fmt.Errorf("must not specify username for %s %q", env, auth.EnvironmentProp)
+ }
+ default:
+ return fmt.Errorf("the %s %q is not supported for MONGODB-OIDC", env, auth.EnvironmentProp)
+ }
+ }
}
- if cs.ZlibLevelSet {
- c.ZlibLevel = &cs.ZlibLevel
- }
- if cs.ZstdLevelSet {
- c.ZstdLevel = &cs.ZstdLevel
- }
+ return nil
+}
- if cs.SSLDisableOCSPEndpointCheckSet {
- c.DisableOCSPEndpointCheck = &cs.SSLDisableOCSPEndpointCheck
+// ApplyURI parses the given URI and sets options accordingly. The URI can contain host names, IPv4/IPv6 literals, or
+// an SRV record that will be resolved when the Client is created. When using an SRV record, TLS support is
+// implicitly enabled. Specify the "tls=false" URI option to override this.
+//
+// If the connection string contains any options that have previously been set, it will overwrite them. Options that
+// correspond to multiple URI parameters, such as WriteConcern, will be completely overwritten if any of the query
+// parameters are specified. If an option is set on ClientOptions after this method is called, that option will override
+// any option applied via the connection string.
+//
+// If the URI format is incorrect or there are conflicting options specified in the URI an error will be recorded and
+// can be retrieved by calling Validate.
+//
+// For more information about the URI format, see https://www.mongodb.com/docs/manual/reference/connection-string/. See
+// mongo.Connect documentation for examples of using URIs for different Client configurations.
+func (c *ClientOptions) ApplyURI(uri string) *ClientOptions {
+ if c.err != nil {
+ return c
}
- if cs.TimeoutSet {
- c.Timeout = &cs.Timeout
- }
+ c.err = setURIOpts(uri, c)
return c
}
@@ -641,6 +696,7 @@ func (c *ClientOptions) ApplyURI(uri string) *ClientOptions {
// URI option (e.g "appName=example_application"). The default is empty, meaning no app name will be sent.
func (c *ClientOptions) SetAppName(s string) *ClientOptions {
c.AppName = &s
+
return c
}
@@ -649,14 +705,15 @@ func (c *ClientOptions) SetAppName(s string) *ClientOptions {
// authentication will be configured.
func (c *ClientOptions) SetAuth(auth Credential) *ClientOptions {
c.Auth = &auth
+
return c
}
// SetCompressors sets the compressors that can be used when communicating with a server. Valid values are:
//
-// 1. "snappy" - requires server version >= 3.4
+// 1. "snappy"
//
-// 2. "zlib" - requires server version >= 3.6
+// 2. "zlib"
//
// 3. "zstd" - requires server version >= 4.2, and driver version >= 1.2.0 with cgo support enabled or driver
// version >= 1.3.0 without cgo.
@@ -679,6 +736,7 @@ func (c *ClientOptions) SetCompressors(comps []string) *ClientOptions {
// default is 30 seconds.
func (c *ClientOptions) SetConnectTimeout(d time.Duration) *ClientOptions {
c.ConnectTimeout = &d
+
return c
}
@@ -687,6 +745,7 @@ func (c *ClientOptions) SetConnectTimeout(d time.Duration) *ClientOptions {
// See https://golang.org/pkg/net/#Dialer for more information about the net.Dialer type.
func (c *ClientOptions) SetDialer(d ContextDialer) *ClientOptions {
c.Dialer = d
+
return c
}
@@ -707,13 +766,16 @@ func (c *ClientOptions) SetDialer(d ContextDialer) *ClientOptions {
// value for this option is false.
func (c *ClientOptions) SetDirect(b bool) *ClientOptions {
c.Direct = &b
+
return c
}
// SetHeartbeatInterval specifies the amount of time to wait between periodic background server checks. This can also be
-// set through the "heartbeatIntervalMS" URI option (e.g. "heartbeatIntervalMS=10000"). The default is 10 seconds.
+// set through the "heartbeatFrequencyMS" URI option (e.g. "heartbeatFrequencyMS=10000"). The default is 10 seconds.
+// The minimum is 500ms.
func (c *ClientOptions) SetHeartbeatInterval(d time.Duration) *ClientOptions {
c.HeartbeatInterval = &d
+
return c
}
@@ -724,6 +786,7 @@ func (c *ClientOptions) SetHeartbeatInterval(d time.Duration) *ClientOptions {
// "localhost:27018", a URI could be "mongodb://localhost:27017,localhost:27018". The default is ["localhost:27017"]
func (c *ClientOptions) SetHosts(s []string) *ClientOptions {
c.Hosts = s
+
return c
}
@@ -739,6 +802,7 @@ func (c *ClientOptions) SetHosts(s []string) *ClientOptions {
// The default value is false.
func (c *ClientOptions) SetLoadBalanced(lb bool) *ClientOptions {
c.LoadBalanced = &lb
+
return c
}
@@ -748,13 +812,14 @@ func (c *ClientOptions) SetLoadBalanced(lb bool) *ClientOptions {
// "localThresholdMS=15000"). The default is 15 milliseconds.
func (c *ClientOptions) SetLocalThreshold(d time.Duration) *ClientOptions {
c.LocalThreshold = &d
+
return c
}
// SetLoggerOptions specifies a LoggerOptions containing options for
// configuring a logger.
-func (c *ClientOptions) SetLoggerOptions(opts *LoggerOptions) *ClientOptions {
- c.LoggerOptions = opts
+func (c *ClientOptions) SetLoggerOptions(lopts *LoggerOptions) *ClientOptions {
+ c.LoggerOptions = lopts
return c
}
@@ -764,6 +829,7 @@ func (c *ClientOptions) SetLoggerOptions(opts *LoggerOptions) *ClientOptions {
// "maxIdleTimeMS=10000"). The default is 0, meaning a connection can remain unused indefinitely.
func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions {
c.MaxConnIdleTime = &d
+
return c
}
@@ -772,6 +838,7 @@ func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions {
// (e.g. "maxPoolSize=100"). If this is 0, maximum connection pool size is not limited. The default is 100.
func (c *ClientOptions) SetMaxPoolSize(u uint64) *ClientOptions {
c.MaxPoolSize = &u
+
return c
}
@@ -780,6 +847,7 @@ func (c *ClientOptions) SetMaxPoolSize(u uint64) *ClientOptions {
// the minimum. This can also be set through the "minPoolSize" URI option (e.g. "minPoolSize=100"). The default is 0.
func (c *ClientOptions) SetMinPoolSize(u uint64) *ClientOptions {
c.MinPoolSize = &u
+
return c
}
@@ -788,6 +856,7 @@ func (c *ClientOptions) SetMinPoolSize(u uint64) *ClientOptions {
// default is 2. Values greater than 100 are not recommended.
func (c *ClientOptions) SetMaxConnecting(u uint64) *ClientOptions {
c.MaxConnecting = &u
+
return c
}
@@ -795,6 +864,7 @@ func (c *ClientOptions) SetMaxConnecting(u uint64) *ClientOptions {
// for more information about the structure of the monitor and events that can be received.
func (c *ClientOptions) SetPoolMonitor(m *event.PoolMonitor) *ClientOptions {
c.PoolMonitor = m
+
return c
}
@@ -802,12 +872,14 @@ func (c *ClientOptions) SetPoolMonitor(m *event.PoolMonitor) *ClientOptions {
// information about the structure of the monitor and events that can be received.
func (c *ClientOptions) SetMonitor(m *event.CommandMonitor) *ClientOptions {
c.Monitor = m
+
return c
}
// SetServerMonitor specifies an SDAM monitor used to monitor SDAM events.
func (c *ClientOptions) SetServerMonitor(m *event.ServerMonitor) *ClientOptions {
c.ServerMonitor = m
+
return c
}
@@ -840,15 +912,17 @@ func (c *ClientOptions) SetReadPreference(rp *readpref.ReadPref) *ClientOptions
}
// SetBSONOptions configures optional BSON marshaling and unmarshaling behavior.
-func (c *ClientOptions) SetBSONOptions(opts *BSONOptions) *ClientOptions {
- c.BSONOptions = opts
+func (c *ClientOptions) SetBSONOptions(bopts *BSONOptions) *ClientOptions {
+ c.BSONOptions = bopts
+
return c
}
// SetRegistry specifies the BSON registry to use for BSON marshalling/unmarshalling operations. The default is
-// bson.DefaultRegistry.
-func (c *ClientOptions) SetRegistry(registry *bsoncodec.Registry) *ClientOptions {
+// bson.NewRegistry().
+func (c *ClientOptions) SetRegistry(registry *bson.Registry) *ClientOptions {
c.Registry = registry
+
return c
}
@@ -859,6 +933,7 @@ func (c *ClientOptions) SetRegistry(registry *bsoncodec.Registry) *ClientOptions
// "replicaSet=replset"). The default is empty.
func (c *ClientOptions) SetReplicaSet(s string) *ClientOptions {
c.ReplicaSet = &s
+
return c
}
@@ -870,9 +945,8 @@ func (c *ClientOptions) SetReplicaSet(s string) *ClientOptions {
// DeleteManyModel instances to be considered retryable. Unacknowledged writes will not be retried, even if this option
// is set to true.
//
-// This option requires server version >= 3.6 and a replica set or sharded cluster and will be ignored for any other
-// cluster type. This can also be set through the "retryWrites" URI option (e.g. "retryWrites=true"). The default is
-// true.
+// This option only works on a replica set or sharded cluster and will be ignored for any other cluster type.
+// This can also be set through the "retryWrites" URI option (e.g. "retryWrites=true"). The default is true.
func (c *ClientOptions) SetRetryWrites(b bool) *ClientOptions {
c.RetryWrites = &b
@@ -886,9 +960,28 @@ func (c *ClientOptions) SetRetryWrites(b bool) *ClientOptions {
// EstimatedDocumentCount, Watch (for Client, Database, and Collection), ListCollections, and ListDatabases. Note that
// operations run through RunCommand are not retried.
//
-// This option requires server version >= 3.6 and driver version >= 1.1.0. The default is true.
+// The default is true.
func (c *ClientOptions) SetRetryReads(b bool) *ClientOptions {
c.RetryReads = &b
+
+ return c
+}
+
+// SetMaxAdaptiveRetries specifies the maximum number of times the driver should retry operations that fail with a
+// server side overload error. MaxAdaptiveRetries can also be set through the "maxAdaptiveRetries" URI option
+// (e.g. "maxAdaptiveRetries=5").
+func (c *ClientOptions) SetMaxAdaptiveRetries(n uint) *ClientOptions {
+ c.MaxAdaptiveRetries = &n
+
+ return c
+}
+
+// SetEnableOverloadRetargeting specifies whether the driver should enable overload retargeting for operations that fail
+// with a server side overload error. EnableOverloadRetargeting can also be set through the "enableOverloadRetargeting"
+// URI option (e.g. "enableOverloadRetargeting=true").
+func (c *ClientOptions) SetEnableOverloadRetargeting(b bool) *ClientOptions {
+ c.EnableOverloadRetargeting = &b
+
return c
}
@@ -897,34 +990,24 @@ func (c *ClientOptions) SetRetryReads(b bool) *ClientOptions {
// "serverSelectionTimeoutMS=30000"). The default value is 30 seconds.
func (c *ClientOptions) SetServerSelectionTimeout(d time.Duration) *ClientOptions {
c.ServerSelectionTimeout = &d
- return c
-}
-// SetSocketTimeout specifies how long the driver will wait for a socket read or write to return before returning a
-// network error. This can also be set through the "socketTimeoutMS" URI option (e.g. "socketTimeoutMS=1000"). The
-// default value is 0, meaning no timeout is used and socket operations can block indefinitely.
-//
-// NOTE(benjirewis): SocketTimeout will be deprecated in a future release. The more general Timeout option may be used
-// in its place to control the amount of time that a single operation can run before returning an error. Setting
-// SocketTimeout and Timeout on a single client will result in undefined behavior.
-func (c *ClientOptions) SetSocketTimeout(d time.Duration) *ClientOptions {
- c.SocketTimeout = &d
return c
}
-// SetTimeout specifies the amount of time that a single operation run on this Client can execute before returning an error.
-// The deadline of any operation run through the Client will be honored above any Timeout set on the Client; Timeout will only
-// be honored if there is no deadline on the operation Context. Timeout can also be set through the "timeoutMS" URI option
-// (e.g. "timeoutMS=1000"). The default value is nil, meaning operations do not inherit a timeout from the Client.
-//
-// If any Timeout is set (even 0) on the Client, the values of MaxTime on operation options, TransactionOptions.MaxCommitTime and
-// SessionOptions.DefaultMaxCommitTime will be ignored. Setting Timeout and SocketTimeout or WriteConcern.wTimeout will result
-// in undefined behavior.
+// SetTimeout specifies the amount of time that a single operation run on this
+// Client can execute before returning an error. The deadline of any operation
+// run through the Client will be honored above any Timeout set on the Client;
+// Timeout will only be honored if there is no deadline on the operation
+// Context. Timeout can also be set through the "timeoutMS" URI option
+// (e.g. "timeoutMS=1000"). The default value is nil, meaning operations do not
+// inherit a timeout from the Client.
//
-// NOTE(benjirewis): SetTimeout represents unstable, provisional API. The behavior of the driver when a Timeout is specified is
-// subject to change.
+// If any Timeout is set (even 0) on the Client, the values of MaxTime on
+// operation options, TransactionOptions.MaxCommitTime and
+// SessionOptions.DefaultMaxCommitTime will be ignored.
func (c *ClientOptions) SetTimeout(d time.Duration) *ClientOptions {
c.Timeout = &d
+
return c
}
@@ -954,6 +1037,7 @@ func (c *ClientOptions) SetTimeout(d time.Duration) *ClientOptions {
// The default is nil, meaning no TLS will be enabled.
func (c *ClientOptions) SetTLSConfig(cfg *tls.Config) *ClientOptions {
c.TLSConfig = cfg
+
return c
}
@@ -962,6 +1046,7 @@ func (c *ClientOptions) SetTLSConfig(cfg *tls.Config) *ClientOptions {
// This should only be used to set custom HTTP client configurations. By default, the connection will use an httputil.DefaultHTTPClient.
func (c *ClientOptions) SetHTTPClient(client *http.Client) *ClientOptions {
c.HTTPClient = client
+
return c
}
@@ -1000,14 +1085,16 @@ func (c *ClientOptions) SetZlibLevel(level int) *ClientOptions {
// best compression. This can also be set through the "zstdCompressionLevel" URI option. Defaults to 6.
func (c *ClientOptions) SetZstdLevel(level int) *ClientOptions {
c.ZstdLevel = &level
+
return c
}
// SetAutoEncryptionOptions specifies an AutoEncryptionOptions instance to automatically encrypt and decrypt commands
// and their results. See the options.AutoEncryptionOptions documentation for more information about the supported
// options.
-func (c *ClientOptions) SetAutoEncryptionOptions(opts *AutoEncryptionOptions) *ClientOptions {
- c.AutoEncryptionOptions = opts
+func (c *ClientOptions) SetAutoEncryptionOptions(aeopts *AutoEncryptionOptions) *ClientOptions {
+ c.AutoEncryptionOptions = aeopts
+
return c
}
@@ -1022,14 +1109,16 @@ func (c *ClientOptions) SetAutoEncryptionOptions(opts *AutoEncryptionOptions) *C
// not be set at the same time and will error if they are. The default value is false.
func (c *ClientOptions) SetDisableOCSPEndpointCheck(disableCheck bool) *ClientOptions {
c.DisableOCSPEndpointCheck = &disableCheck
+
return c
}
// SetServerAPIOptions specifies a ServerAPIOptions instance used to configure the API version sent to the server
// when running commands. See the options.ServerAPIOptions documentation for more information about the supported
// options.
-func (c *ClientOptions) SetServerAPIOptions(opts *ServerAPIOptions) *ClientOptions {
- c.ServerAPIOptions = opts
+func (c *ClientOptions) SetServerAPIOptions(sopts *ServerAPIOptions) *ClientOptions {
+ c.ServerAPIOptions = sopts
+
return c
}
@@ -1048,6 +1137,7 @@ func (c *ClientOptions) SetServerMonitoringMode(mode string) *ClientOptions {
// the "srvMaxHosts" URI option.
func (c *ClientOptions) SetSRVMaxHosts(srvMaxHosts int) *ClientOptions {
c.SRVMaxHosts = &srvMaxHosts
+
return c
}
@@ -1056,153 +1146,15 @@ func (c *ClientOptions) SetSRVMaxHosts(srvMaxHosts int) *ClientOptions {
// URI option.
func (c *ClientOptions) SetSRVServiceName(srvName string) *ClientOptions {
c.SRVServiceName = &srvName
+
return c
}
-// MergeClientOptions combines the given *ClientOptions into a single *ClientOptions in a last one wins fashion.
-// The specified options are merged with the existing options on the client, with the specified options taking
-// precedence.
-func MergeClientOptions(opts ...*ClientOptions) *ClientOptions {
- c := Client()
-
- for _, opt := range opts {
- if opt == nil {
- continue
- }
-
- if opt.Dialer != nil {
- c.Dialer = opt.Dialer
- }
- if opt.AppName != nil {
- c.AppName = opt.AppName
- }
- if opt.Auth != nil {
- c.Auth = opt.Auth
- }
- if opt.AuthenticateToAnything != nil {
- c.AuthenticateToAnything = opt.AuthenticateToAnything
- }
- if opt.Compressors != nil {
- c.Compressors = opt.Compressors
- }
- if opt.ConnectTimeout != nil {
- c.ConnectTimeout = opt.ConnectTimeout
- }
- if opt.Crypt != nil {
- c.Crypt = opt.Crypt
- }
- if opt.HeartbeatInterval != nil {
- c.HeartbeatInterval = opt.HeartbeatInterval
- }
- if len(opt.Hosts) > 0 {
- c.Hosts = opt.Hosts
- }
- if opt.HTTPClient != nil {
- c.HTTPClient = opt.HTTPClient
- }
- if opt.LoadBalanced != nil {
- c.LoadBalanced = opt.LoadBalanced
- }
- if opt.LocalThreshold != nil {
- c.LocalThreshold = opt.LocalThreshold
- }
- if opt.MaxConnIdleTime != nil {
- c.MaxConnIdleTime = opt.MaxConnIdleTime
- }
- if opt.MaxPoolSize != nil {
- c.MaxPoolSize = opt.MaxPoolSize
- }
- if opt.MinPoolSize != nil {
- c.MinPoolSize = opt.MinPoolSize
- }
- if opt.MaxConnecting != nil {
- c.MaxConnecting = opt.MaxConnecting
- }
- if opt.PoolMonitor != nil {
- c.PoolMonitor = opt.PoolMonitor
- }
- if opt.Monitor != nil {
- c.Monitor = opt.Monitor
- }
- if opt.ServerAPIOptions != nil {
- c.ServerAPIOptions = opt.ServerAPIOptions
- }
- if opt.ServerMonitor != nil {
- c.ServerMonitor = opt.ServerMonitor
- }
- if opt.ReadConcern != nil {
- c.ReadConcern = opt.ReadConcern
- }
- if opt.ReadPreference != nil {
- c.ReadPreference = opt.ReadPreference
- }
- if opt.BSONOptions != nil {
- c.BSONOptions = opt.BSONOptions
- }
- if opt.Registry != nil {
- c.Registry = opt.Registry
- }
- if opt.ReplicaSet != nil {
- c.ReplicaSet = opt.ReplicaSet
- }
- if opt.RetryWrites != nil {
- c.RetryWrites = opt.RetryWrites
- }
- if opt.RetryReads != nil {
- c.RetryReads = opt.RetryReads
- }
- if opt.ServerSelectionTimeout != nil {
- c.ServerSelectionTimeout = opt.ServerSelectionTimeout
- }
- if opt.Direct != nil {
- c.Direct = opt.Direct
- }
- if opt.SocketTimeout != nil {
- c.SocketTimeout = opt.SocketTimeout
- }
- if opt.SRVMaxHosts != nil {
- c.SRVMaxHosts = opt.SRVMaxHosts
- }
- if opt.SRVServiceName != nil {
- c.SRVServiceName = opt.SRVServiceName
- }
- if opt.Timeout != nil {
- c.Timeout = opt.Timeout
- }
- if opt.TLSConfig != nil {
- c.TLSConfig = opt.TLSConfig
- }
- if opt.WriteConcern != nil {
- c.WriteConcern = opt.WriteConcern
- }
- if opt.ZlibLevel != nil {
- c.ZlibLevel = opt.ZlibLevel
- }
- if opt.ZstdLevel != nil {
- c.ZstdLevel = opt.ZstdLevel
- }
- if opt.AutoEncryptionOptions != nil {
- c.AutoEncryptionOptions = opt.AutoEncryptionOptions
- }
- if opt.Deployment != nil {
- c.Deployment = opt.Deployment
- }
- if opt.DisableOCSPEndpointCheck != nil {
- c.DisableOCSPEndpointCheck = opt.DisableOCSPEndpointCheck
- }
- if opt.err != nil {
- c.err = opt.err
- }
- if opt.cs != nil {
- c.cs = opt.cs
- }
- if opt.LoggerOptions != nil {
- c.LoggerOptions = opt.LoggerOptions
- }
- if opt.ServerMonitoringMode != nil {
- c.ServerMonitoringMode = opt.ServerMonitoringMode
- }
- }
+// SetDriverInfo configures optional data to include in the handshake's client
+// metadata, delimited by "|" with the driver-generated data. This should be
+// used by libraries wrapping the driver, e.g. ODMs.
+func (c *ClientOptions) SetDriverInfo(info *DriverInfo) *ClientOptions {
+ c.DriverInfo = info
return c
}
@@ -1243,11 +1195,11 @@ func addClientCertFromSeparateFiles(cfg *tls.Config, keyFile, certFile, keyPassw
if certSize > 64*1024*1024 {
return "", errors.New("X.509 certificate must be less than 64 MiB")
}
- dataSize := keySize + certSize + 1
+ dataSize := int64(keySize) + int64(certSize) + 1
if dataSize > math.MaxInt {
return "", errors.New("size overflow")
}
- data := make([]byte, 0, dataSize)
+ data := make([]byte, 0, int(dataSize))
data = append(data, keyData...)
data = append(data, '\n')
data = append(data, certData...)
@@ -1372,3 +1324,45 @@ func extractX509UsernameFromSubject(subject string) string {
return strings.Join(pairs, ",")
}
+
+// MergeClientOptions combines the given *ClientOptions into a single
+// *ClientOptions in a last one wins fashion. The specified options are merged
+// with the existing options on the client, with the specified options taking
+// precedence.
+func MergeClientOptions(opts ...*ClientOptions) *ClientOptions {
+ if len(opts) == 1 {
+ if opts[0] == nil {
+ return Client()
+ }
+
+ return opts[0]
+ }
+
+ c := Client()
+ for _, opt := range opts {
+ if opt == nil {
+ continue
+ }
+ optValue := reflect.ValueOf(opt).Elem()
+ cValue := reflect.ValueOf(c).Elem()
+ for i := 0; i < optValue.NumField(); i++ {
+ field := optValue.Field(i)
+ fieldType := optValue.Type().Field(i)
+ // Check if the field is exported and can be set
+ if field.CanSet() && fieldType.PkgPath == "" && !field.IsZero() {
+ cValue.Field(i).Set(field)
+ }
+ }
+
+ // Manually handle unexported fields
+ if opt.err != nil {
+ c.err = opt.err
+ }
+
+ if opt.connString != nil {
+ c.connString = opt.connString
+ }
+ }
+
+ return c
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/collectionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/collectionoptions.go
new file mode 100644
index 000000000..9cc6d1360
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/collectionoptions.go
@@ -0,0 +1,105 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+)
+
+// CollectionOptions represents arguments that can be used to configure a Collection.
+//
+// See corresponding setter methods for documentation.
+type CollectionOptions struct {
+ ReadConcern *readconcern.ReadConcern
+ WriteConcern *writeconcern.WriteConcern
+ ReadPreference *readpref.ReadPref
+ BSONOptions *BSONOptions
+ Registry *bson.Registry
+}
+
+// CollectionOptionsBuilder contains options to configure a Collection instance.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type CollectionOptionsBuilder struct {
+ Opts []func(*CollectionOptions) error
+}
+
+// Collection creates a new CollectionOptions instance.
+func Collection() *CollectionOptionsBuilder {
+ return &CollectionOptionsBuilder{}
+}
+
+// List returns a list of CollectionOptions setter functions.
+func (c *CollectionOptionsBuilder) List() []func(*CollectionOptions) error {
+ return c.Opts
+}
+
+// SetReadConcern sets the value for the ReadConcern field. ReadConcern is the read concern to use for
+// operations executed on the Collection. The default value is nil, which means that the read concern
+// of the Database used to configure the Collection will be used.
+func (c *CollectionOptionsBuilder) SetReadConcern(rc *readconcern.ReadConcern) *CollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CollectionOptions) error {
+ opts.ReadConcern = rc
+
+ return nil
+ })
+
+ return c
+}
+
+// SetWriteConcern sets the value for the WriteConcern field. WriteConcern is the write concern to
+// use for operations executed on the Collection. The default value is nil, which means that the write
+// concern of the Database used to configure the Collection will be used.
+func (c *CollectionOptionsBuilder) SetWriteConcern(wc *writeconcern.WriteConcern) *CollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CollectionOptions) error {
+ opts.WriteConcern = wc
+
+ return nil
+ })
+
+ return c
+}
+
+// SetReadPreference sets the value for the ReadPreference field. ReadPreference is the read preference
+// to use for operations executed on the Collection. The default value is nil, which means that the
+// read preference of the Database used to configure the Collection will be used.
+func (c *CollectionOptionsBuilder) SetReadPreference(rp *readpref.ReadPref) *CollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CollectionOptions) error {
+ opts.ReadPreference = rp
+
+ return nil
+ })
+
+ return c
+}
+
+// SetBSONOptions configures optional BSON marshaling and unmarshaling behavior. BSONOptions configures
+// optional BSON marshaling and unmarshaling behavior.
+func (c *CollectionOptionsBuilder) SetBSONOptions(bopts *BSONOptions) *CollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CollectionOptions) error {
+ opts.BSONOptions = bopts
+
+ return nil
+ })
+
+ return c
+}
+
+// SetRegistry sets the value for the Registry field. Registry is the BSON registry to marshal and
+// unmarshal documents for operations executed on the Collection. The default value is nil, which
+// means that the registry of the Database used to configure the Collection will be used.
+func (c *CollectionOptionsBuilder) SetRegistry(r *bson.Registry) *CollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CollectionOptions) error {
+ opts.Registry = r
+
+ return nil
+ })
+ return c
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/countoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/countoptions.go
new file mode 100644
index 000000000..9cf5924a4
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/countoptions.go
@@ -0,0 +1,107 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// CountOptions represents arguments that can be used to configure a
+// CountDocuments operation.
+//
+// See corresponding setter methods for documentation.
+type CountOptions struct {
+ Collation *Collation
+ Comment any
+ Hint any
+ Limit *int64
+ Skip *int64
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// CountOptionsBuilder contains options to configure count operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type CountOptionsBuilder struct {
+ Opts []func(*CountOptions) error
+}
+
+// Count creates a new CountOptions instance.
+func Count() *CountOptionsBuilder {
+ return &CountOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (co *CountOptionsBuilder) List() []func(*CountOptions) error {
+ return co.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (co *CountOptionsBuilder) SetCollation(c *Collation) *CountOptionsBuilder {
+ co.Opts = append(co.Opts, func(opts *CountOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return co
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included
+// in server logs, profiling logs, and currentOp queries to help trace the operation. The default is nil,
+// which means that no comment will be included in the logs.
+func (co *CountOptionsBuilder) SetComment(comment any) *CountOptionsBuilder {
+ co.Opts = append(co.Opts, func(opts *CountOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return co
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the aggregation. This should
+// either be the index name as a string or the index specification as a document. The driver will return
+// an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint
+// will be sent.
+func (co *CountOptionsBuilder) SetHint(h any) *CountOptionsBuilder {
+ co.Opts = append(co.Opts, func(opts *CountOptions) error {
+ opts.Hint = h
+
+ return nil
+ })
+
+ return co
+}
+
+// SetLimit sets the value for the Limit field. Specifies the maximum number of documents to count. The
+// default value is 0, which means that there is no limit and all documents matching the filter will be
+// counted.
+func (co *CountOptionsBuilder) SetLimit(i int64) *CountOptionsBuilder {
+ co.Opts = append(co.Opts, func(opts *CountOptions) error {
+ opts.Limit = &i
+
+ return nil
+ })
+
+ return co
+}
+
+// SetSkip sets the value for the Skip field. Specifies the number of documents to skip before counting.
+// The default value is 0.
+func (co *CountOptionsBuilder) SetSkip(i int64) *CountOptionsBuilder {
+ co.Opts = append(co.Opts, func(opts *CountOptions) error {
+ opts.Skip = &i
+
+ return nil
+ })
+
+ return co
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/createcollectionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/createcollectionoptions.go
new file mode 100644
index 000000000..4bac0d040
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/createcollectionoptions.go
@@ -0,0 +1,413 @@
+// 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 (
+ "time"
+)
+
+// DefaultIndexOptions represents the default arguments for a collection to
+// apply on new indexes. This type can be used when creating a new collection
+// through the CreateCollectionOptions.SetDefaultIndexOptions method.
+//
+// See corresponding setter methods for documentation.
+type DefaultIndexOptions struct {
+ StorageEngine any
+}
+
+// DefaultIndexOptionsBuilder contains options to configure default index
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type DefaultIndexOptionsBuilder struct {
+ Opts []func(*DefaultIndexOptions) error
+}
+
+// DefaultIndex creates a new DefaultIndexOptions instance.
+func DefaultIndex() *DefaultIndexOptionsBuilder {
+ return &DefaultIndexOptionsBuilder{}
+}
+
+// List returns a list of DefaultIndexOptions setter functions.
+func (d *DefaultIndexOptionsBuilder) List() []func(*DefaultIndexOptions) error {
+ return d.Opts
+}
+
+// SetStorageEngine sets the value for the StorageEngine field. Specifies the storage engine to use for
+// the index. The value must be a document in the form {: }. The default
+// value is nil, which means that the default storage engine will be used.
+func (d *DefaultIndexOptionsBuilder) SetStorageEngine(storageEngine any) *DefaultIndexOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DefaultIndexOptions) error {
+ opts.StorageEngine = storageEngine
+
+ return nil
+ })
+
+ return d
+}
+
+// TimeSeriesOptions specifies arguments on a time-series collection.
+//
+// See corresponding setter methods for documentation.
+type TimeSeriesOptions struct {
+ TimeField string
+ MetaField *string
+ Granularity *string
+ BucketMaxSpan *time.Duration
+ BucketRounding *time.Duration
+}
+
+// TimeSeriesOptionsBuilder contains options to configure timeseries operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type TimeSeriesOptionsBuilder struct {
+ Opts []func(*TimeSeriesOptions) error
+}
+
+// TimeSeries creates a new TimeSeriesOptions instance.
+func TimeSeries() *TimeSeriesOptionsBuilder {
+ return &TimeSeriesOptionsBuilder{}
+}
+
+// List returns a list of TimeSeriesOptions setter functions.
+func (tso *TimeSeriesOptionsBuilder) List() []func(*TimeSeriesOptions) error {
+ return tso.Opts
+}
+
+// SetTimeField sets the value for the TimeField. TimeField is the top-level field to be used
+// for time. Inserted documents must have this field, and the field must be of the BSON UTC
+// datetime type (0x9).
+func (tso *TimeSeriesOptionsBuilder) SetTimeField(timeField string) *TimeSeriesOptionsBuilder {
+ tso.Opts = append(tso.Opts, func(opts *TimeSeriesOptions) error {
+ opts.TimeField = timeField
+
+ return nil
+ })
+
+ return tso
+}
+
+// SetMetaField sets the value for the MetaField. MetaField is the name of the top-level field
+// describing the series. This field is used to group related data and may be of any BSON type,
+// except for array. This name may not be the same as the TimeField or _id. This field is optional.
+func (tso *TimeSeriesOptionsBuilder) SetMetaField(metaField string) *TimeSeriesOptionsBuilder {
+ tso.Opts = append(tso.Opts, func(opts *TimeSeriesOptions) error {
+ opts.MetaField = &metaField
+
+ return nil
+ })
+
+ return tso
+}
+
+// SetGranularity sets the value for Granularity. Granularity is the granularity of time-series data.
+// Allowed granularity options are "seconds", "minutes" and "hours". This field is optional.
+func (tso *TimeSeriesOptionsBuilder) SetGranularity(granularity string) *TimeSeriesOptionsBuilder {
+ tso.Opts = append(tso.Opts, func(opts *TimeSeriesOptions) error {
+ opts.Granularity = &granularity
+
+ return nil
+ })
+
+ return tso
+}
+
+// SetBucketMaxSpan sets the value for BucketMaxSpan. BucketMaxSpan is the maximum range of time
+// values for a bucket. The time.Duration is rounded down to the nearest second and applied as
+// the command option: "bucketRoundingSeconds". This field is optional.
+func (tso *TimeSeriesOptionsBuilder) SetBucketMaxSpan(dur time.Duration) *TimeSeriesOptionsBuilder {
+ tso.Opts = append(tso.Opts, func(opts *TimeSeriesOptions) error {
+ opts.BucketMaxSpan = &dur
+
+ return nil
+ })
+
+ return tso
+}
+
+// SetBucketRounding sets the value for BucketRounding. BucketRounding is used to determine the
+// minimum time boundary when opening a new bucket by rounding the first timestamp down to the next
+// multiple of this value. The time.Duration is rounded down to the nearest second and applied as
+// the command option: "bucketRoundingSeconds". This field is optional.
+func (tso *TimeSeriesOptionsBuilder) SetBucketRounding(dur time.Duration) *TimeSeriesOptionsBuilder {
+ tso.Opts = append(tso.Opts, func(opts *TimeSeriesOptions) error {
+ opts.BucketRounding = &dur
+
+ return nil
+ })
+
+ return tso
+}
+
+// CreateCollectionOptions represents arguments that can be used to configure a
+// CreateCollection operation.
+//
+// See corresponding setter methods for documentation.
+type CreateCollectionOptions struct {
+ Capped *bool
+ Collation *Collation
+ ChangeStreamPreAndPostImages any
+ DefaultIndexOptions *DefaultIndexOptionsBuilder
+ MaxDocuments *int64
+ SizeInBytes *int64
+ StorageEngine any
+ ValidationAction *string
+ ValidationLevel *string
+ Validator any
+ ExpireAfterSeconds *int64
+ TimeSeriesOptions *TimeSeriesOptionsBuilder
+ EncryptedFields any
+ ClusteredIndex any
+}
+
+// CreateCollectionOptionsBuilder contains options to configure a new
+// collection. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type CreateCollectionOptionsBuilder struct {
+ Opts []func(*CreateCollectionOptions) error
+}
+
+// CreateCollection creates a new CreateCollectionOptions instance.
+func CreateCollection() *CreateCollectionOptionsBuilder {
+ return &CreateCollectionOptionsBuilder{}
+}
+
+// List returns a list of CreateCollectionOptions setter functions.
+func (c *CreateCollectionOptionsBuilder) List() []func(*CreateCollectionOptions) error {
+ return c.Opts
+}
+
+// SetCapped sets the value for the Capped field. Specifies if the collection is capped
+// (see https://www.mongodb.com/docs/manual/core/capped-collections/). If true, the SizeInBytes
+// option must also be specified. The default value is false.
+func (c *CreateCollectionOptionsBuilder) SetCapped(capped bool) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.Capped = &capped
+
+ return nil
+ })
+
+ return c
+}
+
+// SetCollation sets the value for the Collation field. Specifies the default
+// collation for the new collection. The default value is nil.
+func (c *CreateCollectionOptionsBuilder) SetCollation(collation *Collation) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return c
+}
+
+// SetChangeStreamPreAndPostImages sets the value for the ChangeStreamPreAndPostImages field.
+// Specifies how change streams opened against the collection can return pre- and post-images of
+// updated documents. The value must be a document in the form {: }. This
+// option is only valid for MongoDB versions >= 6.0. The default value is nil, which means that
+// change streams opened against the collection will not return pre- and post-images of updated
+// documents in any way.
+func (c *CreateCollectionOptionsBuilder) SetChangeStreamPreAndPostImages(csppi any) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.ChangeStreamPreAndPostImages = &csppi
+
+ return nil
+ })
+
+ return c
+}
+
+// SetDefaultIndexOptions sets the value for the DefaultIndexOptions field.
+// Specifies a default configuration for indexes on the collection. The default
+// value is nil, meaning indexes will be configured using server defaults.
+func (c *CreateCollectionOptionsBuilder) SetDefaultIndexOptions(iopts *DefaultIndexOptionsBuilder) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.DefaultIndexOptions = iopts
+
+ return nil
+ })
+
+ return c
+}
+
+// SetMaxDocuments sets the value for the MaxDocuments field. Specifies the maximum number of documents
+// allowed in a capped collection. The limit specified by the SizeInBytes option takes precedence over
+// this option. If a capped collection reaches its size limit, old documents will be removed, regardless
+// of the number of documents in the collection. The default value is 0, meaning the maximum number of
+// documents is unbounded.
+func (c *CreateCollectionOptionsBuilder) SetMaxDocuments(max int64) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.MaxDocuments = &max
+
+ return nil
+ })
+
+ return c
+}
+
+// SetSizeInBytes sets the value for the SizeInBytes field. Specifies the maximum size in bytes for a
+// capped collection. The default value is 0.
+func (c *CreateCollectionOptionsBuilder) SetSizeInBytes(size int64) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.SizeInBytes = &size
+
+ return nil
+ })
+
+ return c
+}
+
+// SetStorageEngine sets the value for the StorageEngine field. Specifies the storage engine to use for
+// the index. The value must be a document in the form {: }. The default
+// value is nil, which means that the default storage engine will be used.
+func (c *CreateCollectionOptionsBuilder) SetStorageEngine(storageEngine any) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.StorageEngine = &storageEngine
+
+ return nil
+ })
+
+ return c
+}
+
+// SetValidationAction sets the value for the ValidationAction field. Specifies what should happen if a
+// document being inserted does not pass validation. Valid values are "error" and "warn". See
+// https://www.mongodb.com/docs/manual/core/schema-validation/#accept-or-reject-invalid-documents for more
+// information. The default value is "error".
+func (c *CreateCollectionOptionsBuilder) SetValidationAction(action string) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.ValidationAction = &action
+
+ return nil
+ })
+
+ return c
+}
+
+// SetValidationLevel sets the value for the ValidationLevel field. Specifies how strictly the server applies
+// validation rules to existing documents in the collection during update operations. Valid values are "off",
+// "strict", and "moderate". See https://www.mongodb.com/docs/manual/core/schema-validation/#existing-documents
+// for more information. The default value is "strict".
+func (c *CreateCollectionOptionsBuilder) SetValidationLevel(level string) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.ValidationLevel = &level
+
+ return nil
+ })
+
+ return c
+}
+
+// SetValidator sets the value for the Validator field. Sets a document specifying validation rules for the
+// collection. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about
+// schema validation. The default value is nil, meaning no validator will be used for the collection.
+func (c *CreateCollectionOptionsBuilder) SetValidator(validator any) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.Validator = validator
+
+ return nil
+ })
+
+ return c
+}
+
+// SetExpireAfterSeconds sets the value for the ExpireAfterSeconds field. Specifies value
+// indicating after how many seconds old time-series data should be deleted.
+// See https://www.mongodb.com/docs/manual/reference/command/create/ for supported options,
+// and https://www.mongodb.com/docs/manual/core/timeseries-collections/ for more information
+// on time-series collections.
+//
+// This option is only valid for MongoDB versions >= 5.0
+func (c *CreateCollectionOptionsBuilder) SetExpireAfterSeconds(eas int64) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.ExpireAfterSeconds = &eas
+
+ return nil
+ })
+
+ return c
+}
+
+// SetTimeSeriesOptions sets the options for time-series collections. Specifies options for specifying
+// a time-series collection. See https://www.mongodb.com/docs/manual/reference/command/create/ for
+// supported options, and https://www.mongodb.com/docs/manual/core/timeseries-collections/ for more
+// information on time-series collections.
+//
+// This option is only valid for MongoDB versions >= 5.0
+func (c *CreateCollectionOptionsBuilder) SetTimeSeriesOptions(timeSeriesOpts *TimeSeriesOptionsBuilder) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.TimeSeriesOptions = timeSeriesOpts
+
+ return nil
+ })
+
+ return c
+}
+
+// SetEncryptedFields sets the encrypted fields for encrypted collections.
+//
+// This option is only valid for MongoDB versions >= 6.0
+func (c *CreateCollectionOptionsBuilder) SetEncryptedFields(encryptedFields any) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.EncryptedFields = encryptedFields
+
+ return nil
+ })
+
+ return c
+}
+
+// SetClusteredIndex sets the value for the ClusteredIndex field which is used
+// to create a collection with a clustered index.
+//
+// This option is only valid for MongoDB versions >= 5.3
+func (c *CreateCollectionOptionsBuilder) SetClusteredIndex(clusteredIndex any) *CreateCollectionOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateCollectionOptions) error {
+ opts.ClusteredIndex = clusteredIndex
+
+ return nil
+ })
+
+ return c
+}
+
+// CreateViewOptions represents arguments that can be used to configure a
+// CreateView operation.
+//
+// See corresponding setter methods for documentation.
+type CreateViewOptions struct {
+ Collation *Collation
+}
+
+// CreateViewOptionsBuilder contains options to configure a new view. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type CreateViewOptionsBuilder struct {
+ Opts []func(*CreateViewOptions) error
+}
+
+// CreateView creates an new CreateViewOptions instance.
+func CreateView() *CreateViewOptionsBuilder {
+ return &CreateViewOptionsBuilder{}
+}
+
+// List returns a list of TimeSeriesOptions setter functions.
+func (c *CreateViewOptionsBuilder) List() []func(*CreateViewOptions) error {
+ return c.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies the default
+// collation for the new collection. The default value is nil.
+func (c *CreateViewOptionsBuilder) SetCollation(collation *Collation) *CreateViewOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateViewOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return c
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/datakeyoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/datakeyoptions.go
similarity index 63%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/datakeyoptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/datakeyoptions.go
index 5afe8a248..8d24f9d15 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/datakeyoptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/datakeyoptions.go
@@ -7,18 +7,29 @@
package options
// DataKeyOptions represents all possible options used to create a new data key.
+//
+// See corresponding setter methods for documentation.
type DataKeyOptions struct {
- MasterKey interface{}
+ MasterKey any
KeyAltNames []string
-
- // KeyMaterial is used to encrypt data. If omitted, keyMaterial is generated form a cryptographically secure random
- // source. "Key Material" is used interchangeably with "dataKey" and "Data Encryption Key" (DEK).
KeyMaterial []byte
}
+// DataKeyOptionsBuilder contains options to configure DataKey operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type DataKeyOptionsBuilder struct {
+ Opts []func(*DataKeyOptions) error
+}
+
// DataKey creates a new DataKeyOptions instance.
-func DataKey() *DataKeyOptions {
- return &DataKeyOptions{}
+func DataKey() *DataKeyOptionsBuilder {
+ return &DataKeyOptionsBuilder{}
+}
+
+// List returns a list of DataKey setter functions.
+func (dk *DataKeyOptionsBuilder) List() []func(*DataKeyOptions) error {
+ return dk.Opts
}
// SetMasterKey specifies a KMS-specific key used to encrypt the new data key.
@@ -60,45 +71,37 @@ func DataKey() *DataKeyOptions {
// }
//
// If unset, "keyVersion" defaults to the key's primary version and "endpoint" defaults to "cloudkms.googleapis.com".
-func (dk *DataKeyOptions) SetMasterKey(masterKey interface{}) *DataKeyOptions {
- dk.MasterKey = masterKey
+func (dk *DataKeyOptionsBuilder) SetMasterKey(masterKey any) *DataKeyOptionsBuilder {
+ dk.Opts = append(dk.Opts, func(opts *DataKeyOptions) error {
+ opts.MasterKey = masterKey
+
+ return nil
+ })
+
return dk
}
// SetKeyAltNames specifies an optional list of string alternate names used to reference a key. If a key is created'
// with alternate names, encryption may refer to the key by a unique alternate name instead of by _id.
-func (dk *DataKeyOptions) SetKeyAltNames(keyAltNames []string) *DataKeyOptions {
- dk.KeyAltNames = keyAltNames
- return dk
-}
+func (dk *DataKeyOptionsBuilder) SetKeyAltNames(keyAltNames []string) *DataKeyOptionsBuilder {
+ dk.Opts = append(dk.Opts, func(opts *DataKeyOptions) error {
+ opts.KeyAltNames = keyAltNames
+
+ return nil
+ })
-// SetKeyMaterial will set a custom keyMaterial to DataKeyOptions which can be used to encrypt data.
-func (dk *DataKeyOptions) SetKeyMaterial(keyMaterial []byte) *DataKeyOptions {
- dk.KeyMaterial = keyMaterial
return dk
}
-// MergeDataKeyOptions combines the argued DataKeyOptions in a last-one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeDataKeyOptions(opts ...*DataKeyOptions) *DataKeyOptions {
- dko := DataKey()
- for _, opt := range opts {
- if opt == nil {
- continue
- }
+// SetKeyMaterial will set a custom keyMaterial to DataKeyOptions which can be used to encrypt data. If omitted,
+// keyMaterial is generated form a cryptographically secure random source. "Key Material" is used interchangeably
+// with "dataKey" and "Data Encryption Key" (DEK).
+func (dk *DataKeyOptionsBuilder) SetKeyMaterial(keyMaterial []byte) *DataKeyOptionsBuilder {
+ dk.Opts = append(dk.Opts, func(opts *DataKeyOptions) error {
+ opts.KeyMaterial = keyMaterial
- if opt.MasterKey != nil {
- dko.MasterKey = opt.MasterKey
- }
- if opt.KeyAltNames != nil {
- dko.KeyAltNames = opt.KeyAltNames
- }
- if opt.KeyMaterial != nil {
- dko.KeyMaterial = opt.KeyMaterial
- }
- }
+ return nil
+ })
- return dko
+ return dk
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dboptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dboptions.go
new file mode 100644
index 000000000..921935dcb
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dboptions.go
@@ -0,0 +1,106 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+)
+
+// DatabaseOptions represents arguments that can be used to configure a
+// database.
+//
+// See corresponding setter methods for documentation.
+type DatabaseOptions struct {
+ ReadConcern *readconcern.ReadConcern
+ WriteConcern *writeconcern.WriteConcern
+ ReadPreference *readpref.ReadPref
+ BSONOptions *BSONOptions
+ Registry *bson.Registry
+}
+
+// DatabaseOptionsBuilder contains options to configure a database object. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type DatabaseOptionsBuilder struct {
+ Opts []func(*DatabaseOptions) error
+}
+
+// Database creates a new DatabaseOptions instance.
+func Database() *DatabaseOptionsBuilder {
+ return &DatabaseOptionsBuilder{}
+}
+
+// List returns a list of DatabaseOptions setter functions.
+func (d *DatabaseOptionsBuilder) List() []func(*DatabaseOptions) error {
+ return d.Opts
+}
+
+// SetReadConcern sets the value for the ReadConcern field. ReadConcern is the read concern
+// to use for operations executed on the Database. The default value is nil, which means that
+// the read concern of the Client used to configure the Database will be used.
+func (d *DatabaseOptionsBuilder) SetReadConcern(rc *readconcern.ReadConcern) *DatabaseOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DatabaseOptions) error {
+ opts.ReadConcern = rc
+
+ return nil
+ })
+
+ return d
+}
+
+// SetWriteConcern sets the value for the WriteConcern field. WriteConcern is the write concern
+// to use for operations executed on the Database. The default value is nil, which means that
+// the write concern of the Client used to configure the Database will be used.
+func (d *DatabaseOptionsBuilder) SetWriteConcern(wc *writeconcern.WriteConcern) *DatabaseOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DatabaseOptions) error {
+ opts.WriteConcern = wc
+
+ return nil
+ })
+
+ return d
+}
+
+// SetReadPreference sets the value for the ReadPreference field. ReadPreference is the read
+// preference to use for operations executed on the Database. The default value is nil, which
+// means that the read preference of the Client used to configure the Database will be used.
+func (d *DatabaseOptionsBuilder) SetReadPreference(rp *readpref.ReadPref) *DatabaseOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DatabaseOptions) error {
+ opts.ReadPreference = rp
+
+ return nil
+ })
+
+ return d
+}
+
+// SetBSONOptions configures optional BSON marshaling and unmarshaling behavior. BSONOptions
+// configures optional BSON marshaling and unmarshaling behavior.
+func (d *DatabaseOptionsBuilder) SetBSONOptions(bopts *BSONOptions) *DatabaseOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DatabaseOptions) error {
+ opts.BSONOptions = bopts
+
+ return nil
+ })
+
+ return d
+}
+
+// SetRegistry sets the value for the Registry field. Registry is the BSON registry to marshal and
+// unmarshal documents for operations executed on the Database. The default value is nil, which
+// means that the registry of the Client used to configure the Database will be used.
+func (d *DatabaseOptionsBuilder) SetRegistry(r *bson.Registry) *DatabaseOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DatabaseOptions) error {
+ opts.Registry = r
+
+ return nil
+ })
+ return d
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/deleteoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/deleteoptions.go
new file mode 100644
index 000000000..2206abb24
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/deleteoptions.go
@@ -0,0 +1,191 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// DeleteOneOptions represents arguments that can be used to configure DeleteOne
+// operations.
+//
+// See corresponding setter methods for documentation.
+type DeleteOneOptions struct {
+ Collation *Collation
+ Comment any
+ Hint any
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// DeleteOneOptionsBuilder contains options to configure DeleteOne operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type DeleteOneOptionsBuilder struct {
+ Opts []func(*DeleteOneOptions) error
+}
+
+// DeleteOne creates a new DeleteOneOptions instance.
+func DeleteOne() *DeleteOneOptionsBuilder {
+ return &DeleteOneOptionsBuilder{}
+}
+
+// List returns a list of DeleteOneOptions setter functions.
+func (do *DeleteOneOptionsBuilder) List() []func(*DeleteOneOptions) error {
+ return do.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (do *DeleteOneOptionsBuilder) SetCollation(c *Collation) *DeleteOneOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return do
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will
+// be included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (do *DeleteOneOptionsBuilder) SetComment(comment any) *DeleteOneOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return do
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the
+// operation. This should either be the index name as a string or the index
+// specification as a document. This option is only valid for MongoDB versions
+// >= 4.4. Server versions < 4.4 will return an error if this option is
+// specified. The driver will return an error if this option is specified during
+// an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that
+// no hint will be sent.
+func (do *DeleteOneOptionsBuilder) SetHint(hint any) *DeleteOneOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return do
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the delete expression. This
+// option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using
+// this option. This must be a document mapping parameter names to values. Values must be constant
+// or closed expressions that do not reference document fields. Parameters can then be accessed as
+// variables in an aggregate expression context (e.g. "$$var").
+func (do *DeleteOneOptionsBuilder) SetLet(let any) *DeleteOneOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteOneOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return do
+}
+
+// DeleteManyOptions represents arguments that can be used to configure DeleteMany
+// operations.
+//
+// See corresponding setter methods for documentation.
+type DeleteManyOptions struct {
+ Collation *Collation
+ Comment any
+ Hint any
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// DeleteManyOptionsBuilder contains options to configure DeleteMany operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type DeleteManyOptionsBuilder struct {
+ Opts []func(*DeleteManyOptions) error
+}
+
+// DeleteMany creates a new DeleteManyOptions instance.
+func DeleteMany() *DeleteManyOptionsBuilder {
+ return &DeleteManyOptionsBuilder{}
+}
+
+// List returns a list of DeleteOneOptions setter functions.
+func (do *DeleteManyOptionsBuilder) List() []func(*DeleteManyOptions) error {
+ return do.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (do *DeleteManyOptionsBuilder) SetCollation(c *Collation) *DeleteManyOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return do
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (do *DeleteManyOptionsBuilder) SetComment(comment any) *DeleteManyOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return do
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the
+// operation. This should either be the index name as a string or the index
+// specification as a document. This option is only valid for MongoDB versions
+// >= 4.4. Server versions < 4.4 will return an error if this option is
+// specified. The driver will return an error if this option is specified during
+// an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that
+// no hint will be sent.
+func (do *DeleteManyOptionsBuilder) SetHint(hint any) *DeleteManyOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return do
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the delete expression.
+// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error
+// for using this option. This must be a document mapping parameter names to values. Values
+// must be constant or closed expressions that do not reference document fields. Parameters
+// can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (do *DeleteManyOptionsBuilder) SetLet(let any) *DeleteManyOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DeleteManyOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return do
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/distinctoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/distinctoptions.go
new file mode 100644
index 000000000..476c10480
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/distinctoptions.go
@@ -0,0 +1,85 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// DistinctOptions represents arguments that can be used to configure a Distinct
+// operation.
+//
+// See corresponding setter methods for documentation.
+type DistinctOptions struct {
+ Collation *Collation
+ Comment any
+ Hint any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// DistinctOptionsBuilder contains options to configure distinct operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type DistinctOptionsBuilder struct {
+ Opts []func(*DistinctOptions) error
+}
+
+// Distinct creates a new DistinctOptions instance.
+func Distinct() *DistinctOptionsBuilder {
+ return &DistinctOptionsBuilder{}
+}
+
+// List returns a list of DistinctArg setter functions.
+func (do *DistinctOptionsBuilder) List() []func(*DistinctOptions) error {
+ return do.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (do *DistinctOptionsBuilder) SetCollation(c *Collation) *DistinctOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DistinctOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return do
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that
+// will be included in server logs, profiling logs, and currentOp queries to help trace
+// the operation. The default value is nil, which means that no comment will be included
+// in the logs.
+func (do *DistinctOptionsBuilder) SetComment(comment any) *DistinctOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DistinctOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return do
+}
+
+// SetHint specifies the index to use for the operation. This should either be
+// the index name as a string or the index specification as a document. This
+// option is only valid for MongoDB versions >= 7.1. Previous server versions
+// will return an error if an index hint is specified. Distinct returns an error
+// if the hint parameter is a multi-key map. The default value is nil, which
+// means that no index hint will be sent.
+//
+// SetHint sets the Hint field.
+func (do *DistinctOptionsBuilder) SetHint(hint any) *DistinctOptionsBuilder {
+ do.Opts = append(do.Opts, func(opts *DistinctOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return do
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dropcollectionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dropcollectionoptions.go
new file mode 100644
index 000000000..013b4bbb7
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dropcollectionoptions.go
@@ -0,0 +1,45 @@
+// 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
+
+// DropCollectionOptions represents arguments that can be used to configure a
+// Drop operation.
+//
+// See corresponding setter methods for documentation.
+type DropCollectionOptions struct {
+ EncryptedFields any
+}
+
+// DropCollectionOptionsBuilder contains options to configure collection drop
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type DropCollectionOptionsBuilder struct {
+ Opts []func(*DropCollectionOptions) error
+}
+
+// DropCollection creates a new DropCollectionOptions instance.
+func DropCollection() *DropCollectionOptionsBuilder {
+ return &DropCollectionOptionsBuilder{}
+}
+
+// List returns a list of DropCollectionOptions setter functions.
+func (d *DropCollectionOptionsBuilder) List() []func(*DropCollectionOptions) error {
+ return d.Opts
+}
+
+// SetEncryptedFields sets the encrypted fields for encrypted collections.
+//
+// This option is only valid for MongoDB versions >= 6.0
+func (d *DropCollectionOptionsBuilder) SetEncryptedFields(encryptedFields any) *DropCollectionOptionsBuilder {
+ d.Opts = append(d.Opts, func(opts *DropCollectionOptions) error {
+ opts.EncryptedFields = encryptedFields
+
+ return nil
+ })
+
+ return d
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/encryptoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/encryptoptions.go
new file mode 100644
index 000000000..2817fb993
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/encryptoptions.go
@@ -0,0 +1,355 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/bson"
+)
+
+// These constants specify valid values for QueryType
+// QueryType is used for Queryable Encryption.
+const (
+ QueryTypeEquality string = "equality"
+)
+
+// RangeOptions specifies index options for a Queryable Encryption field supporting "range" queries.
+//
+// See corresponding setter methods for documentation.
+type RangeOptions struct {
+ Min *bson.RawValue
+ Max *bson.RawValue
+ Sparsity *int64
+ TrimFactor *int32
+ Precision *int32
+}
+
+// RangeOptionsBuilder contains options to configure RangeOptions for queryable
+// encryption. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type RangeOptionsBuilder struct {
+ Opts []func(*RangeOptions) error
+}
+
+// Range creates a new RangeOptions instance.
+func Range() *RangeOptionsBuilder {
+ return &RangeOptionsBuilder{}
+}
+
+// List returns a list of RangeOptions setter functions.
+func (ro *RangeOptionsBuilder) List() []func(*RangeOptions) error {
+ return ro.Opts
+}
+
+// SetMin sets the range index minimum value.
+func (ro *RangeOptionsBuilder) SetMin(min bson.RawValue) *RangeOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *RangeOptions) error {
+ opts.Min = &min
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetMax sets the range index maximum value.
+func (ro *RangeOptionsBuilder) SetMax(max bson.RawValue) *RangeOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *RangeOptions) error {
+ opts.Max = &max
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetSparsity sets the range index sparsity.
+func (ro *RangeOptionsBuilder) SetSparsity(sparsity int64) *RangeOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *RangeOptions) error {
+ opts.Sparsity = &sparsity
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetTrimFactor sets the range index trim factor.
+func (ro *RangeOptionsBuilder) SetTrimFactor(trimFactor int32) *RangeOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *RangeOptions) error {
+ opts.TrimFactor = &trimFactor
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetPrecision sets the range index precision.
+func (ro *RangeOptionsBuilder) SetPrecision(precision int32) *RangeOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *RangeOptions) error {
+ opts.Precision = &precision
+
+ return nil
+ })
+
+ return ro
+}
+
+// TextOptions specifies index options for a Queryable Encryption field supporting "text" queries.
+//
+// See corresponding setter methods for documentation.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+type TextOptions struct {
+ Substring *SubstringOptions
+ Prefix *PrefixOptions
+ Suffix *SuffixOptions
+ CaseSensitive bool
+ DiacriticSensitive bool
+}
+
+// SubstringOptions specifies options to support substring queries.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+type SubstringOptions struct {
+ StrMaxLength int32
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
+// PrefixOptions specifies options to support prefix queries.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+type PrefixOptions struct {
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
+// SuffixOptions specifies options to support suffix queries.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+type SuffixOptions struct {
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
+// TextOptionsBuilder contains options to configure TextOptions for queryable
+// encryption. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+type TextOptionsBuilder struct {
+ Opts []func(*TextOptions) error
+}
+
+// Text creates a new TextOptions instance.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func Text() *TextOptionsBuilder {
+ return &TextOptionsBuilder{}
+}
+
+// List returns a list of TextOptions setter functions.
+func (to *TextOptionsBuilder) List() []func(*TextOptions) error {
+ return to.Opts
+}
+
+// SetSubstring sets the text index substring value.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (to *TextOptionsBuilder) SetSubstring(substring SubstringOptions) *TextOptionsBuilder {
+ to.Opts = append(to.Opts, func(opts *TextOptions) error {
+ opts.Substring = &substring
+
+ return nil
+ })
+
+ return to
+}
+
+// SetPrefix sets the text index prefix value.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (to *TextOptionsBuilder) SetPrefix(prefix PrefixOptions) *TextOptionsBuilder {
+ to.Opts = append(to.Opts, func(opts *TextOptions) error {
+ opts.Prefix = &prefix
+
+ return nil
+ })
+
+ return to
+}
+
+// SetSuffix sets the text index suffix value.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (to *TextOptionsBuilder) SetSuffix(suffix SuffixOptions) *TextOptionsBuilder {
+ to.Opts = append(to.Opts, func(opts *TextOptions) error {
+ opts.Suffix = &suffix
+
+ return nil
+ })
+
+ return to
+}
+
+// SetCaseSensitive sets the text index caseSensitive value.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (to *TextOptionsBuilder) SetCaseSensitive(caseSensitive bool) *TextOptionsBuilder {
+ to.Opts = append(to.Opts, func(opts *TextOptions) error {
+ opts.CaseSensitive = caseSensitive
+
+ return nil
+ })
+
+ return to
+}
+
+// SetDiacriticSensitive sets the text index diacriticSensitive value.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (to *TextOptionsBuilder) SetDiacriticSensitive(diacriticSensitive bool) *TextOptionsBuilder {
+ to.Opts = append(to.Opts, func(opts *TextOptions) error {
+ opts.DiacriticSensitive = diacriticSensitive
+
+ return nil
+ })
+
+ return to
+}
+
+// EncryptOptions represents arguments to explicitly encrypt a value.
+//
+// See corresponding setter methods for documentation.
+type EncryptOptions struct {
+ KeyID *bson.Binary
+ KeyAltName *string
+ Algorithm string
+ QueryType string
+ ContentionFactor *int64
+ RangeOptions *RangeOptionsBuilder
+ TextOptions *TextOptionsBuilder
+}
+
+// EncryptOptionsBuilder contains options to configure Encryptopts for
+// queryeable encryption. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type EncryptOptionsBuilder struct {
+ Opts []func(*EncryptOptions) error
+}
+
+// List returns a list of EncryptOptions setter functions.
+func (e *EncryptOptionsBuilder) List() []func(*EncryptOptions) error {
+ return e.Opts
+}
+
+// Encrypt creates a new EncryptOptions instance.
+func Encrypt() *EncryptOptionsBuilder {
+ return &EncryptOptionsBuilder{}
+}
+
+// SetKeyID specifies an _id of a data key. This should be a UUID (a bson.Binary with subtype 4).
+func (e *EncryptOptionsBuilder) SetKeyID(keyID bson.Binary) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.KeyID = &keyID
+
+ return nil
+ })
+ return e
+}
+
+// SetKeyAltName identifies a key vault document by 'keyAltName'.
+func (e *EncryptOptionsBuilder) SetKeyAltName(keyAltName string) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.KeyAltName = &keyAltName
+
+ return nil
+ })
+
+ return e
+}
+
+// SetAlgorithm specifies an algorithm to use for encryption. This should be one of the following:
+// - AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic
+// - AEAD_AES_256_CBC_HMAC_SHA_512-Random
+// - Indexed
+// - Unindexed
+// - Range
+// This is required.
+// Indexed and Unindexed are used for Queryable Encryption.
+func (e *EncryptOptionsBuilder) SetAlgorithm(algorithm string) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.Algorithm = algorithm
+
+ return nil
+ })
+
+ return e
+}
+
+// SetQueryType specifies the intended query type. It is only valid to set if algorithm is "Indexed".
+// This should be one of the following:
+// - equality
+// QueryType is used for Queryable Encryption.
+func (e *EncryptOptionsBuilder) SetQueryType(queryType string) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.QueryType = queryType
+
+ return nil
+ })
+
+ return e
+}
+
+// SetContentionFactor specifies the contention factor. It is only valid to set if algorithm is "Indexed".
+// ContentionFactor is used for Queryable Encryption.
+func (e *EncryptOptionsBuilder) SetContentionFactor(contentionFactor int64) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.ContentionFactor = &contentionFactor
+
+ return nil
+ })
+
+ return e
+}
+
+// SetRangeOptions specifies the options to use for explicit encryption with range. It is only valid to set if algorithm is "range".
+func (e *EncryptOptionsBuilder) SetRangeOptions(ro *RangeOptionsBuilder) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.RangeOptions = ro
+
+ return nil
+ })
+
+ return e
+}
+
+// SetTextOptions specifies the options to use for text queries.
+//
+// Beta: This is a preview feature and should only be used for experimental workloads.
+// It is not intended for public use. It is subject to breaking changes.
+func (e *EncryptOptionsBuilder) SetTextOptions(to *TextOptionsBuilder) *EncryptOptionsBuilder {
+ e.Opts = append(e.Opts, func(opts *EncryptOptions) error {
+ opts.TextOptions = to
+
+ return nil
+ })
+
+ return e
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/estimatedcountoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/estimatedcountoptions.go
new file mode 100644
index 000000000..2fd8f87df
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/estimatedcountoptions.go
@@ -0,0 +1,52 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// EstimatedDocumentCountOptions represents arguments that can be used to configure
+// an EstimatedDocumentCount operation.
+//
+// See corresponding setter methods for documentation.
+type EstimatedDocumentCountOptions struct {
+ Comment any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// EstimatedDocumentCountOptionsBuilder contains options to estimate document
+// count. Each option can be set through setter functions. See documentation for
+// each setter function for an explanation of the option.
+type EstimatedDocumentCountOptionsBuilder struct {
+ Opts []func(*EstimatedDocumentCountOptions) error
+}
+
+// EstimatedDocumentCount creates a new EstimatedDocumentCountOptions instance.
+func EstimatedDocumentCount() *EstimatedDocumentCountOptionsBuilder {
+ return &EstimatedDocumentCountOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (eco *EstimatedDocumentCountOptionsBuilder) List() []func(*EstimatedDocumentCountOptions) error {
+ return eco.Opts
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document
+// that will be included in server logs, profiling logs, and currentOp queries to help
+// trace the operation. The default is nil, which means that no comment will be
+// included in the logs.
+func (eco *EstimatedDocumentCountOptionsBuilder) SetComment(comment any) *EstimatedDocumentCountOptionsBuilder {
+ eco.Opts = append(eco.Opts, func(opts *EstimatedDocumentCountOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return eco
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/findoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/findoptions.go
new file mode 100644
index 000000000..b295bd514
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/findoptions.go
@@ -0,0 +1,910 @@
+// 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 (
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+)
+
+// FindOptions represents arguments that can be used to configure a Find
+// operation.
+//
+// See corresponding setter methods for documentation.
+type FindOptions struct {
+ AllowPartialResults *bool
+ Collation *Collation
+ Comment any
+ Hint any
+ Max any
+ MaxAwaitTime *time.Duration
+ Min any
+ OplogReplay *bool
+ Projection any
+ ReturnKey *bool
+ ShowRecordID *bool
+ Skip *int64
+ Sort any
+ // The above are in common with FindOneopts.
+ AllowDiskUse *bool
+ BatchSize *int32
+ CursorType *CursorType
+ Let any
+ Limit *int64
+ NoCursorTimeout *bool
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// FindOptionsBuilder represents functional options that configure an Findopts.
+type FindOptionsBuilder struct {
+ Opts []func(*FindOptions) error
+}
+
+// Find creates a new FindOptions instance.
+func Find() *FindOptionsBuilder {
+ return &FindOptionsBuilder{}
+}
+
+// List returns a list of FindOptions setter functions.
+func (f *FindOptionsBuilder) List() []func(*FindOptions) error {
+ return f.Opts
+}
+
+// SetAllowDiskUse sets the value for the AllowDiskUse field. AllowDiskUse
+// specifies whether the server can write temporary data to disk while executing
+// the Find operation. This option is only valid for MongoDB versions >= 4.4.
+// Server versions < 4.4 will return an error if this option is specified. The
+// default value is false.
+func (f *FindOptionsBuilder) SetAllowDiskUse(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.AllowDiskUse = &b
+ return nil
+ })
+ return f
+}
+
+// SetAllowPartialResults sets the value for the AllowPartialResults field. AllowPartial results
+// specifies whether the Find operation on a sharded cluster can return partial results if some
+// shards are down rather than returning an error. The default value is false.
+func (f *FindOptionsBuilder) SetAllowPartialResults(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.AllowPartialResults = &b
+ return nil
+ })
+ return f
+}
+
+// SetBatchSize sets the value for the BatchSize field. BatchSize is the maximum number of documents
+// to be included in each batch returned by the server.
+func (f *FindOptionsBuilder) SetBatchSize(i int32) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.BatchSize = &i
+ return nil
+ })
+ return f
+}
+
+// SetCollation sets the value for the Collation field. Collation specifies a
+// collation to use for string comparisons during the operation. The default
+// value is nil, which means the default collation of the collection will be
+// used.
+func (f *FindOptionsBuilder) SetCollation(collation *Collation) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Collation = collation
+ return nil
+ })
+ return f
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default is nil, which means that no comment will be included in the logs.
+func (f *FindOptionsBuilder) SetComment(comment any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Comment = &comment
+ return nil
+ })
+ return f
+}
+
+// SetCursorType sets the value for the CursorType field. CursorType specifies the type of cursor
+// that should be created for the operation. The default is NonTailable, which means that the
+// cursor will be closed by the server when the last batch of documents is retrieved.
+func (f *FindOptionsBuilder) SetCursorType(ct CursorType) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.CursorType = &ct
+ return nil
+ })
+ return f
+}
+
+// SetHint sets the value for the Hint field. Hint is the index to use for the Find operation.
+// This should either be the index name as a string or the index specification as a document.
+// The driver will return an error if the hint parameter is a multi-key map. The default
+// value is nil, which means that no hint will be sent.
+func (f *FindOptionsBuilder) SetHint(hint any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Hint = hint
+ return nil
+ })
+ return f
+}
+
+// SetLet sets the value for the Let field. Let specifies parameters for the find expression.
+// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error
+// for using this option. This must be a document mapping parameter names to values. Values
+// must be constant or closed expressions that do not reference document fields. Parameters
+// can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (f *FindOptionsBuilder) SetLet(let any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Let = let
+ return nil
+ })
+ return f
+}
+
+// SetLimit sets the value for the Limit field. Limit is the maximum number of documents to return.
+// The default value is 0, which means that all documents matching the filter will be returned.
+// A negative limit specifies that the resulting documents should be returned in a single batch.
+// The default value is 0.
+func (f *FindOptionsBuilder) SetLimit(i int64) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Limit = &i
+ return nil
+ })
+ return f
+}
+
+// SetMax sets the value for the Max field. Max is a document specifying the exclusive upper bound
+// for a specific index. The default value is nil, which means that there is no maximum value.
+func (f *FindOptionsBuilder) SetMax(max any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Max = max
+ return nil
+ })
+ return f
+}
+
+// SetMaxAwaitTime sets the value for the MaxAwaitTime field. MaxAwaitTime is
+// the maximum amount of time that the server should wait for new documents to
+// satisfy a tailable cursor query. This option is only valid for tailable await
+// cursors (see the CursorType option for more information). For other cursor
+// types, this option is ignored.
+func (f *FindOptionsBuilder) SetMaxAwaitTime(d time.Duration) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.MaxAwaitTime = &d
+ return nil
+ })
+ return f
+}
+
+// SetMin sets the value for the Min field. Min is a document specifying the inclusive lower bound
+// for a specific index. The default value is 0, which means that there is no minimum value.
+func (f *FindOptionsBuilder) SetMin(min any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Min = min
+ return nil
+ })
+ return f
+}
+
+// SetNoCursorTimeout sets the value for the NoCursorTimeout field. NoCursorTimeout specifies
+// whether the cursor created by the operation will not timeout after a period of inactivity.
+// The default value is false.
+func (f *FindOptionsBuilder) SetNoCursorTimeout(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.NoCursorTimeout = &b
+ return nil
+ })
+ return f
+}
+
+// SetOplogReplay sets the value for the OplogReplay field. OplogReplay is for internal
+// replication use only and should not be set.
+//
+// Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by
+// the server if it is set.
+func (f *FindOptionsBuilder) SetOplogReplay(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.OplogReplay = &b
+ return nil
+ })
+ return f
+}
+
+// SetProjection sets the value for the Projection field. Projection is a document describing
+// which fields will be included in the documents returned by the Find operation. The
+// default value is nil, which means all fields will be included.
+func (f *FindOptionsBuilder) SetProjection(projection any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Projection = projection
+ return nil
+ })
+ return f
+}
+
+// SetReturnKey sets the value for the ReturnKey field. ReturnKey specifies whether the
+// documents returned by the Find operation will only contain fields corresponding to the
+// index used. The default value is false.
+func (f *FindOptionsBuilder) SetReturnKey(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.ReturnKey = &b
+ return nil
+ })
+ return f
+}
+
+// SetShowRecordID sets the value for the ShowRecordID field. ShowRecordID specifies whether
+// a $recordId field with a record identifier will be included in the documents returned by
+// the Find operation. The default value is false.
+func (f *FindOptionsBuilder) SetShowRecordID(b bool) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.ShowRecordID = &b
+ return nil
+ })
+ return f
+}
+
+// SetSkip sets the value for the Skip field. Skip is the number of documents to skip before
+// adding documents to the result. The default value is 0.
+func (f *FindOptionsBuilder) SetSkip(i int64) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Skip = &i
+ return nil
+ })
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sort is a document specifying the order in which
+// documents should be returned. The sort parameter is evaluated sequentially, so the driver will
+// return an error if it is a multi-key map (which is unordeded). The default value is nil.
+func (f *FindOptionsBuilder) SetSort(sort any) *FindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOptions) error {
+ opts.Sort = sort
+ return nil
+ })
+ return f
+}
+
+// FindOneOptions represents arguments that can be used to configure a FindOne
+// operation.
+//
+// See corresponding setter methods for documentation.
+type FindOneOptions struct {
+ AllowPartialResults *bool
+ Collation *Collation
+ Comment any
+ Hint any
+ Max any
+ Min any
+ OplogReplay *bool
+ Projection any
+ ReturnKey *bool
+ ShowRecordID *bool
+ Skip *int64
+ Sort any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// FindOneOptionsBuilder represents functional options that configure an
+// FindOneopts.
+type FindOneOptionsBuilder struct {
+ Opts []func(*FindOneOptions) error
+}
+
+// FindOne creates a new FindOneOptions instance.
+func FindOne() *FindOneOptionsBuilder {
+ return &FindOneOptionsBuilder{}
+}
+
+// List returns a list of FindOneOptions setter functions.
+func (f *FindOneOptionsBuilder) List() []func(*FindOneOptions) error {
+ return f.Opts
+}
+
+// SetAllowPartialResults sets the value for the AllowPartialResults field. If true, an operation
+// on a sharded cluster can return partial results if some shards are down rather than returning
+// an error. The default value is false.
+func (f *FindOneOptionsBuilder) SetAllowPartialResults(b bool) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.AllowPartialResults = &b
+ return nil
+ })
+ return f
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (f *FindOneOptionsBuilder) SetCollation(collation *Collation) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Collation = collation
+ return nil
+ })
+ return f
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default is nil, which means that no comment will be included in the logs.
+func (f *FindOneOptionsBuilder) SetComment(comment any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Comment = &comment
+ return nil
+ })
+ return f
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the aggregation.
+// This should either be the index name as a string or the index specification as a document.
+// The driver will return an error if the hint parameter is a multi-key map. The default value
+// is nil, which means that no hint will be sent.
+func (f *FindOneOptionsBuilder) SetHint(hint any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Hint = hint
+ return nil
+ })
+ return f
+}
+
+// SetMax sets the value for the Max field. Sets a document specifying the exclusive upper bound
+// for a specific index. The default value is nil, which means that there is no maximum value.
+func (f *FindOneOptionsBuilder) SetMax(max any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Max = max
+ return nil
+ })
+ return f
+}
+
+// SetMin sets the value for the Min field. Sets a document specifying the inclusive lower bound
+// for a specific index. The default value is 0, which means that there is no minimum value.
+func (f *FindOneOptionsBuilder) SetMin(min any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Min = min
+ return nil
+ })
+ return f
+}
+
+// SetOplogReplay sets the value for the OplogReplay field. OplogReplay is for internal
+// replication use only and should not be set.
+//
+// Deprecated: This option has been deprecated in MongoDB version 4.4 and will be ignored by
+// the server if it is set.
+func (f *FindOneOptionsBuilder) SetOplogReplay(b bool) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.OplogReplay = &b
+ return nil
+ })
+ return f
+}
+
+// SetProjection sets the value for the Projection field. Sets a document describing which fields
+// will be included in the document returned by the operation. The default value is nil, which
+// means all fields will be included.
+func (f *FindOneOptionsBuilder) SetProjection(projection any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Projection = projection
+ return nil
+ })
+ return f
+}
+
+// SetReturnKey sets the value for the ReturnKey field. If true, the document returned by the
+// operation will only contain fields corresponding to the index used. The default value
+// is false.
+func (f *FindOneOptionsBuilder) SetReturnKey(b bool) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.ReturnKey = &b
+ return nil
+ })
+ return f
+}
+
+// SetShowRecordID sets the value for the ShowRecordID field. If true, a $recordId field with
+// a record identifier will be included in the document returned by the operation. The default
+// value is false.
+func (f *FindOneOptionsBuilder) SetShowRecordID(b bool) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.ShowRecordID = &b
+ return nil
+ })
+ return f
+}
+
+// SetSkip sets the value for the Skip field. Specifies the number of documents to skip before
+// selecting the document to be returned. The default value is 0.
+func (f *FindOneOptionsBuilder) SetSkip(i int64) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Skip = &i
+ return nil
+ })
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sets a document specifying the sort order to
+// apply to the query. The first document in the sorted order will be returned. The sort
+// parameter is evaluated sequentially, so the driver will return an error if it is a multi-
+// key map (which is unordeded). The default value is nil.
+func (f *FindOneOptionsBuilder) SetSort(sort any) *FindOneOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
+ opts.Sort = sort
+ return nil
+ })
+ return f
+}
+
+// FindOneAndReplaceOptions represents arguments that can be used to configure a
+// FindOneAndReplace instance.
+//
+// See corresponding setter methods for documentation.
+type FindOneAndReplaceOptions struct {
+ BypassDocumentValidation *bool
+ Collation *Collation
+ Comment any
+ Projection any
+ ReturnDocument *ReturnDocument
+ Sort any
+ Upsert *bool
+ Hint any
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// FindOneAndReplaceOptionsBuilder contains options to perform a findAndModify
+// operation. Each option can be set through setter functions. See documentation
+// for each setter function for an explanation of the option.
+type FindOneAndReplaceOptionsBuilder struct {
+ Opts []func(*FindOneAndReplaceOptions) error
+}
+
+// FindOneAndReplace creates a new FindOneAndReplaceOptions instance.
+func FindOneAndReplace() *FindOneAndReplaceOptionsBuilder {
+ return &FindOneAndReplaceOptionsBuilder{}
+}
+
+// List returns a list of FindOneAndReplaceOptions setter functions.
+func (f *FindOneAndReplaceOptionsBuilder) List() []func(*FindOneAndReplaceOptions) error {
+ return f.Opts
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true, writes
+// executed as part of the operation will opt out of document-level validation on the server. The
+// default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for more
+// information about document validation.
+func (f *FindOneAndReplaceOptionsBuilder) SetBypassDocumentValidation(b bool) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (f *FindOneAndReplaceOptionsBuilder) SetCollation(collation *Collation) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return f
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (f *FindOneAndReplaceOptionsBuilder) SetComment(comment any) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return f
+}
+
+// SetProjection sets the value for the Projection field. Sets a document describing which fields
+// will be included in the document returned by the operation. The default value is nil, which
+// means all fields will be included.
+func (f *FindOneAndReplaceOptionsBuilder) SetProjection(projection any) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Projection = projection
+
+ return nil
+ })
+
+ return f
+}
+
+// SetReturnDocument sets the value for the ReturnDocument field. Specifies whether the original
+// or replaced document should be returned by the operation. The default value is Before, which
+// means the original document will be returned from before the replacement is performed.
+func (f *FindOneAndReplaceOptionsBuilder) SetReturnDocument(rd ReturnDocument) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.ReturnDocument = &rd
+
+ return nil
+ })
+
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sets a document specifying which document should
+// be replaced if the filter used by the operation matches multiple documents in the collection.
+// If set, the first document in the sorted order will be replaced. The sort parameter is evaluated
+// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
+// The default value is nil.
+func (f *FindOneAndReplaceOptionsBuilder) SetSort(sort any) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Sort = sort
+
+ return nil
+ })
+
+ return f
+}
+
+// SetUpsert sets the value for the Upsert field. If true, a new document will be inserted if
+// the filter does not match any documents in the collection. The default value is false.
+func (f *FindOneAndReplaceOptionsBuilder) SetUpsert(b bool) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Upsert = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the operation.
+// This should either be the index name as a string or the index specification as a document.
+// This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an
+// error if this option is specified. For server versions < 4.2, the driver will return an
+// error if this option is specified. The driver will return an error if this option is used
+// with during an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that no hint
+// will be sent.
+func (f *FindOneAndReplaceOptionsBuilder) SetHint(hint any) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return f
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the find one and
+// replace expression. This option is only valid for MongoDB versions >= 5.0. Older
+// servers will report an error for using this option. This must be a document mapping
+// parameter names to values. Values must be constant or closed expressions that do not
+// reference document fields. Parameters can then be accessed as variables in an
+// aggregate expression context (e.g. "$$var").
+func (f *FindOneAndReplaceOptionsBuilder) SetLet(let any) *FindOneAndReplaceOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return f
+}
+
+// FindOneAndUpdateOptions represents arguments that can be used to configure a
+// FindOneAndUpdate options.
+//
+// See corresponding setter methods for documentation.
+type FindOneAndUpdateOptions struct {
+ ArrayFilters []any
+ BypassDocumentValidation *bool
+ Collation *Collation
+ Comment any
+ Projection any
+ ReturnDocument *ReturnDocument
+ Sort any
+ Upsert *bool
+ Hint any
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// FindOneAndUpdateOptionsBuilder contains options to configure a
+// findOneAndUpdate operation. Each option can be set through setter functions.
+// See documentation for each setter function for an explanation of the option.
+type FindOneAndUpdateOptionsBuilder struct {
+ Opts []func(*FindOneAndUpdateOptions) error
+}
+
+// FindOneAndUpdate creates a new FindOneAndUpdateOptions instance.
+func FindOneAndUpdate() *FindOneAndUpdateOptionsBuilder {
+ return &FindOneAndUpdateOptionsBuilder{}
+}
+
+// List returns a list of FindOneAndUpdateOptions setter functions.
+func (f *FindOneAndUpdateOptionsBuilder) List() []func(*FindOneAndUpdateOptions) error {
+ return f.Opts
+}
+
+// SetArrayFilters sets the value for the ArrayFilters field. ArrayFilters is a
+// set of filters specifying to which array elements an update should apply. The
+// default value is nil, which means the update will apply to all array
+// elements.
+func (f *FindOneAndUpdateOptionsBuilder) SetArrayFilters(filters []any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.ArrayFilters = filters
+
+ return nil
+ })
+
+ return f
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the server.
+// The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/
+// for more information about document validation.
+func (f *FindOneAndUpdateOptionsBuilder) SetBypassDocumentValidation(b bool) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (f *FindOneAndUpdateOptionsBuilder) SetCollation(collation *Collation) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return f
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (f *FindOneAndUpdateOptionsBuilder) SetComment(comment any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return f
+}
+
+// SetProjection sets the value for the Projection field. Sets a document describing which fields
+// will be included in the document returned by the operation. The default value is nil, which
+// means all fields will be included.
+func (f *FindOneAndUpdateOptionsBuilder) SetProjection(projection any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Projection = projection
+
+ return nil
+ })
+
+ return f
+}
+
+// SetReturnDocument sets the value for the ReturnDocument field. Specifies whether the original
+// or replaced document should be returned by the operation. The default value is Before, which
+// means the original document will be returned before the replacement is performed.
+func (f *FindOneAndUpdateOptionsBuilder) SetReturnDocument(rd ReturnDocument) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.ReturnDocument = &rd
+
+ return nil
+ })
+
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sets a document specifying which document should
+// be updated if the filter used by the operation matches multiple documents in the collection.
+// If set, the first document in the sorted order will be updated. The sort parameter is evaluated
+// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
+// The default value is nil.
+func (f *FindOneAndUpdateOptionsBuilder) SetSort(sort any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Sort = sort
+
+ return nil
+ })
+
+ return f
+}
+
+// SetUpsert sets the value for the Upsert field. If true, a new document will be inserted if
+// the filter does not match any documents in the collection. The default value is false.
+func (f *FindOneAndUpdateOptionsBuilder) SetUpsert(b bool) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Upsert = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the operation.
+// This should either be the index name as a string or the index specification as a document.
+// This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an
+// error if this option is specified. For server versions < 4.2, the driver will return an
+// error if this option is specified. The driver will return an error if this option is used
+// with during an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that no hint
+// will be sent.
+func (f *FindOneAndUpdateOptionsBuilder) SetHint(hint any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return f
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the find one and update
+// expression. This option is only valid for MongoDB versions >= 5.0. Older servers will
+// report an error for using this option. This must be a document mapping parameter names
+// to values. Values must be constant or closed expressions that do not reference document
+// fields. Parameters can then be accessed as variables in an aggregate expression context
+// (e.g. "$$var").
+func (f *FindOneAndUpdateOptionsBuilder) SetLet(let any) *FindOneAndUpdateOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return f
+}
+
+// FindOneAndDeleteOptions represents arguments that can be used to configure a
+// FindOneAndDelete operation.
+//
+// See corresponding setter methods for documentation.
+type FindOneAndDeleteOptions struct {
+ Collation *Collation
+ Comment any
+ Projection any
+ Sort any
+ Hint any
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// FindOneAndDeleteOptionsBuilder contains options to configure delete
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type FindOneAndDeleteOptionsBuilder struct {
+ Opts []func(*FindOneAndDeleteOptions) error
+}
+
+// FindOneAndDelete creates a new FindOneAndDeleteOptions instance.
+func FindOneAndDelete() *FindOneAndDeleteOptionsBuilder {
+ return &FindOneAndDeleteOptionsBuilder{}
+}
+
+// List returns a list of FindOneAndDeleteOptions setter functions.
+func (f *FindOneAndDeleteOptionsBuilder) List() []func(*FindOneAndDeleteOptions) error {
+ return f.Opts
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (f *FindOneAndDeleteOptionsBuilder) SetCollation(collation *Collation) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return f
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (f *FindOneAndDeleteOptionsBuilder) SetComment(comment any) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return f
+}
+
+// SetProjection sets the value for the Projection field. Sets a document describing which fields
+// will be included in the document returned by the operation. The default value is nil, which
+// means all fields will be included.
+func (f *FindOneAndDeleteOptionsBuilder) SetProjection(projection any) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Projection = projection
+
+ return nil
+ })
+
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sets a document specifying which document should
+// be replaced if the filter used by the operation matches multiple documents in the collection.
+// If set, the first document in the sorted order will be deleted. The sort parameter is evaluated
+// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
+// The default value is nil.
+func (f *FindOneAndDeleteOptionsBuilder) SetSort(sort any) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Sort = sort
+
+ return nil
+ })
+
+ return f
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the operation.
+// This should either be the index name as a string or the index specification as a document.
+// This option is only valid for MongoDB versions >= 4.4. MongoDB version 4.2 will report an
+// error if this option is specified. For server versions < 4.2, the driver will return an
+// error if this option is specified. The driver will return an error if this option is used
+// with during an unacknowledged write operation. The driver will return an error if the hint
+// parameter is a multi-key map. The default value is nil, which means that no hint will be sent.
+func (f *FindOneAndDeleteOptionsBuilder) SetHint(hint any) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Hint = hint
+
+ return nil
+ })
+
+ return f
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the find one and delete
+// expression. This option is only valid for MongoDB versions >= 5.0. Older servers will
+// report an error for using this option. This must be a document mapping parameter names to
+// values. Values must be constant or closed expressions that do not reference document fields.
+// Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (f *FindOneAndDeleteOptionsBuilder) SetLet(let any) *FindOneAndDeleteOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
+ opts.Let = let
+
+ return nil
+ })
+
+ return f
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/gridfsoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/gridfsoptions.go
new file mode 100644
index 000000000..676596cb5
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/gridfsoptions.go
@@ -0,0 +1,342 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+)
+
+// DefaultName is the default name for a GridFS bucket.
+var DefaultName = "fs"
+
+// DefaultChunkSize is the default size of each file chunk in bytes (255 KiB).
+var DefaultChunkSize int32 = 255 * 1024
+
+// DefaultRevision is the default revision number for a download by name operation.
+var DefaultRevision int32 = -1
+
+// BucketOptions represents arguments that can be used to configure GridFS
+// bucket.
+//
+// See corresponding setter methods for documentation.
+type BucketOptions struct {
+ Name *string
+ ChunkSizeBytes *int32
+ WriteConcern *writeconcern.WriteConcern
+ ReadConcern *readconcern.ReadConcern
+ ReadPreference *readpref.ReadPref
+}
+
+// BucketOptionsBuilder contains options to configure a gridfs bucket. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type BucketOptionsBuilder struct {
+ Opts []func(*BucketOptions) error
+}
+
+// GridFSBucket creates a new BucketOptions instance.
+func GridFSBucket() *BucketOptionsBuilder {
+ bo := &BucketOptionsBuilder{}
+ bo.SetName(DefaultName).SetChunkSizeBytes(DefaultChunkSize)
+
+ return bo
+}
+
+// List returns a list of CountOptions setter functions.
+func (b *BucketOptionsBuilder) List() []func(*BucketOptions) error {
+ return b.Opts
+}
+
+// SetName sets the value for the Name field. Specifies the name of the bucket.
+// The default value is "fs".
+func (b *BucketOptionsBuilder) SetName(name string) *BucketOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BucketOptions) error {
+ opts.Name = &name
+
+ return nil
+ })
+
+ return b
+}
+
+// SetChunkSizeBytes sets the value for the ChunkSize field. Specifies the number
+// of bytes in each chunk in the bucket. The default value is 255 KiB.
+func (b *BucketOptionsBuilder) SetChunkSizeBytes(i int32) *BucketOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BucketOptions) error {
+ opts.ChunkSizeBytes = &i
+
+ return nil
+ })
+
+ return b
+}
+
+// SetWriteConcern sets the value for the WriteConcern field. Specifies the write
+// concern for the bucket. The default value is the write concern of the database
+// from which the bucket is created.
+func (b *BucketOptionsBuilder) SetWriteConcern(wc *writeconcern.WriteConcern) *BucketOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BucketOptions) error {
+ opts.WriteConcern = wc
+
+ return nil
+ })
+
+ return b
+}
+
+// SetReadConcern sets the value for the ReadConcern field. Specifies the read
+// concern for the bucket. The default value is the read concern of the database
+// from which the bucket is created.
+func (b *BucketOptionsBuilder) SetReadConcern(rc *readconcern.ReadConcern) *BucketOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BucketOptions) error {
+ opts.ReadConcern = rc
+
+ return nil
+ })
+
+ return b
+}
+
+// SetReadPreference sets the value for the ReadPreference field. Specifies the
+// read preference for the bucket. The default value is the read preference of
+// the database from which the bucket is created.
+func (b *BucketOptionsBuilder) SetReadPreference(rp *readpref.ReadPref) *BucketOptionsBuilder {
+ b.Opts = append(b.Opts, func(opts *BucketOptions) error {
+ opts.ReadPreference = rp
+
+ return nil
+ })
+
+ return b
+}
+
+// GridFSUploadOptions represents arguments that can be used to configure a GridFS
+// upload operation.
+//
+// See corresponding setter methods for documentation.
+type GridFSUploadOptions struct {
+ ChunkSizeBytes *int32
+ Metadata any
+ Registry *bson.Registry
+}
+
+// GridFSUploadOptionsBuilder contains options to configure a GridFS Upload.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type GridFSUploadOptionsBuilder struct {
+ Opts []func(*GridFSUploadOptions) error
+}
+
+// GridFSUpload creates a new GridFSUploadOptions instance.
+func GridFSUpload() *GridFSUploadOptionsBuilder {
+ opts := &GridFSUploadOptionsBuilder{}
+ opts.SetRegistry(defaultRegistry)
+
+ return opts
+}
+
+// List returns a list of GridFSUploadOptions setter functions.
+func (u *GridFSUploadOptionsBuilder) List() []func(*GridFSUploadOptions) error {
+ return u.Opts
+}
+
+// SetChunkSizeBytes sets the value for the ChunkSize field. Specifies the number of
+// bytes in each chunk in the bucket. The default value is DefaultChunkSize (255 KiB).
+func (u *GridFSUploadOptionsBuilder) SetChunkSizeBytes(i int32) *GridFSUploadOptionsBuilder {
+ u.Opts = append(u.Opts, func(opts *GridFSUploadOptions) error {
+ opts.ChunkSizeBytes = &i
+
+ return nil
+ })
+
+ return u
+}
+
+// SetMetadata sets the value for the Metadata field. Specifies additional application data
+// that will be stored in the "metadata" field of the document in the files collection.
+// The default value is nil, which means that the document in the files collection will
+// not contain a "metadata" field.
+func (u *GridFSUploadOptionsBuilder) SetMetadata(doc any) *GridFSUploadOptionsBuilder {
+ u.Opts = append(u.Opts, func(opts *GridFSUploadOptions) error {
+ opts.Metadata = doc
+
+ return nil
+ })
+
+ return u
+}
+
+// SetRegistry sets the bson codec registry for the Registry field. Specifies the BSON
+// registry to use for converting filters to BSON documents. The default value is
+// bson.NewRegistry().
+func (u *GridFSUploadOptionsBuilder) SetRegistry(registry *bson.Registry) *GridFSUploadOptionsBuilder {
+ u.Opts = append(u.Opts, func(opts *GridFSUploadOptions) error {
+ opts.Registry = registry
+
+ return nil
+ })
+
+ return u
+}
+
+// GridFSNameOptions represents arguments that can be used to configure a GridFS
+// DownloadByName operation.
+//
+// See corresponding setter methods for documentation.
+type GridFSNameOptions struct {
+ Revision *int32
+}
+
+// GridFSNameOptionsBuilder contains options to configure a GridFS name. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type GridFSNameOptionsBuilder struct {
+ Opts []func(*GridFSNameOptions) error
+}
+
+// GridFSName creates a new GridFSNameOptions instance.
+func GridFSName() *GridFSNameOptionsBuilder {
+ return &GridFSNameOptionsBuilder{}
+}
+
+// List returns a list of GridFSNameOptions setter functions.
+func (n *GridFSNameOptionsBuilder) List() []func(*GridFSNameOptions) error {
+ return n.Opts
+}
+
+// SetRevision sets the value for the Revision field. Specifies the revision
+// of the file to retrieve. Revision numbers are defined as follows:
+//
+// * 0 = the original stored file
+// * 1 = the first revision
+// * 2 = the second revision
+// * etc..
+// * -2 = the second most recent revision
+// * -1 = the most recent revision.
+//
+// The default value is -1
+func (n *GridFSNameOptionsBuilder) SetRevision(r int32) *GridFSNameOptionsBuilder {
+ n.Opts = append(n.Opts, func(opts *GridFSNameOptions) error {
+ opts.Revision = &r
+
+ return nil
+ })
+
+ return n
+}
+
+// GridFSFindOptions represents arguments that can be used to configure a GridFS
+// Find operation.
+//
+// See corresponding setter methods for documentation.
+type GridFSFindOptions struct {
+ AllowDiskUse *bool
+ BatchSize *int32
+ Limit *int32
+ NoCursorTimeout *bool
+ Skip *int32
+ Sort any
+}
+
+// GridFSFindOptionsBuilder contains options to configure find operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type GridFSFindOptionsBuilder struct {
+ Opts []func(*GridFSFindOptions) error
+}
+
+// GridFSFind creates a new GridFSFindOptions instance.
+func GridFSFind() *GridFSFindOptionsBuilder {
+ return &GridFSFindOptionsBuilder{}
+}
+
+// List returns a list of GridFSFindOptions setter functions.
+func (f *GridFSFindOptionsBuilder) List() []func(*GridFSFindOptions) error {
+ return f.Opts
+}
+
+// SetAllowDiskUse sets the value for the AllowDiskUse field. If true, the server can
+// write temporary data to disk while executing the find operation. The default value
+// is false. This option is only valid for MongoDB versions >= 4.4. For previous server
+// versions, the server will return an error if this option is used.
+func (f *GridFSFindOptionsBuilder) SetAllowDiskUse(b bool) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.AllowDiskUse = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetBatchSize sets the value for the BatchSize field. Specifies the maximum number
+// of documents to be included in each batch returned by the server.
+func (f *GridFSFindOptionsBuilder) SetBatchSize(i int32) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.BatchSize = &i
+
+ return nil
+ })
+
+ return f
+}
+
+// SetLimit sets the value for the Limit field. Specifies the maximum number of
+// documents to return. The default value is 0, which means that all documents
+// matching the filter will be returned. A negative limit specifies that the
+// resulting documents should be returned in a single batch. The default value is 0.
+func (f *GridFSFindOptionsBuilder) SetLimit(i int32) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.Limit = &i
+
+ return nil
+ })
+
+ return f
+}
+
+// SetNoCursorTimeout sets the value for the NoCursorTimeout field. If true, the
+// cursor created by the operation will not timeout after a period of inactivity.
+// The default value is false.
+func (f *GridFSFindOptionsBuilder) SetNoCursorTimeout(b bool) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.NoCursorTimeout = &b
+
+ return nil
+ })
+
+ return f
+}
+
+// SetSkip sets the value for the Skip field. Specifies the number of documents
+// to skip before adding documents to the result. The default value is 0.
+func (f *GridFSFindOptionsBuilder) SetSkip(i int32) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.Skip = &i
+
+ return nil
+ })
+
+ return f
+}
+
+// SetSort sets the value for the Sort field. Sets a document specifying the order
+// in which documents should be returned. The sort parameter is evaluated sequentially,
+// so the driver will return an error if it is a multi-key map (which is unordeded).
+// The default value is nil.
+func (f *GridFSFindOptionsBuilder) SetSort(sort any) *GridFSFindOptionsBuilder {
+ f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
+ opts.Sort = sort
+
+ return nil
+ })
+
+ return f
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/indexoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/indexoptions.go
new file mode 100644
index 000000000..309a77ba9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/indexoptions.go
@@ -0,0 +1,486 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// CreateIndexesOptions represents arguments that can be used to configure
+// IndexView.CreateOne and IndexView.CreateMany operations.
+//
+// See corresponding setter methods for documentation.
+type CreateIndexesOptions struct {
+ CommitQuorum any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// CreateIndexesOptionsBuilder contains options to create indexes. Each option
+// can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+//
+// See corresponding setter methods for documentation.
+type CreateIndexesOptionsBuilder struct {
+ Opts []func(*CreateIndexesOptions) error
+}
+
+// CreateIndexes creates a new CreateIndexesOptions instance.
+func CreateIndexes() *CreateIndexesOptionsBuilder {
+ return &CreateIndexesOptionsBuilder{}
+}
+
+// List returns a list of CreateIndexesOptions setter functions.
+func (c *CreateIndexesOptionsBuilder) List() []func(*CreateIndexesOptions) error {
+ return c.Opts
+}
+
+// SetCommitQuorumInt sets the value for the CommitQuorum field as an int32.
+// Specifies the number of data-bearing members of a replica set, including the primary,
+// that must complete the index builds successfully before the primary marks the indexes
+// as ready.
+//
+// Semantics for int: the number of members that must complete the build.
+//
+// This option is only available on MongoDB versions >= 4.4. A client-side error will
+// be returned if the option is specified for MongoDB versions <= 4.2. The default
+// value is nil, meaning that the server-side default will be used. See
+// dochub.mongodb.org/core/index-commit-quorum for more information.
+func (c *CreateIndexesOptionsBuilder) SetCommitQuorumInt(quorum int32) *CreateIndexesOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateIndexesOptions) error {
+ opts.CommitQuorum = quorum
+
+ return nil
+ })
+
+ return c
+}
+
+// SetCommitQuorumString sets the value for the CommitQuorum field as a string.
+// Specifies the number of data-bearing members of a replica set, including the primary,
+// that must complete the index builds successfully before the primary marks the indexes
+// as ready.
+//
+// Semantics for String: specifies a tag. All members with that tag must complete the build.
+//
+// This option is only available on MongoDB versions >= 4.4. A client-side error will
+// be returned if the option is specified for MongoDB versions <= 4.2. The default
+// value is nil, meaning that the server-side default will be used. See
+// dochub.mongodb.org/core/index-commit-quorum for more information.
+func (c *CreateIndexesOptionsBuilder) SetCommitQuorumString(quorum string) *CreateIndexesOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateIndexesOptions) error {
+ opts.CommitQuorum = quorum
+
+ return nil
+ })
+
+ return c
+}
+
+// SetCommitQuorumMajority sets the value for the CommitQuorum to special "majority" value.
+// Specifies the number of data-bearing members of a replica set, including the primary,
+// that must complete the index builds successfully before the primary marks the indexes
+// as ready.
+//
+// Semantics for "majority": A special value to indicate that more than half the nodes
+// must complete the build.
+//
+// This option is only available on MongoDB versions >= 4.4. A client-side error will
+// be returned if the option is specified for MongoDB versions <= 4.2. The default
+// value is nil, meaning that the server-side default will be used. See
+// dochub.mongodb.org/core/index-commit-quorum for more information.
+func (c *CreateIndexesOptionsBuilder) SetCommitQuorumMajority() *CreateIndexesOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateIndexesOptions) error {
+ opts.CommitQuorum = "majority"
+
+ return nil
+ })
+
+ return c
+}
+
+// SetCommitQuorumVotingMembers sets the value for the CommitQuorum to special "votingMembers" value.
+// Specifies the number of data-bearing members of a replica set, including the primary,
+// that must complete the index builds successfully before the primary marks the indexes
+// as ready.
+//
+// Semantics for "votingMembers": A special value to indicate that all voting data-bearing
+// nodes must complete.
+//
+// This option is only available on MongoDB versions >= 4.4. A client-side error will
+// be returned if the option is specified for MongoDB versions <= 4.2. The default
+// value is nil, meaning that the server-side default will be used. See
+// dochub.mongodb.org/core/index-commit-quorum for more information.
+func (c *CreateIndexesOptionsBuilder) SetCommitQuorumVotingMembers() *CreateIndexesOptionsBuilder {
+ c.Opts = append(c.Opts, func(opts *CreateIndexesOptions) error {
+ opts.CommitQuorum = "votingMembers"
+
+ return nil
+ })
+
+ return c
+}
+
+// DropIndexesOptions represents arguments that can be used to configure
+// IndexView.DropOne and IndexView.DropAll operations.
+type DropIndexesOptions struct {
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// DropIndexesOptionsBuilder contains options to configure dropping indexes.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type DropIndexesOptionsBuilder struct {
+ Opts []func(*DropIndexesOptions) error
+}
+
+// DropIndexes creates a new DropIndexesOptions instance.
+func DropIndexes() *DropIndexesOptionsBuilder {
+ return &DropIndexesOptionsBuilder{}
+}
+
+// List returns a list of DropIndexesOptions setter functions.
+func (d *DropIndexesOptionsBuilder) List() []func(*DropIndexesOptions) error {
+ return d.Opts
+}
+
+// ListIndexesOptions represents arguments that can be used to configure an
+// IndexView.List operation.
+//
+// See corresponding setter methods for documentation.
+type ListIndexesOptions struct {
+ BatchSize *int32
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// ListIndexesOptionsBuilder contains options to configure count operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type ListIndexesOptionsBuilder struct {
+ Opts []func(*ListIndexesOptions) error
+}
+
+// ListIndexes creates a new ListIndexesOptions instance.
+func ListIndexes() *ListIndexesOptionsBuilder {
+ return &ListIndexesOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (l *ListIndexesOptionsBuilder) List() []func(*ListIndexesOptions) error {
+ return l.Opts
+}
+
+// SetBatchSize sets the value for the BatchSize field. Specifies the maximum number
+// of documents to be included in each batch returned by the server.
+func (l *ListIndexesOptionsBuilder) SetBatchSize(i int32) *ListIndexesOptionsBuilder {
+ l.Opts = append(l.Opts, func(opts *ListIndexesOptions) error {
+ opts.BatchSize = &i
+
+ return nil
+ })
+
+ return l
+}
+
+// IndexOptions represents arguments that can be used to configure a new index
+// created through the IndexView.CreateOne or IndexView.CreateMany operations.
+//
+// See corresponding setter methods for documentation.
+type IndexOptions struct {
+ ExpireAfterSeconds *int32
+ Name *string
+ Sparse *bool
+ StorageEngine any
+ Unique *bool
+ Version *int32
+ DefaultLanguage *string
+ LanguageOverride *string
+ TextVersion *int32
+ Weights any
+ SphereVersion *int32
+ Bits *int32
+ Max *float64
+ Min *float64
+ BucketSize *int32
+ PartialFilterExpression any
+ Collation *Collation
+ WildcardProjection any
+ Hidden *bool
+}
+
+// IndexOptionsBuilder contains options to configure index operations. Each option
+// can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type IndexOptionsBuilder struct {
+ Opts []func(*IndexOptions) error
+}
+
+// Index creates a new IndexOptions instance.
+func Index() *IndexOptionsBuilder {
+ return &IndexOptionsBuilder{}
+}
+
+// List returns a list of IndexOptions setter functions.
+func (i *IndexOptionsBuilder) List() []func(*IndexOptions) error {
+ return i.Opts
+}
+
+// SetExpireAfterSeconds sets value for the ExpireAfterSeconds field. Specifies the length
+// of time, in seconds, for documents to remain in the collection. The default value is 0,
+// which means that documents will remain in the collection until they're explicitly
+// deleted or the collection is dropped.
+func (i *IndexOptionsBuilder) SetExpireAfterSeconds(seconds int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.ExpireAfterSeconds = &seconds
+
+ return nil
+ })
+
+ return i
+}
+
+// SetName sets the value for the Name field. Specifies the name of the index. The default
+// value is "[field1]_[direction1]_[field2]_[direction2]...". For example, an index with
+// the specification {name: 1, age: -1} will be named "name_1_age_-1".
+func (i *IndexOptionsBuilder) SetName(name string) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Name = &name
+
+ return nil
+ })
+
+ return i
+}
+
+// SetSparse sets the value of the Sparse field. If true, the index will only reference
+// documents that contain the fields specified in the index. The default is false.
+func (i *IndexOptionsBuilder) SetSparse(sparse bool) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Sparse = &sparse
+
+ return nil
+ })
+
+ return i
+}
+
+// SetStorageEngine sets the value for the StorageEngine field. Specifies the
+// storage engine to use for the index. The value must be a document in the form
+// {: }. The default value is nil, which means that
+// the default storage engine will be used.
+func (i *IndexOptionsBuilder) SetStorageEngine(engine any) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.StorageEngine = engine
+
+ return nil
+ })
+
+ return i
+}
+
+// SetUnique sets the value for the Unique field. If true, the collection will not
+// accept insertion or update of documents where the index key value matches an
+// existing value in the index. The default is false.
+func (i *IndexOptionsBuilder) SetUnique(unique bool) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Unique = &unique
+
+ return nil
+ })
+
+ return i
+}
+
+// SetVersion sets the value for the Version field. Specifies the index version
+// number, either 0 or 1.
+func (i *IndexOptionsBuilder) SetVersion(version int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Version = &version
+
+ return nil
+ })
+
+ return i
+}
+
+// SetDefaultLanguage sets the value for the DefaultLanguage field. Specifies the
+// language that determines the list of stop words and the rules for the stemmer
+// and tokenizer. This option is only applicable for text indexes and is ignored for
+// other index types. The default value is "english".
+func (i *IndexOptionsBuilder) SetDefaultLanguage(language string) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.DefaultLanguage = &language
+
+ return nil
+ })
+
+ return i
+}
+
+// SetLanguageOverride sets the value of the LanguageOverride field. Specifies the name
+// of the field in the collection's documents that contains the override language for the
+// document. This option is only applicable for text indexes and is ignored for other index
+// types. The default value is the value of the DefaultLanguage option.
+func (i *IndexOptionsBuilder) SetLanguageOverride(override string) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.LanguageOverride = &override
+
+ return nil
+ })
+
+ return i
+}
+
+// SetTextVersion sets the value for the TextVersion field. Specifies the index version number
+// for a text index. See https://www.mongodb.com/docs/manual/core/index-text/#text-versions
+// for information about different version numbers.
+func (i *IndexOptionsBuilder) SetTextVersion(version int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.TextVersion = &version
+
+ return nil
+ })
+
+ return i
+}
+
+// SetWeights sets the value for the Weights field. Sets a document that contains field
+// and weight pairs. The weight is an integer ranging from 1 to 99,999, inclusive,
+// indicating the significance of the field relative to the other indexed fields in
+// terms of the score. This option is only applicable for text indexes and is ignored
+// for other index types. The default value is nil, which means that every field will
+// have a weight of 1.
+func (i *IndexOptionsBuilder) SetWeights(weights any) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Weights = weights
+
+ return nil
+ })
+
+ return i
+}
+
+// SetSphereVersion sets the value for the SphereVersion field. Specifies the index version number
+// for a 2D sphere index. See https://www.mongodb.com/docs/manual/core/2dsphere/#dsphere-v2 for
+// information about different version numbers.
+func (i *IndexOptionsBuilder) SetSphereVersion(version int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.SphereVersion = &version
+
+ return nil
+ })
+
+ return i
+}
+
+// SetBits sets the value for the Bits field. Specifies the precision of the stored geohash
+// value of the location data. This option only applies to 2D indexes and is ignored for
+// other index types. The value must be between 1 and 32, inclusive. The default value is 26.
+func (i *IndexOptionsBuilder) SetBits(bits int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Bits = &bits
+
+ return nil
+ })
+
+ return i
+}
+
+// SetMax sets the value for the Max field. Specifies the upper inclusive boundary for
+// longitude and latitude values. This option is only applicable to 2D indexes and
+// is ignored for other index types. The default value is 180.0.
+func (i *IndexOptionsBuilder) SetMax(max float64) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Max = &max
+
+ return nil
+ })
+
+ return i
+}
+
+// SetMin sets the value for the Min field. Specifies the lower inclusive boundary for
+// longitude and latitude values. This option is only applicable to 2D indexes and
+// is ignored for other index types. The default value is -180.0.
+func (i *IndexOptionsBuilder) SetMin(min float64) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Min = &min
+
+ return nil
+ })
+
+ return i
+}
+
+// SetBucketSize sets the value for the BucketSize field. Specifies the number of units
+// within which to group location values. Location values that are within BucketSize
+// units of each other will be grouped in the same bucket. This option is only applicable
+// to geoHaystack indexes and is ignored for other index types. The value must be greater
+// than 0.
+func (i *IndexOptionsBuilder) SetBucketSize(bucketSize int32) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.BucketSize = &bucketSize
+
+ return nil
+ })
+
+ return i
+}
+
+// SetPartialFilterExpression sets the value for the PartialFilterExpression field. Sets
+// a document that defines which collection documents the index should reference.
+func (i *IndexOptionsBuilder) SetPartialFilterExpression(expression any) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.PartialFilterExpression = expression
+
+ return nil
+ })
+
+ return i
+}
+
+// SetCollation sets the value for the Collation field. Specifies the collation to use for
+// string comparisons for the index.
+func (i *IndexOptionsBuilder) SetCollation(collation *Collation) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Collation = collation
+
+ return nil
+ })
+
+ return i
+}
+
+// SetWildcardProjection sets the value for the WildcardProjection field. Sets a document
+// that defines the wildcard projection for the index.
+func (i *IndexOptionsBuilder) SetWildcardProjection(wildcardProjection any) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.WildcardProjection = wildcardProjection
+
+ return nil
+ })
+
+ return i
+}
+
+// SetHidden sets the value for the Hidden field. If true, the index will exist on the
+// target collection but will not be used by the query planner when executing operations.
+// This option is only valid for MongoDB versions >= 4.4. The default value is false.
+func (i *IndexOptionsBuilder) SetHidden(hidden bool) *IndexOptionsBuilder {
+ i.Opts = append(i.Opts, func(opts *IndexOptions) error {
+ opts.Hidden = &hidden
+
+ return nil
+ })
+
+ return i
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/insertoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/insertoptions.go
new file mode 100644
index 000000000..532f28506
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/insertoptions.go
@@ -0,0 +1,133 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// InsertOneOptions represents arguments that can be used to configure an InsertOne
+// operation.
+//
+// See corresponding setter methods for documentation.
+type InsertOneOptions struct {
+ BypassDocumentValidation *bool
+ Comment any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// InsertOneOptionsBuilder represents functional options that configure an
+// InsertOneopts.
+type InsertOneOptionsBuilder struct {
+ Opts []func(*InsertOneOptions) error
+}
+
+// InsertOne creates a new InsertOneOptions instance.
+func InsertOne() *InsertOneOptionsBuilder {
+ return &InsertOneOptionsBuilder{}
+}
+
+// List returns a list of InsertOneOptions setter functions.
+func (ioo *InsertOneOptionsBuilder) List() []func(*InsertOneOptions) error {
+ return ioo.Opts
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the
+// server. The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/
+// for more information about document validation.
+func (ioo *InsertOneOptionsBuilder) SetBypassDocumentValidation(b bool) *InsertOneOptionsBuilder {
+ ioo.Opts = append(ioo.Opts, func(opts *InsertOneOptions) error {
+ opts.BypassDocumentValidation = &b
+ return nil
+ })
+ return ioo
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be included in server logs, profiling logs, and currentOp queries to help trace
+// the operation. The default value is nil, which means that no comment will be included in the logs.
+func (ioo *InsertOneOptionsBuilder) SetComment(comment any) *InsertOneOptionsBuilder {
+ ioo.Opts = append(ioo.Opts, func(opts *InsertOneOptions) error {
+ opts.Comment = &comment
+ return nil
+ })
+ return ioo
+}
+
+// InsertManyOptions represents arguments that can be used to configure an
+// InsertMany operation.
+//
+// See corresponding setter methods for documentation.
+type InsertManyOptions struct {
+ BypassDocumentValidation *bool
+ Comment any
+ Ordered *bool
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// InsertManyOptionsBuilder contains options to configure insert operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type InsertManyOptionsBuilder struct {
+ Opts []func(*InsertManyOptions) error
+}
+
+// InsertMany creates a new InsertManyOptions instance.
+func InsertMany() *InsertManyOptionsBuilder {
+ opts := &InsertManyOptionsBuilder{}
+ opts.SetOrdered(DefaultOrdered)
+
+ return opts
+}
+
+// List returns a list of InsertManyOptions setter functions.
+func (imo *InsertManyOptionsBuilder) List() []func(*InsertManyOptions) error {
+ return imo.Opts
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the
+// server. The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/
+// for more information about document validation.
+func (imo *InsertManyOptionsBuilder) SetBypassDocumentValidation(b bool) *InsertManyOptionsBuilder {
+ imo.Opts = append(imo.Opts, func(opts *InsertManyOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return imo
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (imo *InsertManyOptionsBuilder) SetComment(comment any) *InsertManyOptionsBuilder {
+ imo.Opts = append(imo.Opts, func(opts *InsertManyOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return imo
+}
+
+// SetOrdered sets the value for the Ordered field. If true, no writes will be executed after
+// one fails. The default value is true.
+func (imo *InsertManyOptionsBuilder) SetOrdered(b bool) *InsertManyOptionsBuilder {
+ imo.Opts = append(imo.Opts, func(opts *InsertManyOptions) error {
+ opts.Ordered = &b
+
+ return nil
+ })
+
+ return imo
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listcollectionsoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listcollectionsoptions.go
new file mode 100644
index 000000000..c69a6dc4d
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listcollectionsoptions.go
@@ -0,0 +1,77 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// ListCollectionsOptions represents arguments that can be used to configure a
+// ListCollections operation.
+//
+// See corresponding setter methods for documentation.
+type ListCollectionsOptions struct {
+ NameOnly *bool
+ BatchSize *int32
+ AuthorizedCollections *bool
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// ListCollectionsOptionsBuilder contains options to configure list collection
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type ListCollectionsOptionsBuilder struct {
+ Opts []func(*ListCollectionsOptions) error
+}
+
+// ListCollections creates a new ListCollectionsOptions instance.
+func ListCollections() *ListCollectionsOptionsBuilder {
+ return &ListCollectionsOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (lc *ListCollectionsOptionsBuilder) List() []func(*ListCollectionsOptions) error {
+ return lc.Opts
+}
+
+// SetNameOnly sets the value for the NameOnly field. If true, each collection document will only
+// contain a field for the collection name. The default value is false.
+func (lc *ListCollectionsOptionsBuilder) SetNameOnly(b bool) *ListCollectionsOptionsBuilder {
+ lc.Opts = append(lc.Opts, func(opts *ListCollectionsOptions) error {
+ opts.NameOnly = &b
+
+ return nil
+ })
+
+ return lc
+}
+
+// SetBatchSize sets the value for the BatchSize field. Specifies the maximum number of documents
+// to be included in each batch returned by the server.
+func (lc *ListCollectionsOptionsBuilder) SetBatchSize(size int32) *ListCollectionsOptionsBuilder {
+ lc.Opts = append(lc.Opts, func(opts *ListCollectionsOptions) error {
+ opts.BatchSize = &size
+
+ return nil
+ })
+
+ return lc
+}
+
+// SetAuthorizedCollections sets the value for the AuthorizedCollections field. If true, and
+// NameOnly is true, limits the documents returned to only contain collections the user is
+// authorized to use. The default value is false.
+func (lc *ListCollectionsOptionsBuilder) SetAuthorizedCollections(b bool) *ListCollectionsOptionsBuilder {
+ lc.Opts = append(lc.Opts, func(opts *ListCollectionsOptions) error {
+ opts.AuthorizedCollections = &b
+
+ return nil
+ })
+
+ return lc
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listdatabasesoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listdatabasesoptions.go
new file mode 100644
index 000000000..09fd4fd78
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listdatabasesoptions.go
@@ -0,0 +1,54 @@
+// 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
+
+// ListDatabasesOptions represents arguments that can be used to configure a
+// ListDatabases operation.
+//
+// See corresponding setter methods for documentation.
+type ListDatabasesOptions struct {
+ NameOnly *bool
+ AuthorizedDatabases *bool
+}
+
+// ListDatabasesOptionsBuilder represents functional options that configure a
+// ListDatabasesopts.
+type ListDatabasesOptionsBuilder struct {
+ Opts []func(*ListDatabasesOptions) error
+}
+
+// ListDatabases creates a new ListDatabasesOptions instance.
+func ListDatabases() *ListDatabasesOptionsBuilder {
+ return &ListDatabasesOptionsBuilder{}
+}
+
+// List returns a list of ListDatabasesOptions setter functions.
+func (ld *ListDatabasesOptionsBuilder) List() []func(*ListDatabasesOptions) error {
+ return ld.Opts
+}
+
+// SetNameOnly sets the value for the NameOnly field. If true, only the Name field of the returned
+// DatabaseSpecification objects will be populated. The default value is false.
+func (ld *ListDatabasesOptionsBuilder) SetNameOnly(b bool) *ListDatabasesOptionsBuilder {
+ ld.Opts = append(ld.Opts, func(opts *ListDatabasesOptions) error {
+ opts.NameOnly = &b
+ return nil
+ })
+ return ld
+}
+
+// SetAuthorizedDatabases sets the value for the AuthorizedDatabases field. If true, only the
+// databases which the user is authorized to see will be returned. For more information about the
+// behavior of this option, see https://www.mongodb.com/docs/manual/reference/privilege-actions/#find.
+// The default value is true.
+func (ld *ListDatabasesOptionsBuilder) SetAuthorizedDatabases(b bool) *ListDatabasesOptionsBuilder {
+ ld.Opts = append(ld.Opts, func(opts *ListDatabasesOptions) error {
+ opts.AuthorizedDatabases = &b
+ return nil
+ })
+ return ld
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/cancellation_listener.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/lister.go
similarity index 52%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/cancellation_listener.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/lister.go
index caca98805..3b3783b4b 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/cancellation_listener.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/lister.go
@@ -1,14 +1,13 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
+// Copyright (C) MongoDB, Inc. 2024-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 topology
+package options
-import "context"
-
-type cancellationListener interface {
- Listen(context.Context, func())
- StopListening() bool
+// Lister is an interface that wraps a List method to return a
+// slice of option setters.
+type Lister[T any] interface {
+ List() []func(*T) error
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/loggeroptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/loggeroptions.go
similarity index 75%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/loggeroptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/loggeroptions.go
index b83793581..0eb7ce421 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/loggeroptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/loggeroptions.go
@@ -7,7 +7,7 @@
package options
import (
- "go.mongodb.org/mongo-driver/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
)
// LogLevel is an enumeration representing the supported log severity levels.
@@ -63,51 +63,51 @@ type LogSink interface {
//
// "Level V(0) is the default, and logger.V(0).Info() has the same
// meaning as logger.Info()."
- Info(level int, message string, keysAndValues ...interface{})
+ Info(level int, message string, keysAndValues ...any)
// Error logs an error message with the given key/value pairs
- Error(err error, message string, keysAndValues ...interface{})
+ Error(err error, message string, keysAndValues ...any)
}
-// LoggerOptions represent options used to configure Logging in the Go Driver.
+// LoggerOptions represent arguments used to configure Logging in the Go Driver.
+//
+// See corresponding setter methods for documentation.
type LoggerOptions struct {
- // ComponentLevels is a map of LogComponent to LogLevel. The LogLevel
- // for a given LogComponent will be used to determine if a log message
- // should be logged.
- ComponentLevels map[LogComponent]LogLevel
-
- // Sink is the LogSink that will be used to log messages. If this is
- // nil, the driver will use the standard logging library.
- Sink LogSink
-
- // MaxDocumentLength is the maximum length of a document to be logged.
- // If the underlying document is larger than this value, it will be
- // truncated and appended with an ellipses "...".
+ ComponentLevels map[LogComponent]LogLevel
+ Sink LogSink
MaxDocumentLength uint
}
// Logger creates a new LoggerOptions instance.
func Logger() *LoggerOptions {
- return &LoggerOptions{
- ComponentLevels: map[LogComponent]LogLevel{},
- }
+ return &LoggerOptions{}
}
-// SetComponentLevel sets the LogLevel value for a LogComponent.
+// SetComponentLevel sets the LogLevel value for a LogComponent. ComponentLevels is a map of
+// LogComponent to LogLevel. The LogLevel for a given LogComponent will be used to determine
+// if a log message should be logged.
func (opts *LoggerOptions) SetComponentLevel(component LogComponent, level LogLevel) *LoggerOptions {
+ if opts.ComponentLevels == nil {
+ opts.ComponentLevels = map[LogComponent]LogLevel{}
+ }
+
opts.ComponentLevels[component] = level
return opts
}
-// SetMaxDocumentLength sets the maximum length of a document to be logged.
+// SetMaxDocumentLength sets the maximum length of a document to be logged. Sink is the
+// LogSink that will be used to log messages. If this is nil, the driver will use the
+// standard logging library.
func (opts *LoggerOptions) SetMaxDocumentLength(maxDocumentLength uint) *LoggerOptions {
opts.MaxDocumentLength = maxDocumentLength
return opts
}
-// SetSink sets the LogSink to use for logging.
+// SetSink sets the LogSink to use for logging. MaxDocumentLength is the maximum length
+// of a document to be logged. If the underlying document is larger than this value, it
+// will be truncated and appended with an ellipses "...".
func (opts *LoggerOptions) SetSink(sink LogSink) *LoggerOptions {
opts.Sink = sink
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/mongooptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/mongooptions.go
new file mode 100644
index 000000000..ebbab53f9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/mongooptions.go
@@ -0,0 +1,70 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/bson"
+)
+
+var defaultRegistry = bson.NewRegistry()
+
+// 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
+}
+
+// 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 modified document for replace and update change events
+ // if the post-image for this event is available.
+ WhenAvailable FullDocument = "whenAvailable"
+)
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/replaceoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/replaceoptions.go
new file mode 100644
index 000000000..794a77eb9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/replaceoptions.go
@@ -0,0 +1,144 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// ReplaceOptions represents arguments that can be used to configure a ReplaceOne
+// operation.
+//
+// See corresponding setter methods for documentation.
+type ReplaceOptions struct {
+ BypassDocumentValidation *bool
+ Collation *Collation
+ Comment any
+ Hint any
+ Upsert *bool
+ Let any
+ Sort any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// ReplaceOptionsBuilder contains options to configure replace operations. Each
+// option can be set through setter functions. See documentation for each setter
+// function for an explanation of the option.
+type ReplaceOptionsBuilder struct {
+ Opts []func(*ReplaceOptions) error
+}
+
+// Replace creates a new ReplaceOptions instance.
+func Replace() *ReplaceOptionsBuilder {
+ return &ReplaceOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (ro *ReplaceOptionsBuilder) List() []func(*ReplaceOptions) error {
+ return ro.Opts
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the server.
+// The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for
+// more information about document validation.
+func (ro *ReplaceOptionsBuilder) SetBypassDocumentValidation(b bool) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (ro *ReplaceOptionsBuilder) SetCollation(c *Collation) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will
+// be included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (ro *ReplaceOptionsBuilder) SetComment(comment any) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the
+// operation. This should either be the index name as a string or the index
+// specification as a document. This option is only valid for MongoDB versions
+// >= 4.2. Server versions < 4.2 will return an error if this option is
+// specified. The driver will return an error if this option is specified during
+// an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that
+// no hint will be sent.
+func (ro *ReplaceOptionsBuilder) SetHint(h any) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Hint = h
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetUpsert sets the value for the Upsert field. If true, a new document will be inserted
+// if the filter does not match any documents in the collection. The default value is false.
+func (ro *ReplaceOptionsBuilder) SetUpsert(b bool) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Upsert = &b
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the aggregate expression.
+// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error
+// for using this option. This must be a document mapping parameter names to values. Values
+// must be constant or closed expressions that do not reference document fields. Parameters
+// can then be accessed as variables in an aggregate expression context (e.g. "$$var").
+func (ro *ReplaceOptionsBuilder) SetLet(l any) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Let = l
+
+ return nil
+ })
+
+ return ro
+}
+
+// SetSort sets the value for the Sort field. Specifies a document specifying which document should
+// be replaced if the filter used by the operation matches multiple documents in the collection. If
+// set, the first document in the sorted order will be replaced. This option is only valid for MongoDB
+// versions >= 8.0. The sort parameter is evaluated sequentially, so the driver will return an error
+// if it is a multi-key map (which is unordeded). The default value is nil.
+func (ro *ReplaceOptionsBuilder) SetSort(s any) *ReplaceOptionsBuilder {
+ ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
+ opts.Sort = s
+
+ return nil
+ })
+
+ return ro
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/rewrapdatakeyoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/rewrapdatakeyoptions.go
new file mode 100644
index 000000000..3dab855f3
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/rewrapdatakeyoptions.go
@@ -0,0 +1,57 @@
+// Copyright (C) MongoDB, Inc. 2022-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
+
+// RewrapManyDataKeyOptions represents all possible options used to decrypt and
+// encrypt all matching data keys with a possibly new masterKey.
+//
+// See corresponding setter methods for documentation.
+type RewrapManyDataKeyOptions struct {
+ Provider *string
+ MasterKey any
+}
+
+// RewrapManyDataKeyOptionsBuilder contains options to configure rewraping a
+// data key. Each option can be set through setter functions. See documentation
+// for each setter function for an explanation of the option.
+type RewrapManyDataKeyOptionsBuilder struct {
+ Opts []func(*RewrapManyDataKeyOptions) error
+}
+
+// RewrapManyDataKey creates a new RewrapManyDataKeyOptions instance.
+func RewrapManyDataKey() *RewrapManyDataKeyOptionsBuilder {
+ return new(RewrapManyDataKeyOptionsBuilder)
+}
+
+// List returns a list of CountOptions setter functions.
+func (rmdko *RewrapManyDataKeyOptionsBuilder) List() []func(*RewrapManyDataKeyOptions) error {
+ return rmdko.Opts
+}
+
+// SetProvider sets the value for the Provider field. Provider identifies the new KMS provider.
+// If omitted, encrypting uses the current KMS provider.
+func (rmdko *RewrapManyDataKeyOptionsBuilder) SetProvider(provider string) *RewrapManyDataKeyOptionsBuilder {
+ rmdko.Opts = append(rmdko.Opts, func(opts *RewrapManyDataKeyOptions) error {
+ opts.Provider = &provider
+
+ return nil
+ })
+
+ return rmdko
+}
+
+// SetMasterKey sets the value for the MasterKey field. MasterKey identifies the new masterKey.
+// If omitted, rewraps with the current masterKey.
+func (rmdko *RewrapManyDataKeyOptionsBuilder) SetMasterKey(masterKey any) *RewrapManyDataKeyOptionsBuilder {
+ rmdko.Opts = append(rmdko.Opts, func(opts *RewrapManyDataKeyOptions) error {
+ opts.MasterKey = masterKey
+
+ return nil
+ })
+
+ return rmdko
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/runcmdoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/runcmdoptions.go
new file mode 100644
index 000000000..d2e5d690a
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/runcmdoptions.go
@@ -0,0 +1,49 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+)
+
+// RunCmdOptions represents arguments that can be used to configure a RunCommand
+// operation.
+//
+// See corresponding setter methods for documentation.
+type RunCmdOptions struct {
+ ReadPreference *readpref.ReadPref
+}
+
+// RunCmdOptionsBuilder contains options to configure runCommand operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type RunCmdOptionsBuilder struct {
+ Opts []func(*RunCmdOptions) error
+}
+
+// RunCmd creates a new RunCmdOptions instance.
+func RunCmd() *RunCmdOptionsBuilder {
+ return &RunCmdOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (rc *RunCmdOptionsBuilder) List() []func(*RunCmdOptions) error {
+ return rc.Opts
+}
+
+// SetReadPreference sets value for the ReadPreference field. Specifies the read preference
+// to use for the operation. The default value is nil, which means that the primary read
+// preference will be used.
+func (rc *RunCmdOptionsBuilder) SetReadPreference(rp *readpref.ReadPref) *RunCmdOptionsBuilder {
+ rc.Opts = append(rc.Opts, func(opts *RunCmdOptions) error {
+ opts.ReadPreference = rp
+
+ return nil
+ })
+
+ return rc
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/searchindexoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/searchindexoptions.go
new file mode 100644
index 000000000..933c65104
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/searchindexoptions.go
@@ -0,0 +1,118 @@
+// Copyright (C) MongoDB, Inc. 2023-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
+
+// SearchIndexesOptions represents arguments that can be used to configure a
+// SearchIndexView.
+type SearchIndexesOptions struct {
+ Name *string
+ Type *string
+}
+
+// SearchIndexesOptionsBuilder contains options to configure search index
+// operations. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type SearchIndexesOptionsBuilder struct {
+ Opts []func(*SearchIndexesOptions) error
+}
+
+// SearchIndexes creates a new SearchIndexesOptions instance.
+func SearchIndexes() *SearchIndexesOptionsBuilder {
+ return &SearchIndexesOptionsBuilder{}
+}
+
+// List returns a list of CountOptions setter functions.
+func (sio *SearchIndexesOptionsBuilder) List() []func(*SearchIndexesOptions) error {
+ return sio.Opts
+}
+
+// SetName sets the value for the Name field.
+func (sio *SearchIndexesOptionsBuilder) SetName(name string) *SearchIndexesOptionsBuilder {
+ sio.Opts = append(sio.Opts, func(opts *SearchIndexesOptions) error {
+ opts.Name = &name
+
+ return nil
+ })
+
+ return sio
+}
+
+// SetType sets the value for the Type field.
+func (sio *SearchIndexesOptionsBuilder) SetType(typ string) *SearchIndexesOptionsBuilder {
+ sio.Opts = append(sio.Opts, func(opts *SearchIndexesOptions) error {
+ opts.Type = &typ
+
+ return nil
+ })
+
+ return sio
+}
+
+// CreateSearchIndexesOptions represents arguments that can be used to configure
+// a SearchIndexView.CreateOne or SearchIndexView.CreateMany operation.
+type CreateSearchIndexesOptions struct{}
+
+// CreateSearchIndexesOptionsBuilder contains options to configure creating
+// search indexes. Each option can be set through setter functions. See
+// documentation for each setter function for an explanation of the option.
+type CreateSearchIndexesOptionsBuilder struct {
+ Opts []func(*CreateSearchIndexesOptions) error
+}
+
+// List returns a list of CreateSearchIndexesOptions setter functions.
+func (csio *CreateSearchIndexesOptionsBuilder) List() []func(*CreateSearchIndexesOptions) error {
+ return csio.Opts
+}
+
+// ListSearchIndexesOptions represents arguments that can be used to configure a
+// SearchIndexView.List operation.
+type ListSearchIndexesOptions struct {
+ AggregateOptions *AggregateOptions
+}
+
+// ListSearchIndexesOptionsBuilder contains options that can be used to
+// configure a SearchIndexView.List operation.
+type ListSearchIndexesOptionsBuilder struct {
+ Opts []func(*ListSearchIndexesOptions) error
+}
+
+// List returns a list of ListSearchIndexesOptions setter functions.
+func (lsi *ListSearchIndexesOptionsBuilder) List() []func(*ListSearchIndexesOptions) error {
+ return lsi.Opts
+}
+
+// DropSearchIndexOptions represents arguments that can be used to configure a
+// SearchIndexView.DropOne operation.
+type DropSearchIndexOptions struct{}
+
+// DropSearchIndexOptionsBuilder contains options to configure dropping search
+// indexes. Each option can be set through setter functions. See documentation
+// for each setter function for an explanation of the option.
+type DropSearchIndexOptionsBuilder struct {
+ Opts []func(*DropSearchIndexOptions) error
+}
+
+// List returns a list of DropSearchIndexOptions setter functions.
+func (dsio *DropSearchIndexOptionsBuilder) List() []func(*DropSearchIndexOptions) error {
+ return dsio.Opts
+}
+
+// UpdateSearchIndexOptions represents arguments that can be used to configure a
+// SearchIndexView.UpdateOne operation.
+type UpdateSearchIndexOptions struct{}
+
+// UpdateSearchIndexOptionsBuilder contains options to configure updating search
+// indexes. Each option can be set through setter functions. See documentation
+// for each setter function for an explanation of the option.
+type UpdateSearchIndexOptionsBuilder struct {
+ Opts []func(*UpdateSearchIndexOptions) error
+}
+
+// List returns a list of UpdateSearchIndexOptions setter functions.
+func (usio *UpdateSearchIndexOptionsBuilder) List() []func(*UpdateSearchIndexOptions) error {
+ return usio.Opts
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/serverapioptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/serverapioptions.go
similarity index 74%
rename from vendor/go.mongodb.org/mongo-driver/mongo/options/serverapioptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/options/serverapioptions.go
index 4eef2e199..8f38dbc9e 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/options/serverapioptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/serverapioptions.go
@@ -10,22 +10,27 @@ import (
"fmt"
)
-// ServerAPIOptions represents options used to configure the API version sent to the server
-// when running commands.
+// ServerAPIOptions represents arguments used to configure the API version sent to
+// the server when running commands.
//
-// Sending a specified server API version causes the server to behave in a manner compatible with that
-// API version. It also causes the driver to behave in a manner compatible with the driver’s behavior as
-// of the release when the driver first started to support the specified server API version.
+// Sending a specified server API version causes the server to behave in a
+// manner compatible with that API version. It also causes the driver to behave
+// in a manner compatible with the driver’s behavior as of the release when the
+// driver first started to support the specified server API version.
//
-// The user must specify a ServerAPIVersion if including ServerAPIOptions in their client. That version
-// must also be currently supported by the driver. This version of the driver supports API version "1".
+// The user must specify a ServerAPIVersion if including ServerAPIOptions in
+// their client. That version must also be currently supported by the driver.
+// This version of the driver supports API version "1".
+//
+// See corresponding setter methods for documentation.
type ServerAPIOptions struct {
ServerAPIVersion ServerAPIVersion
Strict *bool
DeprecationErrors *bool
}
-// ServerAPI creates a new ServerAPIOptions configured with the provided serverAPIversion.
+// ServerAPI creates a new ServerAPIOptions configured with the provided
+// serverAPIversion.
func ServerAPI(serverAPIVersion ServerAPIVersion) *ServerAPIOptions {
return &ServerAPIOptions{ServerAPIVersion: serverAPIVersion}
}
@@ -33,12 +38,14 @@ func ServerAPI(serverAPIVersion ServerAPIVersion) *ServerAPIOptions {
// SetStrict specifies whether the server should return errors for features that are not part of the API version.
func (s *ServerAPIOptions) SetStrict(strict bool) *ServerAPIOptions {
s.Strict = &strict
+
return s
}
// SetDeprecationErrors specifies whether the server should return errors for deprecated features.
func (s *ServerAPIOptions) SetDeprecationErrors(deprecationErrors bool) *ServerAPIOptions {
s.DeprecationErrors = &deprecationErrors
+
return s
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/sessionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/sessionoptions.go
new file mode 100644
index 000000000..a017e8c06
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/sessionoptions.go
@@ -0,0 +1,87 @@
+// 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 "go.mongodb.org/mongo-driver/v2/bson"
+
+// DefaultCausalConsistency is the default value for the CausalConsistency option.
+var DefaultCausalConsistency = true
+
+// SessionOptions represents arguments that can be used to configure a Session.
+//
+// See corresponding setter methods for documentation.
+type SessionOptions struct {
+ CausalConsistency *bool
+ DefaultTransactionOptions *TransactionOptionsBuilder
+ Snapshot *bool
+ SnapshotTime *bson.Timestamp
+}
+
+// SessionOptionsBuilder represents functional options that configure a Sessionopts.
+type SessionOptionsBuilder struct {
+ Opts []func(*SessionOptions) error
+}
+
+// Session creates a new SessionOptions instance.
+func Session() *SessionOptionsBuilder {
+ return &SessionOptionsBuilder{}
+}
+
+// List returns a list of SessionOptions setter functions.
+func (s *SessionOptionsBuilder) List() []func(*SessionOptions) error {
+ return s.Opts
+}
+
+// SetCausalConsistency sets the value for the CausalConsistency field. If true, causal
+// consistency will be enabled for the session. This option cannot be set to true if Snapshot
+// is set to true. The default value is true unless Snapshot is set to true. See
+// https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#sessions
+// for more information.
+func (s *SessionOptionsBuilder) SetCausalConsistency(b bool) *SessionOptionsBuilder {
+ s.Opts = append(s.Opts, func(opts *SessionOptions) error {
+ opts.CausalConsistency = &b
+ return nil
+ })
+ return s
+}
+
+// SetDefaultTransactionOptions sets the value for the DefaultTransactionOptions field.
+// Specifies the default options for transactions started in the session. If this object
+// or any value on the object is nil, the client-level read concern, write concern,
+// and/or read preference will be used to start the session.
+func (s *SessionOptionsBuilder) SetDefaultTransactionOptions(dt *TransactionOptionsBuilder) *SessionOptionsBuilder {
+ s.Opts = append(s.Opts, func(opts *SessionOptions) error {
+ opts.DefaultTransactionOptions = dt
+ return nil
+ })
+ return s
+}
+
+// SetSnapshot sets the value for the Snapshot field. If true, all read operations performed
+// with this session will be read from the same snapshot. This option cannot be set to true
+// if CausalConsistency is set to true. Transactions and write operations are not allowed on
+// snapshot sessions and will error. The default value is false.
+func (s *SessionOptionsBuilder) SetSnapshot(b bool) *SessionOptionsBuilder {
+ s.Opts = append(s.Opts, func(opts *SessionOptions) error {
+ opts.Snapshot = &b
+ return nil
+ })
+ return s
+}
+
+// SetSnapshotTime sets the value for the SnapshotTime field. Specifies the
+// timestamp to use for snapshot reads within the session. This option can only
+// be set if Snapshot is set to true. If not provided, the snapshot time will be
+// determined automatically from the atClusterTime of the first read operation
+// performed in the session. The default value is nil.
+func (s *SessionOptionsBuilder) SetSnapshotTime(t bson.Timestamp) *SessionOptionsBuilder {
+ s.Opts = append(s.Opts, func(opts *SessionOptions) error {
+ opts.SnapshotTime = &t
+ return nil
+ })
+ return s
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/transactionoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/transactionoptions.go
new file mode 100644
index 000000000..56af34d32
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/transactionoptions.go
@@ -0,0 +1,79 @@
+// 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 (
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+)
+
+// TransactionOptions represents arguments that can be used to configure a
+// transaction.
+//
+// See corresponding setter methods for documentation.
+type TransactionOptions struct {
+ ReadConcern *readconcern.ReadConcern
+ ReadPreference *readpref.ReadPref
+ WriteConcern *writeconcern.WriteConcern
+}
+
+// TransactionOptionsBuilder contains arguments to configure count operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type TransactionOptionsBuilder struct {
+ Opts []func(*TransactionOptions) error
+}
+
+// Transaction creates a new TransactionOptions instance.
+func Transaction() *TransactionOptionsBuilder {
+ return &TransactionOptionsBuilder{}
+}
+
+// List returns a list of TransactionOptions setter functions.
+func (t *TransactionOptionsBuilder) List() []func(*TransactionOptions) error {
+ return t.Opts
+}
+
+// SetReadConcern sets the value for the ReadConcern field. Specifies the read concern for operations
+// in the transaction. The default value is nil, which means that the default read concern of the
+// session used to start the transaction will be used.
+func (t *TransactionOptionsBuilder) SetReadConcern(rc *readconcern.ReadConcern) *TransactionOptionsBuilder {
+ t.Opts = append(t.Opts, func(opts *TransactionOptions) error {
+ opts.ReadConcern = rc
+
+ return nil
+ })
+
+ return t
+}
+
+// SetReadPreference sets the value for the ReadPreference field. Specifies the read preference for
+// operations in the transaction. The default value is nil, which means that the default read
+// preference of the session used to start the transaction will be used.
+func (t *TransactionOptionsBuilder) SetReadPreference(rp *readpref.ReadPref) *TransactionOptionsBuilder {
+ t.Opts = append(t.Opts, func(opts *TransactionOptions) error {
+ opts.ReadPreference = rp
+
+ return nil
+ })
+
+ return t
+}
+
+// SetWriteConcern sets the value for the WriteConcern field. Specifies the write concern for
+// operations in the transaction. The default value is nil, which means that the default
+// write concern of the session used to start the transaction will be used.
+func (t *TransactionOptionsBuilder) SetWriteConcern(wc *writeconcern.WriteConcern) *TransactionOptionsBuilder {
+ t.Opts = append(t.Opts, func(opts *TransactionOptions) error {
+ opts.WriteConcern = wc
+
+ return nil
+ })
+
+ return t
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/updateoptions.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/updateoptions.go
new file mode 100644
index 000000000..c5d15b7a1
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/options/updateoptions.go
@@ -0,0 +1,293 @@
+// 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 "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+
+// UpdateOneOptions represents arguments that can be used to configure UpdateOne
+// operations.
+//
+// See corresponding setter methods for documentation.
+type UpdateOneOptions struct {
+ ArrayFilters []any
+ BypassDocumentValidation *bool
+ Collation *Collation
+ Comment any
+ Hint any
+ Upsert *bool
+ Let any
+ Sort any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// UpdateOneOptionsBuilder contains options to configure UpdateOne operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type UpdateOneOptionsBuilder struct {
+ Opts []func(*UpdateOneOptions) error
+}
+
+// UpdateOne creates a new UpdateOneOptions instance.
+func UpdateOne() *UpdateOneOptionsBuilder {
+ return &UpdateOneOptionsBuilder{}
+}
+
+// List returns a list of UpdateOneOptions setter functions.
+func (uo *UpdateOneOptionsBuilder) List() []func(*UpdateOneOptions) error {
+ return uo.Opts
+}
+
+// SetArrayFilters sets the value for the ArrayFilters field. ArrayFilters is a
+// set of filters specifying to which array elements an update should apply. The
+// default value is nil, which means the update will apply to all array
+// elements.
+func (uo *UpdateOneOptionsBuilder) SetArrayFilters(af []any) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.ArrayFilters = af
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the server.
+// The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for
+// more information about document validation.
+func (uo *UpdateOneOptionsBuilder) SetBypassDocumentValidation(b bool) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (uo *UpdateOneOptionsBuilder) SetCollation(c *Collation) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (uo *UpdateOneOptionsBuilder) SetComment(comment any) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the
+// operation. This should either be the index name as a string or the index
+// specification as a document. This option is only valid for MongoDB versions
+// >= 4.2. Server versions < 4.2 will return an error if this option is
+// specified. The driver will return an error if this option is specified during
+// an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that
+// no hint will be sent.
+func (uo *UpdateOneOptionsBuilder) SetHint(h any) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Hint = h
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetUpsert sets the value for the Upsert field. If true, a new document will be inserted if the
+// filter does not match any documents in the collection. The default value is false.
+func (uo *UpdateOneOptionsBuilder) SetUpsert(b bool) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Upsert = &b
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the update expression. This
+// option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using
+// this option. This must be a document mapping parameter names to values. Values must be constant
+// or closed expressions that do not reference document fields. Parameters can then be accessed
+// as variables in an aggregate expression context (e.g. "$$var").
+func (uo *UpdateOneOptionsBuilder) SetLet(l any) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Let = l
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetSort sets the value for the Sort field. Specifies a document specifying which document should
+// be updated if the filter used by the operation matches multiple documents in the collection. If
+// set, the first document in the sorted order will be updated. This option is only valid for MongoDB
+// versions >= 8.0. The sort parameter is evaluated sequentially, so the driver will return an error
+// if it is a multi-key map (which is unordeded). The default value is nil.
+func (uo *UpdateOneOptionsBuilder) SetSort(s any) *UpdateOneOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
+ opts.Sort = s
+
+ return nil
+ })
+
+ return uo
+}
+
+// UpdateManyOptions represents arguments that can be used to configure UpdateMany
+// operations.
+//
+// See corresponding setter methods for documentation.
+type UpdateManyOptions struct {
+ ArrayFilters []any
+ BypassDocumentValidation *bool
+ Collation *Collation
+ Comment any
+ Hint any
+ Upsert *bool
+ Let any
+
+ // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any
+ // release.
+ Internal optionsutil.Options
+}
+
+// UpdateManyOptionsBuilder contains options to configure UpdateMany operations.
+// Each option can be set through setter functions. See documentation for each
+// setter function for an explanation of the option.
+type UpdateManyOptionsBuilder struct {
+ Opts []func(*UpdateManyOptions) error
+}
+
+// UpdateMany creates a new UpdateManyOptions instance.
+func UpdateMany() *UpdateManyOptionsBuilder {
+ return &UpdateManyOptionsBuilder{}
+}
+
+// List returns a list of UpdateManyOptions setter functions.
+func (uo *UpdateManyOptionsBuilder) List() []func(*UpdateManyOptions) error {
+ return uo.Opts
+}
+
+// SetArrayFilters sets the value for the ArrayFilters field. ArrayFilters is a
+// set of filters specifying to which array elements an update should apply. The
+// default value is nil, which means the update will apply to all array
+// elements.
+func (uo *UpdateManyOptionsBuilder) SetArrayFilters(af []any) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.ArrayFilters = af
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetBypassDocumentValidation sets the value for the BypassDocumentValidation field. If true,
+// writes executed as part of the operation will opt out of document-level validation on the server.
+// The default value is false. See https://www.mongodb.com/docs/manual/core/schema-validation/ for
+// more information about document validation.
+func (uo *UpdateManyOptionsBuilder) SetBypassDocumentValidation(b bool) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.BypassDocumentValidation = &b
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetCollation sets the value for the Collation field. Specifies a collation to
+// use for string comparisons during the operation. The default value is nil,
+// which means the default collation of the collection will be used.
+func (uo *UpdateManyOptionsBuilder) SetCollation(c *Collation) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.Collation = c
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetComment sets the value for the Comment field. Specifies a string or document that will be
+// included in server logs, profiling logs, and currentOp queries to help trace the operation.
+// The default value is nil, which means that no comment will be included in the logs.
+func (uo *UpdateManyOptionsBuilder) SetComment(comment any) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.Comment = comment
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetHint sets the value for the Hint field. Specifies the index to use for the
+// operation. This should either be the index name as a string or the index
+// specification as a document. This option is only valid for MongoDB versions
+// >= 4.2. Server versions < 4.2 will return an error if this option is
+// specified. The driver will return an error if this option is specified during
+// an unacknowledged write operation. The driver will return an error if the
+// hint parameter is a multi-key map. The default value is nil, which means that
+// no hint will be sent.
+func (uo *UpdateManyOptionsBuilder) SetHint(h any) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.Hint = h
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetUpsert sets the value for the Upsert field. If true, a new document will be inserted if the
+// filter does not match any documents in the collection. The default value is false.
+func (uo *UpdateManyOptionsBuilder) SetUpsert(b bool) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.Upsert = &b
+
+ return nil
+ })
+
+ return uo
+}
+
+// SetLet sets the value for the Let field. Specifies parameters for the update expression. This
+// option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using
+// this option. This must be a document mapping parameter names to values. Values must be constant
+// or closed expressions that do not reference document fields. Parameters can then be accessed
+// as variables in an aggregate expression context (e.g. "$$var").
+func (uo *UpdateManyOptionsBuilder) SetLet(l any) *UpdateManyOptionsBuilder {
+ uo.Opts = append(uo.Opts, func(opts *UpdateManyOptions) error {
+ opts.Let = l
+
+ return nil
+ })
+
+ return uo
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/readconcern/readconcern.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readconcern/readconcern.go
similarity index 57%
rename from vendor/go.mongodb.org/mongo-driver/mongo/readconcern/readconcern.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/readconcern/readconcern.go
index 51408e142..dc1542704 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/readconcern/readconcern.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readconcern/readconcern.go
@@ -8,14 +8,7 @@
//
// For more information about MongoDB read concerns, see
// https://www.mongodb.com/docs/manual/reference/read-concern/
-package readconcern // import "go.mongodb.org/mongo-driver/mongo/readconcern"
-
-import (
- "errors"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
+package readconcern
// A ReadConcern defines a MongoDB read concern, which allows you to control the consistency and
// isolation properties of the data read from replica sets and replica set shards.
@@ -26,31 +19,13 @@ type ReadConcern struct {
Level string
}
-// Option is an option to provide when creating a ReadConcern.
-//
-// Deprecated: Use the ReadConcern literal declaration instead. For example:
-//
-// &readconcern.ReadConcern{Level: "local"}
-type Option func(concern *ReadConcern)
-
-// Level creates an option that sets the level of a ReadConcern.
-//
-// Deprecated: Use the ReadConcern literal declaration instead. For example:
-//
-// &readconcern.ReadConcern{Level: "local"}
-func Level(level string) Option {
- return func(concern *ReadConcern) {
- concern.Level = level
- }
-}
-
// Local returns a ReadConcern that requests data from the instance with no guarantee that the data
// has been written to a majority of the replica set members (i.e. may be rolled back).
//
// For more information about read concern "local", see
// https://www.mongodb.com/docs/manual/reference/read-concern-local/
func Local() *ReadConcern {
- return New(Level("local"))
+ return &ReadConcern{Level: "local"}
}
// Majority returns a ReadConcern that requests data that has been acknowledged by a majority of the
@@ -59,7 +34,7 @@ func Local() *ReadConcern {
// For more information about read concern "majority", see
// https://www.mongodb.com/docs/manual/reference/read-concern-majority/
func Majority() *ReadConcern {
- return New(Level("majority"))
+ return &ReadConcern{Level: "majority"}
}
// Linearizable returns a ReadConcern that requests data that reflects all successful
@@ -68,7 +43,7 @@ func Majority() *ReadConcern {
// For more information about read concern "linearizable", see
// https://www.mongodb.com/docs/manual/reference/read-concern-linearizable/
func Linearizable() *ReadConcern {
- return New(Level("linearizable"))
+ return &ReadConcern{Level: "linearizable"}
}
// Available returns a ReadConcern that requests data from an instance with no guarantee that the
@@ -77,7 +52,7 @@ func Linearizable() *ReadConcern {
// For more information about read concern "available", see
// https://www.mongodb.com/docs/manual/reference/read-concern-available/
func Available() *ReadConcern {
- return New(Level("available"))
+ return &ReadConcern{Level: "available"}
}
// Snapshot returns a ReadConcern that requests majority-committed data as it appears across shards
@@ -86,44 +61,5 @@ func Available() *ReadConcern {
// For more information about read concern "snapshot", see
// https://www.mongodb.com/docs/manual/reference/read-concern-snapshot/
func Snapshot() *ReadConcern {
- return New(Level("snapshot"))
-}
-
-// New constructs a new read concern from the given string.
-//
-// Deprecated: Use the ReadConcern literal declaration instead. For example:
-//
-// &readconcern.ReadConcern{Level: "local"}
-func New(options ...Option) *ReadConcern {
- concern := &ReadConcern{}
-
- for _, option := range options {
- option(concern)
- }
-
- return concern
-}
-
-// MarshalBSONValue implements the bson.ValueMarshaler interface.
-//
-// Deprecated: Marshaling a ReadConcern to BSON will not be supported in Go Driver 2.0.
-func (rc *ReadConcern) MarshalBSONValue() (bsontype.Type, []byte, error) {
- if rc == nil {
- return 0, nil, errors.New("cannot marshal nil ReadConcern")
- }
-
- var elems []byte
-
- if len(rc.Level) > 0 {
- elems = bsoncore.AppendStringElement(elems, "level", rc.Level)
- }
-
- return bsontype.EmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
-}
-
-// GetLevel returns the read concern level.
-//
-// Deprecated: Use the ReadConcern.Level field instead.
-func (rc *ReadConcern) GetLevel() string {
- return rc.Level
+ return &ReadConcern{Level: "snapshot"}
}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/mode.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/mode.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/mongo/readpref/mode.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/mode.go
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/options.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/options.go
similarity index 85%
rename from vendor/go.mongodb.org/mongo-driver/mongo/readpref/options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/options.go
index c59b0705f..5cd9c9f69 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/options.go
@@ -10,7 +10,7 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/tag"
+ "go.mongodb.org/mongo-driver/v2/tag"
)
// ErrInvalidTagSet indicates that an invalid set of tags was specified.
@@ -71,10 +71,15 @@ func WithTagSets(tagSets ...tag.Set) Option {
}
}
-// WithHedgeEnabled specifies whether or not hedged reads should be enabled in the server. This feature requires MongoDB
-// server version 4.4 or higher. For more information about hedged reads, see
-// https://www.mongodb.com/docs/manual/core/sharded-cluster-query-router/#mongos-hedged-reads. If not specified, the default
-// is to not send a value to the server, which will result in the server defaults being used.
+// WithHedgeEnabled specifies whether or not hedged reads should be enabled in
+// the server. This feature requires MongoDB server version 4.4 or higher. For
+// more information about hedged reads, see
+// https://www.mongodb.com/docs/manual/core/sharded-cluster-query-router/#mongos-hedged-reads.
+// If not specified, the default is to not send a value to the server, which
+// will result in the server defaults being used.
+//
+// Deprecated: Hedged reads are deprecated in MongoDB 8.0 and may be removed in
+// a future MongoDB version.
func WithHedgeEnabled(hedgeEnabled bool) Option {
return func(rp *ReadPref) error {
rp.hedgeEnabled = &hedgeEnabled
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/readpref.go
similarity index 89%
rename from vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/readpref.go
index e2a1d7f34..bfe12296e 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/readpref.go
@@ -5,7 +5,7 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Package readpref defines read preferences for MongoDB queries.
-package readpref // import "go.mongodb.org/mongo-driver/mongo/readpref"
+package readpref
import (
"bytes"
@@ -13,12 +13,10 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/tag"
+ "go.mongodb.org/mongo-driver/v2/tag"
)
-var (
- errInvalidReadPreference = errors.New("can not specify tags, max staleness, or hedge with mode primary")
-)
+var errInvalidReadPreference = errors.New("can not specify tags, max staleness, or hedge with mode primary")
// Primary constructs a read preference with a PrimaryMode.
func Primary() *ReadPref {
@@ -103,8 +101,12 @@ func (r *ReadPref) TagSets() []tag.Set {
return r.tagSets
}
-// HedgeEnabled returns whether or not hedged reads are enabled for this read preference. If this option was not
-// specified during read preference construction, nil is returned.
+// HedgeEnabled returns whether or not hedged reads are enabled for this read
+// preference. If this option was not specified during read preference
+// construction, nil is returned.
+//
+// Deprecated: Hedged reads are deprecated in MongoDB 8.0 and may be removed in
+// a future MongoDB version.
func (r *ReadPref) HedgeEnabled() *bool {
return r.hedgeEnabled
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/results.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/results.go
new file mode 100644
index 000000000..e50157e6d
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/results.go
@@ -0,0 +1,286 @@
+// 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 mongo
+
+import (
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+)
+
+// ClientBulkWriteResult is the result type returned by a client-level BulkWrite operation.
+type ClientBulkWriteResult struct {
+ // The number of documents inserted.
+ InsertedCount int64
+
+ // The number of documents matched by filters in update and replace operations.
+ MatchedCount int64
+
+ // The number of documents modified by update and replace operations.
+ ModifiedCount int64
+
+ // The number of documents deleted.
+ DeletedCount int64
+
+ // The number of documents upserted by update and replace operations.
+ UpsertedCount int64
+
+ // A map of operation index to the _id of each inserted document.
+ InsertResults map[int]ClientBulkWriteInsertResult
+
+ // A map of operation index to the _id of each updated document.
+ UpdateResults map[int]ClientBulkWriteUpdateResult
+
+ // A map of operation index to the _id of each deleted document.
+ DeleteResults map[int]ClientBulkWriteDeleteResult
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+
+ // HasVerboseResults indicates whether this result contains verbose results.
+ HasVerboseResults bool
+}
+
+// ClientBulkWriteInsertResult is the result type returned by a client-level bulk write of InsertOne operation.
+type ClientBulkWriteInsertResult struct {
+ // The _id of the inserted document. A value generated by the driver will be of type primitive.ObjectID.
+ InsertedID any
+}
+
+// ClientBulkWriteUpdateResult is the result type returned from a client-level bulk write of UpdateOne, UpdateMany, and ReplaceOne operation.
+type ClientBulkWriteUpdateResult struct {
+ MatchedCount int64 // The number of documents matched by the filter.
+ ModifiedCount int64 // The number of documents modified by the operation.
+ UpsertedID any // The _id field of the upserted document, or nil if no upsert was done.
+}
+
+// ClientBulkWriteDeleteResult is the result type returned by a client-level bulk write DeleteOne and DeleteMany operation.
+type ClientBulkWriteDeleteResult struct {
+ DeletedCount int64 // The number of documents deleted.
+}
+
+// BulkWriteResult is the result type returned by a BulkWrite operation.
+type BulkWriteResult struct {
+ // The number of documents inserted.
+ InsertedCount int64
+
+ // The number of documents matched by filters in update and replace operations.
+ MatchedCount int64
+
+ // The number of documents modified by update and replace operations.
+ ModifiedCount int64
+
+ // The number of documents deleted.
+ DeletedCount int64
+
+ // The number of documents upserted by update and replace operations.
+ UpsertedCount int64
+
+ // A map of operation index to the _id of each upserted document.
+ UpsertedIDs map[int64]any
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+}
+
+// InsertOneResult is the result type returned by an InsertOne operation.
+type InsertOneResult struct {
+ // The _id of the inserted document. A value generated by the driver will be of type bson.ObjectID.
+ InsertedID any
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+}
+
+// InsertManyResult is a result type returned by an InsertMany operation.
+type InsertManyResult struct {
+ // The _id values of the inserted documents. Values generated by the driver will be of type bson.ObjectID.
+ InsertedIDs []any
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+}
+
+// TODO(GODRIVER-2367): Remove the BSON struct tags on DeleteResult.
+
+// DeleteResult is the result type returned by DeleteOne and DeleteMany operations.
+type DeleteResult struct {
+ DeletedCount int64 // The number of documents deleted.
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+}
+
+// RewrapManyDataKeyResult is the result of the bulk write operation used to update the key vault collection with
+// rewrapped data keys.
+type RewrapManyDataKeyResult struct {
+ *BulkWriteResult
+}
+
+// ListDatabasesResult is a result of a ListDatabases operation.
+type ListDatabasesResult struct {
+ // A slice containing one DatabaseSpecification for each database matched by the operation's filter.
+ Databases []DatabaseSpecification
+
+ // The total size of the database files of the returned databases in bytes.
+ // This will be the sum of the SizeOnDisk field for each specification in Databases.
+ TotalSize int64
+}
+
+func newListDatabasesResultFromOperation(res operation.ListDatabasesResult) ListDatabasesResult {
+ var ldr ListDatabasesResult
+ ldr.Databases = make([]DatabaseSpecification, 0, len(res.Databases))
+ for _, spec := range res.Databases {
+ ldr.Databases = append(
+ ldr.Databases,
+ DatabaseSpecification{Name: spec.Name, SizeOnDisk: spec.SizeOnDisk, Empty: spec.Empty},
+ )
+ }
+ ldr.TotalSize = res.TotalSize
+ return ldr
+}
+
+// DatabaseSpecification contains information for a database. This type is returned as part of ListDatabasesResult.
+type DatabaseSpecification struct {
+ Name string // The name of the database.
+ SizeOnDisk int64 // The total size of the database files on disk in bytes.
+ Empty bool // Specifies whether or not the database is empty.
+}
+
+// UpdateResult is the result type returned from UpdateOne, UpdateMany, and ReplaceOne operations.
+type UpdateResult struct {
+ MatchedCount int64 // The number of documents matched by the filter.
+ ModifiedCount int64 // The number of documents modified by the operation.
+ UpsertedCount int64 // The number of documents upserted by the operation.
+ UpsertedID any // The _id field of the upserted document, or nil if no upsert was done.
+
+ // Operation performed with an acknowledged write. Values for other fields may
+ // not be deterministic if the write operation was unacknowledged.
+ Acknowledged bool
+}
+
+// IndexSpecification represents an index in a database. This type is returned by the IndexView.ListSpecifications
+// function and is also used in the CollectionSpecification type.
+type IndexSpecification struct {
+ // The index name.
+ Name string
+
+ // The namespace for the index. This is a string in the format "databaseName.collectionName".
+ Namespace string
+
+ // The keys specification document for the index.
+ KeysDocument bson.Raw
+
+ // The index version.
+ Version int32
+
+ // The length of time, in seconds, for documents to remain in the collection. The default value is 0, which means
+ // that documents will remain in the collection until they're explicitly deleted or the collection is dropped.
+ ExpireAfterSeconds *int32
+
+ // If true, the index will only reference documents that contain the fields specified in the index. The default is
+ // false.
+ Sparse *bool
+
+ // If true, the collection will not accept insertion or update of documents where the index key value matches an
+ // existing value in the index. The default is false.
+ Unique *bool
+
+ // The clustered index.
+ Clustered *bool
+}
+
+type indexListSpecificationResponse struct {
+ Name string `bson:"name"`
+ Namespace string `bson:"ns"`
+ KeysDocument bson.Raw `bson:"key"`
+ Version int32 `bson:"v"`
+ ExpireAfterSeconds *int32 `bson:"expireAfterSeconds"`
+ Sparse *bool `bson:"sparse"`
+ Unique *bool `bson:"unique"`
+ Clustered *bool `bson:"clustered"`
+}
+
+// CollectionSpecification represents a collection in a database. This type is returned by the
+// Database.ListCollectionSpecifications function.
+type CollectionSpecification struct {
+ // The collection name.
+ Name string
+
+ // The type of the collection. This will either be "collection" or "view".
+ Type string
+
+ // Whether or not the collection is readOnly.
+ ReadOnly bool
+
+ // The collection UUID as a bson.Binary with subtype 4.
+ UUID *bson.Binary
+
+ // A document containing the options used to construct the collection.
+ Options bson.Raw
+
+ // An IndexSpecification instance with details about the collection's _id index.
+ IDIndex IndexSpecification
+}
+
+// DistinctResult represents an array of BSON data returned from an operation.
+// If the operation resulted in an error, all DistinctResult methods will return
+// that error. If the operation did not return any data, all DistinctResult
+// methods will return ErrNoDocuments.
+type DistinctResult struct {
+ err error
+ arr bson.RawArray
+ reg *bson.Registry
+ bsonOpts *options.BSONOptions
+}
+
+// Decode will unmarshal the array represented by this DistinctResult into v. If
+// there was an error from the operation that created this DistinctReuslt, that
+// error will be returned. If the operation returned no array, Decode will
+// return ErrNoDocuments.
+//
+// If the operation was successful and returned an array, Decode will return any
+// errors from the unmarshalling process without any modification. If v is nil
+// or is a typed nil, an error will be returned.
+func (dr *DistinctResult) Decode(v any) error {
+ doc := bsoncore.NewDocumentBuilder().
+ AppendValue("arr", bsoncore.Value{
+ Type: bsoncore.TypeArray,
+ Data: dr.arr,
+ }).Build()
+
+ dec := getDecoder(doc, dr.bsonOpts, dr.reg)
+
+ return dec.Decode(&struct{ Arr any }{Arr: v})
+}
+
+// Err provides a way to check for query errors without calling Decode. Err
+// returns the error, if any, that was encountered while running the operation.
+// If the operation was successful but did not return any documents, Err returns
+// ErrNoDocuments. If this error is not nil, this error will also be returned
+// from Decode.
+func (dr *DistinctResult) Err() error {
+ return dr.err
+}
+
+// Raw returns the document represented by this DistinctResult as a bson.Raw. If
+// there was an error from the operation that created this DistinctResult, both
+// the result and that error will be returned. If the operation returned no
+// documents, this will return (nil, ErrNoDocuments).
+func (dr *DistinctResult) Raw() (bson.RawArray, error) {
+ if dr.err != nil {
+ return nil, dr.err
+ }
+
+ return dr.arr, nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/search_index_view.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/search_index_view.go
similarity index 73%
rename from vendor/go.mongodb.org/mongo-driver/mongo/search_index_view.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/search_index_view.go
index 3253a73a2..2ac92eb8c 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/search_index_view.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/search_index_view.go
@@ -8,19 +8,27 @@ package mongo
import (
"context"
+ "errors"
"fmt"
"strconv"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
-// SearchIndexView is a type that can be used to create, drop, list and update search indexes on a collection. A SearchIndexView for
-// a collection can be created by a call to Collection.SearchIndexes().
+// SearchIndexView is a type that can be used to create, drop, list and update
+// search indexes on a collection. A SearchIndexView for a collection can be
+// created by a call to Collection.SearchIndexes().
+//
+// Search index commands are asynchronous and return from the server before
+// the index is successfully updated, created or dropped. In order to determine
+// when an index has been created / updated, users are expected to run the
+// listSearchIndexes repeatedly until index changes appear.
type SearchIndexView struct {
coll *Collection
}
@@ -29,10 +37,10 @@ type SearchIndexView struct {
type SearchIndexModel struct {
// A document describing the definition for the search index. It cannot be nil.
// See https://www.mongodb.com/docs/atlas/atlas-search/create-index/ for reference.
- Definition interface{}
+ Definition any
// The search index options.
- Options *options.SearchIndexesOptions
+ Options *options.SearchIndexesOptionsBuilder
}
// List executes a listSearchIndexes command and returns a cursor over the search indexes in the collection.
@@ -43,32 +51,41 @@ type SearchIndexModel struct {
// documentation).
func (siv SearchIndexView) List(
ctx context.Context,
- searchIdxOpts *options.SearchIndexesOptions,
- opts ...*options.ListSearchIndexesOptions,
+ searchIdxOpts options.Lister[options.SearchIndexesOptions],
+ opts ...options.Lister[options.ListSearchIndexesOptions],
) (*Cursor, error) {
if ctx == nil {
ctx = context.Background()
}
+ searchIdxArgs, err := mongoutil.NewOptions[options.SearchIndexesOptions](searchIdxOpts)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
index := bson.D{}
- if searchIdxOpts != nil && searchIdxOpts.Name != nil {
- index = bson.D{{"name", *searchIdxOpts.Name}}
+ if searchIdxArgs != nil && searchIdxArgs.Name != nil {
+ index = bson.D{{"name", *searchIdxArgs.Name}}
}
- aggregateOpts := make([]*options.AggregateOptions, len(opts))
- for i, opt := range opts {
- aggregateOpts[i] = opt.AggregateOpts
+ args, err := mongoutil.NewOptions[options.ListSearchIndexesOptions](opts...)
+ if err != nil {
+ return nil, err
}
- return siv.coll.Aggregate(ctx, Pipeline{{{"$listSearchIndexes", index}}}, aggregateOpts...)
+ aggregateOpts := mongoutil.NewOptionsLister(args.AggregateOptions, nil)
+
+ return siv.coll.Aggregate(ctx, Pipeline{{{"$listSearchIndexes", index}}}, aggregateOpts)
}
// CreateOne executes a createSearchIndexes command to create a search index on the collection and returns the name of the new
// search index. See the SearchIndexView.CreateMany documentation for more information and an example.
+//
+// This is an asynchronous operation.
func (siv SearchIndexView) CreateOne(
ctx context.Context,
model SearchIndexModel,
- opts ...*options.CreateSearchIndexesOptions,
+ opts ...options.Lister[options.CreateSearchIndexesOptions],
) (string, error) {
names, err := siv.CreateMany(ctx, []SearchIndexModel{model}, opts...)
if err != nil {
@@ -85,10 +102,12 @@ func (siv SearchIndexView) CreateOne(
//
// The opts parameter can be used to specify options for this operation (see the options.CreateSearchIndexesOptions
// documentation).
+//
+// This is an asynchronous operation.
func (siv SearchIndexView) CreateMany(
ctx context.Context,
models []SearchIndexModel,
- _ ...*options.CreateSearchIndexesOptions,
+ _ ...options.Lister[options.CreateSearchIndexesOptions],
) ([]string, error) {
var indexes bsoncore.Document
aidx, indexes := bsoncore.AppendArrayStart(indexes)
@@ -105,11 +124,19 @@ func (siv SearchIndexView) CreateMany(
var iidx int32
iidx, indexes = bsoncore.AppendDocumentElementStart(indexes, strconv.Itoa(i))
- if model.Options != nil && model.Options.Name != nil {
- indexes = bsoncore.AppendStringElement(indexes, "name", *model.Options.Name)
- }
- if model.Options != nil && model.Options.Type != nil {
- indexes = bsoncore.AppendStringElement(indexes, "type", *model.Options.Type)
+ if model.Options != nil {
+ searchIndexArgs, err := mongoutil.NewOptions[options.SearchIndexesOptions](model.Options)
+ if err != nil {
+ return nil, fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ if searchIndexArgs.Name != nil {
+ indexes = bsoncore.AppendStringElement(indexes, "name", *searchIndexArgs.Name)
+ }
+
+ if searchIndexArgs.Type != nil {
+ indexes = bsoncore.AppendStringElement(indexes, "type", *searchIndexArgs.Type)
+ }
}
indexes = bsoncore.AppendDocumentElement(indexes, "definition", definition)
@@ -167,10 +194,12 @@ func (siv SearchIndexView) CreateMany(
//
// The opts parameter can be used to specify options for this operation (see the options.DropSearchIndexOptions
// documentation).
+//
+// This is an asynchronous operation.
func (siv SearchIndexView) DropOne(
ctx context.Context,
name string,
- _ ...*options.DropSearchIndexOptions,
+ _ ...options.Lister[options.DropSearchIndexOptions],
) error {
if name == "*" {
return ErrMultipleIndexDrop
@@ -201,7 +230,8 @@ func (siv SearchIndexView) DropOne(
Timeout(siv.coll.client.timeout).Authenticator(siv.coll.client.authenticator)
err = op.Execute(ctx)
- if de, ok := err.(driver.Error); ok && de.NamespaceNotFound() {
+ var de driver.Error
+ if errors.As(err, &de) && de.NamespaceNotFound() {
return nil
}
return err
@@ -215,11 +245,13 @@ func (siv SearchIndexView) DropOne(
//
// The opts parameter can be used to specify options for this operation (see the options.UpdateSearchIndexOptions
// documentation).
+//
+// This is an asynchronous operation.
func (siv SearchIndexView) UpdateOne(
ctx context.Context,
name string,
- definition interface{},
- _ ...*options.UpdateSearchIndexOptions,
+ definition any,
+ _ ...options.Lister[options.UpdateSearchIndexOptions],
) error {
if definition == nil {
return fmt.Errorf("search index definition cannot be nil")
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/session.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/session.go
new file mode 100644
index 000000000..63089dee5
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/session.go
@@ -0,0 +1,386 @@
+// 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 mongo
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/mongoutil"
+ "go.mongodb.org/mongo-driver/v2/internal/randutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
+)
+
+// ErrWrongClient is returned when a user attempts to pass in a session created by a different client than
+// the method call is using.
+var ErrWrongClient = errors.New("session was not created by this client")
+
+var (
+ withTransactionTimeout = 120 * time.Second
+ backoffInitial = 5 * time.Millisecond
+ backoffMax = 500 * time.Millisecond
+)
+
+// Session is a MongoDB logical session. Sessions can be used to enable causal
+// consistency for a group of operations or to execute operations in an ACID
+// transaction. A new Session can be created from a Client instance. A Session
+// created from a Client must only be used to execute operations using that
+// Client or a Database or Collection created from that Client. For more
+// information about sessions, and their use cases, see
+// https://www.mongodb.com/docs/manual/reference/server-sessions/,
+// https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#causal-consistency, and
+// https://www.mongodb.com/docs/manual/core/transactions/.
+//
+// Implementations of Session are not safe for concurrent use by multiple
+// goroutines.
+type Session struct {
+ clientSession *session.Client
+ client *Client
+ deployment driver.Deployment
+ didCommitAfterStart bool // true if commit was called after start with no other operations
+}
+
+type sessionKey struct{}
+
+// NewSessionContext returns a Context that holds the given Session. If the
+// Context already contains a Session, that Session will be replaced with the
+// one provided.
+//
+// The returned Context can be used with Collection methods like
+// [Collection.InsertOne] or [Collection.Find] to run operations in a Session.
+func NewSessionContext(parent context.Context, sess *Session) context.Context {
+ return context.WithValue(parent, sessionKey{}, sess)
+}
+
+// SessionFromContext extracts the mongo.Session object stored in a Context. This can be used on a SessionContext that
+// was created implicitly through one of the callback-based session APIs or explicitly by calling NewSessionContext. If
+// there is no Session stored in the provided Context, nil is returned.
+func SessionFromContext(ctx context.Context) *Session {
+ val := ctx.Value(sessionKey{})
+ if val == nil {
+ return nil
+ }
+
+ sess, ok := val.(*Session)
+ if !ok {
+ return nil
+ }
+
+ return sess
+}
+
+// ID returns the current ID document associated with the session. The ID
+// document is in the form {"id": }.
+func (s *Session) ID() bson.Raw {
+ return bson.Raw(s.clientSession.SessionID)
+}
+
+// EndSession aborts any existing transactions and close the session.
+func (s *Session) EndSession(ctx context.Context) {
+ if s.clientSession.TransactionInProgress() {
+ // ignore all errors aborting during an end session
+ _ = s.AbortTransaction(ctx)
+ }
+ s.clientSession.EndSession()
+}
+
+// WithTransaction starts a transaction on this session and runs the fn
+// callback. Errors with the TransientTransactionError and
+// UnknownTransactionCommitResult labels are retried for up to 120 seconds.
+// Inside the callback, the SessionContext must be used as the Context parameter
+// for any operations that should be part of the transaction. If the ctx
+// parameter already has a Session attached to it, it will be replaced by this
+// session. The fn callback may be run multiple times during WithTransaction due
+// to retry attempts, so it must be idempotent.
+//
+// If a command inside the callback fn fails, it may cause the transaction on
+// the server to be aborted. This situation is normally handled transparently by
+// the driver. However, if the application does not return that error from the
+// fn, the driver will not be able to determine whether the transaction was
+// aborted or not. The driver will then retry the block indefinitely.
+//
+// To avoid this situation, the application MUST NOT silently handle errors
+// within the callback fn. If the application needs to handle errors within the
+// block, it MUST return them after doing so.
+//
+// Non-retryable operation errors or any operation errors that occur after the
+// timeout expires will be returned without retrying. If the callback fails, the
+// driver will call AbortTransaction. Because this method must succeed to ensure
+// that server-side resources are properly cleaned up, context deadlines and
+// cancellations will not be respected during this call. For a usage example,
+// see the Client.StartSession method documentation.
+func (s *Session) WithTransaction(
+ ctx context.Context,
+ fn func(ctx context.Context) (any, error),
+ opts ...options.Lister[options.TransactionOptions],
+) (any, error) {
+ transTimeout := withTransactionTimeout
+ if s.client.timeout != nil {
+ transTimeout = *s.client.timeout
+ }
+ startTime := time.Now()
+ timeout := time.NewTimer(transTimeout)
+ defer timeout.Stop()
+ var expDur time.Duration
+ var err error
+ for {
+ if expDur == 0 {
+ expDur = backoffInitial
+ } else {
+ if expDur > backoffMax {
+ expDur = backoffMax
+ }
+ backoff := expDur * time.Duration(randutil.JitterInt63n(512)) / 512
+ if time.Since(startTime)+backoff > transTimeout {
+ return nil, timeoutError{Wrapped: err}
+ }
+ sleep := time.NewTimer(backoff)
+ select {
+ case <-timeout.C:
+ sleep.Stop()
+ return nil, timeoutError{Wrapped: err}
+ case <-sleep.C:
+ }
+ if expDur < backoffMax {
+ expDur += expDur / 2
+ }
+ }
+
+ err = s.StartTransaction(opts...)
+ if err != nil {
+ return nil, err
+ }
+
+ var res any
+ res, err = fn(NewSessionContext(ctx, s))
+ if err != nil {
+ if s.clientSession.TransactionRunning() {
+ // Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and
+ // cancellations, but forwards Value requests to the original one.
+ _ = s.AbortTransaction(newBackgroundContext(ctx))
+ }
+
+ select {
+ case <-timeout.C:
+ return nil, timeoutError{Wrapped: err}
+ default:
+ }
+
+ if errorHasLabel(err, driver.TransientTransactionError) {
+ continue
+ }
+ return res, err
+ }
+
+ // Check if callback intentionally aborted and, if so, return immediately
+ // with no error.
+ err = s.clientSession.CheckAbortTransaction()
+ if err != nil {
+ return res, nil
+ }
+
+ // If context has errored, run AbortTransaction and return, as the CommitLoop
+ // has no chance of succeeding.
+ //
+ // Aborting after a failed CommitTransaction is dangerous. Failed transaction
+ // commits may unpin the session server-side, and subsequent transaction aborts
+ // may run on a new mongos which could end up with commit and abort being executed
+ // simultaneously.
+ if ctx.Err() != nil {
+ // Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and
+ // cancellations, but forwards Value requests to the original one.
+ _ = s.AbortTransaction(newBackgroundContext(ctx))
+ return nil, ctx.Err()
+ }
+
+ CommitLoop:
+ for {
+ err = s.CommitTransaction(newBackgroundContext(ctx))
+ // End when error is nil, as transaction has been committed.
+ if err == nil {
+ return res, nil
+ }
+
+ var cerr CommandError
+ if errors.As(err, &cerr) {
+ if cerr.HasErrorLabel(driver.UnknownTransactionCommitResult) && !cerr.IsMaxTimeMSExpiredError() {
+ select {
+ case <-timeout.C:
+ return res, timeoutError{Wrapped: err}
+ default:
+ }
+ continue
+ }
+ if cerr.HasErrorLabel(driver.TransientTransactionError) {
+ break CommitLoop
+ }
+ }
+ return res, err
+ }
+ }
+}
+
+// StartTransaction starts a new transaction. This method returns an error if
+// there is already a transaction in-progress for this session.
+func (s *Session) StartTransaction(opts ...options.Lister[options.TransactionOptions]) error {
+ err := s.clientSession.CheckStartTransaction()
+ if err != nil {
+ return err
+ }
+
+ s.didCommitAfterStart = false
+
+ args, err := mongoutil.NewOptions[options.TransactionOptions](opts...)
+ if err != nil {
+ return fmt.Errorf("failed to construct options from builder: %w", err)
+ }
+
+ coreOpts := &session.TransactionOptions{
+ ReadConcern: args.ReadConcern,
+ ReadPreference: args.ReadPreference,
+ WriteConcern: args.WriteConcern,
+ }
+
+ return s.clientSession.StartTransaction(coreOpts)
+}
+
+// AbortTransaction aborts the active transaction for this session. This method
+// returns an error if there is no active transaction for this session or if the
+// transaction has been committed or aborted.
+func (s *Session) AbortTransaction(ctx context.Context) error {
+ err := s.clientSession.CheckAbortTransaction()
+ if err != nil {
+ return err
+ }
+
+ // Do not run the abort command if the transaction is in starting state
+ if s.clientSession.TransactionStarting() || s.didCommitAfterStart {
+ return s.clientSession.AbortTransaction()
+ }
+
+ selector := makePinnedSelector(s.clientSession, &serverselector.Write{})
+
+ s.clientSession.Aborting = true
+ _ = operation.NewAbortTransaction().Session(s.clientSession).ClusterClock(s.client.clock).Database("admin").
+ Deployment(s.deployment).WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector).
+ Retry(driver.RetryOncePerCommand).MaxAdaptiveRetries(s.client.effectiveAdaptiveRetries(true)).
+ EnableOverloadRetargeting(s.client.enableOverloadRetargeting).
+ CommandMonitor(s.client.monitor).
+ RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)).ServerAPI(s.client.serverAPI).
+ Authenticator(s.client.authenticator).Logger(s.client.logger).Execute(ctx)
+
+ s.clientSession.Aborting = false
+ _ = s.clientSession.AbortTransaction()
+
+ return nil
+}
+
+// CommitTransaction commits the active transaction for this session. This
+// method returns an error if there is no active transaction for this session or
+// if the transaction has been aborted.
+func (s *Session) CommitTransaction(ctx context.Context) error {
+ err := s.clientSession.CheckCommitTransaction()
+ if err != nil {
+ return err
+ }
+
+ // Do not run the commit command if the transaction is in started state
+ if s.clientSession.TransactionStarting() || s.didCommitAfterStart {
+ s.didCommitAfterStart = true
+ return s.clientSession.CommitTransaction()
+ }
+
+ if s.clientSession.TransactionCommitted() {
+ s.clientSession.RetryingCommit = true
+ }
+
+ selector := makePinnedSelector(s.clientSession, &serverselector.Write{})
+
+ s.clientSession.Committing = true
+ op := operation.NewCommitTransaction().
+ Session(s.clientSession).ClusterClock(s.client.clock).Database("admin").Deployment(s.deployment).
+ WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector).Retry(driver.RetryOncePerCommand).
+ MaxAdaptiveRetries(s.client.effectiveAdaptiveRetries(true)).
+ EnableOverloadRetargeting(s.client.enableOverloadRetargeting).
+ CommandMonitor(s.client.monitor).RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)).
+ ServerAPI(s.client.serverAPI).Authenticator(s.client.authenticator).Logger(s.client.logger)
+
+ err = op.Execute(ctx)
+ // Return error without updating transaction state if it is a timeout, as the transaction has not
+ // actually been committed.
+ if IsTimeout(err) {
+ return wrapErrors(err)
+ }
+ s.clientSession.Committing = false
+ commitErr := s.clientSession.CommitTransaction()
+
+ // We set the write concern to majority for subsequent calls to CommitTransaction.
+ s.clientSession.UpdateCommitTransactionWriteConcern()
+
+ if err != nil {
+ return wrapErrors(err)
+ }
+ return commitErr
+}
+
+// ClusterTime returns the current cluster time document associated with the
+// session.
+func (s *Session) ClusterTime() bson.Raw {
+ return s.clientSession.ClusterTime
+}
+
+// SnapshotTime returns the current snapshot time associated with the session.
+func (s *Session) SnapshotTime() bson.Timestamp {
+ return s.clientSession.SnapshotTime
+}
+
+// AdvanceClusterTime advances the cluster time for a session. This method
+// returns an error if the session has ended.
+func (s *Session) AdvanceClusterTime(d bson.Raw) error {
+ return s.clientSession.AdvanceClusterTime(d)
+}
+
+// OperationTime returns the current operation time document associated with the
+// session.
+func (s *Session) OperationTime() *bson.Timestamp {
+ return s.clientSession.OperationTime
+}
+
+// AdvanceOperationTime advances the operation time for a session. This method
+// returns an error if the session has ended.
+func (s *Session) AdvanceOperationTime(ts *bson.Timestamp) error {
+ return s.clientSession.AdvanceOperationTime(ts)
+}
+
+// Client is the Client associated with the session.
+func (s *Session) Client() *Client {
+ return s.client
+}
+
+// TransactionRunning returns true if the session has started a transaction and
+// it hasn't been committed or aborted.
+func (s *Session) TransactionRunning() bool {
+ return s.clientSession != nil && s.clientSession.TransactionRunning()
+}
+
+// sessionFromContext checks for a sessionImpl in the argued context and returns the session if it
+// exists
+func sessionFromContext(ctx context.Context) *session.Client {
+ if ses := SessionFromContext(ctx); ses != nil {
+ return ses.clientSession
+ }
+
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/single_result.go
similarity index 76%
rename from vendor/go.mongodb.org/mongo-driver/mongo/single_result.go
rename to vendor/go.mongodb.org/mongo-driver/v2/mongo/single_result.go
index f6ed4dc88..5cae29846 100644
--- a/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/single_result.go
@@ -9,11 +9,9 @@ package mongo
import (
"context"
"errors"
- "fmt"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
)
// ErrNoDocuments is returned by SingleResult methods when the operation that created the SingleResult did not return
@@ -29,23 +27,32 @@ type SingleResult struct {
cur *Cursor
rdr bson.Raw
bsonOpts *options.BSONOptions
- reg *bsoncodec.Registry
+ reg *bson.Registry
+
+ // Operation performed with an acknowledged write. Values returned by
+ // SingleResult methods may not be deterministic if the write operation was
+ // unacknowledged and so should not be relied upon.
+ Acknowledged bool
}
// NewSingleResultFromDocument creates a SingleResult with the provided error, registry, and an underlying Cursor pre-loaded with
-// the provided document, error and registry. If no registry is provided, bson.DefaultRegistry will be used. If an error distinct
+// the provided document, error and registry. If no registry is provided, bson.NewRegistry() will be used. If an error distinct
// from the one provided occurs during creation of the SingleResult, that error will be stored on the returned SingleResult.
//
// The document parameter must be a non-nil document.
-func NewSingleResultFromDocument(document interface{}, err error, registry *bsoncodec.Registry) *SingleResult {
+func NewSingleResultFromDocument(
+ document any,
+ err error,
+ registry *bson.Registry,
+) *SingleResult {
if document == nil {
return &SingleResult{err: ErrNilDocument}
}
if registry == nil {
- registry = bson.DefaultRegistry
+ registry = defaultRegistry
}
- cur, createErr := NewCursorFromDocuments([]interface{}{document}, err, registry)
+ cur, createErr := NewCursorFromDocuments([]any{document}, err, registry)
if createErr != nil {
return &SingleResult{err: createErr}
}
@@ -63,7 +70,7 @@ func NewSingleResultFromDocument(document interface{}, err error, registry *bson
//
// If the operation was successful and returned a document, Decode will return any errors from the unmarshalling process
// without any modification. If v is nil or is a typed nil, an error will be returned.
-func (sr *SingleResult) Decode(v interface{}) error {
+func (sr *SingleResult) Decode(v any) error {
if sr.err != nil {
return sr.err
}
@@ -75,10 +82,7 @@ func (sr *SingleResult) Decode(v interface{}) error {
return sr.err
}
- dec, err := getDecoder(sr.rdr, sr.bsonOpts, sr.reg)
- if err != nil {
- return fmt.Errorf("error configuring BSON decoder: %w", err)
- }
+ dec := getDecoder(sr.rdr, sr.bsonOpts, sr.reg)
return dec.Decode(v)
}
@@ -95,16 +99,8 @@ func (sr *SingleResult) Raw() (bson.Raw, error) {
if sr.err = sr.setRdrContents(); sr.err != nil {
return nil, sr.err
}
- return sr.rdr, nil
-}
-// DecodeBytes will return the document represented by this SingleResult as a bson.Raw. If there was an error from the
-// operation that created this SingleResult, both the result and that error will be returned. If the operation returned
-// no documents, this will return (nil, ErrNoDocuments).
-//
-// Deprecated: Use [SingleResult.Raw] instead.
-func (sr *SingleResult) DecodeBytes() (bson.Raw, error) {
- return sr.Raw()
+ return sr.rdr, nil
}
// setRdrContents will set the contents of rdr by iterating the underlying cursor if necessary.
@@ -124,7 +120,9 @@ func (sr *SingleResult) setRdrContents() error {
return ErrNoDocuments
}
+
sr.rdr = sr.cur.Current
+
return nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/mongo/writeconcern/writeconcern.go b/vendor/go.mongodb.org/mongo-driver/v2/mongo/writeconcern/writeconcern.go
new file mode 100644
index 000000000..208f230ef
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/mongo/writeconcern/writeconcern.go
@@ -0,0 +1,132 @@
+// 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 writeconcern defines write concerns for MongoDB operations.
+//
+// For more information about MongoDB write concerns, see
+// https://www.mongodb.com/docs/manual/reference/write-concern/
+package writeconcern
+
+// WCMajority can be used to create a WriteConcern with a W value of "majority".
+const WCMajority = "majority"
+
+// A WriteConcern defines a MongoDB write concern, which describes the level of acknowledgment
+// requested from MongoDB for write operations to a standalone mongod, to replica sets, or to
+// sharded clusters.
+//
+// For more information about MongoDB write concerns, see
+// https://www.mongodb.com/docs/manual/reference/write-concern/
+type WriteConcern struct {
+ // W requests acknowledgment that the write operation has propagated to a
+ // specified number of mongod instances or to mongod instances with
+ // specified tags. It sets the "w" option in a MongoDB write concern.
+ //
+ // W values must be a string or an int.
+ //
+ // Common values are:
+ // - "majority": requests acknowledgment that write operations have been
+ // durably committed to the calculated majority of the data-bearing
+ // voting members.
+ // - 1: requests acknowledgment that write operations have been written
+ // to 1 node.
+ // - 0: requests no acknowledgment of write operations
+ //
+ // For more information about the "w" option, see
+ // https://www.mongodb.com/docs/manual/reference/write-concern/#w-option
+ W any
+
+ // Journal requests acknowledgment from MongoDB that the write operation has
+ // been written to the on-disk journal. It sets the "j" option in a MongoDB
+ // write concern.
+ //
+ // For more information about the "j" option, see
+ // https://www.mongodb.com/docs/manual/reference/write-concern/#j-option
+ Journal *bool
+}
+
+// Unacknowledged returns a WriteConcern that requests no acknowledgment of
+// write operations.
+//
+// For more information about write concern "w: 0", see
+// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-number-
+func Unacknowledged() *WriteConcern {
+ return &WriteConcern{W: 0}
+}
+
+// W1 returns a WriteConcern that requests acknowledgment that write operations
+// have been written to memory on one node (e.g. the standalone mongod or the
+// primary in a replica set).
+//
+// For more information about write concern "w: 1", see
+// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-number-
+func W1() *WriteConcern {
+ return &WriteConcern{W: 1}
+}
+
+// Journaled returns a WriteConcern that requests acknowledgment that write
+// operations have been written to the on-disk journal on MongoDB.
+//
+// The database's default value for "w" determines how many nodes must write to
+// their on-disk journal before the write operation is acknowledged.
+//
+// For more information about write concern "j: true", see
+// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-ournal
+func Journaled() *WriteConcern {
+ journal := true
+ return &WriteConcern{Journal: &journal}
+}
+
+// Majority returns a WriteConcern that requests acknowledgment that write
+// operations have been durably committed to the calculated majority of the
+// data-bearing voting members.
+//
+// Write concern "w: majority" typically requires write operations to be written
+// to the on-disk journal before they are acknowledged, unless journaling is
+// disabled on MongoDB or the "writeConcernMajorityJournalDefault" replica set
+// configuration is set to false.
+//
+// For more information about write concern "w: majority", see
+// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-majority-
+func Majority() *WriteConcern {
+ return &WriteConcern{W: WCMajority}
+}
+
+// Custom returns a WriteConcern that requests acknowledgment that write
+// operations have propagated to tagged members that satisfy the custom write
+// concern defined in "settings.getLastErrorModes".
+//
+// For more information about custom write concern names, see
+// https://www.mongodb.com/docs/manual/reference/write-concern/#mongodb-writeconcern-writeconcern.-custom-write-concern-name-
+func Custom(tag string) *WriteConcern {
+ return &WriteConcern{W: tag}
+}
+
+// Acknowledged indicates whether or not a write with the given write concern will be acknowledged.
+func (wc *WriteConcern) Acknowledged() bool {
+ // Only {w: 0} or {w: 0, j: false} are an unacknowledged write concerns. All other values are
+ // acknowledged.
+ return wc == nil || wc.W != 0 || (wc.Journal != nil && *wc.Journal)
+}
+
+// IsValid returns true if the WriteConcern is valid.
+func (wc *WriteConcern) IsValid() bool {
+ if wc == nil {
+ return true
+ }
+
+ switch w := wc.W.(type) {
+ case int:
+ // A write concern with {w: int} must have a non-negative value and
+ // cannot have the combination {w: 0, j: true}.
+ return w >= 0 && (w > 0 || wc.Journal == nil || !*wc.Journal)
+ case string, nil:
+ // A write concern with {w: string} or no w specified is always valid.
+ return true
+ default:
+ // A write concern with an unsupported w type is not valid.
+ return false
+ }
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/tag/tag.go b/vendor/go.mongodb.org/mongo-driver/v2/tag/tag.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/tag/tag.go
rename to vendor/go.mongodb.org/mongo-driver/v2/tag/tag.go
index 4faff5254..170cb383f 100644
--- a/vendor/go.mongodb.org/mongo-driver/tag/tag.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/tag/tag.go
@@ -8,7 +8,7 @@
//
// For more information about read preference tags, see
// https://www.mongodb.com/docs/manual/core/read-preference-tags/
-package tag // import "go.mongodb.org/mongo-driver/tag"
+package tag
import (
"bytes"
@@ -31,7 +31,7 @@ func (tag Tag) String() string {
// For more information about read preference tags, see
// https://www.mongodb.com/docs/manual/core/read-preference-tags/
func NewTagSetFromMap(m map[string]string) Set {
- var set Set
+ set := make(Set, 0, len(m))
for k, v := range m {
set = append(set, Tag{Name: k, Value: v})
}
diff --git a/vendor/go.mongodb.org/mongo-driver/version/version.go b/vendor/go.mongodb.org/mongo-driver/v2/version/version.go
similarity index 95%
rename from vendor/go.mongodb.org/mongo-driver/version/version.go
rename to vendor/go.mongodb.org/mongo-driver/v2/version/version.go
index a727d0fb0..06e95553a 100644
--- a/vendor/go.mongodb.org/mongo-driver/version/version.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/version/version.go
@@ -11,4 +11,4 @@
package version
// Driver is the current version of the driver.
-var Driver = "1.17.9"
+var Driver = "2.6.0"
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/array.go
similarity index 70%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/array.go
index 6bc0afa70..bfedbc866 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/array.go
@@ -82,35 +82,79 @@ func (a Array) DebugString() string {
// String outputs an ExtendedJSON version of Array. If the Array is not valid, this method
// returns an empty string.
func (a Array) String() string {
- if len(a) < 5 {
- return ""
+ str, _ := a.StringN(-1)
+ return str
+}
+
+// StringN stringifies an array. If N is non-negative, it will truncate the string to N bytes.
+// Otherwise, it will return the full string representation. The second return value indicates
+// whether the string was truncated or not.
+func (a Array) StringN(n int) (string, bool) {
+ length, rem, ok := ReadLength(a)
+ if !ok || length < 5 {
+ return "", false
+ }
+ length -= 4 // length bytes
+ length-- // final null byte
+
+ if n == 0 {
+ return "", true
}
+
var buf strings.Builder
buf.WriteByte('[')
- length, rem, _ := ReadLength(a) // We know we have enough bytes to read the length
+ var truncated bool
+ var elem Element
+ var str string
+ first := true
+ for length > 0 && !truncated {
+ needStrLen := -1
+ // Set needStrLen if n is positive, meaning we want to limit the string length.
+ if n > 0 {
+ // Stop stringifying if we reach the limit, that also ensures needStrLen is
+ // greater than 0 if we need to limit the length.
+ if buf.Len() >= n {
+ truncated = true
+ break
+ }
+ needStrLen = n - buf.Len()
+ }
- length -= 4
+ // Append a comma if this is not the first element.
+ if !first {
+ buf.WriteByte(',')
+ // If we are truncating, we need to account for the comma in the length.
+ if needStrLen > 0 {
+ needStrLen--
+ if needStrLen == 0 {
+ truncated = true
+ break
+ }
+ }
+ }
- var elem Element
- var ok bool
- for length > 1 {
elem, rem, ok = ReadElement(rem)
length -= int32(len(elem))
- if !ok {
- return ""
- }
- buf.WriteString(elem.Value().String())
- if length > 1 {
- buf.WriteByte(',')
+ // Exit on malformed element.
+ if !ok || length < 0 {
+ return "", false
}
+
+ // Delegate to StringN() on the element.
+ str, truncated = elem.Value().StringN(needStrLen)
+ buf.WriteString(str)
+
+ first = false
}
- if length != 1 { // Missing final null byte or inaccurate length
- return ""
+
+ if n <= 0 || (buf.Len() < n && !truncated) {
+ buf.WriteByte(']')
+ } else {
+ truncated = true
}
- buf.WriteByte(']')
- return buf.String()
+ return buf.String(), truncated
}
// Values returns this array as a slice of values. The returned slice will contain valid values.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_arraybuilder.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_arraybuilder.go
similarity index 92%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_arraybuilder.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_arraybuilder.go
index 7e6937d89..8856c1133 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_arraybuilder.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_arraybuilder.go
@@ -8,9 +8,6 @@ package bsoncore
import (
"strconv"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
)
// ArrayBuilder builds a bson array
@@ -84,7 +81,7 @@ func (a *ArrayBuilder) AppendString(str string) *ArrayBuilder {
}
// AppendObjectID will append oid to ArrayBuilder.doc
-func (a *ArrayBuilder) AppendObjectID(oid primitive.ObjectID) *ArrayBuilder {
+func (a *ArrayBuilder) AppendObjectID(oid objectID) *ArrayBuilder {
a.arr = AppendObjectIDElement(a.arr, a.incrementKey(), oid)
return a
}
@@ -127,7 +124,7 @@ func (a *ArrayBuilder) AppendRegex(pattern, options string) *ArrayBuilder {
}
// AppendDBPointer will append ns and oid to a.arr
-func (a *ArrayBuilder) AppendDBPointer(ns string, oid primitive.ObjectID) *ArrayBuilder {
+func (a *ArrayBuilder) AppendDBPointer(ns string, oid objectID) *ArrayBuilder {
a.arr = AppendDBPointerElement(a.arr, a.incrementKey(), ns, oid)
return a
}
@@ -163,8 +160,8 @@ func (a *ArrayBuilder) AppendInt64(i64 int64) *ArrayBuilder {
}
// AppendDecimal128 will append d128 to a.arr
-func (a *ArrayBuilder) AppendDecimal128(d128 primitive.Decimal128) *ArrayBuilder {
- a.arr = AppendDecimal128Element(a.arr, a.incrementKey(), d128)
+func (a *ArrayBuilder) AppendDecimal128(high, low uint64) *ArrayBuilder {
+ a.arr = AppendDecimal128Element(a.arr, a.incrementKey(), high, low)
return a
}
@@ -189,7 +186,7 @@ func (a *ArrayBuilder) AppendValue(val Value) *ArrayBuilder {
// StartArray starts building an inline Array. After this document is completed,
// the user must call a.FinishArray
func (a *ArrayBuilder) StartArray() *ArrayBuilder {
- a.arr = AppendHeader(a.arr, bsontype.Array, a.incrementKey())
+ a.arr = AppendHeader(a.arr, TypeArray, a.incrementKey())
a.startArray()
return a
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_documentbuilder.go
similarity index 92%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_documentbuilder.go
index 52162f8aa..931fc6bff 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_documentbuilder.go
@@ -6,11 +6,6 @@
package bsoncore
-import (
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
-
// DocumentBuilder builds a bson document
type DocumentBuilder struct {
doc []byte
@@ -54,7 +49,7 @@ func (db *DocumentBuilder) AppendDocument(key string, doc []byte) *DocumentBuild
// AppendArray will append a bson array using key and arr to DocumentBuilder.doc
func (db *DocumentBuilder) AppendArray(key string, arr []byte) *DocumentBuilder {
- db.doc = AppendHeader(db.doc, bsontype.Array, key)
+ db.doc = AppendHeader(db.doc, TypeArray, key)
db.doc = AppendArray(db.doc, arr)
return db
}
@@ -72,7 +67,7 @@ func (db *DocumentBuilder) AppendString(key string, str string) *DocumentBuilder
}
// AppendObjectID will append oid to DocumentBuilder.doc with the given key
-func (db *DocumentBuilder) AppendObjectID(key string, oid primitive.ObjectID) *DocumentBuilder {
+func (db *DocumentBuilder) AppendObjectID(key string, oid objectID) *DocumentBuilder {
db.doc = AppendObjectIDElement(db.doc, key, oid)
return db
}
@@ -115,7 +110,7 @@ func (db *DocumentBuilder) AppendRegex(key, pattern, options string) *DocumentBu
}
// AppendDBPointer will append ns and oid to using key to db.doc
-func (db *DocumentBuilder) AppendDBPointer(key string, ns string, oid primitive.ObjectID) *DocumentBuilder {
+func (db *DocumentBuilder) AppendDBPointer(key string, ns string, oid objectID) *DocumentBuilder {
db.doc = AppendDBPointerElement(db.doc, key, ns, oid)
return db
}
@@ -151,8 +146,8 @@ func (db *DocumentBuilder) AppendInt64(key string, i64 int64) *DocumentBuilder {
}
// AppendDecimal128 will append d128 to db.doc using provided key
-func (db *DocumentBuilder) AppendDecimal128(key string, d128 primitive.Decimal128) *DocumentBuilder {
- db.doc = AppendDecimal128Element(db.doc, key, d128)
+func (db *DocumentBuilder) AppendDecimal128(key string, high, low uint64) *DocumentBuilder {
+ db.doc = AppendDecimal128Element(db.doc, key, high, low)
return db
}
@@ -177,7 +172,7 @@ func (db *DocumentBuilder) AppendValue(key string, val Value) *DocumentBuilder {
// StartDocument starts building an inline document element with the provided key
// After this document is completed, the user must call finishDocument
func (db *DocumentBuilder) StartDocument(key string) *DocumentBuilder {
- db.doc = AppendHeader(db.doc, bsontype.EmbeddedDocument, key)
+ db.doc = AppendHeader(db.doc, TypeEmbeddedDocument, key)
db = db.startDocument()
return db
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bsoncore.go
similarity index 73%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bsoncore.go
index 03925d7ad..52b001cbf 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bsoncore.go
@@ -4,7 +4,7 @@
// 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 bsoncore // import "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+package bsoncore
import (
"bytes"
@@ -15,8 +15,7 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/v2/internal/binaryutil"
)
const (
@@ -28,15 +27,17 @@ const (
invalidRegexPanicMsg = "BSON regex values cannot contain null bytes"
)
+type objectID = [12]byte
+
// AppendType will append t to dst and return the extended buffer.
-func AppendType(dst []byte, t bsontype.Type) []byte { return append(dst, byte(t)) }
+func AppendType(dst []byte, t Type) []byte { return append(dst, byte(t)) }
// AppendKey will append key to dst and return the extended buffer.
func AppendKey(dst []byte, key string) []byte { return append(dst, key+nullTerminator...) }
// AppendHeader will append Type t and key to dst and return the extended
// buffer.
-func AppendHeader(dst []byte, t bsontype.Type, key string) []byte {
+func AppendHeader(dst []byte, t Type, key string) []byte {
if !isValidCString(key) {
panic(invalidKeyPanicMsg)
}
@@ -51,26 +52,26 @@ func AppendHeader(dst []byte, t bsontype.Type, key string) []byte {
// ReadType will return the first byte of the provided []byte as a type. If
// there is no available byte, false is returned.
-func ReadType(src []byte) (bsontype.Type, []byte, bool) {
+func ReadType(src []byte) (Type, []byte, bool) {
if len(src) < 1 {
return 0, src, false
}
- return bsontype.Type(src[0]), src[1:], true
+ return Type(src[0]), src[1:], true
}
// ReadKey will read a key from src. The 0x00 byte will not be present
// in the returned string. If there are not enough bytes available, false is
// returned.
-func ReadKey(src []byte) (string, []byte, bool) { return readcstring(src) }
+func ReadKey(src []byte) (string, []byte, bool) { return binaryutil.ReadCString(src) }
// ReadKeyBytes will read a key from src as bytes. The 0x00 byte will
// not be present in the returned string. If there are not enough bytes
// available, false is returned.
-func ReadKeyBytes(src []byte) ([]byte, []byte, bool) { return readcstringbytes(src) }
+func ReadKeyBytes(src []byte) ([]byte, []byte, bool) { return binaryutil.ReadCStringBytes(src) }
// ReadHeader will read a type byte and a key from src. If both of these
// values cannot be read, false is returned.
-func ReadHeader(src []byte) (t bsontype.Type, key string, rem []byte, ok bool) {
+func ReadHeader(src []byte) (t Type, key string, rem []byte, ok bool) {
t, rem, ok = ReadType(src)
if !ok {
return 0, "", src, false
@@ -102,22 +103,23 @@ func ReadElement(src []byte) (Element, []byte, bool) {
if len(src) < 1 {
return nil, src, false
}
- t := bsontype.Type(src[0])
- idx := bytes.IndexByte(src[1:], 0x00)
- if idx == -1 {
+ t := Type(src[0])
+ idx := 1
+ for idx < len(src) && src[idx] != 0x00 {
+ idx++
+ }
+ if idx >= len(src) {
return nil, src, false
}
- length, ok := valueLength(src[idx+2:], t) // We add 2 here because we called IndexByte with src[1:]
+ idx++ // Move past the null byte
+ length, ok := valueLength(src[idx:], t)
if !ok {
return nil, src, false
}
- elemLength := 1 + idx + 1 + int(length)
+ elemLength := idx + int(length)
if elemLength > len(src) {
return nil, src, false
}
- if elemLength < 0 {
- return nil, src, false
- }
return src[:elemLength], src[elemLength:], true
}
@@ -130,7 +132,7 @@ func AppendValueElement(dst []byte, key string, value Value) []byte {
// ReadValue reads the next value as the provided types and returns a Value, the remaining bytes,
// and a boolean indicating if the read was successful.
-func ReadValue(src []byte, t bsontype.Type) (Value, []byte, bool) {
+func ReadValue(src []byte, t Type) (Value, []byte, bool) {
data, rem, ok := readValue(src, t)
if !ok {
return Value{}, src, false
@@ -140,19 +142,19 @@ func ReadValue(src []byte, t bsontype.Type) (Value, []byte, bool) {
// AppendDouble will append f to dst and return the extended buffer.
func AppendDouble(dst []byte, f float64) []byte {
- return appendu64(dst, math.Float64bits(f))
+ return binaryutil.Append64(dst, math.Float64bits(f))
}
// AppendDoubleElement will append a BSON double element using key and f to dst
// and return the extended buffer.
func AppendDoubleElement(dst []byte, key string, f float64) []byte {
- return AppendDouble(AppendHeader(dst, bsontype.Double, key), f)
+ return AppendDouble(AppendHeader(dst, TypeDouble, key), f)
}
// ReadDouble will read a float64 from src. If there are not enough bytes it
// will return false.
func ReadDouble(src []byte) (float64, []byte, bool) {
- bits, src, ok := readu64(src)
+ bits, src, ok := binaryutil.ReadU64(src)
if !ok {
return 0, src, false
}
@@ -167,7 +169,7 @@ func AppendString(dst []byte, s string) []byte {
// AppendStringElement will append a BSON string element using key and val to dst
// and return the extended buffer.
func AppendStringElement(dst []byte, key, val string) []byte {
- return AppendString(AppendHeader(dst, bsontype.String, key), val)
+ return AppendString(AppendHeader(dst, TypeString, key), val)
}
// ReadString will read a string from src. If there are not enough bytes it
@@ -196,7 +198,7 @@ func AppendDocumentStartInline(dst []byte, index *int32) []byte {
// AppendDocumentElementStart writes a document element header and then reserves the length bytes.
func AppendDocumentElementStart(dst []byte, key string) (index int32, b []byte) {
- return AppendDocumentStart(AppendHeader(dst, bsontype.EmbeddedDocument, key))
+ return AppendDocumentStart(AppendHeader(dst, TypeEmbeddedDocument, key))
}
// AppendDocumentEnd writes the null byte for a document and updates the length of the document.
@@ -216,7 +218,7 @@ func AppendDocument(dst []byte, doc []byte) []byte { return append(dst, doc...)
// AppendDocumentElement will append a BSON embedded document element using key
// and doc to dst and return the extended buffer.
func AppendDocumentElement(dst []byte, key string, doc []byte) []byte {
- return AppendDocument(AppendHeader(dst, bsontype.EmbeddedDocument, key), doc)
+ return AppendDocument(AppendHeader(dst, TypeEmbeddedDocument, key), doc)
}
// BuildDocument will create a document with the given slice of elements and will append
@@ -233,13 +235,13 @@ func BuildDocument(dst []byte, elems ...[]byte) []byte {
// BuildDocumentValue creates an Embedded Document value from the given elements.
func BuildDocumentValue(elems ...[]byte) Value {
- return Value{Type: bsontype.EmbeddedDocument, Data: BuildDocument(nil, elems...)}
+ return Value{Type: TypeEmbeddedDocument, Data: BuildDocument(nil, elems...)}
}
// BuildDocumentElement will append a BSON embedded document element using key and the provided
// elements and return the extended buffer.
func BuildDocumentElement(dst []byte, key string, elems ...[]byte) []byte {
- return BuildDocument(AppendHeader(dst, bsontype.EmbeddedDocument, key), elems...)
+ return BuildDocument(AppendHeader(dst, TypeEmbeddedDocument, key), elems...)
}
// BuildDocumentFromElements is an alaias for the BuildDocument function.
@@ -256,7 +258,7 @@ func AppendArrayStart(dst []byte) (index int32, b []byte) { return ReserveLength
// AppendArrayElementStart appends an array element header and then the length bytes for an array,
// returning the index where the length starts.
func AppendArrayElementStart(dst []byte, key string) (index int32, b []byte) {
- return AppendArrayStart(AppendHeader(dst, bsontype.Array, key))
+ return AppendArrayStart(AppendHeader(dst, TypeArray, key))
}
// AppendArrayEnd appends the null byte to an array and calculates the length, inserting that
@@ -269,7 +271,7 @@ func AppendArray(dst []byte, arr []byte) []byte { return append(dst, arr...) }
// AppendArrayElement will append a BSON array element using key and arr to dst
// and return the extended buffer.
func AppendArrayElement(dst []byte, key string, arr []byte) []byte {
- return AppendArray(AppendHeader(dst, bsontype.Array, key), arr)
+ return AppendArray(AppendHeader(dst, TypeArray, key), arr)
}
// BuildArray will append a BSON array to dst built from values.
@@ -285,7 +287,7 @@ func BuildArray(dst []byte, values ...Value) []byte {
// BuildArrayElement will create an array element using the provided values.
func BuildArrayElement(dst []byte, key string, values ...Value) []byte {
- return BuildArray(AppendHeader(dst, bsontype.Array, key), values...)
+ return BuildArray(AppendHeader(dst, TypeArray, key), values...)
}
// ReadArray will read an array from src. If there are not enough bytes it
@@ -304,7 +306,7 @@ func AppendBinary(dst []byte, subtype byte, b []byte) []byte {
// AppendBinaryElement will append a BSON binary element using key, subtype, and
// b to dst and return the extended buffer.
func AppendBinaryElement(dst []byte, key string, subtype byte, b []byte) []byte {
- return AppendBinary(AppendHeader(dst, bsontype.Binary, key), subtype, b)
+ return AppendBinary(AppendHeader(dst, TypeBinary, key), subtype, b)
}
// ReadBinary will read a subtype and bin from src. If there are not enough bytes it
@@ -336,27 +338,28 @@ func ReadBinary(src []byte) (subtype byte, bin []byte, rem []byte, ok bool) {
// AppendUndefinedElement will append a BSON undefined element using key to dst
// and return the extended buffer.
func AppendUndefinedElement(dst []byte, key string) []byte {
- return AppendHeader(dst, bsontype.Undefined, key)
+ return AppendHeader(dst, TypeUndefined, key)
}
// AppendObjectID will append oid to dst and return the extended buffer.
-func AppendObjectID(dst []byte, oid primitive.ObjectID) []byte { return append(dst, oid[:]...) }
+func AppendObjectID(dst []byte, oid objectID) []byte { return append(dst, oid[:]...) }
// AppendObjectIDElement will append a BSON ObjectID element using key and oid to dst
// and return the extended buffer.
-func AppendObjectIDElement(dst []byte, key string, oid primitive.ObjectID) []byte {
- return AppendObjectID(AppendHeader(dst, bsontype.ObjectID, key), oid)
+func AppendObjectIDElement(dst []byte, key string, oid objectID) []byte {
+ return AppendObjectID(AppendHeader(dst, TypeObjectID, key), oid)
}
// ReadObjectID will read an ObjectID from src. If there are not enough bytes it
// will return false.
-func ReadObjectID(src []byte) (primitive.ObjectID, []byte, bool) {
- if len(src) < 12 {
- return primitive.ObjectID{}, src, false
+func ReadObjectID(src []byte) ([12]byte, []byte, bool) {
+ var oid objectID
+ idLen := cap(oid)
+ if len(src) < idLen {
+ return oid, src, false
}
- var oid primitive.ObjectID
- copy(oid[:], src[0:12])
- return oid, src[12:], true
+ copy(oid[:], src[0:idLen])
+ return oid, src[idLen:], true
}
// AppendBoolean will append b to dst and return the extended buffer.
@@ -370,7 +373,7 @@ func AppendBoolean(dst []byte, b bool) []byte {
// AppendBooleanElement will append a BSON boolean element using key and b to dst
// and return the extended buffer.
func AppendBooleanElement(dst []byte, key string, b bool) []byte {
- return AppendBoolean(AppendHeader(dst, bsontype.Boolean, key), b)
+ return AppendBoolean(AppendHeader(dst, TypeBoolean, key), b)
}
// ReadBoolean will read a bool from src. If there are not enough bytes it
@@ -384,17 +387,17 @@ func ReadBoolean(src []byte) (bool, []byte, bool) {
}
// AppendDateTime will append dt to dst and return the extended buffer.
-func AppendDateTime(dst []byte, dt int64) []byte { return appendi64(dst, dt) }
+func AppendDateTime(dst []byte, dt int64) []byte { return binaryutil.Append64(dst, dt) }
// AppendDateTimeElement will append a BSON datetime element using key and dt to dst
// and return the extended buffer.
func AppendDateTimeElement(dst []byte, key string, dt int64) []byte {
- return AppendDateTime(AppendHeader(dst, bsontype.DateTime, key), dt)
+ return AppendDateTime(AppendHeader(dst, TypeDateTime, key), dt)
}
// ReadDateTime will read an int64 datetime from src. If there are not enough bytes it
// will return false.
-func ReadDateTime(src []byte) (int64, []byte, bool) { return readi64(src) }
+func ReadDateTime(src []byte) (int64, []byte, bool) { return binaryutil.ReadI64(src) }
// AppendTime will append time as a BSON DateTime to dst and return the extended buffer.
func AppendTime(dst []byte, t time.Time) []byte {
@@ -404,19 +407,19 @@ func AppendTime(dst []byte, t time.Time) []byte {
// AppendTimeElement will append a BSON datetime element using key and dt to dst
// and return the extended buffer.
func AppendTimeElement(dst []byte, key string, t time.Time) []byte {
- return AppendTime(AppendHeader(dst, bsontype.DateTime, key), t)
+ return AppendTime(AppendHeader(dst, TypeDateTime, key), t)
}
// ReadTime will read an time.Time datetime from src. If there are not enough bytes it
// will return false.
func ReadTime(src []byte) (time.Time, []byte, bool) {
- dt, rem, ok := readi64(src)
+ dt, rem, ok := binaryutil.ReadI64(src)
return time.Unix(dt/1e3, dt%1e3*1e6), rem, ok
}
// AppendNullElement will append a BSON null element using key to dst
// and return the extended buffer.
-func AppendNullElement(dst []byte, key string) []byte { return AppendHeader(dst, bsontype.Null, key) }
+func AppendNullElement(dst []byte, key string) []byte { return AppendHeader(dst, TypeNull, key) }
// AppendRegex will append pattern and options to dst and return the extended buffer.
func AppendRegex(dst []byte, pattern, options string) []byte {
@@ -430,17 +433,17 @@ func AppendRegex(dst []byte, pattern, options string) []byte {
// AppendRegexElement will append a BSON regex element using key, pattern, and
// options to dst and return the extended buffer.
func AppendRegexElement(dst []byte, key, pattern, options string) []byte {
- return AppendRegex(AppendHeader(dst, bsontype.Regex, key), pattern, options)
+ return AppendRegex(AppendHeader(dst, TypeRegex, key), pattern, options)
}
// ReadRegex will read a pattern and options from src. If there are not enough bytes it
// will return false.
func ReadRegex(src []byte) (pattern, options string, rem []byte, ok bool) {
- pattern, rem, ok = readcstring(src)
+ pattern, rem, ok = binaryutil.ReadCString(src)
if !ok {
return "", "", src, false
}
- options, rem, ok = readcstring(rem)
+ options, rem, ok = binaryutil.ReadCString(rem)
if !ok {
return "", "", src, false
}
@@ -448,26 +451,26 @@ func ReadRegex(src []byte) (pattern, options string, rem []byte, ok bool) {
}
// AppendDBPointer will append ns and oid to dst and return the extended buffer.
-func AppendDBPointer(dst []byte, ns string, oid primitive.ObjectID) []byte {
+func AppendDBPointer(dst []byte, ns string, oid objectID) []byte {
return append(appendstring(dst, ns), oid[:]...)
}
// AppendDBPointerElement will append a BSON DBPointer element using key, ns,
// and oid to dst and return the extended buffer.
-func AppendDBPointerElement(dst []byte, key, ns string, oid primitive.ObjectID) []byte {
- return AppendDBPointer(AppendHeader(dst, bsontype.DBPointer, key), ns, oid)
+func AppendDBPointerElement(dst []byte, key, ns string, oid objectID) []byte {
+ return AppendDBPointer(AppendHeader(dst, TypeDBPointer, key), ns, oid)
}
// ReadDBPointer will read a ns and oid from src. If there are not enough bytes it
// will return false.
-func ReadDBPointer(src []byte) (ns string, oid primitive.ObjectID, rem []byte, ok bool) {
+func ReadDBPointer(src []byte) (ns string, oid [12]byte, rem []byte, ok bool) {
ns, rem, ok = readstring(src)
if !ok {
- return "", primitive.ObjectID{}, src, false
+ return "", objectID{}, src, false
}
oid, rem, ok = ReadObjectID(rem)
if !ok {
- return "", primitive.ObjectID{}, src, false
+ return "", objectID{}, src, false
}
return ns, oid, rem, true
}
@@ -478,7 +481,7 @@ func AppendJavaScript(dst []byte, js string) []byte { return appendstring(dst, j
// AppendJavaScriptElement will append a BSON JavaScript element using key and
// js to dst and return the extended buffer.
func AppendJavaScriptElement(dst []byte, key, js string) []byte {
- return AppendJavaScript(AppendHeader(dst, bsontype.JavaScript, key), js)
+ return AppendJavaScript(AppendHeader(dst, TypeJavaScript, key), js)
}
// ReadJavaScript will read a js string from src. If there are not enough bytes it
@@ -491,7 +494,7 @@ func AppendSymbol(dst []byte, symbol string) []byte { return appendstring(dst, s
// AppendSymbolElement will append a BSON symbol element using key and symbol to dst
// and return the extended buffer.
func AppendSymbolElement(dst []byte, key, symbol string) []byte {
- return AppendSymbol(AppendHeader(dst, bsontype.Symbol, key), symbol)
+ return AppendSymbol(AppendHeader(dst, TypeSymbol, key), symbol)
}
// ReadSymbol will read a symbol string from src. If there are not enough bytes it
@@ -510,7 +513,7 @@ func AppendCodeWithScope(dst []byte, code string, scope []byte) []byte {
// key, code, and scope to dst
// and return the extended buffer.
func AppendCodeWithScopeElement(dst []byte, key, code string, scope []byte) []byte {
- return AppendCodeWithScope(AppendHeader(dst, bsontype.CodeWithScope, key), code, scope)
+ return AppendCodeWithScope(AppendHeader(dst, TypeCodeWithScope, key), code, scope)
}
// ReadCodeWithScope will read code and scope from src. If there are not enough bytes it
@@ -534,37 +537,37 @@ func ReadCodeWithScope(src []byte) (code string, scope []byte, rem []byte, ok bo
}
// AppendInt32 will append i32 to dst and return the extended buffer.
-func AppendInt32(dst []byte, i32 int32) []byte { return appendi32(dst, i32) }
+func AppendInt32(dst []byte, i32 int32) []byte { return binaryutil.Append32(dst, i32) }
// AppendInt32Element will append a BSON int32 element using key and i32 to dst
// and return the extended buffer.
func AppendInt32Element(dst []byte, key string, i32 int32) []byte {
- return AppendInt32(AppendHeader(dst, bsontype.Int32, key), i32)
+ return AppendInt32(AppendHeader(dst, TypeInt32, key), i32)
}
// ReadInt32 will read an int32 from src. If there are not enough bytes it
// will return false.
-func ReadInt32(src []byte) (int32, []byte, bool) { return readi32(src) }
+func ReadInt32(src []byte) (int32, []byte, bool) { return binaryutil.ReadI32(src) }
// AppendTimestamp will append t and i to dst and return the extended buffer.
func AppendTimestamp(dst []byte, t, i uint32) []byte {
- return appendu32(appendu32(dst, i), t) // i is the lower 4 bytes, t is the higher 4 bytes
+ return binaryutil.Append32(binaryutil.Append32(dst, i), t) // i is the lower 4 bytes, t is the higher 4 bytes
}
// AppendTimestampElement will append a BSON timestamp element using key, t, and
// i to dst and return the extended buffer.
func AppendTimestampElement(dst []byte, key string, t, i uint32) []byte {
- return AppendTimestamp(AppendHeader(dst, bsontype.Timestamp, key), t, i)
+ return AppendTimestamp(AppendHeader(dst, TypeTimestamp, key), t, i)
}
// ReadTimestamp will read t and i from src. If there are not enough bytes it
// will return false.
func ReadTimestamp(src []byte) (t, i uint32, rem []byte, ok bool) {
- i, rem, ok = readu32(src)
+ i, rem, ok = binaryutil.ReadU32(src)
if !ok {
return 0, 0, src, false
}
- t, rem, ok = readu32(rem)
+ t, rem, ok = binaryutil.ReadU32(rem)
if !ok {
return 0, 0, src, false
}
@@ -572,60 +575,59 @@ func ReadTimestamp(src []byte) (t, i uint32, rem []byte, ok bool) {
}
// AppendInt64 will append i64 to dst and return the extended buffer.
-func AppendInt64(dst []byte, i64 int64) []byte { return appendi64(dst, i64) }
+func AppendInt64(dst []byte, i64 int64) []byte { return binaryutil.Append64(dst, i64) }
// AppendInt64Element will append a BSON int64 element using key and i64 to dst
// and return the extended buffer.
func AppendInt64Element(dst []byte, key string, i64 int64) []byte {
- return AppendInt64(AppendHeader(dst, bsontype.Int64, key), i64)
+ return AppendInt64(AppendHeader(dst, TypeInt64, key), i64)
}
// ReadInt64 will read an int64 from src. If there are not enough bytes it
// will return false.
-func ReadInt64(src []byte) (int64, []byte, bool) { return readi64(src) }
+func ReadInt64(src []byte) (int64, []byte, bool) { return binaryutil.ReadI64(src) }
-// AppendDecimal128 will append d128 to dst and return the extended buffer.
-func AppendDecimal128(dst []byte, d128 primitive.Decimal128) []byte {
- high, low := d128.GetBytes()
- return appendu64(appendu64(dst, low), high)
+// AppendDecimal128 will append high and low parts of a d128 to dst and return the extended buffer.
+func AppendDecimal128(dst []byte, high, low uint64) []byte {
+ return binaryutil.Append64(binaryutil.Append64(dst, low), high)
}
-// AppendDecimal128Element will append a BSON primitive.28 element using key and
+// AppendDecimal128Element will append high and low parts of a BSON bson.Decimal128 element using key and
// d128 to dst and return the extended buffer.
-func AppendDecimal128Element(dst []byte, key string, d128 primitive.Decimal128) []byte {
- return AppendDecimal128(AppendHeader(dst, bsontype.Decimal128, key), d128)
+func AppendDecimal128Element(dst []byte, key string, high, low uint64) []byte {
+ return AppendDecimal128(AppendHeader(dst, TypeDecimal128, key), high, low)
}
-// ReadDecimal128 will read a primitive.Decimal128 from src. If there are not enough bytes it
+// ReadDecimal128 will read high and low parts of a bson.Decimal128 from src. If there are not enough bytes it
// will return false.
-func ReadDecimal128(src []byte) (primitive.Decimal128, []byte, bool) {
- l, rem, ok := readu64(src)
+func ReadDecimal128(src []byte) (high uint64, low uint64, rem []byte, ok bool) {
+ low, rem, ok = binaryutil.ReadU64(src)
if !ok {
- return primitive.Decimal128{}, src, false
+ return 0, 0, src, false
}
- h, rem, ok := readu64(rem)
+ high, rem, ok = binaryutil.ReadU64(rem)
if !ok {
- return primitive.Decimal128{}, src, false
+ return 0, 0, src, false
}
- return primitive.NewDecimal128(h, l), rem, true
+ return high, low, rem, true
}
// AppendMaxKeyElement will append a BSON max key element using key to dst
// and return the extended buffer.
func AppendMaxKeyElement(dst []byte, key string) []byte {
- return AppendHeader(dst, bsontype.MaxKey, key)
+ return AppendHeader(dst, TypeMaxKey, key)
}
// AppendMinKeyElement will append a BSON min key element using key to dst
// and return the extended buffer.
func AppendMinKeyElement(dst []byte, key string) []byte {
- return AppendHeader(dst, bsontype.MinKey, key)
+ return AppendHeader(dst, TypeMinKey, key)
}
// EqualValue will return true if the two values are equal.
-func EqualValue(t1, t2 bsontype.Type, v1, v2 []byte) bool {
+func EqualValue(t1, t2 Type, v1, v2 []byte) bool {
if t1 != t2 {
return false
}
@@ -643,34 +645,34 @@ func EqualValue(t1, t2 bsontype.Type, v1, v2 []byte) bool {
// valueLength will determine the length of the next value contained in src as if it
// is type t. The returned bool will be false if there are not enough bytes in src for
// a value of type t.
-func valueLength(src []byte, t bsontype.Type) (int32, bool) {
+func valueLength(src []byte, t Type) (int32, bool) {
var length int32
ok := true
switch t {
- case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope:
+ case TypeArray, TypeEmbeddedDocument, TypeCodeWithScope:
length, _, ok = ReadLength(src)
- case bsontype.Binary:
+ case TypeBinary:
length, _, ok = ReadLength(src)
length += 4 + 1 // binary length + subtype byte
- case bsontype.Boolean:
+ case TypeBoolean:
length = 1
- case bsontype.DBPointer:
+ case TypeDBPointer:
length, _, ok = ReadLength(src)
length += 4 + 12 // string length + ObjectID length
- case bsontype.DateTime, bsontype.Double, bsontype.Int64, bsontype.Timestamp:
+ case TypeDateTime, TypeDouble, TypeInt64, TypeTimestamp:
length = 8
- case bsontype.Decimal128:
+ case TypeDecimal128:
length = 16
- case bsontype.Int32:
+ case TypeInt32:
length = 4
- case bsontype.JavaScript, bsontype.String, bsontype.Symbol:
+ case TypeJavaScript, TypeString, TypeSymbol:
length, _, ok = ReadLength(src)
length += 4
- case bsontype.MaxKey, bsontype.MinKey, bsontype.Null, bsontype.Undefined:
+ case TypeMaxKey, TypeMinKey, TypeNull, TypeUndefined:
length = 0
- case bsontype.ObjectID:
+ case TypeObjectID:
length = 12
- case bsontype.Regex:
+ case TypeRegex:
regex := bytes.IndexByte(src, 0x00)
if regex < 0 {
ok = false
@@ -689,7 +691,7 @@ func valueLength(src []byte, t bsontype.Type) (int32, bool) {
return length, ok
}
-func readValue(src []byte, t bsontype.Type) ([]byte, []byte, bool) {
+func readValue(src []byte, t Type) ([]byte, []byte, bool) {
length, ok := valueLength(src, t)
if !ok || int(length) > len(src) {
return nil, src, false
@@ -711,90 +713,19 @@ func UpdateLength(dst []byte, index, length int32) []byte {
return dst
}
-func appendLength(dst []byte, l int32) []byte { return appendi32(dst, l) }
-
-func appendi32(dst []byte, i32 int32) []byte {
- b := []byte{0, 0, 0, 0}
- binary.LittleEndian.PutUint32(b, uint32(i32))
- return append(dst, b...)
-}
+func appendLength(dst []byte, l int32) []byte { return binaryutil.Append32(dst, l) }
// ReadLength reads an int32 length from src and returns the length and the remaining bytes. If
// there aren't enough bytes to read a valid length, src is returned unomdified and the returned
// bool will be false.
func ReadLength(src []byte) (int32, []byte, bool) {
- ln, src, ok := readi32(src)
+ ln, src, ok := binaryutil.ReadI32(src)
if ln < 0 {
return ln, src, false
}
return ln, src, ok
}
-func readi32(src []byte) (int32, []byte, bool) {
- if len(src) < 4 {
- return 0, src, false
- }
- return int32(binary.LittleEndian.Uint32(src)), src[4:], true
-}
-
-func appendi64(dst []byte, i64 int64) []byte {
- b := []byte{0, 0, 0, 0, 0, 0, 0, 0}
- binary.LittleEndian.PutUint64(b, uint64(i64))
- return append(dst, b...)
-}
-
-func readi64(src []byte) (int64, []byte, bool) {
- if len(src) < 8 {
- return 0, src, false
- }
- return int64(binary.LittleEndian.Uint64(src)), src[8:], true
-}
-
-func appendu32(dst []byte, u32 uint32) []byte {
- b := []byte{0, 0, 0, 0}
- binary.LittleEndian.PutUint32(b, u32)
- return append(dst, b...)
-}
-
-func readu32(src []byte) (uint32, []byte, bool) {
- if len(src) < 4 {
- return 0, src, false
- }
-
- return binary.LittleEndian.Uint32(src), src[4:], true
-}
-
-func appendu64(dst []byte, u64 uint64) []byte {
- b := []byte{0, 0, 0, 0, 0, 0, 0, 0}
- binary.LittleEndian.PutUint64(b, u64)
- return append(dst, b...)
-}
-
-func readu64(src []byte) (uint64, []byte, bool) {
- if len(src) < 8 {
- return 0, src, false
- }
- return binary.LittleEndian.Uint64(src), src[8:], true
-}
-
-// keep in sync with readcstringbytes
-func readcstring(src []byte) (string, []byte, bool) {
- idx := bytes.IndexByte(src, 0x00)
- if idx < 0 {
- return "", src, false
- }
- return string(src[:idx]), src[idx+1:], true
-}
-
-// keep in sync with readcstring
-func readcstringbytes(src []byte) ([]byte, []byte, bool) {
- idx := bytes.IndexByte(src, 0x00)
- if idx < 0 {
- return nil, src, false
- }
- return src[:idx], src[idx+1:], true
-}
-
func appendstring(dst []byte, s string) []byte {
l := int32(len(s) + 1)
dst = appendLength(dst, l)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/document.go
similarity index 84%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/document.go
index 3f360f1ae..d2733df72 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/document.go
@@ -13,7 +13,7 @@ import (
"strconv"
"strings"
- "go.mongodb.org/mongo-driver/bson/bsontype"
+ "go.mongodb.org/mongo-driver/v2/internal/binaryutil"
)
// ValidationError is an error type returned when attempting to validate a document or array.
@@ -63,13 +63,13 @@ func (ibe InsufficientBytesError) Equal(err2 error) bool {
// the path is neither an embedded document nor an array.
type InvalidDepthTraversalError struct {
Key string
- Type bsontype.Type
+ Type Type
}
func (idte InvalidDepthTraversalError) Error() string {
return fmt.Sprintf(
"attempt to traverse into %s, but it's type is %s, not %s nor %s",
- idte.Key, idte.Type, bsontype.EmbeddedDocument, bsontype.Array,
+ idte.Key, idte.Type, TypeEmbeddedDocument, TypeArray,
)
}
@@ -114,7 +114,7 @@ func newBufferFromReader(r io.Reader) ([]byte, error) {
return nil, err
}
- length, _, _ := readi32(lengthBytes[:]) // ignore ok since we always have enough bytes to read a length
+ length, _, _ := binaryutil.ReadI32(lengthBytes[:]) // ignore ok since we always have enough bytes to read a length
if length < 0 {
return nil, ErrInvalidLength
}
@@ -167,15 +167,15 @@ func (d Document) LookupErr(key ...string) (Value, error) {
continue
}
if len(key) > 1 {
- tt := bsontype.Type(elem[0])
+ tt := Type(elem[0])
switch tt {
- case bsontype.EmbeddedDocument:
+ case TypeEmbeddedDocument:
val, err := elem.Value().Document().LookupErr(key[1:]...)
if err != nil {
return Value{}, err
}
return val, nil
- case bsontype.Array:
+ case TypeArray:
// Convert to Document to continue Lookup recursion.
val, err := Document(elem.Value().Array()).LookupErr(key[1:]...)
if err != nil {
@@ -263,34 +263,79 @@ func (d Document) DebugString() string {
// String outputs an ExtendedJSON version of Document. If the document is not valid, this method
// returns an empty string.
func (d Document) String() string {
- if len(d) < 5 {
- return ""
+ str, _ := d.StringN(-1)
+ return str
+}
+
+// StringN stringifies a document. If N is non-negative, it will truncate the string to N bytes.
+// Otherwise, it will return the full string representation. The second return value indicates
+// whether the string was truncated or not.
+func (d Document) StringN(n int) (string, bool) {
+ length, rem, ok := ReadLength(d)
+ if !ok || length < 5 {
+ return "", false
}
- var buf strings.Builder
- buf.WriteByte('{')
+ length -= 4 // length bytes
+ length-- // final null byte
- length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
+ if n == 0 {
+ return "", true
+ }
- length -= 4
+ var buf strings.Builder
+ buf.WriteByte('{')
+ var truncated bool
var elem Element
- var ok bool
+ var str string
first := true
- for length > 1 {
+ for length > 0 && !truncated {
+ needStrLen := -1
+ // Set needStrLen if n is positive, meaning we want to limit the string length.
+ if n > 0 {
+ // Stop stringifying if we reach the limit, that also ensures needStrLen is
+ // greater than 0 if we need to limit the length.
+ if buf.Len() >= n {
+ truncated = true
+ break
+ }
+ needStrLen = n - buf.Len()
+ }
+
+ // Append a comma if this is not the first element.
if !first {
buf.WriteByte(',')
+ // If we are truncating, we need to account for the comma in the length.
+ if needStrLen > 0 {
+ needStrLen--
+ if needStrLen == 0 {
+ truncated = true
+ break
+ }
+ }
}
+
elem, rem, ok = ReadElement(rem)
length -= int32(len(elem))
- if !ok {
- return ""
+ // Exit on malformed element.
+ if !ok || length < 0 {
+ return "", false
}
- buf.WriteString(elem.String())
+
+ // Delegate to StringN() on the element.
+ str, truncated = elem.StringN(needStrLen)
+ buf.WriteString(str)
+
first = false
}
- buf.WriteByte('}')
- return buf.String()
+ if n <= 0 || (buf.Len() < n && !truncated) {
+ buf.WriteByte('}')
+ } else {
+ truncated = true
+ }
+
+ return buf.String(), truncated
}
// Elements returns this document as a slice of elements. The returned slice will contain valid
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/element.go
similarity index 68%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/element.go
index 9c1ab2ae9..4214e5a7c 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/element.go
@@ -9,8 +9,9 @@ package bsoncore
import (
"bytes"
"fmt"
+ "strings"
- "go.mongodb.org/mongo-driver/bson/bsontype"
+ "go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil"
)
// MalformedElementError represents a class of errors that RawElement methods return.
@@ -70,7 +71,7 @@ func (e Element) Validate() error {
if idx == -1 {
return ErrElementMissingKey
}
- return Value{Type: bsontype.Type(e[0]), Data: e[idx+2:]}.Validate()
+ return Value{Type: Type(e[0]), Data: e[idx+2:]}.Validate()
}
// CompareKey will compare this element's key to key. This method makes it easy to compare keys
@@ -107,7 +108,7 @@ func (e Element) ValueErr() (Value, error) {
return Value{}, ErrElementMissingKey
}
- val, rem, exists := ReadValue(e[idx+2:], bsontype.Type(e[0]))
+ val, rem, exists := ReadValue(e[idx+2:], Type(e[0]))
if !exists {
return Value{}, NewInsufficientBytesError(e, rem)
}
@@ -116,20 +117,80 @@ func (e Element) ValueErr() (Value, error) {
// String implements the fmt.String interface. The output will be in extended JSON format.
func (e Element) String() string {
+ str, _ := e.StringN(-1)
+ return str
+}
+
+// StringN will return values in extended JSON format that will stringify an element upto N bytes.
+// If N is non-negative, it will truncate the string to N bytes. Otherwise, it will return the full
+// string representation. The second return value indicates whether the string was truncated or not.
+// If the element is not valid, this returns an empty string
+func (e Element) StringN(n int) (string, bool) {
if len(e) == 0 {
- return ""
+ return "", false
}
- t := bsontype.Type(e[0])
- idx := bytes.IndexByte(e[1:], 0x00)
- if idx == -1 {
- return ""
+ if n == 0 {
+ return "", true
}
- key, valBytes := []byte(e[1:idx+1]), []byte(e[idx+2:])
- val, _, valid := ReadValue(valBytes, t)
+ if n == 1 {
+ return `"`, true
+ }
+
+ t := Type(e[0])
+ idx := bytes.IndexByte(e[1:], 0x00)
+ if idx <= 0 {
+ return "", false
+ }
+ key := e[1 : idx+1]
+
+ var buf strings.Builder
+ buf.WriteByte('"')
+ const suffix = `": `
+ switch {
+ case n < 0 || idx <= n-buf.Len()-len(suffix):
+ buf.Write(key)
+ buf.WriteString(suffix)
+ case idx < n:
+ buf.Write(key)
+ buf.WriteString(suffix[:n-idx-1])
+ return buf.String(), true
+ default:
+ buf.WriteString(bsoncoreutil.Truncate(string(key), n-1))
+ return buf.String(), true
+ }
+
+ needStrLen := -1
+ // Set needStrLen if n is positive, meaning we want to limit the string length.
+ if n > 0 {
+ // Stop stringifying if we reach the limit, that also ensures needStrLen is
+ // greater than 0 if we need to limit the length.
+ if buf.Len() >= n {
+ return buf.String(), true
+ }
+ needStrLen = n - buf.Len()
+ }
+
+ val, _, valid := ReadValue(e[idx+2:], t)
if !valid {
- return ""
+ return "", false
}
- return "\"" + string(key) + "\": " + val.String()
+
+ var str string
+ var truncated bool
+ if _, ok := val.StringValueOK(); ok {
+ str, truncated = val.StringN(needStrLen)
+ } else if arr, ok := val.ArrayOK(); ok {
+ str, truncated = arr.StringN(needStrLen)
+ } else {
+ str = val.String()
+ if needStrLen > 0 && len(str) > needStrLen {
+ truncated = true
+ str = bsoncoreutil.Truncate(str, needStrLen)
+ }
+ }
+
+ buf.WriteString(str)
+ return buf.String(), truncated
}
// DebugString outputs a human readable version of RawElement. It will attempt to stringify the
@@ -138,7 +199,7 @@ func (e Element) DebugString() string {
if len(e) == 0 {
return ""
}
- t := bsontype.Type(e[0])
+ t := Type(e[0])
idx := bytes.IndexByte(e[1:], 0x00)
if idx == -1 {
return fmt.Sprintf(`bson.Element{[%s]}`, t)
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/iterator.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/iterator.go
new file mode 100644
index 000000000..9c8ea5b87
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/iterator.go
@@ -0,0 +1,113 @@
+// Copyright (C) MongoDB, Inc. 2022-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 bsoncore
+
+import (
+ "errors"
+ "fmt"
+ "io"
+)
+
+// errCorruptedDocument is returned when a full document couldn't be read from
+// the sequence.
+var errCorruptedDocument = errors.New("invalid DocumentSequence: corrupted document")
+
+// Iterator maintains a list of BSON values and keeps track of the current
+// position in relation to its Next() method.
+type Iterator struct {
+ List Array // List of BSON values
+ pos int // The position of the iterator in the list in reference to Next()
+}
+
+// Count returned the number of elements in the iterator's list.
+func (iter *Iterator) Count() int {
+ if iter == nil {
+ return 0
+ }
+
+ _, rem, ok := ReadLength(iter.List)
+ if !ok {
+ return 0
+ }
+
+ var count int
+ for len(rem) > 1 {
+ _, rem, ok = ReadElement(rem)
+ if !ok {
+ return 0
+ }
+ count++
+ }
+ return count
+}
+
+// Empty returns true if the iterator's list is empty.
+func (iter *Iterator) Empty() bool {
+ return len(iter.List) <= 5
+}
+
+// Reset will reset the iteration point for the Next method to the beginning of
+// the list.
+func (iter *Iterator) Reset() {
+ iter.pos = 0
+}
+
+// Documents traverses the list as documents and returns them. This method
+// assumes that the underlying list is composed of documents and will return
+// an error otherwise.
+func (iter *Iterator) Documents() ([]Document, error) {
+ if iter == nil || len(iter.List) == 0 {
+ return nil, nil
+ }
+
+ vals, err := iter.List.Values()
+ if err != nil {
+ return nil, errCorruptedDocument
+ }
+
+ docs := make([]Document, 0, len(vals))
+ for _, v := range vals {
+ if v.Type != TypeEmbeddedDocument {
+ return nil, fmt.Errorf("invalid DocumentSequence: a non-document value was found in sequence")
+ }
+
+ docs = append(docs, v.Data)
+ }
+
+ return docs, nil
+}
+
+// Next retrieves the next value from the list and returns it. This method will
+// return io.EOF when it has reached the end of the list.
+func (iter *Iterator) Next() (*Value, error) {
+ if iter == nil || iter.pos >= len(iter.List) {
+ return nil, io.EOF
+ }
+
+ if iter.pos < 4 {
+ if len(iter.List) < 4 {
+ return nil, errCorruptedDocument
+ }
+
+ iter.pos = 4 // Skip the length of the document
+ }
+
+ rem := iter.List[iter.pos:]
+ if len(rem) == 1 && rem[0] == 0x00 {
+ return nil, io.EOF // At the end of the document
+ }
+
+ elem, _, ok := ReadElement(rem)
+ if !ok {
+ return nil, errCorruptedDocument
+ }
+
+ iter.pos += len(elem)
+ val := elem.Value()
+
+ return &val, nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/tables.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/tables.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/tables.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/tables.go
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/type.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/type.go
new file mode 100644
index 000000000..30b6cc437
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/type.go
@@ -0,0 +1,85 @@
+// 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 bsoncore
+
+// Type represents a BSON type.
+type Type byte
+
+// String returns the string representation of the BSON type's name.
+func (bt Type) String() string {
+ switch bt {
+ case '\x01':
+ return "double"
+ case '\x02':
+ return "string"
+ case '\x03':
+ return "embedded document"
+ case '\x04':
+ return "array"
+ case '\x05':
+ return "binary"
+ case '\x06':
+ return "undefined"
+ case '\x07':
+ return "objectID"
+ case '\x08':
+ return "boolean"
+ case '\x09':
+ return "UTC datetime"
+ case '\x0A':
+ return "null"
+ case '\x0B':
+ return "regex"
+ case '\x0C':
+ return "dbPointer"
+ case '\x0D':
+ return "javascript"
+ case '\x0E':
+ return "symbol"
+ case '\x0F':
+ return "code with scope"
+ case '\x10':
+ return "32-bit integer"
+ case '\x11':
+ return "timestamp"
+ case '\x12':
+ return "64-bit integer"
+ case '\x13':
+ return "128-bit decimal"
+ case '\x7F':
+ return "max key"
+ case '\xFF':
+ return "min key"
+ default:
+ return "invalid"
+ }
+}
+
+// BSON element types as described in https://bsonspec.org/spec.html.
+const (
+ TypeDouble Type = 0x01
+ TypeString Type = 0x02
+ TypeEmbeddedDocument Type = 0x03
+ TypeArray Type = 0x04
+ TypeBinary Type = 0x05
+ TypeUndefined Type = 0x06
+ TypeObjectID Type = 0x07
+ TypeBoolean Type = 0x08
+ TypeDateTime Type = 0x09
+ TypeNull Type = 0x0A
+ TypeRegex Type = 0x0B
+ TypeDBPointer Type = 0x0C
+ TypeJavaScript Type = 0x0D
+ TypeSymbol Type = 0x0E
+ TypeCodeWithScope Type = 0x0F
+ TypeInt32 Type = 0x10
+ TypeTimestamp Type = 0x11
+ TypeInt64 Type = 0x12
+ TypeDecimal128 Type = 0x13
+ TypeMaxKey Type = 0x7F
+ TypeMinKey Type = 0xFF
+)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/value.go
similarity index 76%
rename from vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/value.go
index fcb0428bb..847d27084 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/value.go
@@ -9,6 +9,7 @@ package bsoncore
import (
"bytes"
"encoding/base64"
+ "encoding/hex"
"fmt"
"math"
"sort"
@@ -17,14 +18,14 @@ import (
"time"
"unicode/utf8"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil"
+ "go.mongodb.org/mongo-driver/v2/internal/decimal128"
)
// ElementTypeError specifies that a method to obtain a BSON value an incorrect type was called on a bson.Value.
type ElementTypeError struct {
Method string
- Type bsontype.Type
+ Type Type
}
// Error implements the error interface.
@@ -34,7 +35,7 @@ func (ete ElementTypeError) Error() string {
// Value represents a BSON value with a type and raw bytes.
type Value struct {
- Type bsontype.Type
+ Type Type
Data []byte
}
@@ -50,7 +51,7 @@ func (v Value) Validate() error {
// IsNumber returns true if the type of v is a numeric BSON type.
func (v Value) IsNumber() bool {
switch v.Type {
- case bsontype.Double, bsontype.Int32, bsontype.Int64, bsontype.Decimal128:
+ case TypeDouble, TypeInt32, TypeInt64, TypeDecimal128:
return true
default:
return false
@@ -65,25 +66,25 @@ func (v Value) AsInt32() int32 {
}
var i32 int32
switch v.Type {
- case bsontype.Double:
+ case TypeDouble:
f64, _, ok := ReadDouble(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
i32 = int32(f64)
- case bsontype.Int32:
+ case TypeInt32:
var ok bool
i32, _, ok = ReadInt32(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
- case bsontype.Int64:
+ case TypeInt64:
i64, _, ok := ReadInt64(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
i32 = int32(i64)
- case bsontype.Decimal128:
+ case TypeDecimal128:
panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
}
return i32
@@ -97,25 +98,25 @@ func (v Value) AsInt32OK() (int32, bool) {
}
var i32 int32
switch v.Type {
- case bsontype.Double:
+ case TypeDouble:
f64, _, ok := ReadDouble(v.Data)
if !ok {
return 0, false
}
i32 = int32(f64)
- case bsontype.Int32:
+ case TypeInt32:
var ok bool
i32, _, ok = ReadInt32(v.Data)
if !ok {
return 0, false
}
- case bsontype.Int64:
+ case TypeInt64:
i64, _, ok := ReadInt64(v.Data)
if !ok {
return 0, false
}
i32 = int32(i64)
- case bsontype.Decimal128:
+ case TypeDecimal128:
return 0, false
}
return i32, true
@@ -129,26 +130,25 @@ func (v Value) AsInt64() int64 {
}
var i64 int64
switch v.Type {
- case bsontype.Double:
+ case TypeDouble:
f64, _, ok := ReadDouble(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
i64 = int64(f64)
- case bsontype.Int32:
- var ok bool
+ case TypeInt32:
i32, _, ok := ReadInt32(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
i64 = int64(i32)
- case bsontype.Int64:
+ case TypeInt64:
var ok bool
i64, _, ok = ReadInt64(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
- case bsontype.Decimal128:
+ case TypeDecimal128:
panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
}
return i64
@@ -162,26 +162,25 @@ func (v Value) AsInt64OK() (int64, bool) {
}
var i64 int64
switch v.Type {
- case bsontype.Double:
+ case TypeDouble:
f64, _, ok := ReadDouble(v.Data)
if !ok {
return 0, false
}
i64 = int64(f64)
- case bsontype.Int32:
- var ok bool
+ case TypeInt32:
i32, _, ok := ReadInt32(v.Data)
if !ok {
return 0, false
}
i64 = int64(i32)
- case bsontype.Int64:
+ case TypeInt64:
var ok bool
i64, _, ok = ReadInt64(v.Data)
if !ok {
return 0, false
}
- case bsontype.Decimal128:
+ case TypeDecimal128:
return 0, false
}
return i64, true
@@ -189,17 +188,69 @@ func (v Value) AsInt64OK() (int64, bool) {
// AsFloat64 returns a BSON number as an float64. If the BSON type is not a numeric one, this method
// will panic.
-//
-// TODO(GODRIVER-2751): Implement AsFloat64.
-// func (v Value) AsFloat64() float64
+func (v Value) AsFloat64() float64 {
+ if !v.IsNumber() {
+ panic(ElementTypeError{"bsoncore.Value.AsFloat64", v.Type})
+ }
+ var f64 float64
+ switch v.Type {
+ case TypeDouble:
+ var ok bool
+ f64, _, ok = ReadDouble(v.Data)
+ if !ok {
+ panic(NewInsufficientBytesError(v.Data, v.Data))
+ }
+ case TypeInt32:
+ i32, _, ok := ReadInt32(v.Data)
+ if !ok {
+ panic(NewInsufficientBytesError(v.Data, v.Data))
+ }
+ f64 = float64(i32)
+ case TypeInt64:
+ i64, _, ok := ReadInt64(v.Data)
+ if !ok {
+ panic(NewInsufficientBytesError(v.Data, v.Data))
+ }
+ f64 = float64(i64)
+ case TypeDecimal128:
+ panic(ElementTypeError{"bsoncore.Value.AsFloat64", v.Type})
+ }
+ return f64
+}
// AsFloat64OK functions the same as AsFloat64 but returns a boolean instead of panicking. False
// indicates an error.
-//
-// TODO(GODRIVER-2751): Implement AsFloat64OK.
-// func (v Value) AsFloat64OK() (float64, bool)
+func (v Value) AsFloat64OK() (float64, bool) {
+ if !v.IsNumber() {
+ return 0, false
+ }
+ var f64 float64
+ switch v.Type {
+ case TypeDouble:
+ var ok bool
+ f64, _, ok = ReadDouble(v.Data)
+ if !ok {
+ return 0, false
+ }
+ case TypeInt32:
+ i32, _, ok := ReadInt32(v.Data)
+ if !ok {
+ return 0, false
+ }
+ f64 = float64(i32)
+ case TypeInt64:
+ i64, _, ok := ReadInt64(v.Data)
+ if !ok {
+ return 0, false
+ }
+ f64 = float64(i64)
+ case TypeDecimal128:
+ return 0, false
+ }
+ return f64, true
+}
-// Equal compaes v to v2 and returns true if they are equal.
+// Equal compares v to v2 and returns true if they are equal.
func (v Value) Equal(v2 Value) bool {
if v.Type != v2.Type {
return false
@@ -208,151 +259,171 @@ func (v Value) Equal(v2 Value) bool {
return bytes.Equal(v.Data, v2.Data)
}
+func idHex(id [12]byte) string {
+ var buf [24]byte
+ hex.Encode(buf[:], id[:])
+ return string(buf[:])
+}
+
// String implements the fmt.String interface. This method will return values in extended JSON
// format. If the value is not valid, this returns an empty string
func (v Value) String() string {
+ str, _ := v.StringN(-1)
+ return str
+}
+
+// StringN will return values in extended JSON format that will stringify a value upto N bytes.
+// If N is non-negative, it will truncate the string to N bytes. Otherwise, it will return the full
+// string representation. The second return value indicates whether the string was truncated or not.
+// If the value is not valid, this returns an empty string
+func (v Value) StringN(n int) (string, bool) {
+ var str string
switch v.Type {
- case bsontype.Double:
- f64, ok := v.DoubleOK()
+ case TypeString:
+ s, ok := v.StringValueOK()
if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$numberDouble":"%s"}`, formatDouble(f64))
- case bsontype.String:
- str, ok := v.StringValueOK()
- if !ok {
- return ""
+ return "", false
}
- return escapeString(str)
- case bsontype.EmbeddedDocument:
+ str = escapeString(s)
+ case TypeEmbeddedDocument:
doc, ok := v.DocumentOK()
if !ok {
- return ""
+ return "", false
}
- return doc.String()
- case bsontype.Array:
+ return doc.StringN(n)
+ case TypeArray:
arr, ok := v.ArrayOK()
if !ok {
- return ""
+ return "", false
}
- return arr.String()
- case bsontype.Binary:
+ return arr.StringN(n)
+ case TypeDouble:
+ f64, ok := v.DoubleOK()
+ if !ok {
+ return "", false
+ }
+ str = fmt.Sprintf(`{"$numberDouble":"%s"}`, formatDouble(f64))
+ case TypeBinary:
subtype, data, ok := v.BinaryOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$binary":{"base64":"%s","subType":"%02x"}}`, base64.StdEncoding.EncodeToString(data), subtype)
- case bsontype.Undefined:
- return `{"$undefined":true}`
- case bsontype.ObjectID:
+ str = fmt.Sprintf(`{"$binary":{"base64":"%s","subType":"%02x"}}`, base64.StdEncoding.EncodeToString(data), subtype)
+ case TypeUndefined:
+ str = `{"$undefined":true}`
+ case TypeObjectID:
oid, ok := v.ObjectIDOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$oid":"%s"}`, oid.Hex())
- case bsontype.Boolean:
+ str = fmt.Sprintf(`{"$oid":"%s"}`, idHex(oid))
+ case TypeBoolean:
b, ok := v.BooleanOK()
if !ok {
- return ""
+ return "", false
}
- return strconv.FormatBool(b)
- case bsontype.DateTime:
+ str = strconv.FormatBool(b)
+ case TypeDateTime:
dt, ok := v.DateTimeOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$date":{"$numberLong":"%d"}}`, dt)
- case bsontype.Null:
- return "null"
- case bsontype.Regex:
+ str = fmt.Sprintf(`{"$date":{"$numberLong":"%d"}}`, dt)
+ case TypeNull:
+ str = "null"
+ case TypeRegex:
pattern, options, ok := v.RegexOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(
+ str = fmt.Sprintf(
`{"$regularExpression":{"pattern":%s,"options":"%s"}}`,
escapeString(pattern), sortStringAlphebeticAscending(options),
)
- case bsontype.DBPointer:
+ case TypeDBPointer:
ns, pointer, ok := v.DBPointerOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$dbPointer":{"$ref":%s,"$id":{"$oid":"%s"}}}`, escapeString(ns), pointer.Hex())
- case bsontype.JavaScript:
+ str = fmt.Sprintf(`{"$dbPointer":{"$ref":%s,"$id":{"$oid":"%s"}}}`, escapeString(ns), idHex(pointer))
+ case TypeJavaScript:
js, ok := v.JavaScriptOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$code":%s}`, escapeString(js))
- case bsontype.Symbol:
+ str = fmt.Sprintf(`{"$code":%s}`, escapeString(js))
+ case TypeSymbol:
symbol, ok := v.SymbolOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$symbol":%s}`, escapeString(symbol))
- case bsontype.CodeWithScope:
+ str = fmt.Sprintf(`{"$symbol":%s}`, escapeString(symbol))
+ case TypeCodeWithScope:
code, scope, ok := v.CodeWithScopeOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope)
- case bsontype.Int32:
+ str = fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope)
+ case TypeInt32:
i32, ok := v.Int32OK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$numberInt":"%d"}`, i32)
- case bsontype.Timestamp:
+ str = fmt.Sprintf(`{"$numberInt":"%d"}`, i32)
+ case TypeTimestamp:
t, i, ok := v.TimestampOK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$timestamp":{"t":%v,"i":%v}}`, t, i)
- case bsontype.Int64:
+ str = fmt.Sprintf(`{"$timestamp":{"t":%v,"i":%v}}`, t, i)
+ case TypeInt64:
i64, ok := v.Int64OK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$numberLong":"%d"}`, i64)
- case bsontype.Decimal128:
- d128, ok := v.Decimal128OK()
+ str = fmt.Sprintf(`{"$numberLong":"%d"}`, i64)
+ case TypeDecimal128:
+ h, l, ok := v.Decimal128OK()
if !ok {
- return ""
+ return "", false
}
- return fmt.Sprintf(`{"$numberDecimal":"%s"}`, d128.String())
- case bsontype.MinKey:
- return `{"$minKey":1}`
- case bsontype.MaxKey:
- return `{"$maxKey":1}`
+ str = fmt.Sprintf(`{"$numberDecimal":"%s"}`, decimal128.String(h, l))
+ case TypeMinKey:
+ str = `{"$minKey":1}`
+ case TypeMaxKey:
+ str = `{"$maxKey":1}`
default:
- return ""
+ str = ""
+ }
+ if n >= 0 && len(str) > n {
+ return bsoncoreutil.Truncate(str, n), true
}
+ return str, false
}
// DebugString outputs a human readable version of Document. It will attempt to stringify the
// valid components of the document even if the entire document is not valid.
func (v Value) DebugString() string {
switch v.Type {
- case bsontype.String:
+ case TypeString:
str, ok := v.StringValueOK()
if !ok {
return ""
}
return escapeString(str)
- case bsontype.EmbeddedDocument:
+ case TypeEmbeddedDocument:
doc, ok := v.DocumentOK()
if !ok {
return ""
}
return doc.DebugString()
- case bsontype.Array:
+ case TypeArray:
arr, ok := v.ArrayOK()
if !ok {
return ""
}
return arr.DebugString()
- case bsontype.CodeWithScope:
+ case TypeCodeWithScope:
code, scope, ok := v.CodeWithScopeOK()
if !ok {
return ""
@@ -368,9 +439,9 @@ func (v Value) DebugString() string {
}
// Double returns the float64 value for this element.
-// It panics if e's BSON type is not bsontype.Double.
+// It panics if e's BSON type is not TypeDouble.
func (v Value) Double() float64 {
- if v.Type != bsontype.Double {
+ if v.Type != TypeDouble {
panic(ElementTypeError{"bsoncore.Value.Double", v.Type})
}
f64, _, ok := ReadDouble(v.Data)
@@ -382,7 +453,7 @@ func (v Value) Double() float64 {
// DoubleOK is the same as Double, but returns a boolean instead of panicking.
func (v Value) DoubleOK() (float64, bool) {
- if v.Type != bsontype.Double {
+ if v.Type != TypeDouble {
return 0, false
}
f64, _, ok := ReadDouble(v.Data)
@@ -393,12 +464,12 @@ func (v Value) DoubleOK() (float64, bool) {
}
// StringValue returns the string balue for this element.
-// It panics if e's BSON type is not bsontype.String.
+// It panics if e's BSON type is not TypeString.
//
// NOTE: This method is called StringValue to avoid a collision with the String method which
// implements the fmt.Stringer interface.
func (v Value) StringValue() string {
- if v.Type != bsontype.String {
+ if v.Type != TypeString {
panic(ElementTypeError{"bsoncore.Value.StringValue", v.Type})
}
str, _, ok := ReadString(v.Data)
@@ -411,7 +482,7 @@ func (v Value) StringValue() string {
// StringValueOK is the same as StringValue, but returns a boolean instead of
// panicking.
func (v Value) StringValueOK() (string, bool) {
- if v.Type != bsontype.String {
+ if v.Type != TypeString {
return "", false
}
str, _, ok := ReadString(v.Data)
@@ -424,7 +495,7 @@ func (v Value) StringValueOK() (string, bool) {
// Document returns the BSON document the Value represents as a Document. It panics if the
// value is a BSON type other than document.
func (v Value) Document() Document {
- if v.Type != bsontype.EmbeddedDocument {
+ if v.Type != TypeEmbeddedDocument {
panic(ElementTypeError{"bsoncore.Value.Document", v.Type})
}
doc, _, ok := ReadDocument(v.Data)
@@ -437,7 +508,7 @@ func (v Value) Document() Document {
// DocumentOK is the same as Document, except it returns a boolean
// instead of panicking.
func (v Value) DocumentOK() (Document, bool) {
- if v.Type != bsontype.EmbeddedDocument {
+ if v.Type != TypeEmbeddedDocument {
return nil, false
}
doc, _, ok := ReadDocument(v.Data)
@@ -450,7 +521,7 @@ func (v Value) DocumentOK() (Document, bool) {
// Array returns the BSON array the Value represents as an Array. It panics if the
// value is a BSON type other than array.
func (v Value) Array() Array {
- if v.Type != bsontype.Array {
+ if v.Type != TypeArray {
panic(ElementTypeError{"bsoncore.Value.Array", v.Type})
}
arr, _, ok := ReadArray(v.Data)
@@ -463,7 +534,7 @@ func (v Value) Array() Array {
// ArrayOK is the same as Array, except it returns a boolean instead
// of panicking.
func (v Value) ArrayOK() (Array, bool) {
- if v.Type != bsontype.Array {
+ if v.Type != TypeArray {
return nil, false
}
arr, _, ok := ReadArray(v.Data)
@@ -476,7 +547,7 @@ func (v Value) ArrayOK() (Array, bool) {
// Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
// other than binary.
func (v Value) Binary() (subtype byte, data []byte) {
- if v.Type != bsontype.Binary {
+ if v.Type != TypeBinary {
panic(ElementTypeError{"bsoncore.Value.Binary", v.Type})
}
subtype, data, _, ok := ReadBinary(v.Data)
@@ -489,7 +560,7 @@ func (v Value) Binary() (subtype byte, data []byte) {
// BinaryOK is the same as Binary, except it returns a boolean instead of
// panicking.
func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) {
- if v.Type != bsontype.Binary {
+ if v.Type != TypeBinary {
return 0x00, nil, false
}
subtype, data, _, ok = ReadBinary(v.Data)
@@ -501,8 +572,8 @@ func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) {
// ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON
// type other than objectid.
-func (v Value) ObjectID() primitive.ObjectID {
- if v.Type != bsontype.ObjectID {
+func (v Value) ObjectID() [12]byte {
+ if v.Type != TypeObjectID {
panic(ElementTypeError{"bsoncore.Value.ObjectID", v.Type})
}
oid, _, ok := ReadObjectID(v.Data)
@@ -514,13 +585,13 @@ func (v Value) ObjectID() primitive.ObjectID {
// ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
// panicking.
-func (v Value) ObjectIDOK() (primitive.ObjectID, bool) {
- if v.Type != bsontype.ObjectID {
- return primitive.ObjectID{}, false
+func (v Value) ObjectIDOK() ([12]byte, bool) {
+ if v.Type != TypeObjectID {
+ return objectID{}, false
}
oid, _, ok := ReadObjectID(v.Data)
if !ok {
- return primitive.ObjectID{}, false
+ return objectID{}, false
}
return oid, true
}
@@ -528,7 +599,7 @@ func (v Value) ObjectIDOK() (primitive.ObjectID, bool) {
// Boolean returns the boolean value the Value represents. It panics if the
// value is a BSON type other than boolean.
func (v Value) Boolean() bool {
- if v.Type != bsontype.Boolean {
+ if v.Type != TypeBoolean {
panic(ElementTypeError{"bsoncore.Value.Boolean", v.Type})
}
b, _, ok := ReadBoolean(v.Data)
@@ -541,7 +612,7 @@ func (v Value) Boolean() bool {
// BooleanOK is the same as Boolean, except it returns a boolean instead of
// panicking.
func (v Value) BooleanOK() (bool, bool) {
- if v.Type != bsontype.Boolean {
+ if v.Type != TypeBoolean {
return false, false
}
b, _, ok := ReadBoolean(v.Data)
@@ -554,7 +625,7 @@ func (v Value) BooleanOK() (bool, bool) {
// DateTime returns the BSON datetime value the Value represents as a
// unix timestamp. It panics if the value is a BSON type other than datetime.
func (v Value) DateTime() int64 {
- if v.Type != bsontype.DateTime {
+ if v.Type != TypeDateTime {
panic(ElementTypeError{"bsoncore.Value.DateTime", v.Type})
}
dt, _, ok := ReadDateTime(v.Data)
@@ -567,7 +638,7 @@ func (v Value) DateTime() int64 {
// DateTimeOK is the same as DateTime, except it returns a boolean instead of
// panicking.
func (v Value) DateTimeOK() (int64, bool) {
- if v.Type != bsontype.DateTime {
+ if v.Type != TypeDateTime {
return 0, false
}
dt, _, ok := ReadDateTime(v.Data)
@@ -580,7 +651,7 @@ func (v Value) DateTimeOK() (int64, bool) {
// Time returns the BSON datetime value the Value represents. It panics if the value is a BSON
// type other than datetime.
func (v Value) Time() time.Time {
- if v.Type != bsontype.DateTime {
+ if v.Type != TypeDateTime {
panic(ElementTypeError{"bsoncore.Value.Time", v.Type})
}
dt, _, ok := ReadDateTime(v.Data)
@@ -593,7 +664,7 @@ func (v Value) Time() time.Time {
// TimeOK is the same as Time, except it returns a boolean instead of
// panicking.
func (v Value) TimeOK() (time.Time, bool) {
- if v.Type != bsontype.DateTime {
+ if v.Type != TypeDateTime {
return time.Time{}, false
}
dt, _, ok := ReadDateTime(v.Data)
@@ -606,7 +677,7 @@ func (v Value) TimeOK() (time.Time, bool) {
// Regex returns the BSON regex value the Value represents. It panics if the value is a BSON
// type other than regex.
func (v Value) Regex() (pattern, options string) {
- if v.Type != bsontype.Regex {
+ if v.Type != TypeRegex {
panic(ElementTypeError{"bsoncore.Value.Regex", v.Type})
}
pattern, options, _, ok := ReadRegex(v.Data)
@@ -619,7 +690,7 @@ func (v Value) Regex() (pattern, options string) {
// RegexOK is the same as Regex, except it returns a boolean instead of
// panicking.
func (v Value) RegexOK() (pattern, options string, ok bool) {
- if v.Type != bsontype.Regex {
+ if v.Type != TypeRegex {
return "", "", false
}
pattern, options, _, ok = ReadRegex(v.Data)
@@ -631,8 +702,8 @@ func (v Value) RegexOK() (pattern, options string, ok bool) {
// DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON
// type other than DBPointer.
-func (v Value) DBPointer() (string, primitive.ObjectID) {
- if v.Type != bsontype.DBPointer {
+func (v Value) DBPointer() (string, [12]byte) {
+ if v.Type != TypeDBPointer {
panic(ElementTypeError{"bsoncore.Value.DBPointer", v.Type})
}
ns, pointer, _, ok := ReadDBPointer(v.Data)
@@ -644,13 +715,13 @@ func (v Value) DBPointer() (string, primitive.ObjectID) {
// DBPointerOK is the same as DBPoitner, except that it returns a boolean
// instead of panicking.
-func (v Value) DBPointerOK() (string, primitive.ObjectID, bool) {
- if v.Type != bsontype.DBPointer {
- return "", primitive.ObjectID{}, false
+func (v Value) DBPointerOK() (string, [12]byte, bool) {
+ if v.Type != TypeDBPointer {
+ return "", objectID{}, false
}
ns, pointer, _, ok := ReadDBPointer(v.Data)
if !ok {
- return "", primitive.ObjectID{}, false
+ return "", objectID{}, false
}
return ns, pointer, true
}
@@ -658,7 +729,7 @@ func (v Value) DBPointerOK() (string, primitive.ObjectID, bool) {
// JavaScript returns the BSON JavaScript code value the Value represents. It panics if the value is
// a BSON type other than JavaScript code.
func (v Value) JavaScript() string {
- if v.Type != bsontype.JavaScript {
+ if v.Type != TypeJavaScript {
panic(ElementTypeError{"bsoncore.Value.JavaScript", v.Type})
}
js, _, ok := ReadJavaScript(v.Data)
@@ -671,7 +742,7 @@ func (v Value) JavaScript() string {
// JavaScriptOK is the same as Javascript, excepti that it returns a boolean
// instead of panicking.
func (v Value) JavaScriptOK() (string, bool) {
- if v.Type != bsontype.JavaScript {
+ if v.Type != TypeJavaScript {
return "", false
}
js, _, ok := ReadJavaScript(v.Data)
@@ -684,7 +755,7 @@ func (v Value) JavaScriptOK() (string, bool) {
// Symbol returns the BSON symbol value the Value represents. It panics if the value is a BSON
// type other than symbol.
func (v Value) Symbol() string {
- if v.Type != bsontype.Symbol {
+ if v.Type != TypeSymbol {
panic(ElementTypeError{"bsoncore.Value.Symbol", v.Type})
}
symbol, _, ok := ReadSymbol(v.Data)
@@ -697,7 +768,7 @@ func (v Value) Symbol() string {
// SymbolOK is the same as Symbol, excepti that it returns a boolean
// instead of panicking.
func (v Value) SymbolOK() (string, bool) {
- if v.Type != bsontype.Symbol {
+ if v.Type != TypeSymbol {
return "", false
}
symbol, _, ok := ReadSymbol(v.Data)
@@ -710,7 +781,7 @@ func (v Value) SymbolOK() (string, bool) {
// CodeWithScope returns the BSON JavaScript code with scope the Value represents.
// It panics if the value is a BSON type other than JavaScript code with scope.
func (v Value) CodeWithScope() (string, Document) {
- if v.Type != bsontype.CodeWithScope {
+ if v.Type != TypeCodeWithScope {
panic(ElementTypeError{"bsoncore.Value.CodeWithScope", v.Type})
}
code, scope, _, ok := ReadCodeWithScope(v.Data)
@@ -723,7 +794,7 @@ func (v Value) CodeWithScope() (string, Document) {
// CodeWithScopeOK is the same as CodeWithScope, except that it returns a boolean instead of
// panicking.
func (v Value) CodeWithScopeOK() (string, Document, bool) {
- if v.Type != bsontype.CodeWithScope {
+ if v.Type != TypeCodeWithScope {
return "", nil, false
}
code, scope, _, ok := ReadCodeWithScope(v.Data)
@@ -736,7 +807,7 @@ func (v Value) CodeWithScopeOK() (string, Document, bool) {
// Int32 returns the int32 the Value represents. It panics if the value is a BSON type other than
// int32.
func (v Value) Int32() int32 {
- if v.Type != bsontype.Int32 {
+ if v.Type != TypeInt32 {
panic(ElementTypeError{"bsoncore.Value.Int32", v.Type})
}
i32, _, ok := ReadInt32(v.Data)
@@ -749,7 +820,7 @@ func (v Value) Int32() int32 {
// Int32OK is the same as Int32, except that it returns a boolean instead of
// panicking.
func (v Value) Int32OK() (int32, bool) {
- if v.Type != bsontype.Int32 {
+ if v.Type != TypeInt32 {
return 0, false
}
i32, _, ok := ReadInt32(v.Data)
@@ -762,7 +833,7 @@ func (v Value) Int32OK() (int32, bool) {
// Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
// BSON type other than timestamp.
func (v Value) Timestamp() (t, i uint32) {
- if v.Type != bsontype.Timestamp {
+ if v.Type != TypeTimestamp {
panic(ElementTypeError{"bsoncore.Value.Timestamp", v.Type})
}
t, i, _, ok := ReadTimestamp(v.Data)
@@ -775,7 +846,7 @@ func (v Value) Timestamp() (t, i uint32) {
// TimestampOK is the same as Timestamp, except that it returns a boolean
// instead of panicking.
func (v Value) TimestampOK() (t, i uint32, ok bool) {
- if v.Type != bsontype.Timestamp {
+ if v.Type != TypeTimestamp {
return 0, 0, false
}
t, i, _, ok = ReadTimestamp(v.Data)
@@ -788,7 +859,7 @@ func (v Value) TimestampOK() (t, i uint32, ok bool) {
// Int64 returns the int64 the Value represents. It panics if the value is a BSON type other than
// int64.
func (v Value) Int64() int64 {
- if v.Type != bsontype.Int64 {
+ if v.Type != TypeInt64 {
panic(ElementTypeError{"bsoncore.Value.Int64", v.Type})
}
i64, _, ok := ReadInt64(v.Data)
@@ -801,7 +872,7 @@ func (v Value) Int64() int64 {
// Int64OK is the same as Int64, except that it returns a boolean instead of
// panicking.
func (v Value) Int64OK() (int64, bool) {
- if v.Type != bsontype.Int64 {
+ if v.Type != TypeInt64 {
return 0, false
}
i64, _, ok := ReadInt64(v.Data)
@@ -813,28 +884,28 @@ func (v Value) Int64OK() (int64, bool) {
// Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than
// decimal.
-func (v Value) Decimal128() primitive.Decimal128 {
- if v.Type != bsontype.Decimal128 {
+func (v Value) Decimal128() (uint64, uint64) {
+ if v.Type != TypeDecimal128 {
panic(ElementTypeError{"bsoncore.Value.Decimal128", v.Type})
}
- d128, _, ok := ReadDecimal128(v.Data)
+ h, l, _, ok := ReadDecimal128(v.Data)
if !ok {
panic(NewInsufficientBytesError(v.Data, v.Data))
}
- return d128
+ return h, l
}
// Decimal128OK is the same as Decimal128, except that it returns a boolean
// instead of panicking.
-func (v Value) Decimal128OK() (primitive.Decimal128, bool) {
- if v.Type != bsontype.Decimal128 {
- return primitive.Decimal128{}, false
+func (v Value) Decimal128OK() (uint64, uint64, bool) {
+ if v.Type != TypeDecimal128 {
+ return 0, 0, false
}
- d128, _, ok := ReadDecimal128(v.Data)
+ h, l, _, ok := ReadDecimal128(v.Data)
if !ok {
- return primitive.Decimal128{}, false
+ return 0, 0, false
}
- return d128, true
+ return h, l, true
}
var hexChars = "0123456789abcdef"
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/auth.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/auth.go
similarity index 79%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/auth.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/auth.go
index 34a4a68f5..bfc7bbdb9 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/auth.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/auth.go
@@ -11,19 +11,18 @@ import (
"errors"
"fmt"
"net/http"
-
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "strings"
+
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
const sourceExternal = "$external"
-// Config contains the configuration for an Authenticator.
-type Config = driver.AuthConfig
-
// AuthenticatorFactory constructs an authenticator.
type AuthenticatorFactory func(*Cred, *http.Client) (Authenticator, error)
@@ -33,7 +32,6 @@ func init() {
RegisterAuthenticatorFactory("", newDefaultAuthenticator)
RegisterAuthenticatorFactory(SCRAMSHA1, newScramSHA1Authenticator)
RegisterAuthenticatorFactory(SCRAMSHA256, newScramSHA256Authenticator)
- RegisterAuthenticatorFactory(MONGODBCR, newMongoDBCRAuthenticator)
RegisterAuthenticatorFactory(PLAIN, newPlainAuthenticator)
RegisterAuthenticatorFactory(GSSAPI, newGSSAPIAuthenticator)
RegisterAuthenticatorFactory(MongoDBX509, newMongoDBX509Authenticator)
@@ -43,6 +41,12 @@ func init() {
// CreateAuthenticator creates an authenticator.
func CreateAuthenticator(name string, cred *Cred, httpClient *http.Client) (Authenticator, error) {
+ // Return a custom error to indicate why auth mechanism "MONGODB-CR" is
+ // missing, even though it was previously available.
+ if strings.EqualFold(name, "MONGODB-CR") {
+ return nil, errors.New(`auth mechanism "MONGODB-CR" is no longer available in any supported version of MongoDB`)
+ }
+
if f, ok := authFactories[name]; ok {
return f(cred, httpClient)
}
@@ -67,6 +71,11 @@ type HandshakeOptions struct {
ClusterClock *session.ClusterClock
ServerAPI *driver.ServerAPIOptions
LoadBalanced bool
+
+ // Fields provided by a library that wraps the Go Driver.
+ OuterLibraryName string
+ OuterLibraryVersion string
+ OuterLibraryPlatform string
}
type authHandshaker struct {
@@ -81,7 +90,11 @@ var _ driver.Handshaker = (*authHandshaker)(nil)
// GetHandshakeInformation performs the initial MongoDB handshake to retrieve the required information for the provided
// connection.
-func (ah *authHandshaker) GetHandshakeInformation(ctx context.Context, addr address.Address, conn driver.Connection) (driver.HandshakeInformation, error) {
+func (ah *authHandshaker) GetHandshakeInformation(
+ ctx context.Context,
+ addr address.Address,
+ conn *mnet.Connection,
+) (driver.HandshakeInformation, error) {
if ah.wrapped != nil {
return ah.wrapped.GetHandshakeInformation(ctx, addr, conn)
}
@@ -92,7 +105,10 @@ func (ah *authHandshaker) GetHandshakeInformation(ctx context.Context, addr addr
SASLSupportedMechs(ah.options.DBUser).
ClusterClock(ah.options.ClusterClock).
ServerAPI(ah.options.ServerAPI).
- LoadBalanced(ah.options.LoadBalanced)
+ LoadBalanced(ah.options.LoadBalanced).
+ OuterLibraryName(ah.options.OuterLibraryName).
+ OuterLibraryVersion(ah.options.OuterLibraryVersion).
+ OuterLibraryPlatform(ah.options.OuterLibraryPlatform)
if ah.options.Authenticator != nil {
if speculativeAuth, ok := ah.options.Authenticator.(SpeculativeAuthenticator); ok {
@@ -125,19 +141,17 @@ func (ah *authHandshaker) GetHandshakeInformation(ctx context.Context, addr addr
}
// FinishHandshake performs authentication for conn if necessary.
-func (ah *authHandshaker) FinishHandshake(ctx context.Context, conn driver.Connection) error {
+func (ah *authHandshaker) FinishHandshake(ctx context.Context, conn *mnet.Connection) error {
performAuth := ah.options.PerformAuthentication
if performAuth == nil {
performAuth = func(serv description.Server) bool {
// Authentication is possible against all server types except arbiters
- return serv.Kind != description.RSArbiter
+ return serv.Kind != description.ServerKindRSArbiter
}
}
- desc := conn.Description()
- if performAuth(desc) && ah.options.Authenticator != nil {
- cfg := &Config{
- Description: desc,
+ if performAuth(conn.Description()) && ah.options.Authenticator != nil {
+ cfg := &driver.AuthConfig{
Connection: conn,
ClusterClock: ah.options.ClusterClock,
HandshakeInfo: ah.handshakeInfo,
@@ -155,7 +169,7 @@ func (ah *authHandshaker) FinishHandshake(ctx context.Context, conn driver.Conne
return ah.wrapped.FinishHandshake(ctx, conn)
}
-func (ah *authHandshaker) authenticate(ctx context.Context, cfg *Config) error {
+func (ah *authHandshaker) authenticate(ctx context.Context, cfg *driver.AuthConfig) error {
// If the initial hello reply included a response to the speculative authentication attempt, we only need to
// conduct the remainder of the conversation.
if speculativeResponse := ah.handshakeInfo.SpeculativeAuthenticate; speculativeResponse != nil {
@@ -179,6 +193,15 @@ func Handshaker(h driver.Handshaker, options *HandshakeOptions) driver.Handshake
}
}
+// Config holds the information necessary to perform an authentication attempt.
+type Config struct {
+ Connection *mnet.Connection
+ ClusterClock *session.ClusterClock
+ HandshakeInfo driver.HandshakeInformation
+ ServerAPI *driver.ServerAPIOptions
+ HTTPClient *http.Client
+}
+
// Authenticator handles authenticating a connection.
type Authenticator = driver.Authenticator
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/aws_conv.go
similarity index 92%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/aws_conv.go
index 616182d9c..06dd04376 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/aws_conv.go
@@ -17,11 +17,10 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
- v4signer "go.mongodb.org/mongo-driver/internal/aws/signer/v4"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
+ v4signer "go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
type clientState int
@@ -41,8 +40,8 @@ type awsConversation struct {
}
type serverMessage struct {
- Nonce primitive.Binary `bson:"s"`
- Host string `bson:"h"`
+ Nonce bson.Binary `bson:"s"`
+ Host string `bson:"h"`
}
const (
@@ -69,7 +68,7 @@ func (ac *awsConversation) Step(challenge []byte) (response []byte, err error) {
ac.state = clientDone
ac.valid = true
default:
- response, err = nil, errors.New("Conversation already completed")
+ response, err = nil, errors.New("conversation already completed")
}
return
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/conversation.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/conversation.go
similarity index 84%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/conversation.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/conversation.go
index fe8f472c9..13839d7f8 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/conversation.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/conversation.go
@@ -9,7 +9,8 @@ package auth
import (
"context"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
// SpeculativeConversation represents an authentication conversation that can be merged with the initial connection
@@ -22,7 +23,7 @@ import (
// authenticate the provided connection.
type SpeculativeConversation interface {
FirstMessage() (bsoncore.Document, error)
- Finish(ctx context.Context, cfg *Config, firstResponse bsoncore.Document) error
+ Finish(ctx context.Context, cfg *driver.AuthConfig, firstResponse bsoncore.Document) error
}
// SpeculativeAuthenticator represents an authenticator that supports speculative authentication.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/cred.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/cred.go
similarity index 87%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/cred.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/cred.go
index a9685f6ed..ed3377738 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/cred.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/cred.go
@@ -7,7 +7,7 @@
package auth
import (
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
// Cred is the type of user credential
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/awscreds.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/awscreds.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/awscreds.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/awscreds.go
index 06bba4534..36595c209 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/awscreds.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/awscreds.go
@@ -11,9 +11,9 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
- "go.mongodb.org/mongo-driver/internal/credproviders"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/credproviders"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
const (
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/azurecreds.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/azurecreds.go
similarity index 86%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/azurecreds.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/azurecreds.go
index d8f105a9d..c6d4b473a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/azurecreds.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/azurecreds.go
@@ -11,9 +11,9 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
- "go.mongodb.org/mongo-driver/internal/credproviders"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/credproviders"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// AzureCredentialProvider provides Azure credentials.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/gcpcreds.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/gcpcreds.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/gcpcreds.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/gcpcreds.go
index 74f352e36..f265bf857 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds/gcpcreds.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/gcpcreds.go
@@ -14,7 +14,7 @@ import (
"net/http"
"os"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// GCPCredentialProvider provides GCP credentials.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/default.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/default.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/default.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/default.go
index 785a41951..0033379df 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/default.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/default.go
@@ -11,7 +11,7 @@ import (
"fmt"
"net/http"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
func newDefaultAuthenticator(cred *Cred, httpClient *http.Client) (Authenticator, error) {
@@ -32,8 +32,8 @@ func newDefaultAuthenticator(cred *Cred, httpClient *http.Client) (Authenticator
}, nil
}
-// DefaultAuthenticator uses SCRAM-SHA-1 or MONGODB-CR depending
-// on the server version.
+// DefaultAuthenticator uses SCRAM-SHA-1 or SCRAM-SHA-256, depending on the
+// server's SASL supported mechanisms.
type DefaultAuthenticator struct {
Cred *Cred
@@ -52,19 +52,21 @@ func (a *DefaultAuthenticator) CreateSpeculativeConversation() (SpeculativeConve
}
// Auth authenticates the connection.
-func (a *DefaultAuthenticator) Auth(ctx context.Context, cfg *Config) error {
- var actual Authenticator
- var err error
-
- switch chooseAuthMechanism(cfg) {
- case SCRAMSHA256:
- actual, err = newScramSHA256Authenticator(a.Cred, a.httpClient)
- case SCRAMSHA1:
- actual, err = newScramSHA1Authenticator(a.Cred, a.httpClient)
- default:
- actual, err = newMongoDBCRAuthenticator(a.Cred, a.httpClient)
- }
+func (a *DefaultAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
+ actual, err := func() (Authenticator, error) {
+ // If a server provides a list of supported mechanisms, we choose
+ // SCRAM-SHA-256 if it exists or else MUST use SCRAM-SHA-1.
+ // Otherwise, we decide based on what is supported.
+ if saslSupportedMechs := cfg.HandshakeInfo.SaslSupportedMechs; saslSupportedMechs != nil {
+ for _, v := range saslSupportedMechs {
+ if v == SCRAMSHA256 {
+ return newScramSHA256Authenticator(a.Cred, a.httpClient)
+ }
+ }
+ }
+ return newScramSHA1Authenticator(a.Cred, a.httpClient)
+ }()
if err != nil {
return newAuthError("error creating authenticator", err)
}
@@ -76,18 +78,3 @@ func (a *DefaultAuthenticator) Auth(ctx context.Context, cfg *Config) error {
func (a *DefaultAuthenticator) Reauth(_ context.Context, _ *driver.AuthConfig) error {
return newAuthError("DefaultAuthenticator does not support reauthentication", nil)
}
-
-// If a server provides a list of supported mechanisms, we choose
-// SCRAM-SHA-256 if it exists or else MUST use SCRAM-SHA-1.
-// Otherwise, we decide based on what is supported.
-func chooseAuthMechanism(cfg *Config) string {
- if saslSupportedMechs := cfg.HandshakeInfo.SaslSupportedMechs; saslSupportedMechs != nil {
- for _, v := range saslSupportedMechs {
- if v == SCRAMSHA256 {
- return v
- }
- }
- }
-
- return SCRAMSHA1
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi.go
similarity index 85%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi.go
index b342e9a7d..dd2a64d40 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi.go
@@ -5,8 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build gssapi && (windows || linux || darwin)
-// +build gssapi
-// +build windows linux darwin
package auth
@@ -16,8 +14,8 @@ import (
"net"
"net/http"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi"
)
// GSSAPI is the mechanism name for GSSAPI.
@@ -45,15 +43,14 @@ type GSSAPIAuthenticator struct {
}
// Auth authenticates the connection.
-func (a *GSSAPIAuthenticator) Auth(ctx context.Context, cfg *Config) error {
- target := cfg.Description.Addr.String()
+func (a *GSSAPIAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
+ target := cfg.Connection.Description().Addr.String()
hostname, _, err := net.SplitHostPort(target)
if err != nil {
return newAuthError(fmt.Sprintf("invalid endpoint (%s) specified: %s", target, err), nil)
}
client, err := gssapi.New(hostname, a.Username, a.Password, a.PasswordSet, a.Props)
-
if err != nil {
return newAuthError("error creating gssapi", err)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_enabled.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_enabled.go
index e50553c7a..2f4541210 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_enabled.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !gssapi
-// +build !gssapi
package auth
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_supported.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_supported.go
index 12046ff67..b53f2df31 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_supported.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build gssapi && !windows && !linux && !darwin
-// +build gssapi,!windows,!linux,!darwin
package auth
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss.go
index 496057882..43f6d9323 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss.go
@@ -18,6 +18,7 @@ package gssapi
#include "gss_wrapper.h"
*/
import "C"
+
import (
"context"
"fmt"
@@ -98,7 +99,6 @@ func (sc *SaslClient) Start() (string, []byte, error) {
}
func (sc *SaslClient) Next(_ context.Context, challenge []byte) ([]byte, error) {
-
var buf unsafe.Pointer
var bufLen C.size_t
var outBuf unsafe.Pointer
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi.go
index f1da5a852..a8b0ad5a6 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi.go
@@ -11,6 +11,7 @@ package gssapi
// #include "sspi_wrapper.h"
import "C"
+
import (
"context"
"fmt"
@@ -122,7 +123,6 @@ func (sc *SaslClient) Start() (string, []byte, error) {
}
func (sc *SaslClient) Next(_ context.Context, challenge []byte) ([]byte, error) {
-
var outBuf C.PVOID
var outBufLen C.ULONG
@@ -181,8 +181,10 @@ func (sc *SaslClient) getError(prefix string) error {
return getError(prefix, sc.state.status)
}
-var initOnce sync.Once
-var initError error
+var (
+ initOnce sync.Once
+ initError error
+)
func initSSPI() {
rc := C.sspi_init()
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbaws.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongodbaws.go
similarity index 90%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbaws.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongodbaws.go
index 679c54e9f..dd9661e1a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbaws.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongodbaws.go
@@ -11,10 +11,10 @@ import (
"errors"
"net/http"
- "go.mongodb.org/mongo-driver/internal/aws/credentials"
- "go.mongodb.org/mongo-driver/internal/credproviders"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds"
+ "go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
+ "go.mongodb.org/mongo-driver/v2/internal/credproviders"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds"
)
// MongoDBAWS is the mechanism name for MongoDBAWS.
@@ -46,7 +46,7 @@ type MongoDBAWSAuthenticator struct {
}
// Auth authenticates the connection.
-func (a *MongoDBAWSAuthenticator) Auth(ctx context.Context, cfg *Config) error {
+func (a *MongoDBAWSAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
providers := creds.NewAWSCredentialProvider(a.httpClient, a.credentials)
adapter := &awsSaslAdapter{
conversation: &awsConversation{
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/oidc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/oidc.go
similarity index 82%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/oidc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/oidc.go
index 13fd10ec3..571f3f396 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/oidc.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/oidc.go
@@ -13,46 +13,59 @@ import (
"io"
"net/http"
"net/url"
+ "os"
"regexp"
"strings"
"sync"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
)
// MongoDBOIDC is the string constant for the MONGODB-OIDC authentication mechanism.
const MongoDBOIDC = "MONGODB-OIDC"
-// EnvironmentProp is the property key name that specifies the environment for the OIDC authenticator.
-const EnvironmentProp = "ENVIRONMENT"
+// Valid authMechanismProperties keys for MONGODB-OIDC.
+const (
+ // EnvironmentProp is the property key name that specifies the environment for the OIDC authenticator.
+ EnvironmentProp = "ENVIRONMENT"
-// ResourceProp is the property key name that specifies the token resource for GCP and AZURE OIDC auth.
-const ResourceProp = "TOKEN_RESOURCE"
+ // ResourceProp is the property key name that specifies the token resource for GCP and AZURE OIDC auth.
+ ResourceProp = "TOKEN_RESOURCE"
-// AllowedHostsProp is the property key name that specifies the allowed hosts for the OIDC authenticator.
-const AllowedHostsProp = "ALLOWED_HOSTS"
+ // AllowedHostsProp is the property key name that specifies the allowed hosts for the OIDC authenticator.
+ AllowedHostsProp = "ALLOWED_HOSTS"
+)
+
+// Valid ENVIRONMENT authMechismProperty values for MONGODB-OIDC.
+const (
+ // AzureEnvironmentValue is the value for the Azure environment.
+ AzureEnvironmentValue = "azure"
-// AzureEnvironmentValue is the value for the Azure environment.
-const AzureEnvironmentValue = "azure"
+ // GCPEnvironmentValue is the value for the GCP environment.
+ GCPEnvironmentValue = "gcp"
-// GCPEnvironmentValue is the value for the GCP environment.
-const GCPEnvironmentValue = "gcp"
+ // K8SEnvironmentValue is the value for Kubernetes environments.
+ K8SEnvironmentValue = "k8s"
-// TestEnvironmentValue is the value for the test environment.
-const TestEnvironmentValue = "test"
+ // TestEnvironmentValue is the value for the test environment.
+ TestEnvironmentValue = "test"
+)
-const apiVersion = 1
-const invalidateSleepTimeout = 100 * time.Millisecond
+const (
+ apiVersion = 1
+ invalidateSleepTimeout = 100 * time.Millisecond
-// The CSOT specification says to apply a 1-minute timeout if "CSOT is not applied". That's
-// ambiguous for the v1.x Go Driver because it could mean either "no timeout provided" or "CSOT not
-// enabled". Always use a maximum timeout duration of 1 minute, allowing us to ignore the ambiguity.
-// Contexts with a shorter timeout are unaffected.
-const machineCallbackTimeout = time.Minute
-const humanCallbackTimeout = 5 * time.Minute
+ // The CSOT specification says to apply a 1-minute timeout if "CSOT is not applied". That's
+ // ambiguous for the v1.x Go Driver because it could mean either "no timeout provided" or "CSOT not
+ // enabled". Always use a maximum timeout duration of 1 minute, allowing us to ignore the ambiguity.
+ // Contexts with a shorter timeout are unaffected.
+ machineCallbackTimeout = time.Minute
+ humanCallbackTimeout = 5 * time.Minute
+)
var defaultAllowedHosts = []*regexp.Regexp{
regexp.MustCompile(`^.*[.]mongodb[.]net(:\d+)?$`),
@@ -62,6 +75,7 @@ var defaultAllowedHosts = []*regexp.Regexp{
regexp.MustCompile(`^localhost(:\d+)?$`),
regexp.MustCompile(`^127[.]0[.]0[.]1(:\d+)?$`),
regexp.MustCompile(`^::1(:\d+)?$`),
+ regexp.MustCompile(`^.*[.]mongo[.]com(:\d+)?$`),
}
// OIDCCallback is a function that takes a context and OIDCArgs and returns an OIDCCredential.
@@ -76,10 +90,12 @@ type OIDCCredential = driver.OIDCCredential
// IDPInfo contains the information needed to perform OIDC authentication with an Identity Provider.
type IDPInfo = driver.IDPInfo
-var _ driver.Authenticator = (*OIDCAuthenticator)(nil)
-var _ SpeculativeAuthenticator = (*OIDCAuthenticator)(nil)
-var _ SaslClient = (*oidcOneStep)(nil)
-var _ SaslClient = (*oidcTwoStep)(nil)
+var (
+ _ driver.Authenticator = (*OIDCAuthenticator)(nil)
+ _ SpeculativeAuthenticator = (*OIDCAuthenticator)(nil)
+ _ SaslClient = (*oidcOneStep)(nil)
+ _ SaslClient = (*oidcTwoStep)(nil)
+)
// OIDCAuthenticator is synchronized and handles caching of the access token, refreshToken,
// and IDPInfo. It also provides a mechanism to refresh the access token, but this functionality
@@ -118,14 +134,12 @@ func newOIDCAuthenticator(cred *Cred, httpClient *http.Client) (Authenticator, e
if cred.Props != nil {
if env, ok := cred.Props[EnvironmentProp]; ok {
switch strings.ToLower(env) {
- case AzureEnvironmentValue:
- fallthrough
- case GCPEnvironmentValue:
+ case AzureEnvironmentValue, GCPEnvironmentValue:
if _, ok := cred.Props[ResourceProp]; !ok {
return nil, fmt.Errorf("%q must be specified for %q %q", ResourceProp, env, EnvironmentProp)
}
fallthrough
- case TestEnvironmentValue:
+ case K8SEnvironmentValue, TestEnvironmentValue:
if cred.OIDCMachineCallback != nil || cred.OIDCHumanCallback != nil {
return nil, fmt.Errorf("OIDC callbacks are not allowed for %q %q", env, EnvironmentProp)
}
@@ -178,7 +192,7 @@ func (oa *OIDCAuthenticator) setAllowedHosts() error {
return nil
}
-func (oa *OIDCAuthenticator) validateConnectionAddressWithAllowedHosts(conn driver.Connection) error {
+func (oa *OIDCAuthenticator) validateConnectionAddressWithAllowedHosts(conn *mnet.Connection) error {
if oa.allowedHosts == nil {
// should be unreachable, but this is a safety check.
return newAuthError(fmt.Sprintf("%q missing", AllowedHostsProp), nil)
@@ -201,7 +215,7 @@ type oidcOneStep struct {
}
type oidcTwoStep struct {
- conn driver.Connection
+ conn *mnet.Connection
oa *OIDCAuthenticator
}
@@ -280,6 +294,8 @@ func (oa *OIDCAuthenticator) providerCallback() (OIDCCallback, error) {
return nil, newAuthError(fmt.Sprintf("%q must be specified for GCP OIDC", ResourceProp), nil)
}
return getGCPOIDCCallback(resource, oa.httpClient), nil
+ case K8SEnvironmentValue:
+ return k8sOIDCCallback, nil
}
return nil, fmt.Errorf("%q %q not supported for MONGODB-OIDC", EnvironmentProp, env)
@@ -359,9 +375,32 @@ func getGCPOIDCCallback(resource string, httpClient *http.Client) OIDCCallback {
}
}
+// k8sOIDCCallbackfunc is the callback for the Kubernetes token provider.
+func k8sOIDCCallback(context.Context, *OIDCArgs) (*OIDCCredential, error) {
+ // Check for the presence of the Azure and AWS token file path environment
+ // variables. If neither are set, use the GKE default token file path.
+ var path string
+ if p := os.Getenv("AZURE_FEDERATED_TOKEN_FILE"); p != "" {
+ path = p
+ } else if p := os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE"); p != "" {
+ path = p
+ } else {
+ path = "/var/run/secrets/kubernetes.io/serviceaccount/token"
+ }
+
+ token, err := os.ReadFile(path)
+ if err != nil {
+ return nil, fmt.Errorf("error reading OIDC token from %q: %w", path, err)
+ }
+
+ return &OIDCCredential{
+ AccessToken: string(token),
+ }, nil
+}
+
func (oa *OIDCAuthenticator) getAccessToken(
ctx context.Context,
- conn driver.Connection,
+ conn *mnet.Connection,
args *OIDCArgs,
callback OIDCCallback,
) (string, error) {
@@ -412,7 +451,7 @@ func (oa *OIDCAuthenticator) getAccessToken(
// tokenGenID of the OIDCAuthenticator. It should never actually be greater than, but only equal,
// but this is a safety check, since extra invalidation is only a performance impact, not a
// correctness impact.
-func (oa *OIDCAuthenticator) invalidateAccessToken(conn driver.Connection) {
+func (oa *OIDCAuthenticator) invalidateAccessToken(conn *mnet.Connection) {
oa.mu.Lock()
defer oa.mu.Unlock()
tokenGenID := conn.OIDCTokenGenID()
@@ -427,13 +466,13 @@ func (oa *OIDCAuthenticator) invalidateAccessToken(conn driver.Connection) {
// Reauth reauthenticates the connection when the server returns a 391 code. Reauth is part of the
// driver.Authenticator interface.
-func (oa *OIDCAuthenticator) Reauth(ctx context.Context, cfg *Config) error {
+func (oa *OIDCAuthenticator) Reauth(ctx context.Context, cfg *driver.AuthConfig) error {
oa.invalidateAccessToken(cfg.Connection)
return oa.Auth(ctx, cfg)
}
// Auth authenticates the connection.
-func (oa *OIDCAuthenticator) Auth(ctx context.Context, cfg *Config) error {
+func (oa *OIDCAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
var err error
if cfg == nil {
@@ -483,7 +522,7 @@ func (oa *OIDCAuthenticator) Auth(ctx context.Context, cfg *Config) error {
return newAuthError("no OIDC callback provided", nil)
}
-func (oa *OIDCAuthenticator) doAuthHuman(ctx context.Context, cfg *Config, humanCallback OIDCCallback, idpInfo *IDPInfo, refreshToken *string) error {
+func (oa *OIDCAuthenticator) doAuthHuman(ctx context.Context, cfg *driver.AuthConfig, humanCallback OIDCCallback, idpInfo *IDPInfo, refreshToken *string) error {
// Ensure that the connection address is allowed by the allowed hosts.
err := oa.validateConnectionAddressWithAllowedHosts(cfg.Connection)
if err != nil {
@@ -520,7 +559,7 @@ func (oa *OIDCAuthenticator) doAuthHuman(ctx context.Context, cfg *Config, human
return ConductSaslConversation(subCtx, cfg, sourceExternal, ots)
}
-func (oa *OIDCAuthenticator) doAuthMachine(ctx context.Context, cfg *Config, machineCallback OIDCCallback) error {
+func (oa *OIDCAuthenticator) doAuthMachine(ctx context.Context, cfg *driver.AuthConfig, machineCallback OIDCCallback) error {
subCtx, cancel := context.WithTimeout(ctx, machineCallbackTimeout)
accessToken, err := oa.getAccessToken(subCtx,
cfg.Connection,
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/plain.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/plain.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/plain.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/plain.go
index fb0645aaa..69342bb1e 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/plain.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/plain.go
@@ -10,7 +10,7 @@ import (
"context"
"net/http"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
// PLAIN is the mechanism name for PLAIN.
@@ -45,7 +45,7 @@ type PlainAuthenticator struct {
}
// Auth authenticates the connection.
-func (a *PlainAuthenticator) Auth(ctx context.Context, cfg *Config) error {
+func (a *PlainAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
return ConductSaslConversation(ctx, cfg, sourceExternal, &plainSaslClient{
username: a.Username,
password: a.Password,
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/sasl.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/sasl.go
similarity index 92%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/sasl.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/sasl.go
index 1ef67f02b..659fe45e2 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/sasl.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/sasl.go
@@ -10,10 +10,10 @@ import (
"context"
"fmt"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
)
// SaslClient is the client piece of a sasl conversation.
@@ -94,7 +94,7 @@ type saslResponse struct {
}
// Finish completes the conversation based on the first server response to authenticate the given connection.
-func (sc *saslConversation) Finish(ctx context.Context, cfg *Config, firstResponse bsoncore.Document) error {
+func (sc *saslConversation) Finish(ctx context.Context, cfg *driver.AuthConfig, firstResponse bsoncore.Document) error {
if closer, ok := sc.client.(SaslClientCloser); ok {
defer closer.Close()
}
@@ -153,7 +153,7 @@ func (sc *saslConversation) Finish(ctx context.Context, cfg *Config, firstRespon
}
// ConductSaslConversation runs a full SASL conversation to authenticate the given connection.
-func ConductSaslConversation(ctx context.Context, cfg *Config, authSource string, client SaslClient) error {
+func ConductSaslConversation(ctx context.Context, cfg *driver.AuthConfig, authSource string, client SaslClient) error {
// Create a non-speculative SASL conversation.
conversation := newSaslConversation(client, authSource, false)
saslStartDoc, err := conversation.FirstMessage()
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/scram.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/scram.go
similarity index 87%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/scram.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/scram.go
index 0d7deaee0..c6440b3a1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/scram.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/scram.go
@@ -18,8 +18,8 @@ import (
"github.com/xdg-go/scram"
"github.com/xdg-go/stringprep"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
const (
@@ -30,11 +30,9 @@ const (
SCRAMSHA256 = "SCRAM-SHA-256"
)
-var (
- // Additional options for the saslStart command to enable a shorter SCRAM conversation
- scramStartOptions bsoncore.Document = bsoncore.BuildDocumentFromElements(nil,
- bsoncore.AppendBooleanElement(nil, "skipEmptyExchange", true),
- )
+// Additional options for the saslStart command to enable a shorter SCRAM conversation
+var scramStartOptions bsoncore.Document = bsoncore.BuildDocumentFromElements(nil,
+ bsoncore.AppendBooleanElement(nil, "skipEmptyExchange", true),
)
func newScramSHA1Authenticator(cred *Cred, _ *http.Client) (Authenticator, error) {
@@ -86,7 +84,7 @@ type ScramAuthenticator struct {
var _ SpeculativeAuthenticator = (*ScramAuthenticator)(nil)
// Auth authenticates the provided connection by conducting a full SASL conversation.
-func (a *ScramAuthenticator) Auth(ctx context.Context, cfg *Config) error {
+func (a *ScramAuthenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
err := ConductSaslConversation(ctx, cfg, a.source, a.createSaslClient())
if err != nil {
return newAuthError("sasl conversation error", err)
@@ -116,8 +114,10 @@ type scramSaslAdapter struct {
conversation *scram.ClientConversation
}
-var _ SaslClient = (*scramSaslAdapter)(nil)
-var _ ExtraOptionsSaslClient = (*scramSaslAdapter)(nil)
+var (
+ _ SaslClient = (*scramSaslAdapter)(nil)
+ _ ExtraOptionsSaslClient = (*scramSaslAdapter)(nil)
+)
func (a *scramSaslAdapter) Start() (string, []byte, error) {
step, err := a.conversation.Step("")
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/util.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/util.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/util.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/util.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/x509.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/x509.go
similarity index 90%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/x509.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/x509.go
index 1b84e00b4..f83902343 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/x509.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/x509.go
@@ -10,9 +10,9 @@ import (
"context"
"net/http"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
)
// MongoDBX509 is the mechanism name for MongoDBX509.
@@ -55,7 +55,7 @@ func createFirstX509Message() bsoncore.Document {
// Finish implements the SpeculativeConversation interface and is a no-op because an X509 conversation only has one
// step.
-func (c *x509Conversation) Finish(context.Context, *Config, bsoncore.Document) error {
+func (c *x509Conversation) Finish(context.Context, *driver.AuthConfig, bsoncore.Document) error {
return nil
}
@@ -65,7 +65,7 @@ func (a *MongoDBX509Authenticator) CreateSpeculativeConversation() (SpeculativeC
}
// Auth authenticates the provided connection by conducting an X509 authentication conversation.
-func (a *MongoDBX509Authenticator) Auth(ctx context.Context, cfg *Config) error {
+func (a *MongoDBX509Authenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error {
requestDoc := createFirstX509Message()
authCmd := operation.
NewCommand(requestDoc).
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batch_cursor.go
similarity index 66%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batch_cursor.go
index 2aa0aca69..564981c7f 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batch_cursor.go
@@ -14,14 +14,15 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/codecutil"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/codecutil"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// ErrNoCursor is returned by NewCursorResponse when the database response does
@@ -33,7 +34,7 @@ var ErrNoCursor = errors.New("database response does not contain a cursor")
type BatchCursor struct {
clientSession *session.Client
clock *session.ClusterClock
- comment interface{}
+ comment any
encoderFn codecutil.EncoderFn
database string
collection string
@@ -42,16 +43,22 @@ type BatchCursor struct {
server Server
serverDescription description.Server
errorProcessor ErrorProcessor // This will only be set when pinning to a connection.
- connection PinnedConnection
+ connection *mnet.Connection
batchSize int32
- maxTimeMS int64
- currentBatch *bsoncore.DocumentSequence
+ currentBatch *bsoncore.Iterator
firstBatch bool
cmdMonitor *event.CommandMonitor
postBatchResumeToken bsoncore.Document
crypt Crypt
serverAPI *ServerAPIOptions
+ // maxAwaitTime is only valid for tailable awaitData cursors. If this option
+ // is set, it will be used as the "maxTimeMS" field on getMore commands.
+ maxAwaitTime *time.Duration
+
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+
// legacy server (< 3.2) fields
limit int32
numReturned int32 // number of docs returned by server
@@ -62,34 +69,38 @@ type BatchCursor struct {
type CursorResponse struct {
Server Server
ErrorProcessor ErrorProcessor // This will only be set when pinning to a connection.
- Connection PinnedConnection
+ Connection *mnet.Connection
Desc description.Server
- FirstBatch *bsoncore.DocumentSequence
+ FirstBatch *bsoncore.Iterator
Database string
Collection string
ID int64
postBatchResumeToken bsoncore.Document
}
-// NewCursorResponse constructs a cursor response from the given response and
-// server. If the provided database response does not contain a cursor, it
-// returns ErrNoCursor.
-//
-// NewCursorResponse can be used within the ProcessResponse method for an operation.
-func NewCursorResponse(info ResponseInfo) (CursorResponse, error) {
- response := info.ServerResponse
+// ExtractCursorDocument retrieves cursor document from a database response. If the
+// provided response does not contain a cursor, it returns ErrNoCursor.
+func ExtractCursorDocument(response bsoncore.Document) (bsoncore.Document, error) {
cur, err := response.LookupErr("cursor")
if errors.Is(err, bsoncore.ErrElementNotFound) {
- return CursorResponse{}, ErrNoCursor
+ return nil, ErrNoCursor
}
if err != nil {
- return CursorResponse{}, fmt.Errorf("error getting cursor from database response: %w", err)
+ return nil, fmt.Errorf("error getting cursor from database response: %w", err)
}
curDoc, ok := cur.DocumentOK()
if !ok {
- return CursorResponse{}, fmt.Errorf("cursor should be an embedded document but is BSON type %s", cur.Type)
+ return nil, fmt.Errorf("cursor should be an embedded document but is BSON type %s", cur.Type)
}
- elems, err := curDoc.Elements()
+ return curDoc, nil
+}
+
+// NewCursorResponse constructs a cursor response from the given cursor document
+// extracted from a database response.
+//
+// NewCursorResponse can be used within the ProcessResponse method for an operation.
+func NewCursorResponse(response bsoncore.Document, info ResponseInfo) (CursorResponse, error) {
+ elems, err := response.Elements()
if err != nil {
return CursorResponse{}, fmt.Errorf("error getting elements from cursor: %w", err)
}
@@ -102,7 +113,8 @@ func NewCursorResponse(info ResponseInfo) (CursorResponse, error) {
if !ok {
return CursorResponse{}, fmt.Errorf("firstBatch should be an array but is a BSON %s", elem.Value().Type)
}
- curresp.FirstBatch = &bsoncore.DocumentSequence{Style: bsoncore.ArrayStyle, Data: arr}
+
+ curresp.FirstBatch = &bsoncore.Iterator{List: arr}
case "ns":
ns, ok := elem.Value().StringValueOK()
if !ok {
@@ -115,21 +127,23 @@ func NewCursorResponse(info ResponseInfo) (CursorResponse, error) {
curresp.Database = database
curresp.Collection = collection
case "id":
- curresp.ID, ok = elem.Value().Int64OK()
+ id, ok := elem.Value().Int64OK()
if !ok {
return CursorResponse{}, fmt.Errorf("id should be an int64 but it is a BSON %s", elem.Value().Type)
}
+ curresp.ID = id
case "postBatchResumeToken":
- curresp.postBatchResumeToken, ok = elem.Value().DocumentOK()
+ token, ok := elem.Value().DocumentOK()
if !ok {
return CursorResponse{}, fmt.Errorf("post batch resume token should be a document but it is a BSON %s", elem.Value().Type)
}
+ curresp.postBatchResumeToken = token
}
}
// If the deployment is behind a load balancer and the cursor has a non-zero ID, pin the cursor to a connection and
// use the same connection to execute getMore and killCursors commands.
- if curresp.Desc.LoadBalanced() && curresp.ID != 0 {
+ if driverutil.IsServerLoadBalanced(curresp.Desc) && curresp.ID != 0 {
// Cache the server as an ErrorProcessor to use when constructing deployments for cursor commands.
ep, ok := curresp.Server.(ErrorProcessor)
if !ok {
@@ -137,14 +151,14 @@ func NewCursorResponse(info ResponseInfo) (CursorResponse, error) {
}
curresp.ErrorProcessor = ep
- refConn, ok := info.Connection.(PinnedConnection)
- if !ok {
+ refConn := info.Connection.Pinner
+ if refConn == nil {
return CursorResponse{}, fmt.Errorf("expected Connection used to establish a cursor to implement PinnedConnection, but got %T", info.Connection)
}
if err := refConn.PinToCursor(); err != nil {
return CursorResponse{}, fmt.Errorf("error incrementing connection reference count when creating a cursor: %w", err)
}
- curresp.Connection = refConn
+ curresp.Connection = info.Connection
}
return curresp, nil
@@ -154,17 +168,35 @@ func NewCursorResponse(info ResponseInfo) (CursorResponse, error) {
type CursorOptions struct {
BatchSize int32
Comment bsoncore.Value
- MaxTimeMS int64
Limit int32
CommandMonitor *event.CommandMonitor
Crypt Crypt
ServerAPI *ServerAPIOptions
- MarshalValueEncoderFn func(io.Writer) (*bson.Encoder, error)
+ MarshalValueEncoderFn func(io.Writer) *bson.Encoder
+
+ // MaxAwaitTime is only valid for tailable awaitData cursors. If this option
+ // is set, it will be used as the "maxTimeMS" field on getMore commands.
+ MaxAwaitTime *time.Duration
+
+ MaxAdaptiveRetries uint
+ EnableOverloadRetargeting bool
+}
+
+// SetMaxAwaitTime will set the maxTimeMS value on getMore commands for
+// tailable awaitData cursors.
+func (cursorOptions *CursorOptions) SetMaxAwaitTime(dur time.Duration) {
+ cursorOptions.MaxAwaitTime = &dur
}
// NewBatchCursor creates a new BatchCursor from the provided parameters.
-func NewBatchCursor(cr CursorResponse, clientSession *session.Client, clock *session.ClusterClock, opts CursorOptions) (*BatchCursor, error) {
- ds := cr.FirstBatch
+func NewBatchCursor(
+ cr CursorResponse,
+ clientSession *session.Client,
+ clock *session.ClusterClock,
+ opts CursorOptions,
+) (*BatchCursor, error) {
+ firstBatch := cr.FirstBatch
+
bc := &BatchCursor{
clientSession: clientSession,
clock: clock,
@@ -176,7 +208,7 @@ func NewBatchCursor(cr CursorResponse, clientSession *session.Client, clock *ses
connection: cr.Connection,
errorProcessor: cr.ErrorProcessor,
batchSize: opts.BatchSize,
- maxTimeMS: opts.MaxTimeMS,
+ maxAwaitTime: opts.MaxAwaitTime,
cmdMonitor: opts.CommandMonitor,
firstBatch: true,
postBatchResumeToken: cr.postBatchResumeToken,
@@ -184,48 +216,32 @@ func NewBatchCursor(cr CursorResponse, clientSession *session.Client, clock *ses
serverAPI: opts.ServerAPI,
serverDescription: cr.Desc,
encoderFn: opts.MarshalValueEncoderFn,
- }
- if ds != nil {
- bc.numReturned = int32(ds.DocumentCount())
+ maxAdaptiveRetries: opts.MaxAdaptiveRetries,
+ enableOverloadRetargeting: opts.EnableOverloadRetargeting,
}
- if cr.Desc.WireVersion == nil {
- bc.limit = opts.Limit
-
- // Take as many documents from the batch as needed.
- if bc.limit != 0 && bc.limit < bc.numReturned {
- for i := int32(0); i < bc.limit; i++ {
- _, err := ds.Next()
- if err != nil {
- return nil, err
- }
- }
- ds.Data = ds.Data[:ds.Pos]
- ds.ResetIterator()
- }
+
+ if firstBatch != nil {
+ bc.numReturned = int32(firstBatch.Count())
}
- bc.currentBatch = ds
+ bc.currentBatch = firstBatch
+
return bc, nil
}
// NewEmptyBatchCursor returns a batch cursor that is empty.
func NewEmptyBatchCursor() *BatchCursor {
- return &BatchCursor{currentBatch: new(bsoncore.DocumentSequence)}
+ return &BatchCursor{currentBatch: new(bsoncore.Iterator)}
}
-// NewBatchCursorFromDocuments returns a batch cursor with current batch set to a sequence-style
-// DocumentSequence containing the provided documents.
-func NewBatchCursorFromDocuments(documents []byte) *BatchCursor {
+// NewBatchCursorFromList returns a batch cursor with current batch set to an
+// itertor that can traverse the BSON data contained within the array.
+func NewBatchCursorFromList(array []byte) *BatchCursor {
return &BatchCursor{
- currentBatch: &bsoncore.DocumentSequence{
- Data: documents,
- Style: bsoncore.SequenceStyle,
- },
- // BatchCursors created with this function have no associated ID nor server, so no getMore
- // calls will be made.
- id: 0,
- server: nil,
+ currentBatch: &bsoncore.Iterator{List: array},
+ id: 0,
+ server: nil,
}
}
@@ -260,10 +276,14 @@ func (bc *BatchCursor) Next(ctx context.Context) bool {
// Batch will return a DocumentSequence for the current batch of documents. The returned
// DocumentSequence is only valid until the next call to Next or Close.
-func (bc *BatchCursor) Batch() *bsoncore.DocumentSequence { return bc.currentBatch }
+func (bc *BatchCursor) Batch() *bsoncore.Iterator {
+ return bc.currentBatch
+}
// Err returns the latest error encountered.
-func (bc *BatchCursor) Err() error { return bc.err }
+func (bc *BatchCursor) Err() error {
+ return bc.err
+}
// Close closes this batch cursor.
func (bc *BatchCursor) Close(ctx context.Context) error {
@@ -273,9 +293,9 @@ func (bc *BatchCursor) Close(ctx context.Context) error {
err := bc.KillCursor(ctx)
bc.id = 0
- bc.currentBatch.Data = nil
- bc.currentBatch.Style = 0
- bc.currentBatch.ResetIterator()
+
+ bc.currentBatch.List = nil
+ bc.currentBatch.Reset()
connErr := bc.unpinConnection()
if err == nil {
@@ -285,7 +305,7 @@ func (bc *BatchCursor) Close(ctx context.Context) error {
}
func (bc *BatchCursor) unpinConnection() error {
- if bc.connection == nil {
+ if bc.connection == nil || bc.connection.Pinner == nil {
return nil
}
@@ -304,7 +324,7 @@ func (bc *BatchCursor) Server() Server {
}
func (bc *BatchCursor) clearBatch() {
- bc.currentBatch.Data = bc.currentBatch.Data[:0]
+ bc.currentBatch.List = bc.currentBatch.List[:0]
}
// KillCursor kills cursor on server without closing batch cursor
@@ -316,7 +336,7 @@ func (bc *BatchCursor) KillCursor(ctx context.Context) error {
return Operation{
CommandFn: func(dst []byte, _ description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "killCursors", bc.collection)
- dst = bsoncore.BuildArrayElement(dst, "cursors", bsoncore.Value{Type: bsontype.Int64, Data: bsoncore.AppendInt64(nil, bc.id)})
+ dst = bsoncore.BuildArrayElement(dst, "cursors", bsoncore.Value{Type: bsoncore.TypeInt64, Data: bsoncore.AppendInt64(nil, bc.id)})
return dst, nil
},
Database: bc.database,
@@ -370,13 +390,40 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
bc.err = Operation{
CommandFn: func(dst []byte, _ description.SelectedServer) ([]byte, error) {
+ // If maxAwaitTime > remaining timeoutMS - minRoundTripTime, then use
+ // send remaining TimeoutMS - minRoundTripTime allowing the server an
+ // opportunity to respond with an empty batch.
+ var maxTimeMS int64
+ if bc.maxAwaitTime != nil {
+ _, ctxDeadlineSet := ctx.Deadline()
+
+ if ctxDeadlineSet {
+ rttMonitor := bc.Server().RTTMonitor()
+
+ var ok bool
+ maxTimeMS, ok = driverutil.CalculateMaxTimeMS(ctx, rttMonitor.Min())
+ if !ok && maxTimeMS <= 0 {
+ return nil, fmt.Errorf(
+ "calculated server-side timeout (%v ms) is less than or equal to 0 (%v): %w",
+ maxTimeMS,
+ rttMonitor.Stats(),
+ ErrDeadlineWouldBeExceeded)
+ }
+ }
+
+ if !ctxDeadlineSet || bc.maxAwaitTime.Milliseconds() < maxTimeMS {
+ maxTimeMS = bc.maxAwaitTime.Milliseconds()
+ }
+ }
+
dst = bsoncore.AppendInt64Element(dst, "getMore", bc.id)
dst = bsoncore.AppendStringElement(dst, "collection", bc.collection)
if numToReturn > 0 {
dst = bsoncore.AppendInt32Element(dst, "batchSize", numToReturn)
}
- if bc.maxTimeMS > 0 {
- dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", bc.maxTimeMS)
+
+ if maxTimeMS > 0 {
+ dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", maxTimeMS)
}
comment, err := codecutil.MarshalValue(bc.comment, bc.encoderFn)
@@ -385,7 +432,7 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
}
// The getMore command does not support commenting pre-4.4.
- if comment.Type != bsontype.Type(0) && bc.serverDescription.WireVersion.Max >= 9 {
+ if comment.Type != bsoncore.Type(0) && bc.serverDescription.WireVersion.Max >= 9 {
dst = bsoncore.AppendValueElement(dst, "comment", comment)
}
@@ -393,8 +440,7 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
},
Database: bc.database,
Deployment: bc.getOperationDeployment(),
- ProcessResponseFn: func(info ResponseInfo) error {
- response := info.ServerResponse
+ ProcessResponseFn: func(_ context.Context, response bsoncore.Document, _ ResponseInfo) error {
id, ok := response.Lookup("cursor", "id").Int64OK()
if !ok {
return fmt.Errorf("cursor.id should be an int64 but is a BSON %s", response.Lookup("cursor", "id").Type)
@@ -405,10 +451,12 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
if !ok {
return fmt.Errorf("cursor.nextBatch should be an array but is a BSON %s", response.Lookup("cursor", "nextBatch").Type)
}
- bc.currentBatch.Style = bsoncore.ArrayStyle
- bc.currentBatch.Data = batch
- bc.currentBatch.ResetIterator()
- bc.numReturned += int32(bc.currentBatch.DocumentCount()) // Required for legacy operations which don't support limit.
+
+ bc.currentBatch.List = batch
+ bc.currentBatch.Reset()
+
+ // Required for legacy operations which don't support limit.
+ bc.numReturned += int32(bc.currentBatch.Count())
pbrt, err := response.LookupErr("cursor", "postBatchResumeToken")
if err != nil {
@@ -426,12 +474,20 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
return nil
},
- Client: bc.clientSession,
- Clock: bc.clock,
- Legacy: LegacyGetMore,
- CommandMonitor: bc.cmdMonitor,
- Crypt: bc.crypt,
- ServerAPI: bc.serverAPI,
+ Client: bc.clientSession,
+ Clock: bc.clock,
+ Legacy: LegacyGetMore,
+ CommandMonitor: bc.cmdMonitor,
+ MaxAdaptiveRetries: bc.maxAdaptiveRetries,
+ EnableOverloadRetargeting: bc.enableOverloadRetargeting,
+ Crypt: bc.crypt,
+ ServerAPI: bc.serverAPI,
+
+ // Omit the automatically-calculated maxTimeMS because setting maxTimeMS
+ // on a non-awaitData cursor causes a server error. For awaitData
+ // cursors, maxTimeMS is set when maxAwaitTime is specified by the above
+ // CommandFn.
+ OmitMaxTimeMS: true,
// No read preference is passed to the getMore command,
// resulting in the default read preference: "primaryPreferred".
@@ -475,18 +531,18 @@ func (bc *BatchCursor) SetBatchSize(size int32) {
bc.batchSize = size
}
-// SetMaxTime will set the maximum amount of time the server will allow the
+// SetMaxAwaitTime will set the maximum amount of time the server will allow the
// operations to execute. The server will error if this field is set but the
// cursor is not configured with awaitData=true.
//
// The time.Duration value passed by this setter will be converted and rounded
// down to the nearest millisecond.
-func (bc *BatchCursor) SetMaxTime(dur time.Duration) {
- bc.maxTimeMS = int64(dur / time.Millisecond)
+func (bc *BatchCursor) SetMaxAwaitTime(dur time.Duration) {
+ bc.maxAwaitTime = &dur
}
// SetComment sets the comment for future getMore operations.
-func (bc *BatchCursor) SetComment(comment interface{}) {
+func (bc *BatchCursor) SetComment(comment any) {
bc.comment = comment
}
@@ -500,27 +556,35 @@ func (bc *BatchCursor) getOperationDeployment() Deployment {
return SingleServerDeployment{bc.server}
}
+// MaxAwaitTime returns the maximum amount of time the server will allow
+// the operations to execute. This is only valid for tailable awaitData cursors.
+func (bc *BatchCursor) MaxAwaitTime() *time.Duration {
+ return bc.maxAwaitTime
+}
+
// loadBalancedCursorDeployment is used as a Deployment for getMore and killCursors commands when pinning to a
// connection in load balanced mode. This type also functions as an ErrorProcessor to ensure that SDAM errors are
// handled for these commands in this mode.
type loadBalancedCursorDeployment struct {
errorProcessor ErrorProcessor
- conn PinnedConnection
+ conn *mnet.Connection
}
-var _ Deployment = (*loadBalancedCursorDeployment)(nil)
-var _ Server = (*loadBalancedCursorDeployment)(nil)
-var _ ErrorProcessor = (*loadBalancedCursorDeployment)(nil)
+var (
+ _ Deployment = (*loadBalancedCursorDeployment)(nil)
+ _ Server = (*loadBalancedCursorDeployment)(nil)
+ _ ErrorProcessor = (*loadBalancedCursorDeployment)(nil)
+)
-func (lbcd *loadBalancedCursorDeployment) SelectServer(_ context.Context, _ description.ServerSelector) (Server, error) {
+func (lbcd *loadBalancedCursorDeployment) SelectServer(context.Context, description.ServerSelector) (Server, error) {
return lbcd, nil
}
func (lbcd *loadBalancedCursorDeployment) Kind() description.TopologyKind {
- return description.LoadBalanced
+ return description.TopologyKindLoadBalanced
}
-func (lbcd *loadBalancedCursorDeployment) Connection(_ context.Context) (Connection, error) {
+func (lbcd *loadBalancedCursorDeployment) Connection(context.Context) (*mnet.Connection, error) {
return lbcd.conn, nil
}
@@ -529,6 +593,12 @@ func (lbcd *loadBalancedCursorDeployment) RTTMonitor() RTTMonitor {
return &csot.ZeroRTTMonitor{}
}
-func (lbcd *loadBalancedCursorDeployment) ProcessError(err error, conn Connection) ProcessErrorResult {
- return lbcd.errorProcessor.ProcessError(err, conn)
+func (lbcd *loadBalancedCursorDeployment) ProcessError(err error, desc mnet.Describer) ProcessErrorResult {
+ return lbcd.errorProcessor.ProcessError(err, desc)
+}
+
+// GetServerSelectionTimeout returns zero as a server selection timeout is not
+// applicable for load-balanced cursor deployments.
+func (*loadBalancedCursorDeployment) GetServerSelectionTimeout() time.Duration {
+ return 0
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batches.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batches.go
new file mode 100644
index 000000000..51a32bc96
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batches.go
@@ -0,0 +1,116 @@
+// Copyright (C) MongoDB, Inc. 2022-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 driver
+
+import (
+ "io"
+ "strconv"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
+)
+
+// Batches contains the necessary information to batch split an operation. This is only used for write
+// operations.
+type Batches struct {
+ Identifier string
+ Documents []bsoncore.Document
+ Ordered *bool
+
+ offset int
+}
+
+var _ OperationBatches = &Batches{}
+
+// AppendBatchSequence appends dst with document sequence of batches as long as the limits of max count, max
+// document size, or total size allows. It returns the number of batches appended, the new appended slice, and
+// any error raised. It returns the origenal input slice if nothing can be appends within the limits.
+func (b *Batches) AppendBatchSequence(dst []byte, maxCount, totalSize int) (int, []byte, error) {
+ if b.Size() == 0 {
+ return 0, dst, io.EOF
+ }
+ l := len(dst)
+ var idx int32
+ dst = wiremessage.AppendMsgSectionType(dst, wiremessage.DocumentSequence)
+ idx, dst = bsoncore.ReserveLength(dst)
+ dst = append(dst, b.Identifier...)
+ dst = append(dst, 0x00)
+ var size int
+ var n int
+ for i := b.offset; i < len(b.Documents); i++ {
+ if n == maxCount {
+ break
+ }
+ doc := b.Documents[i]
+ size += len(doc)
+ if size > totalSize {
+ break
+ }
+ dst = append(dst, doc...)
+ n++
+ }
+ if n == 0 {
+ return 0, dst[:l], nil
+ }
+ dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
+ return n, dst, nil
+}
+
+// AppendBatchArray appends dst with array of batches as long as the limits of max count, max document size, or
+// total size allows. It returns the number of batches appended, the new appended slice, and any error raised. It
+// returns the origenal input slice if nothing can be appends within the limits.
+func (b *Batches) AppendBatchArray(dst []byte, maxCount, totalSize int) (int, []byte, error) {
+ if b.Size() == 0 {
+ return 0, dst, io.EOF
+ }
+ l := len(dst)
+ aidx, dst := bsoncore.AppendArrayElementStart(dst, b.Identifier)
+ var size int
+ var n int
+ for i := b.offset; i < len(b.Documents); i++ {
+ if n == maxCount {
+ break
+ }
+ doc := b.Documents[i]
+ size += len(doc)
+ if size > totalSize {
+ break
+ }
+ dst = bsoncore.AppendDocumentElement(dst, strconv.Itoa(n), doc)
+ n++
+ }
+ if n == 0 {
+ return 0, dst[:l], nil
+ }
+ var err error
+ dst, err = bsoncore.AppendArrayEnd(dst, aidx)
+ if err != nil {
+ return 0, nil, err
+ }
+ return n, dst, nil
+}
+
+// IsOrdered indicates if the batches are ordered.
+func (b *Batches) IsOrdered() *bool {
+ return b.Ordered
+}
+
+// AdvanceBatches advances the batches with the given input.
+func (b *Batches) AdvanceBatches(n int) {
+ b.offset += n
+ if b.offset > len(b.Documents) {
+ b.offset = len(b.Documents)
+ }
+}
+
+// Size returns the size of batches remained.
+func (b *Batches) Size() int {
+ if b.offset > len(b.Documents) {
+ return 0
+ }
+ return len(b.Documents) - b.offset
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/compression.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/compression.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/compression.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/compression.go
index d9a6c68fe..349781f4e 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/compression.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/compression.go
@@ -13,9 +13,9 @@ import (
"io"
"sync"
- "github.com/golang/snappy"
+ "github.com/klauspost/compress/snappy"
"github.com/klauspost/compress/zstd"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)
// CompressionOpts holds settings for how to compress a payload
@@ -110,7 +110,7 @@ func (e *zlibEncoder) Encode(dst, src []byte) ([]byte, error) {
}
var zstdBufPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
s := make([]byte, 0)
return &s
},
@@ -147,7 +147,7 @@ func CompressPayload(in []byte, opts CompressionOpts) ([]byte, error) {
}
var zstdReaderPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
r, _ := zstd.NewReader(nil)
return r
},
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring/connstring.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring/connstring.go
index fd69eb490..256cc9d8a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring/connstring.go
@@ -11,7 +11,7 @@
//
// WARNING: THIS PACKAGE IS EXPERIMENTAL AND MAY BE MODIFIED OR REMOVED WITHOUT
// NOTICE! USE WITH EXTREME CAUTION!
-package connstring // import "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
+package connstring
import (
"errors"
@@ -22,11 +22,10 @@ import (
"strings"
"time"
- "go.mongodb.org/mongo-driver/internal/randutil"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth"
- "go.mongodb.org/mongo-driver/x/mongo/driver/dns"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
+ "go.mongodb.org/mongo-driver/v2/internal/randutil"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)
const (
@@ -149,6 +148,10 @@ type ConnString struct {
RetryWritesSet bool
RetryReads bool
RetryReadsSet bool
+ MaxAdaptiveRetries uint
+ MaxAdaptiveRetriesSet bool
+ EnableOverloadRetargeting bool
+ EnableOverloadRetargetingSet bool
MaxStaleness time.Duration
MaxStalenessSet bool
ReplicaSet string
@@ -188,10 +191,6 @@ type ConnString struct {
ZstdLevel int
ZstdLevelSet bool
- WTimeout time.Duration
- WTimeoutSet bool
- WTimeoutSetFromOption bool
-
Options map[string][]string
UnknownOptions map[string][]string
}
@@ -222,7 +221,7 @@ func (u *ConnString) Validate() error {
// Check for invalid write concern (i.e. w=0 and j=true)
if u.WNumberSet && u.WNumber == 0 && u.JSet && u.J {
- return writeconcern.ErrInconsistent
+ return errors.New("a write concern cannot have both w=0 and j=true")
}
// Check for invalid use of direct connections.
@@ -302,8 +301,6 @@ func (u *ConnString) setDefaultAuthParams(dbName string) error {
} else if u.AuthSource != "$external" {
return fmt.Errorf("auth source must be $external")
}
- case "mongodb-cr":
- fallthrough
case "scram-sha-1":
fallthrough
case "scram-sha-256":
@@ -531,6 +528,23 @@ func (u *ConnString) addOptions(connectionArgPairs []string) error {
}
u.RetryReadsSet = true
+ case "maxadaptiveretries":
+ n, err := strconv.Atoi(value)
+ if err != nil || n < 0 {
+ return fmt.Errorf("invalid value for %q: %q", key, value)
+ }
+ u.MaxAdaptiveRetries = uint(n)
+ u.MaxAdaptiveRetriesSet = true
+ case "enableoverloadretargeting":
+ switch value {
+ case "true":
+ u.EnableOverloadRetargeting = true
+ case "false":
+ u.EnableOverloadRetargeting = false
+ default:
+ return fmt.Errorf("invalid value for %q: %q", key, value)
+ }
+ u.EnableOverloadRetargetingSet = true
case "servermonitoringmode":
if !IsValidServerMonitoringMode(value) {
return fmt.Errorf("invalid value for %q: %q", key, value)
@@ -661,24 +675,6 @@ func (u *ConnString) addOptions(connectionArgPairs []string) error {
u.WString = value
u.WNumberSet = false
-
- case "wtimeoutms":
- n, err := strconv.Atoi(value)
- if err != nil || n < 0 {
- return fmt.Errorf("invalid value for %q: %q", key, value)
- }
- u.WTimeout = time.Duration(n) * time.Millisecond
- u.WTimeoutSet = true
- case "wtimeout":
- // Defer to wtimeoutms, but not to a manually-set option.
- if u.WTimeoutSet {
- break
- }
- n, err := strconv.Atoi(value)
- if err != nil || n < 0 {
- return fmt.Errorf("invalid value for %q: %q", key, value)
- }
- u.WTimeout = time.Duration(n) * time.Millisecond
case "zlibcompressionlevel":
level, err := strconv.Atoi(value)
if err != nil || (level < -1 || level > 9) {
@@ -719,16 +715,6 @@ func (u *ConnString) addOptions(connectionArgPairs []string) error {
func (u *ConnString) validateAuth() error {
switch strings.ToLower(u.AuthMechanism) {
- case "mongodb-cr":
- if u.Username == "" {
- return fmt.Errorf("username required for MONGO-CR")
- }
- if u.Password == "" {
- return fmt.Errorf("password required for MONGO-CR")
- }
- if u.AuthMechanismProperties != nil {
- return fmt.Errorf("MONGO-CR cannot have mechanism properties")
- }
case "mongodb-x509":
if u.Password != "" {
return fmt.Errorf("password cannot be specified for MONGO-X509")
@@ -1048,11 +1034,6 @@ func (p *parser) parse(original string) (*ConnString, error) {
return nil, err
}
- // If WTimeout was set from manual options passed in, set WTImeoutSet to true.
- if connStr.WTimeoutSetFromOption {
- connStr.WTimeoutSet = true
- }
-
return connStr, nil
}
@@ -1078,7 +1059,6 @@ func extractQueryArgsFromURI(uri string) ([]string, error) {
return nil, nil
}
return strings.FieldsFunc(uri, func(r rune) bool { return r == ';' || r == '&' }), nil
-
}
type extractedDatabase struct {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/crypt.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/crypt.go
index 576c007d6..bc6020acb 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/crypt.go
@@ -9,16 +9,13 @@ package driver
import (
"context"
"crypto/tls"
- "errors"
"fmt"
- "io"
"strings"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options"
)
const (
@@ -138,8 +135,8 @@ func (c *crypt) CreateDataKey(ctx context.Context, kmsProvider string, opts *opt
// RewrapDataKey attempts to rewrap the document data keys matching the filter, preparing the re-wrapped documents to
// be returned as a slice of bsoncore.Document.
func (c *crypt) RewrapDataKey(ctx context.Context, filter []byte,
- opts *options.RewrapManyDataKeyOptions) ([]bsoncore.Document, error) {
-
+ opts *options.RewrapManyDataKeyOptions,
+) ([]bsoncore.Document, error) {
cryptCtx, err := c.mongoCrypt.RewrapDataKeyContext(filter, opts)
if err != nil {
return nil, err
@@ -174,11 +171,11 @@ func (c *crypt) RewrapDataKey(ctx context.Context, filter []byte,
rewrappedDocuments := []bsoncore.Document{}
for _, rewrappedDocumentValue := range rewrappedDocumentValues {
- if rewrappedDocumentValue.Type != bsontype.EmbeddedDocument {
+ if rewrappedDocumentValue.Type != bsoncore.TypeEmbeddedDocument {
// If a value in the document's array returned by mongocrypt is anything other than an embedded document,
// then something is wrong and we should terminate the routine.
return nil, fmt.Errorf("expected value of type %q, got: %q",
- bsontype.EmbeddedDocument.String(),
+ bsoncore.TypeEmbeddedDocument.String(),
rewrappedDocumentValue.Type.String())
}
rewrappedDocuments = append(rewrappedDocuments, rewrappedDocumentValue.Document())
@@ -400,8 +397,8 @@ func (c *crypt) decryptKey(kmsCtx *mongocrypt.KmsContext) error {
res := make([]byte, bytesNeeded)
bytesRead, err := conn.Read(res)
- if err != nil && !errors.Is(err, io.EOF) {
- return err
+ if err != nil {
+ return kmsCtx.RequestError()
}
if err = kmsCtx.FeedResponse(res[:bytesRead]); err != nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/server.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/server.go
new file mode 100644
index 000000000..7d2e679a2
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/server.go
@@ -0,0 +1,144 @@
+// Copyright (C) MongoDB, Inc. 2024-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 description
+
+import (
+ "fmt"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/tag"
+)
+
+// ServerKind represents the type of a single server in a topology.
+type ServerKind uint32
+
+// These constants are the possible types of servers.
+const (
+ ServerKindStandalone ServerKind = 1
+ ServerKindRSMember ServerKind = 2
+ ServerKindRSPrimary ServerKind = 4 + ServerKindRSMember
+ ServerKindRSSecondary ServerKind = 8 + ServerKindRSMember
+ ServerKindRSArbiter ServerKind = 16 + ServerKindRSMember
+ ServerKindRSGhost ServerKind = 32 + ServerKindRSMember
+ ServerKindMongos ServerKind = 256
+ ServerKindLoadBalancer ServerKind = 512
+)
+
+// UnknownStr represents an unknown server kind.
+const UnknownStr = "Unknown"
+
+// String returns a stringified version of the kind or "Unknown" if the kind is
+// invalid.
+func (kind ServerKind) String() string {
+ switch kind {
+ case ServerKindStandalone:
+ return "Standalone"
+ case ServerKindRSMember:
+ return "RSOther"
+ case ServerKindRSPrimary:
+ return "RSPrimary"
+ case ServerKindRSSecondary:
+ return "RSSecondary"
+ case ServerKindRSArbiter:
+ return "RSArbiter"
+ case ServerKindRSGhost:
+ return "RSGhost"
+ case ServerKindMongos:
+ return "Mongos"
+ case ServerKindLoadBalancer:
+ return "LoadBalancer"
+ }
+
+ return UnknownStr
+}
+
+// Unknown is an unknown server or topology kind.
+const Unknown = 0
+
+// TopologyVersion represents a software version.
+type TopologyVersion struct {
+ ProcessID bson.ObjectID
+ Counter int64
+}
+
+// VersionRange represents a range of versions.
+type VersionRange struct {
+ Min int32
+ Max int32
+}
+
+// Server contains information about a node in a cluster. This is created from
+// hello command responses. If the value of the Kind field is LoadBalancer, only
+// the Addr and Kind fields will be set. All other fields will be set to the
+// zero value of the field's type.
+type Server struct {
+ Addr address.Address
+
+ Arbiters []string
+ AverageRTT time.Duration
+ AverageRTTSet bool
+ Compression []string // compression methods returned by server
+ CanonicalAddr address.Address
+ ElectionID bson.ObjectID
+ HeartbeatInterval time.Duration
+ HelloOK bool
+ Hosts []string
+ IsCryptd bool
+ LastError error
+ LastUpdateTime time.Time
+ LastWriteTime time.Time
+ MaxBatchCount uint32
+ MaxDocumentSize uint32
+ MaxMessageSize uint32
+ Members []address.Address
+ Passives []string
+ Passive bool
+ Primary address.Address
+ ReadOnly bool
+ ServiceID *bson.ObjectID // Only set for servers that are deployed behind a load balancer.
+ SessionTimeoutMinutes *int64
+ SetName string
+ SetVersion uint32
+ Tags tag.Set
+ TopologyVersion *TopologyVersion
+ Kind ServerKind
+ WireVersion *VersionRange
+}
+
+func (s Server) String() string {
+ str := fmt.Sprintf("Addr: %s, Type: %s", s.Addr, s.Kind)
+ if len(s.Tags) != 0 {
+ str += fmt.Sprintf(", Tag sets: %s", s.Tags)
+ }
+
+ if s.AverageRTTSet {
+ str += fmt.Sprintf(", Average RTT: %d", s.AverageRTT)
+ }
+
+ if s.LastError != nil {
+ str += fmt.Sprintf(", Last error: %s", s.LastError)
+ }
+ return str
+}
+
+// SelectedServer augments the Server type by also including the TopologyKind of
+// the topology that includes the server. This type should be used to track the
+// state of a server that was selected to perform an operation.
+type SelectedServer struct {
+ Server
+ Kind TopologyKind
+}
+
+// ServerSelector is an interface implemented by types that can perform server
+// selection given a topology description and list of candidate servers. The
+// selector should filter the provided candidates list and return a subset that
+// matches some criteria.
+type ServerSelector interface {
+ SelectServer(Topology, []Server) ([]Server, error)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/topology.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/topology.go
new file mode 100644
index 000000000..e152a7ce9
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/topology.go
@@ -0,0 +1,60 @@
+// Copyright (C) MongoDB, Inc. 2024-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 description
+
+import "fmt"
+
+// TopologyKind represents a specific topology configuration.
+type TopologyKind uint32
+
+// These constants are the available topology configurations.
+const (
+ TopologyKindSingle TopologyKind = 1
+ TopologyKindReplicaSet TopologyKind = 2
+ TopologyKindReplicaSetNoPrimary TopologyKind = 4 + TopologyKindReplicaSet
+ TopologyKindReplicaSetWithPrimary TopologyKind = 8 + TopologyKindReplicaSet
+ TopologyKindSharded TopologyKind = 256
+ TopologyKindLoadBalanced TopologyKind = 512
+)
+
+// Topology contains information about a MongoDB cluster.
+type Topology struct {
+ Servers []Server
+ SetName string
+ Kind TopologyKind
+ SessionTimeoutMinutes *int64
+ CompatibilityErr error
+}
+
+// String implements the Stringer interface.
+func (t Topology) String() string {
+ var serversStr string
+ for _, s := range t.Servers {
+ serversStr += "{ " + s.String() + " }, "
+ }
+ return fmt.Sprintf("Type: %s, Servers: [%s]", t.Kind, serversStr)
+}
+
+// String implements the fmt.Stringer interface.
+func (kind TopologyKind) String() string {
+ switch kind {
+ case TopologyKindSingle:
+ return "Single"
+ case TopologyKindReplicaSet:
+ return "ReplicaSet"
+ case TopologyKindReplicaSetNoPrimary:
+ return "ReplicaSetNoPrimary"
+ case TopologyKindReplicaSetWithPrimary:
+ return "ReplicaSetWithPrimary"
+ case TopologyKindSharded:
+ return "Sharded"
+ case TopologyKindLoadBalanced:
+ return "LoadBalanced"
+ }
+
+ return "Unknown"
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns/dns.go
similarity index 87%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns/dns.go
index 9334d493e..1252dc5f8 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns/dns.go
@@ -113,20 +113,23 @@ func (r *Resolver) fetchSeedlistFromSRV(host string, srvName string, stopOnErr b
func validateSRVResult(recordFromSRV, inputHostName string) error {
separatedInputDomain := strings.Split(strings.ToLower(inputHostName), ".")
separatedRecord := strings.Split(strings.ToLower(recordFromSRV), ".")
- if len(separatedRecord) < 2 {
- return errors.New("DNS name must contain at least 2 labels")
+ if l := len(separatedInputDomain); l < 3 && len(separatedRecord) <= l {
+ return fmt.Errorf("server record (%d levels) should have more domain levels than parent URI (%d levels)", l, len(separatedRecord))
}
if len(separatedRecord) < len(separatedInputDomain) {
- return errors.New("Domain suffix from SRV record not matched input domain")
+ return errors.New("domain suffix from SRV record not matched input domain")
}
- inputDomainSuffix := separatedInputDomain[1:]
- domainSuffixOffset := len(separatedRecord) - (len(separatedInputDomain) - 1)
+ inputDomainSuffix := separatedInputDomain
+ if len(inputDomainSuffix) > 2 {
+ inputDomainSuffix = inputDomainSuffix[1:]
+ }
+ domainSuffixOffset := len(separatedRecord) - len(inputDomainSuffix)
recordDomainSuffix := separatedRecord[domainSuffixOffset:]
for ix, label := range inputDomainSuffix {
if label != recordDomainSuffix[ix] {
- return errors.New("Domain suffix from SRV record not matched input domain")
+ return errors.New("domain suffix from SRV record not matched input domain")
}
}
return nil
@@ -142,11 +145,11 @@ func validateTXTResult(paramsFromTXT []string) error {
for _, param := range paramsFromTXT {
kv := strings.SplitN(param, "=", 2)
if len(kv) != 2 {
- return errors.New("Invalid TXT record")
+ return errors.New("invalid TXT record")
}
key := strings.ToLower(kv[0])
if _, ok := allowedTXTOptions[key]; !ok {
- return fmt.Errorf("Cannot specify option '%s' in TXT record", kv[0])
+ return fmt.Errorf("cannot specify option '%s' in TXT record", kv[0])
}
}
return nil
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/driver.go
similarity index 72%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/driver.go
index 363f4d6be..49ce715ca 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/driver.go
@@ -11,17 +11,18 @@
//
// WARNING: THIS PACKAGE IS EXPERIMENTAL AND MAY BE MODIFIED OR REMOVED WITHOUT
// NOTICE! USE WITH EXTREME CAUTION!
-package driver // import "go.mongodb.org/mongo-driver/x/mongo/driver"
+package driver
import (
"context"
"time"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// AuthConfig holds the information necessary to perform an authentication attempt.
@@ -29,7 +30,7 @@ import (
// reexports this under the old name to avoid breaking the public api.
type AuthConfig struct {
Description description.Server
- Connection Connection
+ Connection *mnet.Connection
ClusterClock *session.ClusterClock
HandshakeInfo HandshakeInformation
ServerAPI *ServerAPIOptions
@@ -85,6 +86,12 @@ type Cred struct {
type Deployment interface {
SelectServer(context.Context, description.ServerSelector) (Server, error)
Kind() description.TopologyKind
+
+ // GetServerSelectionTimeout returns a timeout that should be used to set a
+ // deadline for server selection. This logic is not handleded internally by
+ // the ServerSelector, as a resulting deadline may be applicable by follow-up
+ // operations such as checking out a connection.
+ GetServerSelectionTimeout() time.Duration
}
// Connector represents a type that can connect to a server.
@@ -114,32 +121,12 @@ type Subscriber interface {
// Server represents a MongoDB server. Implementations should pool connections and handle the
// retrieving and returning of connections.
type Server interface {
- Connection(context.Context) (Connection, error)
+ Connection(context.Context) (*mnet.Connection, error)
// RTTMonitor returns the round-trip time monitor associated with this server.
RTTMonitor() RTTMonitor
}
-// Connection represents a connection to a MongoDB server.
-type Connection interface {
- WriteWireMessage(context.Context, []byte) error
- ReadWireMessage(ctx context.Context) ([]byte, error)
- Description() description.Server
-
- // Close closes any underlying connection and returns or frees any resources held by the
- // connection. Close is idempotent and can be called multiple times, although subsequent calls
- // to Close may return an error. A connection cannot be used after it is closed.
- Close() error
-
- ID() string
- ServerConnectionID() *int64
- DriverConnectionID() uint64 // TODO(GODRIVER-2824): change type to int64.
- Address() address.Address
- Stale() bool
- OIDCTokenGenID() uint64
- SetOIDCTokenGenID(uint64)
-}
-
// RTTMonitor represents a round-trip-time monitor.
type RTTMonitor interface {
// EWMA returns the exponentially weighted moving average observed round-trip time.
@@ -148,34 +135,12 @@ type RTTMonitor interface {
// Min returns the minimum observed round-trip time over the window period.
Min() time.Duration
- // P90 returns the 90th percentile observed round-trip time over the window period.
- P90() time.Duration
-
// Stats returns stringified stats of the current state of the monitor.
Stats() string
}
var _ RTTMonitor = &csot.ZeroRTTMonitor{}
-// PinnedConnection represents a Connection that can be pinned by one or more cursors or transactions. Implementations
-// of this interface should maintain the following invariants:
-//
-// 1. Each Pin* call should increment the number of references for the connection.
-// 2. Each Unpin* call should decrement the number of references for the connection.
-// 3. Calls to Close() should be ignored until all resources have unpinned the connection.
-type PinnedConnection interface {
- Connection
- PinToCursor() error
- PinToTransaction() error
- UnpinFromCursor() error
- UnpinFromTransaction() error
-}
-
-// The session.LoadBalancedTransactionConnection type is a copy of PinnedConnection that was introduced to avoid
-// import cycles. This compile-time assertion ensures that these types remain in sync if the PinnedConnection interface
-// is changed in the future.
-var _ PinnedConnection = (session.LoadBalancedTransactionConnection)(nil)
-
// LocalAddresser is a type that is able to supply its local address
type LocalAddresser interface {
LocalAddress() address.Address
@@ -187,28 +152,6 @@ type Expirable interface {
Alive() bool
}
-// StreamerConnection represents a Connection that supports streaming wire protocol messages using the moreToCome and
-// exhaustAllowed flags.
-//
-// The SetStreaming and CurrentlyStreaming functions correspond to the moreToCome flag on server responses. If a
-// response has moreToCome set, SetStreaming(true) will be called and CurrentlyStreaming() should return true.
-//
-// CanStream corresponds to the exhaustAllowed flag. The operations layer will set exhaustAllowed on outgoing wire
-// messages to inform the server that the driver supports streaming.
-type StreamerConnection interface {
- Connection
- SetStreaming(bool)
- CurrentlyStreaming() bool
- SupportsStreaming() bool
-}
-
-// Compressor is an interface used to compress wire messages. If a Connection supports compression
-// it should implement this interface as well. The CompressWireMessage method will be called during
-// the execution of an operation if the wire message is allowed to be compressed.
-type Compressor interface {
- CompressWireMessage(src, dst []byte) ([]byte, error)
-}
-
// ProcessErrorResult represents the result of a ErrorProcessor.ProcessError() call. Exact values for this type can be
// checked directly (e.g. res == ServerMarkedUnknown), but it is recommended that applications use the ServerChanged()
// function instead.
@@ -228,7 +171,7 @@ const (
// If this type is implemented by a Server, then Operation.Execute will call it's ProcessError
// method after it decodes a wire message.
type ErrorProcessor interface {
- ProcessError(err error, conn Connection) ProcessErrorResult
+ ProcessError(err error, desc mnet.Describer) ProcessErrorResult
}
// HandshakeInformation contains information extracted from a MongoDB connection handshake. This is a helper type that
@@ -247,8 +190,8 @@ type HandshakeInformation struct {
// handshake over a provided driver.Connection. This is used during connection
// initialization. Implementations must be goroutine safe.
type Handshaker interface {
- GetHandshakeInformation(context.Context, address.Address, Connection) (HandshakeInformation, error)
- FinishHandshake(context.Context, Connection) error
+ GetHandshakeInformation(context.Context, address.Address, *mnet.Connection) (HandshakeInformation, error)
+ FinishHandshake(context.Context, *mnet.Connection) error
}
// SingleServerDeployment is an implementation of Deployment that always returns a single server.
@@ -262,16 +205,24 @@ func (ssd SingleServerDeployment) SelectServer(context.Context, description.Serv
return ssd.Server, nil
}
-// Kind implements the Deployment interface. It always returns description.Single.
-func (SingleServerDeployment) Kind() description.TopologyKind { return description.Single }
+// Kind implements the Deployment interface. It always returns description.TopologyKindSingle.
+func (SingleServerDeployment) Kind() description.TopologyKind { return description.TopologyKindSingle }
+
+// GetServerSelectionTimeout returns zero as a server selection timeout is not
+// applicable for single server deployments.
+func (SingleServerDeployment) GetServerSelectionTimeout() time.Duration {
+ return 0
+}
// SingleConnectionDeployment is an implementation of Deployment that always returns the same Connection. This
// implementation should only be used for connection handshakes and server heartbeats as it does not implement
// ErrorProcessor, which is necessary for application operations.
-type SingleConnectionDeployment struct{ C Connection }
+type SingleConnectionDeployment struct{ C *mnet.Connection }
-var _ Deployment = SingleConnectionDeployment{}
-var _ Server = SingleConnectionDeployment{}
+var (
+ _ Deployment = SingleConnectionDeployment{}
+ _ Server = SingleConnectionDeployment{}
+)
// SelectServer implements the Deployment interface. This method does not use the
// description.SelectedServer provided and instead returns itself. The Connections returned from the
@@ -280,11 +231,19 @@ func (scd SingleConnectionDeployment) SelectServer(context.Context, description.
return scd, nil
}
-// Kind implements the Deployment interface. It always returns description.Single.
-func (SingleConnectionDeployment) Kind() description.TopologyKind { return description.Single }
+// GetServerSelectionTimeout returns zero as a server selection timeout is not
+// applicable for single connection deployment.
+func (SingleConnectionDeployment) GetServerSelectionTimeout() time.Duration {
+ return 0
+}
+
+// Kind implements the Deployment interface. It always returns description.TopologyKindSingle.
+func (SingleConnectionDeployment) Kind() description.TopologyKind {
+ return description.TopologyKindSingle
+}
// Connection implements the Server interface. It always returns the embedded connection.
-func (scd SingleConnectionDeployment) Connection(context.Context) (Connection, error) {
+func (scd SingleConnectionDeployment) Connection(context.Context) (*mnet.Connection, error) {
return scd.C, nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/errors.go
similarity index 86%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/errors.go
index 59c3992e9..81a9b3e67 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/errors.go
@@ -13,10 +13,10 @@ import (
"fmt"
"strings"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
// LegacyNotPrimaryErrMsg is the error message that older MongoDB servers (see
@@ -25,7 +25,22 @@ import (
const LegacyNotPrimaryErrMsg = "not master"
var (
- retryableCodes = []int32{11600, 11602, 10107, 13435, 13436, 189, 91, 7, 6, 89, 9001, 262}
+ retryableCodes = []int32{
+ 6, // HostUnreachable
+ 7, // HostNotFound
+ 89, // NetworkTimeout
+ 91, // ShutdownInProgress
+ 134, // ReadConcernMajorityNotAvailableYet
+ 189, // PrimarySteppedDown
+ 262, // ExceededTimeLimit
+ 9001, // SocketException
+ 10107, // NotWritablePrimary
+ 11600, // InterruptedAtShutdown
+ 11602, // InterruptedDueToReplStateChange
+ 13435, // NotPrimaryNoSecondaryOk
+ 13436, // NotPrimaryOrSecondary
+ }
+
nodeIsRecoveringCodes = []int32{11600, 11602, 13436, 189, 91}
notPrimaryCodes = []int32{10107, 13435, 10058}
nodeIsShuttingDownCodes = []int32{11600, 91}
@@ -59,8 +74,10 @@ var (
ErrDeadlineWouldBeExceeded = fmt.Errorf(
"operation not sent to server, as Timeout would be exceeded: %w",
context.DeadlineExceeded)
- // ErrNegativeMaxTime is returned when MaxTime on an operation is a negative value.
- ErrNegativeMaxTime = errors.New("a negative value was provided for MaxTime on an operation")
+ // ErrSystemOverloadedError is returned when the server reports that it is overloaded
+ ErrSystemOverloadedError = "SystemOverloadedError"
+ // ErrRetryableError is returned when the server reports that the operation is retryable
+ ErrRetryableError = "RetryableError"
)
// QueryFailureError is an error representing a command failure as a document.
@@ -127,7 +144,7 @@ func (wce WriteCommandError) Error() string {
}
// Retryable returns true if the error is retryable
-func (wce WriteCommandError) Retryable(wireVersion *description.VersionRange) bool {
+func (wce WriteCommandError) Retryable(serverKind description.ServerKind, wireVersion *description.VersionRange) bool {
for _, label := range wce.Labels {
if label == RetryableWriteError {
return true
@@ -140,16 +157,14 @@ func (wce WriteCommandError) Retryable(wireVersion *description.VersionRange) bo
if wce.WriteConcernError == nil {
return false
}
- return wce.WriteConcernError.Retryable()
+ return wce.WriteConcernError.Retryable(serverKind, wireVersion)
}
// HasErrorLabel returns true if the error contains the specified label.
func (wce WriteCommandError) HasErrorLabel(label string) bool {
- if wce.Labels != nil {
- for _, l := range wce.Labels {
- if l == label {
- return true
- }
+ for _, l := range wce.Labels {
+ if l == label {
+ return true
}
}
return false
@@ -175,7 +190,14 @@ func (wce WriteConcernError) Error() string {
}
// Retryable returns true if the error is retryable
-func (wce WriteConcernError) Retryable() bool {
+func (wce WriteConcernError) Retryable(serverKind description.ServerKind, wireVersion *description.VersionRange) bool {
+ if serverKind == description.ServerKindMongos && wireVersion.Max < 9 {
+ // For a pre-4.4 mongos response, we can trust that mongos will have already
+ // retried the operation if necessary. Drivers should not retry to avoid
+ // "excessive retrying".
+ return false
+ }
+
for _, code := range retryableCodes {
if wce.Code == int64(code) {
return true
@@ -283,11 +305,9 @@ func (e Error) Unwrap() error {
// HasErrorLabel returns true if the error contains the specified label.
func (e Error) HasErrorLabel(label string) bool {
- if e.Labels != nil {
- for _, l := range e.Labels {
- if l == label {
- return true
- }
+ for _, l := range e.Labels {
+ if l == label {
+ return true
}
}
return false
@@ -378,7 +398,7 @@ func (e Error) NamespaceNotFound() bool {
// ExtractErrorFromServerResponse extracts an error from a server response bsoncore.Document
// if there is one. Also used in testing for SDAM.
-func ExtractErrorFromServerResponse(ctx context.Context, doc bsoncore.Document) error {
+func ExtractErrorFromServerResponse(doc bsoncore.Document) error {
var errmsg, codeName string
var code int32
var labels []string
@@ -394,19 +414,19 @@ func ExtractErrorFromServerResponse(ctx context.Context, doc bsoncore.Document)
switch elem.Key() {
case "ok":
switch elem.Value().Type {
- case bson.TypeInt32:
+ case bsoncore.TypeInt32:
if elem.Value().Int32() == 1 {
ok = true
}
- case bson.TypeInt64:
+ case bsoncore.TypeInt64:
if elem.Value().Int64() == 1 {
ok = true
}
- case bson.TypeDouble:
+ case bsoncore.TypeDouble:
if elem.Value().Double() == 1 {
ok = true
}
- case bson.TypeBoolean:
+ case bsoncore.TypeBoolean:
if elem.Value().Boolean() {
ok = true
}
@@ -503,7 +523,7 @@ func ExtractErrorFromServerResponse(ctx context.Context, doc bsoncore.Document)
if !ok {
break
}
- version, err := description.NewTopologyVersion(bson.Raw(doc))
+ version, err := driverutil.NewTopologyVersion(bson.Raw(doc))
if err == nil {
tv = version
}
@@ -524,15 +544,15 @@ func ExtractErrorFromServerResponse(ctx context.Context, doc bsoncore.Document)
Raw: doc,
}
- // If CSOT is enabled and we get a MaxTimeMSExpired error, assume that
- // the error was caused by setting "maxTimeMS" on the command based on
- // the context deadline or on "timeoutMS". In that case, make the error
- // wrap context.DeadlineExceeded so that users can always check
+ // If we get a MaxTimeMSExpired error, assume that the error was caused
+ // by setting "maxTimeMS" on the command based on the context deadline
+ // or on "timeoutMS". In that case, make the error wrap
+ // context.DeadlineExceeded so that users can always check
//
// errors.Is(err, context.DeadlineExceeded)
//
// for either client-side or server-side timeouts.
- if csot.IsTimeoutContext(ctx) && err.Code == 50 {
+ if err.Code == 50 {
err.Wrapped = context.DeadlineExceeded
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/legacy.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/legacy.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/legacy.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/legacy.go
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet/connection.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet/connection.go
new file mode 100644
index 000000000..5190c92a8
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet/connection.go
@@ -0,0 +1,137 @@
+// Copyright (C) MongoDB, Inc. 2023-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 mnet
+
+import (
+ "context"
+ "io"
+ "sync/atomic"
+
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+)
+
+// ReadWriteCloser represents a Connection where server operations
+// can read from, written to, and closed.
+type ReadWriteCloser interface {
+ Read(ctx context.Context) ([]byte, error)
+ Write(ctx context.Context, wm []byte) error
+ io.Closer
+}
+
+// Describer represents a Connection that can be described.
+type Describer interface {
+ Description() description.Server
+ ID() string
+ ServerConnectionID() *int64
+ DriverConnectionID() int64
+ Address() address.Address
+ Stale() bool
+ OIDCTokenGenID() uint64
+ SetOIDCTokenGenID(uint64)
+}
+
+// Streamer represents a Connection that supports streaming wire protocol
+// messages using the moreToCome and exhaustAllowed flags.
+//
+// The SetStreaming and CurrentlyStreaming functions correspond to the
+// moreToCome flag on server responses. If a response has moreToCome set,
+// SetStreaming(true) will be called and CurrentlyStreaming() should return
+// true.
+//
+// CanStream corresponds to the exhaustAllowed flag. The operations layer will
+// set exhaustAllowed on outgoing wire messages to inform the server that the
+// driver supports streaming.
+type Streamer interface {
+ SetStreaming(bool)
+ CurrentlyStreaming() bool
+ SupportsStreaming() bool
+}
+
+// Compressor is an interface used to compress wire messages. If a Connection
+// supports compression it should implement this interface as well. The
+// CompressWireMessage method will be called during the execution of an
+// operation if the wire message is allowed to be compressed.
+type Compressor interface {
+ CompressWireMessage(src, dst []byte) ([]byte, error)
+}
+
+// Pinner represents a Connection that can be pinned by one or more cursors or
+// transactions. Implementations of this interface should maintain the following
+// invariants:
+//
+// 1. Each Pin* call should increment the number of references for the
+// connection.
+// 2. Each Unpin* call should decrement the number of references for the
+// connection.
+// 3. Calls to Close() should be ignored until all resources have unpinned the
+// connection.
+type Pinner interface {
+ PinToCursor() error
+ PinToTransaction() error
+ UnpinFromCursor() error
+ UnpinFromTransaction() error
+}
+
+// Connection represents a connection to a MongoDB server.
+type Connection struct {
+ closed uint32
+
+ ReadWriteCloser
+ Describer
+ Streamer
+ Compressor
+ Pinner
+}
+
+// Close closes the connection.
+func (c *Connection) Close() error {
+ // Logically mark the connection as closed.
+ atomic.StoreUint32(&c.closed, 1)
+
+ return c.ReadWriteCloser.Close()
+}
+
+// Closed returns true if the connection has been logically closed.
+func (c *Connection) Closed() bool {
+ return atomic.LoadUint32(&c.closed) == 1
+}
+
+// NewConnection creates a new Connection with the provided component. This
+// constructor returns a component that is already a Connection to avoid
+// mis-asserting the composite interfaces.
+func NewConnection(component interface {
+ ReadWriteCloser
+ Describer
+},
+) *Connection {
+ if _, ok := component.(*Connection); ok {
+ return component.(*Connection)
+ }
+
+ conn := &Connection{
+ ReadWriteCloser: component,
+ }
+
+ if describer, ok := component.(Describer); ok {
+ conn.Describer = describer
+ }
+
+ if streamer, ok := component.(Streamer); ok {
+ conn.Streamer = streamer
+ }
+
+ if compressor, ok := component.(Compressor); ok {
+ conn.Compressor = compressor
+ }
+
+ if pinner, ok := component.(Pinner); ok {
+ conn.Pinner = pinner
+ }
+
+ return conn
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/binary.go
similarity index 99%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/binary.go
index 4e4b51d74..9a6cab0c5 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/binary.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build cse
-// +build cse
package mongocrypt
@@ -14,6 +13,7 @@ package mongocrypt
#include
*/
import "C"
+
import (
"unsafe"
)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors.go
index 3401e7384..eb3746e6a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors.go
@@ -5,12 +5,12 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build cse
-// +build cse
package mongocrypt
// #include
import "C"
+
import (
"fmt"
)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors_not_enabled.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors_not_enabled.go
index 706a0f9e7..970de4462 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors_not_enabled.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !cse
-// +build !cse
package mongocrypt
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt.go
index c5044f8f5..0f003143a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build cse
-// +build cse
package mongocrypt
@@ -15,18 +14,20 @@ package mongocrypt
// #include
// #include
import "C"
+
import (
"context"
"errors"
"fmt"
"net/http"
+ "time"
"unsafe"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/httputil"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options"
)
type kmsProvider interface {
@@ -53,6 +54,7 @@ func NewMongoCrypt(opts *options.MongoCryptOptions) (*MongoCrypt, error) {
if wrapped == nil {
return nil, errors.New("could not create new mongocrypt object")
}
+ C.mongocrypt_setopt_retry_kms(wrapped, true)
httpClient := opts.HTTPClient
if httpClient == nil {
httpClient = httputil.DefaultHTTPClient
@@ -85,9 +87,20 @@ func NewMongoCrypt(opts *options.MongoCryptOptions) (*MongoCrypt, error) {
}
if opts.BypassQueryAnalysis {
- C.mongocrypt_setopt_bypass_query_analysis(wrapped)
+ C.mongocrypt_setopt_bypass_query_analysis(crypt.wrapped)
}
+ var keyExpirationMs uint64 = 60_000 // 60,000 ms
+ if opts.KeyExpiration != nil {
+ if *opts.KeyExpiration <= 0 {
+ keyExpirationMs = 0
+ } else {
+ // find the ceiling integer millisecond for the expiration
+ keyExpirationMs = uint64((*opts.KeyExpiration + time.Millisecond - 1) / time.Millisecond)
+ }
+ }
+ C.mongocrypt_setopt_key_expiration(crypt.wrapped, C.uint64_t(keyExpirationMs))
+
// If loading the crypt_shared library isn't disabled, set the default library search path "$SYSTEM"
// and set a library override path if one was provided.
if !opts.CryptSharedLibDisabled {
@@ -298,6 +311,55 @@ func (m *MongoCrypt) createExplicitEncryptionContext(opts *options.ExplicitEncry
}
}
+ if opts.TextOptions != nil {
+ idx, mongocryptDoc := bsoncore.AppendDocumentStart(nil)
+ if opts.TextOptions.Substring != nil {
+ substringIdx, substringDoc := bsoncore.AppendDocumentStart(nil)
+ substringDoc = bsoncore.AppendInt32Element(substringDoc, "strMaxLength", opts.TextOptions.Substring.StrMaxLength)
+ substringDoc = bsoncore.AppendInt32Element(substringDoc, "strMinQueryLength", opts.TextOptions.Substring.StrMinQueryLength)
+ substringDoc = bsoncore.AppendInt32Element(substringDoc, "strMaxQueryLength", opts.TextOptions.Substring.StrMaxQueryLength)
+ substringDoc, err := bsoncore.AppendDocumentEnd(substringDoc, substringIdx)
+ if err != nil {
+ return nil, fmt.Errorf("error building substring doc: %w", err)
+ }
+ mongocryptDoc = bsoncore.AppendDocumentElement(mongocryptDoc, "substring", substringDoc)
+ }
+ if opts.TextOptions.Prefix != nil {
+ prefixIdx, prefixDoc := bsoncore.AppendDocumentStart(nil)
+ prefixDoc = bsoncore.AppendInt32Element(prefixDoc, "strMinQueryLength", opts.TextOptions.Prefix.StrMinQueryLength)
+ prefixDoc = bsoncore.AppendInt32Element(prefixDoc, "strMaxQueryLength", opts.TextOptions.Prefix.StrMaxQueryLength)
+ prefixDoc, err := bsoncore.AppendDocumentEnd(prefixDoc, prefixIdx)
+ if err != nil {
+ return nil, fmt.Errorf("error building prefix doc: %w", err)
+ }
+ mongocryptDoc = bsoncore.AppendDocumentElement(mongocryptDoc, "prefix", prefixDoc)
+ }
+ if opts.TextOptions.Suffix != nil {
+ suffixIdx, suffixDoc := bsoncore.AppendDocumentStart(nil)
+ suffixDoc = bsoncore.AppendInt32Element(suffixDoc, "strMinQueryLength", opts.TextOptions.Suffix.StrMinQueryLength)
+ suffixDoc = bsoncore.AppendInt32Element(suffixDoc, "strMaxQueryLength", opts.TextOptions.Suffix.StrMaxQueryLength)
+ suffixDoc, err := bsoncore.AppendDocumentEnd(suffixDoc, suffixIdx)
+ if err != nil {
+ return nil, fmt.Errorf("error building suffix doc: %w", err)
+ }
+ mongocryptDoc = bsoncore.AppendDocumentElement(mongocryptDoc, "suffix", suffixDoc)
+ }
+ mongocryptDoc = bsoncore.AppendBooleanElement(mongocryptDoc, "caseSensitive", opts.TextOptions.CaseSensitive)
+ mongocryptDoc = bsoncore.AppendBooleanElement(mongocryptDoc, "diacriticSensitive", opts.TextOptions.DiacriticSensitive)
+
+ mongocryptDoc, err := bsoncore.AppendDocumentEnd(mongocryptDoc, idx)
+ if err != nil {
+ return nil, fmt.Errorf("error building text options doc: %w", err)
+ }
+
+ mongocryptBinary := newBinaryFromBytes(mongocryptDoc)
+ defer mongocryptBinary.close()
+
+ if ok := C.mongocrypt_ctx_setopt_algorithm_text(ctx.wrapped, mongocryptBinary.wrapped); !ok {
+ return nil, fmt.Errorf("error setting text algorithm option: %w", ctx.createErrorFromStatus())
+ }
+ }
+
algoStr := C.CString(opts.Algorithm)
defer C.free(unsafe.Pointer(algoStr))
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context.go
index 04e98d01c..8aa31cd0b 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context.go
@@ -5,14 +5,14 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build cse
-// +build cse
package mongocrypt
// #include
import "C"
+
import (
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// Context represents a mongocrypt_ctx_t handle
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go
index 734662e71..14bc764d1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go
@@ -5,12 +5,11 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !cse
-// +build !cse
package mongocrypt
import (
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// Context represents a mongocrypt_ctx_t handle
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go
index 296a22315..fb3c35433 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go
@@ -5,12 +5,12 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build cse
-// +build cse
package mongocrypt
// #include
import "C"
+import "time"
// KmsContext represents a mongocrypt_kms_ctx_t handle.
type KmsContext struct {
@@ -41,6 +41,8 @@ func (kc *KmsContext) KMSProvider() string {
// Message returns the message to send to the KMS.
func (kc *KmsContext) Message() ([]byte, error) {
+ time.Sleep(time.Duration(C.mongocrypt_kms_ctx_usleep(kc.wrapped)) * time.Microsecond)
+
msgBinary := newBinary()
defer msgBinary.close()
@@ -74,3 +76,11 @@ func (kc *KmsContext) createErrorFromStatus() error {
C.mongocrypt_kms_ctx_status(kc.wrapped, status)
return errorFromStatus(status)
}
+
+// RequestError returns the source of the network error for KMS requests.
+func (kc *KmsContext) RequestError() error {
+ if bool(C.mongocrypt_kms_ctx_fail(kc.wrapped)) {
+ return nil
+ }
+ return kc.createErrorFromStatus()
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go
similarity index 88%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go
index 6bce2f029..acb24e4b0 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !cse
-// +build !cse
package mongocrypt
@@ -37,3 +36,8 @@ func (kc *KmsContext) BytesNeeded() int32 {
func (kc *KmsContext) FeedResponse([]byte) error {
panic(cseNotSupportedMsg)
}
+
+// RequestError returns the source of the network error for KMS requests.
+func (kc *KmsContext) RequestError() error {
+ panic(cseNotSupportedMsg)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go
index 80f500085..1b78b05cc 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !cse
-// +build !cse
// Package mongocrypt is intended for internal use only. It is made available to
// facilitate use cases that require access to internal MongoDB driver
@@ -19,8 +18,8 @@ package mongocrypt
import (
"context"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options"
)
const cseNotSupportedMsg = "client-side encryption not enabled. add the cse build tag to support"
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go
similarity index 57%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go
index 81805e714..2c3673dab 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go
@@ -7,8 +7,8 @@
package options
import (
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// DataKeyOptions specifies options for creating a new data key.
@@ -18,29 +18,6 @@ type DataKeyOptions struct {
MasterKey bsoncore.Document
}
-// DataKey creates a new DataKeyOptions instance.
-func DataKey() *DataKeyOptions {
- return &DataKeyOptions{}
-}
-
-// SetKeyAltNames specifies alternate key names.
-func (dko *DataKeyOptions) SetKeyAltNames(names []string) *DataKeyOptions {
- dko.KeyAltNames = names
- return dko
-}
-
-// SetMasterKey specifies the master key.
-func (dko *DataKeyOptions) SetMasterKey(key bsoncore.Document) *DataKeyOptions {
- dko.MasterKey = key
- return dko
-}
-
-// SetKeyMaterial specifies the key material.
-func (dko *DataKeyOptions) SetKeyMaterial(keyMaterial []byte) *DataKeyOptions {
- dko.KeyMaterial = keyMaterial
- return dko
-}
-
// QueryType describes the type of query the result of Encrypt is used for.
type QueryType int
@@ -51,12 +28,13 @@ const (
// ExplicitEncryptionOptions specifies options for configuring an explicit encryption context.
type ExplicitEncryptionOptions struct {
- KeyID *primitive.Binary
+ KeyID *bson.Binary
KeyAltName *string
Algorithm string
QueryType string
ContentionFactor *int64
RangeOptions *ExplicitRangeOptions
+ TextOptions *ExplicitTextOptions
}
// ExplicitRangeOptions specifies options for the range index.
@@ -68,13 +46,41 @@ type ExplicitRangeOptions struct {
Precision *int32
}
+// ExplicitTextOptions specifies options for the text query.
+type ExplicitTextOptions struct {
+ Substring *SubstringOptions
+ Prefix *PrefixOptions
+ Suffix *SuffixOptions
+ CaseSensitive bool
+ DiacriticSensitive bool
+}
+
+// SubstringOptions specifies options to support substring queries.
+type SubstringOptions struct {
+ StrMaxLength int32
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
+// PrefixOptions specifies options to support prefix queries.
+type PrefixOptions struct {
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
+// SuffixOptions specifies options to support suffix queries.
+type SuffixOptions struct {
+ StrMinQueryLength int32
+ StrMaxQueryLength int32
+}
+
// ExplicitEncryption creates a new ExplicitEncryptionOptions instance.
func ExplicitEncryption() *ExplicitEncryptionOptions {
return &ExplicitEncryptionOptions{}
}
// SetKeyID sets the key identifier.
-func (eeo *ExplicitEncryptionOptions) SetKeyID(keyID primitive.Binary) *ExplicitEncryptionOptions {
+func (eeo *ExplicitEncryptionOptions) SetKeyID(keyID bson.Binary) *ExplicitEncryptionOptions {
eeo.KeyID = &keyID
return eeo
}
@@ -109,6 +115,12 @@ func (eeo *ExplicitEncryptionOptions) SetRangeOptions(ro ExplicitRangeOptions) *
return eeo
}
+// SetTextOptions specifies the text options.
+func (eeo *ExplicitEncryptionOptions) SetTextOptions(to ExplicitTextOptions) *ExplicitEncryptionOptions {
+ eeo.TextOptions = &to
+ return eeo
+}
+
// RewrapManyDataKeyOptions represents all possible options used to decrypt and encrypt all matching data keys with a
// possibly new masterKey.
type RewrapManyDataKeyOptions struct {
@@ -118,41 +130,3 @@ type RewrapManyDataKeyOptions struct {
// MasterKey identifies the new masterKey. If omitted, rewraps with the current masterKey.
MasterKey bsoncore.Document
}
-
-// RewrapManyDataKey creates a new RewrapManyDataKeyOptions instance.
-func RewrapManyDataKey() *RewrapManyDataKeyOptions {
- return new(RewrapManyDataKeyOptions)
-}
-
-// SetProvider sets the value for the Provider field.
-func (rmdko *RewrapManyDataKeyOptions) SetProvider(provider string) *RewrapManyDataKeyOptions {
- rmdko.Provider = &provider
- return rmdko
-}
-
-// SetMasterKey sets the value for the MasterKey field.
-func (rmdko *RewrapManyDataKeyOptions) SetMasterKey(masterKey bsoncore.Document) *RewrapManyDataKeyOptions {
- rmdko.MasterKey = masterKey
- return rmdko
-}
-
-// MergeRewrapManyDataKeyOptions combines the given RewrapManyDataKeyOptions instances into a single
-// RewrapManyDataKeyOptions in a last one wins fashion.
-//
-// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
-// single options struct instead.
-func MergeRewrapManyDataKeyOptions(opts ...*RewrapManyDataKeyOptions) *RewrapManyDataKeyOptions {
- rmdkOpts := RewrapManyDataKey()
- for _, rmdko := range opts {
- if rmdko == nil {
- continue
- }
- if provider := rmdko.Provider; provider != nil {
- rmdkOpts.Provider = provider
- }
- if masterKey := rmdko.MasterKey; masterKey != nil {
- rmdkOpts.MasterKey = masterKey
- }
- }
- return rmdkOpts
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_options.go
new file mode 100644
index 000000000..d97c535ed
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_options.go
@@ -0,0 +1,26 @@
+// 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 (
+ "net/http"
+ "time"
+
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+)
+
+// MongoCryptOptions specifies options to configure a MongoCrypt instance.
+type MongoCryptOptions struct {
+ KmsProviders bsoncore.Document
+ LocalSchemaMap map[string]bsoncore.Document
+ BypassQueryAnalysis bool
+ EncryptedFieldsMap map[string]bsoncore.Document
+ CryptSharedLibDisabled bool
+ CryptSharedLibOverridePath string
+ HTTPClient *http.Client
+ KeyExpiration *time.Duration
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/state.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/state.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/state.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/state.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/cache.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/cache.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/cache.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/cache.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/config.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/config.go
similarity index 97%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/config.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/config.go
index 5b720cd59..5f2e944d0 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/config.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/config.go
@@ -12,7 +12,7 @@ import (
"fmt"
"net/http"
- "go.mongodb.org/mongo-driver/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
"golang.org/x/crypto/ocsp"
)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/ocsp.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/ocsp.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/options.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/options.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation.go
similarity index 69%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation.go
index ec6f69eca..b8be12ebb 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation.go
@@ -18,26 +18,26 @@ import (
"sync"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/handshake"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/csot"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/handshake"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/internal/ptrutil"
+ "go.mongodb.org/mongo-driver/v2/internal/randutil"
+ "go.mongodb.org/mongo-driver/v2/internal/serverselector"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)
-const defaultLocalThreshold = 15 * time.Millisecond
-
var (
// ErrNoDocCommandResponse occurs when the server indicated a response existed, but none was found.
ErrNoDocCommandResponse = errors.New("command returned no documents")
@@ -47,17 +47,32 @@ var (
ErrReplyDocumentMismatch = errors.New("number of documents returned does not match numberReturned field")
// ErrNonPrimaryReadPref is returned when a read is attempted in a transaction with a non-primary read preference.
ErrNonPrimaryReadPref = errors.New("read preference in a transaction must be primary")
+ // ErrEmptyReadConcern indicates that a read concern has no fields set.
+ ErrEmptyReadConcern = errors.New("a read concern must have at least one field set")
+ // ErrEmptyWriteConcern indicates that a write concern has no fields set.
+ ErrEmptyWriteConcern = errors.New("a write concern must have at least one field set")
+ // ErrDocumentTooLarge occurs when a document that is larger than the maximum size accepted by a
+ // server is passed to an insert command.
+ ErrDocumentTooLarge = errors.New("an inserted document is too large")
// errDatabaseNameEmpty occurs when a database name is not provided.
errDatabaseNameEmpty = errors.New("database name cannot be empty")
+ // errNegativeW indicates that a negative integer `w` field was specified.
+ errNegativeW = errors.New("write concern `w` field cannot be a negative number")
+ // errInconsistent indicates that an inconsistent write concern was specified.
+ errInconsistent = errors.New("a write concern cannot have both w=0 and j=true")
)
const (
- // maximum BSON object size when client side encryption is enabled
- cryptMaxBsonObjectSize uint32 = 2097152
+ // maximum BSON object size when in-use encryption is enabled
+ cryptMaxBsonObjectSize int = 2097152
// minimum wire version necessary to use automatic encryption
cryptMinWireVersion int32 = 8
// minimum wire version necessary to use read snapshots
readSnapshotMinWireVersion int32 = 13
+
+ defaultLocalThreshold = 15 * time.Millisecond
+ backoffInitial = 100 * time.Millisecond
+ backoffMax = 10_000 * time.Millisecond
)
// RetryablePoolError is a connection pool error that can be retried while executing an operation.
@@ -92,16 +107,20 @@ type opReply struct {
// startedInformation keeps track of all of the information necessary for monitoring started events.
type startedInformation struct {
- cmd bsoncore.Document
- requestID int32
- cmdName string
- documentSequenceIncluded bool
- connID string
- driverConnectionID uint64 // TODO(GODRIVER-2824): change type to int64.
- serverConnID *int64
- redacted bool
- serviceID *primitive.ObjectID
- serverAddress address.Address
+ cmd bsoncore.Document
+ requestID int32
+ cmdName string
+ documentSequences []struct {
+ identifier string
+ data []byte
+ }
+ processedBatches int
+ connID string
+ driverConnectionID int64
+ serverConnID *int64
+ redacted bool
+ serviceID *bson.ObjectID
+ serverAddress address.Address
}
// finishedInformation keeps track of all of the information necessary for monitoring success and failure events.
@@ -111,30 +130,14 @@ type finishedInformation struct {
response bsoncore.Document
cmdErr error
connID string
- driverConnectionID uint64 // TODO(GODRIVER-2824): change type to int64.
+ driverConnectionID int64
serverConnID *int64
redacted bool
- serviceID *primitive.ObjectID
+ serviceID *bson.ObjectID
serverAddress address.Address
duration time.Duration
}
-// convertInt64PtrToInt32Ptr will convert an int64 pointer reference to an int32 pointer
-// reference. If the int64 value cannot be converted to int32 without causing
-// an overflow, then this function will return nil.
-func convertInt64PtrToInt32Ptr(i64 *int64) *int32 {
- if i64 == nil {
- return nil
- }
-
- if *i64 > math.MaxInt32 || *i64 < math.MinInt32 {
- return nil
- }
-
- i32 := int32(*i64)
- return &i32
-}
-
// success returns true if there was no command error or the command error is a
// "WriteCommandError". Commands that executed on the server and return a status
// of { ok: 1.0 } are considered successful commands and MUST generate a
@@ -151,28 +154,59 @@ func (info finishedInformation) success() bool {
// ResponseInfo contains the context required to parse a server response.
type ResponseInfo struct {
- ServerResponse bsoncore.Document
Server Server
- Connection Connection
+ Connection *mnet.Connection
ConnectionDescription description.Server
CurrentIndex int
+ Error error
}
-func redactStartedInformationCmd(op Operation, info startedInformation) bson.Raw {
+func redactStartedInformationCmd(info startedInformation) bson.Raw {
+ intLen := func(n int) int {
+ if n == 0 {
+ return 1 // Special case: 0 has one digit
+ }
+ count := 0
+ for n > 0 {
+ n /= 10
+ count++
+ }
+ return count
+ }
+
var cmdCopy bson.Raw
// Make a copy of the command. Redact if the command is security
// sensitive and cannot be monitored. If there was a type 1 payload for
// the current batch, convert it to a BSON array
if !info.redacted {
- cmdCopy = make([]byte, len(info.cmd))
- copy(cmdCopy, info.cmd)
+ cmdLen := len(info.cmd)
+ for _, seq := range info.documentSequences {
+ cmdLen += 7 // 2 (header) + 4 (array length) + 1 (array end)
+ cmdLen += len(seq.identifier)
+ data := seq.data
+ i := 0
+ for {
+ doc, rest, ok := bsoncore.ReadDocument(data)
+ if !ok {
+ break
+ }
+ data = rest
+ cmdLen += len(doc)
+ cmdLen += intLen(i)
+ i++
+ }
+ }
- if info.documentSequenceIncluded {
+ cmdCopy = make([]byte, 0, cmdLen)
+ cmdCopy = append(cmdCopy, info.cmd...)
+
+ if len(info.documentSequences) > 0 {
// remove 0 byte at end
cmdCopy = cmdCopy[:len(info.cmd)-1]
- cmdCopy = op.addBatchArray(cmdCopy)
-
+ for _, seq := range info.documentSequences {
+ cmdCopy = appendDocumentArray(cmdCopy, seq.identifier, seq.data)
+ }
// add back 0 byte and update length
cmdCopy, _ = bsoncore.AppendDocumentEnd(cmdCopy, 0)
}
@@ -189,6 +223,16 @@ func redactFinishedInformationResponse(info finishedInformation) bson.Raw {
return bson.Raw{}
}
+// OperationBatches contains the documents that are split when executing a write command that potentially
+// has more documents than can fit in a single command.
+type OperationBatches interface {
+ AppendBatchSequence(dst []byte, maxCount int, totalSize int) (int, []byte, error)
+ AppendBatchArray(dst []byte, maxCount int, totalSize int) (int, []byte, error)
+ IsOrdered() *bool
+ AdvanceBatches(n int)
+ Size() int
+}
+
// Operation is used to execute an operation. It contains all of the common code required to
// select a server, transform an operation into a command, write the command to a connection from
// the selected server, read a response from that connection, process the response, and potentially
@@ -218,7 +262,7 @@ type Operation struct {
// ProcessResponseFn is called after a response to the command is returned. The server is
// provided for types like Cursor that are required to run subsequent commands using the same
// server.
- ProcessResponseFn func(ResponseInfo) error
+ ProcessResponseFn func(context.Context, bsoncore.Document, ResponseInfo) error
// Selector is the server selector that's used during both initial server selection and
// subsequent selection for retries. Depending on the Deployment implementation, the
@@ -267,6 +311,14 @@ type Operation struct {
// possible unless RetryNone is used.
RetryMode *RetryMode
+ // MaxAdaptiveRetries indicates the maximum number of times the driver should retry operations
+ // that fail with a server side overload error.
+ MaxAdaptiveRetries uint
+
+ // EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+ // to the list of deprioritized server addresses.
+ EnableOverloadRetargeting bool
+
// Type specifies the kind of operation this is. There is only one mode that enables retry: Write.
// For more information about what this mode does, please refer to it's definition. Both Type and
// RetryMode must be set for retryability to be enabled.
@@ -274,9 +326,8 @@ type Operation struct {
// Batches contains the documents that are split when executing a write command that potentially
// has more documents than can fit in a single command. This should only be specified for
- // commands that are batch compatible. For more information, please refer to the definition of
- // Batches.
- Batches *Batches
+ // commands that are batch compatible.
+ Batches OperationBatches
// Legacy sets the legacy type for this operation. There are only 3 types that require legacy
// support: find, getMore, and killCursors. For more information about LegacyOperationKind,
@@ -287,7 +338,7 @@ type Operation struct {
// no events will be reported.
CommandMonitor *event.CommandMonitor
- // Crypt specifies a Crypt object to use for automatic client side encryption and decryption.
+ // Crypt specifies a Crypt object to use for automatic in-use encryption and decryption.
Crypt Crypt
// ServerAPI specifies options used to configure the API version sent to the server.
@@ -297,9 +348,6 @@ type Operation struct {
// read preference will not be added to the command on wire versions < 13.
IsOutputAggregate bool
- // MaxTime specifies the maximum amount of time to allow the operation to run on the server.
- MaxTime *time.Duration
-
// Timeout is the amount of time that this operation can execute before returning an error. The default value
// nil, which means that the timeout of the operation's caller will be used.
Timeout *time.Duration
@@ -310,10 +358,9 @@ type Operation struct {
// OP_MSG as well as for logging server selection data.
Name string
- // OmitCSOTMaxTimeMS omits the automatically-calculated "maxTimeMS" from the
- // command when CSOT is enabled. It does not effect "maxTimeMS" set by
- // [Operation.MaxTime].
- OmitCSOTMaxTimeMS bool
+ // OmitMaxTimeMS will ensure that wire messages sent to the server in service
+ // of the operation do not contain a maxTimeMS field.
+ OmitMaxTimeMS bool
// Authenticator is the authenticator to use for this operation when a reauthentication is
// required.
@@ -331,67 +378,6 @@ func (op Operation) shouldEncrypt() bool {
return op.Crypt != nil && !op.Crypt.BypassAutoEncryption()
}
-// filterDeprioritizedServers will filter out the server candidates that have
-// been deprioritized by the operation due to failure.
-//
-// The server selector should try to select a server that is not in the
-// deprioritization list. However, if this is not possible (e.g. there are no
-// other healthy servers in the cluster), the selector may return a
-// deprioritized server.
-func filterDeprioritizedServers(candidates, deprioritized []description.Server) []description.Server {
- if len(deprioritized) == 0 {
- return candidates
- }
-
- dpaSet := make(map[address.Address]*description.Server)
- for i, srv := range deprioritized {
- dpaSet[srv.Addr] = &deprioritized[i]
- }
-
- allowed := []description.Server{}
-
- // Iterate over the candidates and append them to the allowdIndexes slice if
- // they are not in the deprioritizedServers list.
- for _, candidate := range candidates {
- if srv, ok := dpaSet[candidate.Addr]; !ok || !srv.Equal(candidate) {
- allowed = append(allowed, candidate)
- }
- }
-
- // If nothing is allowed, then all available servers must have been
- // deprioritized. In this case, return the candidates list as-is so that the
- // selector can find a suitable server
- if len(allowed) == 0 {
- return candidates
- }
-
- return allowed
-}
-
-// opServerSelector is a wrapper for the server selector that is assigned to the
-// operation. The purpose of this wrapper is to filter candidates with
-// operation-specific logic, such as deprioritizing failing servers.
-type opServerSelector struct {
- selector description.ServerSelector
- deprioritizedServers []description.Server
-}
-
-// SelectServer will filter candidates with operation-specific logic before
-// passing them onto the user-defined or default selector.
-func (oss *opServerSelector) SelectServer(
- topo description.Topology,
- candidates []description.Server,
-) ([]description.Server, error) {
- selectedServers, err := oss.selector.SelectServer(topo, candidates)
- if err != nil {
- return nil, err
- }
-
- filteredServers := filterDeprioritizedServers(selectedServers, oss.deprioritizedServers)
-
- return filteredServers, nil
-}
-
// selectServer handles performing server selection for an operation.
func (op Operation) selectServer(
ctx context.Context,
@@ -408,21 +394,22 @@ func (op Operation) selectServer(
if rp == nil {
rp = readpref.Primary()
}
- selector = description.CompositeSelector([]description.ServerSelector{
- description.ReadPrefSelector(rp),
- description.LatencySelector(defaultLocalThreshold),
- })
- }
- oss := &opServerSelector{
- selector: selector,
- deprioritizedServers: deprioritized,
+ selector = &serverselector.Composite{
+ Selectors: []description.ServerSelector{
+ &serverselector.ReadPref{ReadPref: rp},
+ &serverselector.Latency{Latency: defaultLocalThreshold},
+ },
+ }
}
+ // Wrap the selector to filter out deprioritized servers.
+ deprioritizedSelector := serverselector.NewDeprioritized(selector, deprioritized)
+
ctx = logger.WithOperationName(ctx, op.Name)
ctx = logger.WithOperationID(ctx, requestID)
- return op.Deployment.SelectServer(ctx, oss)
+ return op.Deployment.SelectServer(ctx, deprioritizedSelector)
}
// getServerAndConnection should be used to retrieve a Server and Connection to execute an operation.
@@ -430,11 +417,14 @@ func (op Operation) getServerAndConnection(
ctx context.Context,
requestID int32,
deprioritized []description.Server,
-) (Server, Connection, error) {
+) (Server, *mnet.Connection, error) {
+ ctx, cancel := csot.WithServerSelectionTimeout(ctx, op.Deployment.GetServerSelectionTimeout())
+ defer cancel()
+
server, err := op.selectServer(ctx, requestID, deprioritized)
if err != nil {
if op.Client != nil &&
- !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning() {
+ (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning() {
err = Error{
Message: err.Error(),
Labels: []string{TransientTransactionError},
@@ -447,7 +437,8 @@ func (op Operation) getServerAndConnection(
// If the provided client session has a pinned connection, it should be used for the operation because this
// indicates that we're in a transaction and the target server is behind a load balancer.
if op.Client != nil && op.Client.PinnedConnection != nil {
- return server, op.Client.PinnedConnection, nil
+ conn := mnet.NewConnection(op.Client.PinnedConnection)
+ return server, conn, nil
}
// Otherwise, default to checking out a connection from the server's pool.
@@ -457,19 +448,18 @@ func (op Operation) getServerAndConnection(
}
// If we're in load balanced mode and this is the first operation in a transaction, pin the session to a connection.
- if conn.Description().LoadBalanced() && op.Client != nil && op.Client.TransactionStarting() {
- pinnedConn, ok := conn.(PinnedConnection)
- if !ok {
+ if driverutil.IsServerLoadBalanced(conn.Description()) && op.Client != nil && op.Client.TransactionStarting() {
+ if conn.Pinner == nil {
// Close the original connection to avoid a leak.
_ = conn.Close()
return nil, nil, fmt.Errorf("expected Connection used to start a transaction to be a PinnedConnection, but got %T", conn)
}
- if err := pinnedConn.PinToTransaction(); err != nil {
+ if err := conn.PinToTransaction(); err != nil {
// Close the original connection to avoid a leak.
_ = conn.Close()
return nil, nil, fmt.Errorf("error incrementing connection reference count when starting a transaction: %w", err)
}
- op.Client.PinnedConnection = pinnedConn
+ op.Client.PinnedConnection = conn
}
return server, conn, nil
@@ -486,14 +476,14 @@ func (op Operation) Validate() error {
if op.Database == "" {
return errDatabaseNameEmpty
}
- if op.Client != nil && !writeconcern.AckWrite(op.WriteConcern) {
+ if op.Client != nil && !op.WriteConcern.Acknowledged() {
return errors.New("session provided for an unacknowledged write")
}
return nil
}
var memoryPool = sync.Pool{
- New: func() interface{} {
+ New: func() any {
// Start with 1kb buffers.
b := make([]byte, 1024)
// Return a pointer as the static analysis tool suggests.
@@ -508,15 +498,8 @@ func (op Operation) Execute(ctx context.Context) error {
return err
}
- // If op.Timeout is set, and context is not already a Timeout context, honor
- // op.Timeout in new Timeout context for operation execution.
- if op.Timeout != nil && !csot.IsTimeoutContext(ctx) {
- newCtx, cancelFunc := csot.MakeTimeoutContext(ctx, *op.Timeout)
- // Redefine ctx to be the new timeout-derived context.
- ctx = newCtx
- // Cancel the timeout-derived context at the end of Execute to avoid a context leak.
- defer cancelFunc()
- }
+ ctx, cancel := csot.WithTimeout(ctx, op.Timeout)
+ defer cancel()
if op.Client != nil {
if err := op.Client.StartCommand(); err != nil {
@@ -524,7 +507,7 @@ func (op Operation) Execute(ctx context.Context) error {
}
}
- var retries int
+ defaultRetries := ptrutil.Ptr(uint(0))
if op.RetryMode != nil {
switch op.Type {
case Write:
@@ -533,81 +516,115 @@ func (op Operation) Execute(ctx context.Context) error {
}
switch *op.RetryMode {
case RetryOnce, RetryOncePerCommand:
- retries = 1
+ defaultRetries = ptrutil.Ptr(uint(1))
case RetryContext:
- retries = -1
+ defaultRetries = nil
}
case Read:
switch *op.RetryMode {
case RetryOnce, RetryOncePerCommand:
- retries = 1
+ defaultRetries = ptrutil.Ptr(uint(1))
case RetryContext:
- retries = -1
+ defaultRetries = nil
}
}
- }
- // If context is a Timeout context, automatically set retries to -1 (infinite) if retrying is
- // enabled.
- retryEnabled := op.RetryMode != nil && op.RetryMode.Enabled()
- if csot.IsTimeoutContext(ctx) && retryEnabled {
- retries = -1
+
+ // If context is a Timeout context, automatically set retries to infinite (nil) if retrying is
+ // enabled.
+ if csot.IsTimeoutContext(ctx) && op.RetryMode.Enabled() {
+ defaultRetries = nil
+ }
}
var srvr Server
- var conn Connection
+ var conn *mnet.Connection
var res bsoncore.Document
var operationErr WriteCommandError
var prevErr error
var prevIndefiniteErr error
- batching := op.Batches.Valid()
+ var expDur time.Duration
+ var transactionState session.TransactionState
+ var isOverloadedError bool
+ var attempt uint
retrySupported := false
first := true
currIndex := 0
+ retries := defaultRetries
// deprioritizedServers are a running list of servers that should be
- // deprioritized during server selection. Per the specifications, we should
- // only ever deprioritize the "previous server".
+ // deprioritized during server selection. Servers are accumulated across
+ // retry attempts to avoid repeatedly selecting servers that have failed.
var deprioritizedServers []description.Server
// resetForRetry records the error that caused the retry, decrements retries, and resets the
// retry loop variables to request a new server and a new connection for the next attempt.
- resetForRetry := func(err error) {
- retries--
+ resetForRetry := func(err error) error {
+ attempt++
prevErr = err
- // Set the previous indefinite error to be returned in any case where a retryable write error does not have a
- // NoWritesPerfomed label (the definite case).
- if err, ok := err.(labeledError); ok {
- // If the "prevIndefiniteErr" is nil, then the current error is the first error encountered
- // during the retry attempt cycle. We must persist the first error in the case where all
- // following errors are labeled "NoWritesPerformed", which would otherwise raise nil as the
- // error.
- if prevIndefiniteErr == nil {
- prevIndefiniteErr = err
- }
+ // If the "prevIndefiniteErr" is nil, then the current error is the first error encountered
+ // during the retry attempt cycle.
+ if prevIndefiniteErr == nil {
+ prevIndefiniteErr = err
+ }
- // If the error is not labeled NoWritesPerformed and is retryable, then set the previous
- // indefinite error to be the current error.
- if !err.HasErrorLabel(NoWritesPerformed) && err.HasErrorLabel(RetryableWriteError) {
- prevIndefiniteErr = err
+ // Set the previous indefinite error to be returned only if:
+ // 1. The error does not have a NoWritesPerformed label (the definite case).
+ // 2. The error is not a driver exception (e.g. timeouts, network errors).
+ // 3. The error is not a CSOT timeout.
+ if lerr, ok := err.(labeledError); ok {
+ if !lerr.HasErrorLabel(NoWritesPerformed) {
+ var serverErr Error
+ isDriverException := errors.As(err, &serverErr) && serverErr.Code != 0
+ isCSOTTimeout := errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled)
+ if isDriverException && !isCSOTTimeout {
+ prevIndefiniteErr = err
+ }
}
}
// If we got a connection, close it immediately to release pool resources
// for subsequent retries.
if conn != nil {
- // If we are dealing with a sharded cluster, then mark the failed server
- // as "deprioritized".
- if desc := conn.Description; desc != nil && op.Deployment.Kind() == description.Sharded {
- deprioritizedServers = []description.Server{conn.Description()}
+ if op.Deployment.Kind() == description.TopologyKindSharded ||
+ (isOverloadedError && op.EnableOverloadRetargeting) {
+ deprioritizedServers = append(deprioritizedServers, conn.Description())
}
-
conn.Close()
}
+ // Revert TransactionState as ApplyCommand() advances the state.
+ if op.Client != nil {
+ op.Client.TransactionState = transactionState
+ }
+
// Set the server and connection to nil to request a new server and connection.
srvr = nil
conn = nil
+
+ if isOverloadedError {
+ isOverloadedError = false
+ if expDur == 0 {
+ expDur = backoffInitial
+ } else {
+ expDur *= 2
+ if expDur > backoffMax {
+ expDur = backoffMax
+ }
+ }
+ backoff := expDur * time.Duration(randutil.JitterInt63n(512)) / 512
+ if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < backoff {
+ return err
+ }
+ sleep := time.NewTimer(backoff)
+ select {
+ case <-ctx.Done():
+ sleep.Stop()
+ return err
+ case <-sleep.C:
+ }
+ }
+ return nil
}
wm := memoryPool.Get().(*[]byte)
@@ -632,17 +649,26 @@ func (op Operation) Execute(ctx context.Context) error {
return prevErr
}
+ allowedRetries := retries
+ retries = defaultRetries
+
requestID := wiremessage.NextRequestID()
+ if op.Client != nil {
+ transactionState = op.Client.TransactionState
+ }
+
// If the server or connection are nil, try to select a new server and get a new connection.
if srvr == nil || conn == nil {
srvr, conn, err = op.getServerAndConnection(ctx, requestID, deprioritizedServers)
if err != nil {
- // If the returned error is retryable and there are retries remaining (negative
- // retries means retry indefinitely), then retry the operation. Set the server
- // and connection to nil to request a new server and connection.
- if rerr, ok := err.(RetryablePoolError); ok && rerr.Retryable() && retries != 0 {
- resetForRetry(err)
+ // If the returned error is retryable and there are retries remaining (nil
+ // means retry indefinitely), then retry the operation. Set the server and
+ // connection to nil to request a new server and connection.
+ if rerr, ok := err.(RetryablePoolError); ok && rerr.Retryable() && (allowedRetries == nil || attempt < *allowedRetries) {
+ if err = resetForRetry(err); err != nil {
+ return err
+ }
continue
}
@@ -685,20 +711,17 @@ func (op Operation) Execute(ctx context.Context) error {
// Calling IncrementTxnNumber() for server descriptions or topologies that do not
// support retries (e.g. standalone topologies) will cause server errors. Only do this
// check for the first attempt to keep retried writes in the same transaction.
- if retrySupported && op.RetryMode != nil && op.Type == Write && op.Client != nil {
- op.Client.RetryWrite = false
- if op.RetryMode.Enabled() {
- op.Client.RetryWrite = true
- if !op.Client.Committing && !op.Client.Aborting {
- op.Client.IncrementTxnNumber()
- }
- }
+ retryEnabled := op.RetryMode != nil && op.RetryMode.Enabled()
+ needToIncrease := op.Client != nil && !op.Client.Committing && !op.Client.Aborting
+ if retrySupported && op.Type == Write && retryEnabled && needToIncrease {
+ op.Client.IncrementTxnNumber()
}
first = false
}
- maxTimeMS, err := op.calculateMaxTimeMS(ctx, srvr.RTTMonitor())
+ // Calculate maxTimeMS value to potentially be appended to the wire message.
+ maxTimeMS, err := op.calculateMaxTimeMS(ctx, srvr.RTTMonitor().Min(), srvr.RTTMonitor().Stats())
if err != nil {
return err
}
@@ -709,32 +732,18 @@ func (op Operation) Execute(ctx context.Context) error {
maxTimeMS = 0
}
- desc := description.SelectedServer{Server: conn.Description(), Kind: op.Deployment.Kind()}
-
- if batching {
- targetBatchSize := desc.MaxDocumentSize
- maxDocSize := desc.MaxDocumentSize
- if op.shouldEncrypt() {
- // For client-side encryption, we want the batch to be split at 2 MiB instead of 16MiB.
- // If there's only one document in the batch, it can be up to 16MiB, so we set target batch size to
- // 2MiB but max document size to 16MiB. This will allow the AdvanceBatch call to create a batch
- // with a single large document.
- targetBatchSize = cryptMaxBsonObjectSize
- }
-
- err = op.Batches.AdvanceBatch(int(desc.MaxBatchCount), int(targetBatchSize), int(maxDocSize))
- if err != nil {
- // TODO(GODRIVER-982): Should we also be returning operationErr?
- return err
- }
+ desc := description.SelectedServer{
+ Server: conn.Description(),
+ Kind: op.Deployment.Kind(),
}
+ var moreToCome bool
var startedInfo startedInformation
- *wm, startedInfo, err = op.createWireMessage(ctx, maxTimeMS, (*wm)[:0], desc, conn, requestID)
-
+ *wm, moreToCome, startedInfo, err = op.createWireMessage(ctx, maxTimeMS, (*wm)[:0], desc, conn, requestID)
if err != nil {
return err
}
+ retryEnabled := op.RetryMode != nil && op.RetryMode.Enabled()
// set extra data and send event if possible
startedInfo.connID = conn.ID()
@@ -756,11 +765,8 @@ func (op Operation) Execute(ctx context.Context) error {
op.publishStartedEvent(ctx, startedInfo)
- // get the moreToCome flag information before we compress
- moreToCome := wiremessage.IsMsgMoreToCome(*wm)
-
// compress wiremessage if allowed
- if compressor, ok := conn.(Compressor); ok && op.canCompress(startedInfo.cmdName) {
+ if compressor := conn.Compressor; compressor != nil && op.canCompress(startedInfo.cmdName) {
b := memoryPool.Get().(*[]byte)
*b, err = compressor.CompressWireMessage(*wm, (*b)[:0])
memoryPool.Put(wm)
@@ -778,7 +784,7 @@ func (op Operation) Execute(ctx context.Context) error {
serverConnID: startedInfo.serverConnID,
redacted: startedInfo.redacted,
serviceID: startedInfo.serviceID,
- serverAddress: desc.Server.Addr,
+ serverAddress: desc.Addr,
}
startedTime := time.Now()
@@ -789,14 +795,8 @@ func (op Operation) Execute(ctx context.Context) error {
if ctx.Err() != nil {
err = ctx.Err()
} else if deadline, ok := ctx.Deadline(); ok {
- if csot.IsTimeoutContext(ctx) && time.Now().Add(srvr.RTTMonitor().P90()).After(deadline) {
- err = fmt.Errorf(
- "remaining time %v until context deadline is less than 90th percentile network round-trip time: %w\n%v",
- time.Until(deadline),
- ErrDeadlineWouldBeExceeded,
- srvr.RTTMonitor().Stats())
- } else if time.Now().Add(srvr.RTTMonitor().Min()).After(deadline) {
- err = context.DeadlineExceeded
+ if time.Now().Add(srvr.RTTMonitor().Min()).After(deadline) {
+ err = fmt.Errorf("%w: %v", ErrDeadlineWouldBeExceeded, srvr.RTTMonitor().Stats())
}
}
@@ -827,34 +827,42 @@ func (op Operation) Execute(ctx context.Context) error {
// TODO(GODRIVER-2579): When refactoring the "Execute" method, consider creating a separate method for the
// error handling logic below. This will remove the necessity of the "checkError" goto label.
checkError:
- var perr error
switch tt := err.(type) {
case WriteCommandError:
if e := err.(WriteCommandError); retrySupported && op.Type == Write && e.UnsupportedStorageEngine() {
return ErrUnsupportedStorageEngine
}
+ isOverloadedError = tt.HasErrorLabel(ErrSystemOverloadedError)
+ if isOverloadedError && op.MaxAdaptiveRetries != 0 {
+ retries = ptrutil.Ptr(op.MaxAdaptiveRetries)
+ allowedRetries = ptrutil.Ptr(op.MaxAdaptiveRetries)
+ }
connDesc := conn.Description()
- retryableErr := tt.Retryable(connDesc.WireVersion)
+ retryableErr := tt.Retryable(connDesc.Kind, connDesc.WireVersion)
preRetryWriteLabelVersion := connDesc.WireVersion != nil && connDesc.WireVersion.Max < 9
inTransaction := op.Client != nil &&
- !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning()
+ (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning()
// If retry is enabled and the operation isn't in a transaction, add a RetryableWriteError label for
// retryable errors from pre-4.4 servers
if retryableErr && preRetryWriteLabelVersion && retryEnabled && !inTransaction {
tt.Labels = append(tt.Labels, RetryableWriteError)
}
+ olRetryErr := tt.HasErrorLabel(ErrRetryableError) && isOverloadedError
+ needRetry := (retrySupported && retryEnabled && retryableErr) || (op.MaxAdaptiveRetries != 0 && olRetryErr)
// If retries are supported for the current operation on the first server description,
- // the error is considered retryable, and there are retries remaining (negative retries
- // means retry indefinitely), then retry the operation.
- if retrySupported && retryableErr && retries != 0 {
- if op.Client != nil && op.Client.Committing {
+ // the error is considered retryable, and there are retries remaining (nil means retry
+ // indefinitely), then retry the operation.
+ if needRetry && (allowedRetries == nil || attempt < *allowedRetries) {
+ if op.Client != nil && op.Client.Committing && !olRetryErr {
// Apply majority write concern for retries
op.Client.UpdateCommitTransactionWriteConcern()
op.WriteConcern = op.Client.CurrentWc
}
- resetForRetry(tt)
+ if err = resetForRetry(tt); err != nil {
+ return err
+ }
continue
}
@@ -871,25 +879,26 @@ func (op Operation) Execute(ctx context.Context) error {
// If the operation isn't being retried, process the response
if op.ProcessResponseFn != nil {
info := ResponseInfo{
- ServerResponse: res,
Server: srvr,
Connection: conn,
ConnectionDescription: desc.Server,
CurrentIndex: currIndex,
+ Error: tt,
}
- _ = op.ProcessResponseFn(info)
- }
-
- if batching && len(tt.WriteErrors) > 0 && currIndex > 0 {
- for i := range tt.WriteErrors {
- tt.WriteErrors[i].Index += int64(currIndex)
- }
+ _ = op.ProcessResponseFn(ctx, res, info)
}
// If batching is enabled and either ordered is the default (which is true) or
// explicitly set to true and we have write errors, return the errors.
- if batching && (op.Batches.Ordered == nil || *op.Batches.Ordered) && len(tt.WriteErrors) > 0 {
- return tt
+ if op.Batches != nil && len(tt.WriteErrors) > 0 {
+ if currIndex > 0 {
+ for i := range tt.WriteErrors {
+ tt.WriteErrors[i].Index += int64(currIndex)
+ }
+ }
+ if isOrdered := op.Batches.IsOrdered(); isOrdered == nil || *isOrdered {
+ return tt
+ }
}
if op.Client != nil && op.Client.Committing && tt.WriteConcernError != nil {
// When running commitTransaction we return WriteConcernErrors as an Error.
@@ -933,7 +942,9 @@ func (op Operation) Execute(ctx context.Context) error {
op.Client.UpdateCommitTransactionWriteConcern()
op.WriteConcern = op.Client.CurrentWc
}
- resetForRetry(tt)
+ if err = resetForRetry(tt); err != nil {
+ return err
+ }
continue
}
}
@@ -947,13 +958,18 @@ func (op Operation) Execute(ctx context.Context) error {
return ErrUnsupportedStorageEngine
}
+ isOverloadedError = tt.HasErrorLabel(ErrSystemOverloadedError)
+ if isOverloadedError && op.MaxAdaptiveRetries != 0 {
+ retries = ptrutil.Ptr(op.MaxAdaptiveRetries)
+ allowedRetries = ptrutil.Ptr(op.MaxAdaptiveRetries)
+ }
connDesc := conn.Description()
var retryableErr bool
if op.Type == Write {
retryableErr = tt.RetryableWrite(connDesc.WireVersion)
preRetryWriteLabelVersion := connDesc.WireVersion != nil && connDesc.WireVersion.Max < 9
inTransaction := op.Client != nil &&
- !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning()
+ (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning()
// If retryWrites is enabled and the operation isn't in a transaction, add a RetryableWriteError label
// for network errors and retryable errors from pre-4.4 servers
if retryEnabled && !inTransaction &&
@@ -963,17 +979,21 @@ func (op Operation) Execute(ctx context.Context) error {
} else {
retryableErr = tt.RetryableRead()
}
+ olRetryErr := tt.HasErrorLabel(ErrRetryableError) && isOverloadedError
+ needRetry := (retrySupported && retryEnabled && retryableErr) || (op.MaxAdaptiveRetries != 0 && olRetryErr)
// If retries are supported for the current operation on the first server description,
- // the error is considered retryable, and there are retries remaining (negative retries
- // means retry indefinitely), then retry the operation.
- if retrySupported && retryableErr && retries != 0 {
- if op.Client != nil && op.Client.Committing {
+ // the error is considered retryable, and there are retries remaining (nil means retry
+ // indefinitely), then retry the operation.
+ if needRetry && (allowedRetries == nil || attempt < *allowedRetries) {
+ if op.Client != nil && op.Client.Committing && !olRetryErr {
// Apply majority write concern for retries
op.Client.UpdateCommitTransactionWriteConcern()
op.WriteConcern = op.Client.CurrentWc
}
- resetForRetry(tt)
+ if err = resetForRetry(tt); err != nil {
+ return err
+ }
continue
}
@@ -990,13 +1010,13 @@ func (op Operation) Execute(ctx context.Context) error {
// If the operation isn't being retried, process the response
if op.ProcessResponseFn != nil {
info := ResponseInfo{
- ServerResponse: res,
Server: srvr,
Connection: conn,
ConnectionDescription: desc.Server,
CurrentIndex: currIndex,
+ Error: tt,
}
- _ = op.ProcessResponseFn(info)
+ _ = op.ProcessResponseFn(ctx, res, info)
}
if op.Client != nil && op.Client.Committing && (retryableErr || tt.Code == 50) {
@@ -1010,27 +1030,27 @@ func (op Operation) Execute(ctx context.Context) error {
}
if op.ProcessResponseFn != nil {
info := ResponseInfo{
- ServerResponse: res,
Server: srvr,
Connection: conn,
ConnectionDescription: desc.Server,
CurrentIndex: currIndex,
+ Error: tt,
+ }
+ perr := op.ProcessResponseFn(ctx, res, info)
+ if perr != nil {
+ return perr
}
- perr = op.ProcessResponseFn(info)
- }
- if perr != nil {
- return perr
}
default:
if op.ProcessResponseFn != nil {
info := ResponseInfo{
- ServerResponse: res,
Server: srvr,
Connection: conn,
ConnectionDescription: desc.Server,
CurrentIndex: currIndex,
+ Error: tt,
}
- _ = op.ProcessResponseFn(info)
+ _ = op.ProcessResponseFn(ctx, res, info)
}
return err
}
@@ -1038,23 +1058,25 @@ func (op Operation) Execute(ctx context.Context) error {
// If we're batching and there are batches remaining, advance to the next batch. This isn't
// a retry, so increment the transaction number, reset the retries number, and don't set
// server or connection to nil to continue using the same connection.
- if batching && len(op.Batches.Documents) > 0 {
+ if op.Batches != nil && op.Batches.Size() > startedInfo.processedBatches {
// If retries are supported for the current operation on the current server description,
// the session isn't nil, and client retries are enabled, increment the txn number.
// Calling IncrementTxnNumber() for server descriptions or topologies that do not
// support retries (e.g. standalone topologies) will cause server errors.
- if retrySupported && op.Client != nil && op.RetryMode != nil {
- if op.RetryMode.Enabled() {
- op.Client.IncrementTxnNumber()
- }
+ if retrySupported && op.Client != nil && retryEnabled {
+ op.Client.IncrementTxnNumber()
+
// Reset the retries number for RetryOncePerCommand unless context is a Timeout context, in
- // which case retries should remain as -1 (as many times as possible).
+ // which case retries should remain as nil (as many times as possible).
if *op.RetryMode == RetryOncePerCommand && !csot.IsTimeoutContext(ctx) {
- retries = 1
+ retries = ptrutil.Ptr(uint(1))
}
}
- currIndex += len(op.Batches.Current)
- op.Batches.ClearBatch()
+ isOverloadedError = false
+ expDur = 0
+ attempt = 0
+ currIndex += startedInfo.processedBatches
+ op.Batches.AdvanceBatches(startedInfo.processedBatches)
continue
}
break
@@ -1074,15 +1096,15 @@ func (op Operation) retryable(desc description.Server) bool {
return true
}
if retryWritesSupported(desc) &&
- op.Client != nil && !(op.Client.TransactionInProgress() || op.Client.TransactionStarting()) &&
- writeconcern.AckWrite(op.WriteConcern) {
+ op.Client != nil && (!op.Client.TransactionInProgress() && !op.Client.TransactionStarting()) &&
+ op.WriteConcern.Acknowledged() {
return true
}
case Read:
if op.Client != nil && (op.Client.Committing || op.Client.Aborting) {
return true
}
- if op.Client == nil || !(op.Client.TransactionInProgress() || op.Client.TransactionStarting()) {
+ if op.Client == nil || (!op.Client.TransactionInProgress() && !op.Client.TransactionStarting()) {
return true
}
}
@@ -1091,23 +1113,23 @@ func (op Operation) retryable(desc description.Server) bool {
// roundTrip writes a wiremessage to the connection and then reads a wiremessage. The wm parameter
// is reused when reading the wiremessage.
-func (op Operation) roundTrip(ctx context.Context, conn Connection, wm []byte) ([]byte, error) {
- err := conn.WriteWireMessage(ctx, wm)
+func (op Operation) roundTrip(ctx context.Context, conn *mnet.Connection, wm []byte) ([]byte, error) {
+ err := conn.Write(ctx, wm)
if err != nil {
return nil, op.networkError(err)
}
return op.readWireMessage(ctx, conn)
}
-func (op Operation) readWireMessage(ctx context.Context, conn Connection) (result []byte, err error) {
- wm, err := conn.ReadWireMessage(ctx)
+func (op Operation) readWireMessage(ctx context.Context, conn *mnet.Connection) (result []byte, err error) {
+ wm, err := conn.Read(ctx)
if err != nil {
return nil, op.networkError(err)
}
// If we're using a streamable connection, we set its streaming state based on the moreToCome flag in the server
// response.
- if streamer, ok := conn.(StreamerConnection); ok {
+ if streamer := conn.Streamer; streamer != nil {
streamer.SetStreaming(wiremessage.IsMsgMoreToCome(wm))
}
@@ -1125,10 +1147,12 @@ func (op Operation) readWireMessage(ctx context.Context, conn Connection) (resul
}
// decode
- res, err := op.decodeResult(ctx, opcode, rem)
- // Update cluster/operation time and recovery tokens before handling the error to ensure we're properly updating
- // everything.
- op.updateClusterTimes(res)
+ res, err := op.decodeResult(opcode, rem)
+ // When a cluster clock is given, update cluster/operation time and recovery tokens before handling the error
+ // to ensure we're properly updating everything.
+ if op.Clock != nil {
+ op.updateClusterTimes(res)
+ }
op.updateOperationTime(res)
op.Client.UpdateRecoveryToken(bson.Raw(res))
@@ -1141,7 +1165,7 @@ func (op Operation) readWireMessage(ctx context.Context, conn Connection) (resul
return res, err
}
- // If there is no error, automatically attempt to decrypt all results if client side encryption is enabled.
+ // If there is no error, automatically attempt to decrypt all results if in-use encryption is enabled.
if op.Crypt != nil {
res, err = op.Crypt.Decrypt(ctx, res)
}
@@ -1171,8 +1195,8 @@ func (op Operation) networkError(err error) error {
// moreToComeRoundTrip writes a wiremessage to the provided connection. This is used when an OP_MSG is
// being sent with the moreToCome bit set.
-func (op *Operation) moreToComeRoundTrip(ctx context.Context, conn Connection, wm []byte) (result []byte, err error) {
- err = conn.WriteWireMessage(ctx, wm)
+func (op *Operation) moreToComeRoundTrip(ctx context.Context, conn *mnet.Connection, wm []byte) (result []byte, err error) {
+ err = conn.Write(ctx, wm)
if err != nil {
if op.Client != nil {
op.Client.MarkDirty()
@@ -1211,25 +1235,13 @@ func (Operation) decompressWireMessage(wm []byte) (wiremessage.OpCode, []byte, e
return opcode, uncompressed, nil
}
-func (op Operation) addBatchArray(dst []byte) []byte {
- aidx, dst := bsoncore.AppendArrayElementStart(dst, op.Batches.Identifier)
- for i, doc := range op.Batches.Current {
- dst = bsoncore.AppendDocumentElement(dst, strconv.Itoa(i), doc)
- }
- dst, _ = bsoncore.AppendArrayEnd(dst, aidx)
- return dst
-}
-
func (op Operation) createLegacyHandshakeWireMessage(
- maxTimeMS uint64,
+ ctx context.Context,
+ maxTimeMS int64,
dst []byte,
desc description.SelectedServer,
-) ([]byte, startedInformation, error) {
- var info startedInformation
+) (int, []byte, []byte, error) {
flags := op.secondaryOK(desc)
- var wmindex int32
- info.requestID = wiremessage.NextRequestID()
- wmindex, dst = wiremessage.AppendHeaderStart(dst, info.requestID, 0, wiremessage.OpQuery)
dst = wiremessage.AppendQueryFlags(dst, flags)
dollarCmd := [...]byte{'.', '$', 'c', 'm', 'd'}
@@ -1244,35 +1256,42 @@ func (op Operation) createLegacyHandshakeWireMessage(
wrapper := int32(-1)
rp, err := op.createReadPref(desc, true)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
if len(rp) > 0 {
wrapper, dst = bsoncore.AppendDocumentStart(dst)
- dst = bsoncore.AppendHeader(dst, bsontype.EmbeddedDocument, "$query")
+ dst = bsoncore.AppendHeader(dst, bsoncore.TypeEmbeddedDocument, "$query")
}
idx, dst := bsoncore.AppendDocumentStart(dst)
+
dst, err = op.CommandFn(dst, desc)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
-
- if op.Batches != nil && len(op.Batches.Current) > 0 {
- dst = op.addBatchArray(dst)
+ var n int
+ if op.Batches != nil {
+ n, dst, err = op.Batches.AppendBatchArray(dst, int(desc.MaxBatchCount), int(desc.MaxMessageSize))
+ if err != nil {
+ return 0, dst, nil, err
+ }
+ if n == 0 {
+ return 0, dst, nil, ErrDocumentTooLarge
+ }
}
dst, err = op.addReadConcern(dst, desc)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
- dst, err = op.addWriteConcern(dst, desc)
+ dst, err = op.addWriteConcern(ctx, dst, desc)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
- dst, err = op.addSession(dst, desc)
+ dst, err = op.addSession(dst, desc, false)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
dst = op.addClusterTime(dst, desc)
@@ -1280,70 +1299,62 @@ func (op Operation) createLegacyHandshakeWireMessage(
// If maxTimeMS is greater than 0 append it to wire message. A maxTimeMS value of 0 only explicitly
// specifies the default behavior of no timeout server-side.
if maxTimeMS > 0 {
- dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", int64(maxTimeMS))
+ dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", maxTimeMS)
}
dst, _ = bsoncore.AppendDocumentEnd(dst, idx)
- // Command monitoring only reports the document inside $query
- info.cmd = dst[idx:]
if len(rp) > 0 {
+ idx = wrapper
var err error
dst = bsoncore.AppendDocumentElement(dst, "$readPreference", rp)
- dst, err = bsoncore.AppendDocumentEnd(dst, wrapper)
+ dst, err = bsoncore.AppendDocumentEnd(dst, idx)
if err != nil {
- return dst, info, err
+ return 0, dst, nil, err
}
}
- return bsoncore.UpdateLength(dst, wmindex, int32(len(dst[wmindex:]))), info, nil
+ return n, dst, dst[idx:], nil
}
func (op Operation) createMsgWireMessage(
ctx context.Context,
- maxTimeMS uint64,
+ maxTimeMS int64,
dst []byte,
desc description.SelectedServer,
- conn Connection,
- requestID int32,
-) ([]byte, startedInformation, error) {
- var info startedInformation
+ conn *mnet.Connection,
+ cmdFn func([]byte, description.SelectedServer) ([]byte, error),
+) ([]byte, []byte, error) {
var flags wiremessage.MsgFlag
- var wmindex int32
- // We set the MoreToCome bit if we have a write concern, it's unacknowledged, and we either
- // aren't batching or we are encoding the last batch.
- if op.WriteConcern != nil && !writeconcern.AckWrite(op.WriteConcern) && (op.Batches == nil || len(op.Batches.Documents) == 0) {
- flags = wiremessage.MoreToCome
- }
// Set the ExhaustAllowed flag if the connection supports streaming. This will tell the server that it can
// respond with the MoreToCome flag and then stream responses over this connection.
- if streamer, ok := conn.(StreamerConnection); ok && streamer.SupportsStreaming() {
- flags |= wiremessage.ExhaustAllowed
+ if streamer := conn.Streamer; streamer != nil && streamer.SupportsStreaming() {
+ flags = wiremessage.ExhaustAllowed
}
-
- info.requestID = requestID
- wmindex, dst = wiremessage.AppendHeaderStart(dst, info.requestID, 0, wiremessage.OpMsg)
dst = wiremessage.AppendMsgFlags(dst, flags)
// Body
dst = wiremessage.AppendMsgSectionType(dst, wiremessage.SingleDocument)
idx, dst := bsoncore.AppendDocumentStart(dst)
- dst, err := op.addCommandFields(ctx, dst, desc)
+ var err error
+ dst, err = cmdFn(dst, desc)
if err != nil {
- return dst, info, err
+ return dst, nil, err
}
dst, err = op.addReadConcern(dst, desc)
if err != nil {
- return dst, info, err
+ return dst, nil, err
}
- dst, err = op.addWriteConcern(dst, desc)
+ dst, err = op.addWriteConcern(ctx, dst, desc)
if err != nil {
- return dst, info, err
+ return dst, nil, err
}
- dst, err = op.addSession(dst, desc)
+ retryWrite := op.retryable(conn.Description()) && op.RetryMode != nil && op.RetryMode.Enabled()
+
+ dst, err = op.addSession(dst, desc, retryWrite)
if err != nil {
- return dst, info, err
+ return dst, nil, err
}
dst = op.addClusterTime(dst, desc)
@@ -1351,40 +1362,21 @@ func (op Operation) createMsgWireMessage(
// If maxTimeMS is greater than 0 append it to wire message. A maxTimeMS value of 0 only explicitly
// specifies the default behavior of no timeout server-side.
if maxTimeMS > 0 {
- dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", int64(maxTimeMS))
+ dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", maxTimeMS)
}
dst = bsoncore.AppendStringElement(dst, "$db", op.Database)
rp, err := op.createReadPref(desc, false)
if err != nil {
- return dst, info, err
+ return dst, nil, err
}
if len(rp) > 0 {
dst = bsoncore.AppendDocumentElement(dst, "$readPreference", rp)
}
dst, _ = bsoncore.AppendDocumentEnd(dst, idx)
- // The command document for monitoring shouldn't include the type 1 payload as a document sequence
- info.cmd = dst[idx:]
-
- // add batch as a document sequence if auto encryption is not enabled
- // if auto encryption is enabled, the batch will already be an array in the command document
- if !op.shouldEncrypt() && op.Batches != nil && len(op.Batches.Current) > 0 {
- info.documentSequenceIncluded = true
- dst = wiremessage.AppendMsgSectionType(dst, wiremessage.DocumentSequence)
- idx, dst = bsoncore.ReserveLength(dst)
-
- dst = append(dst, op.Batches.Identifier...)
- dst = append(dst, 0x00)
-
- for _, doc := range op.Batches.Current {
- dst = append(dst, doc...)
- }
- dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
- }
-
- return bsoncore.UpdateLength(dst, wmindex, int32(len(dst[wmindex:]))), info, nil
+ return dst, dst[idx:], nil
}
// isLegacyHandshake returns True if the operation is the first message of
@@ -1397,51 +1389,149 @@ func isLegacyHandshake(op Operation, desc description.SelectedServer) bool {
func (op Operation) createWireMessage(
ctx context.Context,
- maxTimeMS uint64,
+ maxTimeMS int64,
dst []byte,
desc description.SelectedServer,
- conn Connection,
+ conn *mnet.Connection,
requestID int32,
-) ([]byte, startedInformation, error) {
- if isLegacyHandshake(op, desc) {
- return op.createLegacyHandshakeWireMessage(maxTimeMS, dst, desc)
- }
+) ([]byte, bool, startedInformation, error) {
+ var info startedInformation
+ var wmindex int32
+ var err error
- return op.createMsgWireMessage(ctx, maxTimeMS, dst, desc, conn, requestID)
-}
+ unacknowledged := op.WriteConcern != nil && !op.WriteConcern.Acknowledged()
-// addCommandFields adds the fields for a command to the wire message in dst. This assumes that the start of the document
-// has already been added and does not add the final 0 byte.
-func (op Operation) addCommandFields(ctx context.Context, dst []byte, desc description.SelectedServer) ([]byte, error) {
- if !op.shouldEncrypt() {
- return op.CommandFn(dst, desc)
+ fIdx := -1
+ isLegacy := isLegacyHandshake(op, desc)
+ switch {
+ case isLegacy:
+ requestID := wiremessage.NextRequestID()
+ wmindex, dst = wiremessage.AppendHeaderStart(dst, requestID, 0, wiremessage.OpQuery)
+ info.processedBatches, dst, info.cmd, err = op.createLegacyHandshakeWireMessage(ctx, maxTimeMS, dst, desc)
+ case op.shouldEncrypt():
+ if desc.WireVersion.Max < cryptMinWireVersion {
+ return dst, false, info, errors.New("auto-encryption requires a MongoDB version of 4.2")
+ }
+ cmdFn := func(dst []byte, desc description.SelectedServer) ([]byte, error) {
+ info.processedBatches, dst, err = op.addEncryptCommandFields(ctx, dst, desc)
+ return dst, err
+ }
+ wmindex, dst = wiremessage.AppendHeaderStart(dst, requestID, 0, wiremessage.OpMsg)
+ fIdx = len(dst)
+ dst, info.cmd, err = op.createMsgWireMessage(ctx, maxTimeMS, dst, desc, conn, cmdFn)
+ default:
+ wmindex, dst = wiremessage.AppendHeaderStart(dst, requestID, 0, wiremessage.OpMsg)
+ fIdx = len(dst)
+
+ batchOffset := -1
+ switch op.Batches.(type) {
+ case *Batches:
+ dst, info.cmd, err = op.createMsgWireMessage(ctx, maxTimeMS, dst, desc, conn, op.CommandFn)
+ if err == nil && op.Batches != nil {
+ batchOffset = len(dst)
+ info.processedBatches, dst, err = op.Batches.AppendBatchSequence(dst,
+ int(desc.MaxBatchCount), int(desc.MaxMessageSize),
+ )
+ if err != nil {
+ break
+ }
+ if info.processedBatches == 0 {
+ err = ErrDocumentTooLarge
+ }
+ }
+ default:
+ var batches []byte
+ if op.Batches != nil {
+ info.processedBatches, batches, err = op.Batches.AppendBatchSequence(batches,
+ int(desc.MaxBatchCount), int(desc.MaxMessageSize),
+ )
+ if err != nil {
+ break
+ }
+ if info.processedBatches == 0 {
+ err = ErrDocumentTooLarge
+ break
+ }
+ }
+ dst, info.cmd, err = op.createMsgWireMessage(ctx, maxTimeMS, dst, desc, conn, op.CommandFn)
+ if err == nil && len(batches) > 0 {
+ batchOffset = len(dst)
+ dst = append(dst, batches...)
+ }
+ }
+ if err == nil && batchOffset > 0 {
+ // the remaining of dst is expected to be document sequences such as "ops", "nsInfo".
+ for b := dst[batchOffset:]; len(b) > 0; /* nothing */ {
+ stype, data, ok := wiremessage.ReadMsgSectionType(b)
+ if !ok || stype != wiremessage.DocumentSequence {
+ break
+ }
+ var identifier string
+ identifier, data, b, ok = wiremessage.ReadMsgSectionRawDocumentSequence(data)
+ if !ok {
+ break
+ }
+ info.documentSequences = append(info.documentSequences, struct {
+ identifier string
+ data []byte
+ }{identifier, data})
+ }
+ }
+ }
+ if err != nil {
+ return nil, false, info, err
}
- if desc.WireVersion.Max < cryptMinWireVersion {
- return dst, errors.New("auto-encryption requires a MongoDB version of 4.2")
+ var moreToCome bool
+ // We set the MoreToCome bit if we have a write concern, it's unacknowledged, and we either
+ // aren't batching or we are encoding the last batch.
+ batching := op.Batches != nil && op.Batches.Size() > info.processedBatches
+ if fIdx > 0 && unacknowledged && !batching {
+ dst[fIdx] |= byte(wiremessage.MoreToCome)
+ moreToCome = true
}
+ info.requestID = requestID
+ return bsoncore.UpdateLength(dst, wmindex, int32(len(dst[wmindex:]))), moreToCome, info, nil
+}
- // create temporary command document
- cidx, cmdDst := bsoncore.AppendDocumentStart(nil)
+func (op Operation) addEncryptCommandFields(ctx context.Context, dst []byte, desc description.SelectedServer) (int, []byte, error) {
+ idx, cmdDst := bsoncore.AppendDocumentStart(nil)
var err error
+ // create temporary command document
cmdDst, err = op.CommandFn(cmdDst, desc)
if err != nil {
- return dst, err
+ return 0, nil, err
}
- // use a BSON array instead of a type 1 payload because mongocryptd will convert to arrays regardless
- if op.Batches != nil && len(op.Batches.Current) > 0 {
- cmdDst = op.addBatchArray(cmdDst)
+ var n int
+ if op.Batches != nil {
+ if maxBatchCount := int(desc.MaxBatchCount); maxBatchCount > 1 {
+ n, cmdDst, err = op.Batches.AppendBatchArray(cmdDst, maxBatchCount, cryptMaxBsonObjectSize)
+ if err != nil {
+ return 0, nil, err
+ }
+ }
+ if n == 0 {
+ n, cmdDst, err = op.Batches.AppendBatchArray(cmdDst, 1, int(desc.MaxMessageSize))
+ if err != nil {
+ return 0, nil, err
+ }
+ if n == 0 {
+ return 0, nil, ErrDocumentTooLarge
+ }
+ }
+ }
+ cmdDst, err = bsoncore.AppendDocumentEnd(cmdDst, idx)
+ if err != nil {
+ return 0, nil, err
}
- cmdDst, _ = bsoncore.AppendDocumentEnd(cmdDst, cidx)
-
// encrypt the command
encrypted, err := op.Crypt.Encrypt(ctx, op.Database, cmdDst)
if err != nil {
- return dst, err
+ return 0, nil, err
}
// append encrypted command to original destination, removing the first 4 bytes (length) and final byte (terminator)
dst = append(dst, encrypted[4:len(encrypted)-1]...)
- return dst, nil
+ return n, dst, nil
}
// addServerAPI adds the relevant fields for server API specification to the wire message in dst.
@@ -1461,8 +1551,24 @@ func (op Operation) addServerAPI(dst []byte) []byte {
return dst
}
+// MarshalBSONReadConcern marshals a ReadConcern.
+func MarshalBSONReadConcern(rc *readconcern.ReadConcern) (bson.Type, []byte, error) {
+ if rc == nil {
+ return 0, nil, ErrEmptyReadConcern
+ }
+
+ var elems []byte
+ if len(rc.Level) > 0 {
+ elems = bsoncore.AppendStringElement(elems, "level", rc.Level)
+ }
+
+ return bson.TypeEmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
+}
+
func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer) ([]byte, error) {
- if op.MinimumReadConcernWireVersion > 0 && (desc.WireVersion == nil || !desc.WireVersion.Includes(op.MinimumReadConcernWireVersion)) {
+ if op.MinimumReadConcernWireVersion > 0 && (desc.WireVersion == nil ||
+ !driverutil.VersionRangeIncludes(*desc.WireVersion, op.MinimumReadConcernWireVersion)) {
+
return dst, nil
}
rc := op.ReadConcern
@@ -1474,7 +1580,7 @@ func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer)
// start transaction must append afterclustertime IF causally consistent and operation time exists
if rc == nil && client != nil && client.TransactionStarting() && client.Consistent && client.OperationTime != nil {
- rc = readconcern.New()
+ rc = &readconcern.ReadConcern{}
}
if client != nil && client.Snapshot {
@@ -1484,11 +1590,11 @@ func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer)
rc = readconcern.Snapshot()
}
- if rc == nil {
+ _, data, err := MarshalBSONReadConcern(rc) // always returns a document
+ if errors.Is(err, ErrEmptyReadConcern) {
return dst, nil
}
- _, data, err := rc.MarshalBSONValue() // always returns a document
if err != nil {
return dst, err
}
@@ -1499,7 +1605,7 @@ func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer)
data = bsoncore.AppendTimestampElement(data, "afterClusterTime", client.OperationTime.T, client.OperationTime.I)
data, _ = bsoncore.AppendDocumentEnd(data, 0)
}
- if client.Snapshot && client.SnapshotTime != nil {
+ if client.Snapshot && client.SnapshotTimeSet {
data = data[:len(data)-1] // remove the null byte
data = bsoncore.AppendTimestampElement(data, "atClusterTime", client.SnapshotTime.T, client.SnapshotTime.I)
data, _ = bsoncore.AppendDocumentEnd(data, 0)
@@ -1512,8 +1618,62 @@ func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer)
return bsoncore.AppendDocumentElement(dst, "readConcern", data), nil
}
-func (op Operation) addWriteConcern(dst []byte, desc description.SelectedServer) ([]byte, error) {
- if op.MinimumWriteConcernWireVersion > 0 && (desc.WireVersion == nil || !desc.WireVersion.Includes(op.MinimumWriteConcernWireVersion)) {
+// MarshalBSONWriteConcern marshals a WriteConcern.
+func MarshalBSONWriteConcern(wc *writeconcern.WriteConcern, wtimeout time.Duration) (bson.Type, []byte, error) {
+ if wc == nil {
+ return 0, nil, ErrEmptyWriteConcern
+ }
+
+ var elems []byte
+ if wc.W != nil {
+ // Only support string or int values for W. That aligns with the
+ // documentation and the behavior of other functions, like Acknowledged.
+ switch w := wc.W.(type) {
+ case int:
+ if w < 0 {
+ return 0, nil, errNegativeW
+ }
+
+ // If Journal=true and W=0, return an error because that write
+ // concern is ambiguous.
+ if wc.Journal != nil && *wc.Journal && w == 0 {
+ return 0, nil, errInconsistent
+ }
+
+ // Check for lower and upper bounds on architecture-dependent int.
+ if w > math.MaxInt32 {
+ return 0, nil, fmt.Errorf("WriteConcern.W overflows int32: %v", wc.W)
+ }
+
+ elems = bsoncore.AppendInt32Element(elems, "w", int32(w))
+ case string:
+ elems = bsoncore.AppendStringElement(elems, "w", w)
+ default:
+ return 0,
+ nil,
+ fmt.Errorf("WriteConcern.W must be a string or int, but is a %T", wc.W)
+ }
+ }
+
+ if wc.Journal != nil {
+ elems = bsoncore.AppendBooleanElement(elems, "j", *wc.Journal)
+ }
+
+ if wtimeout != 0 {
+ elems = bsoncore.AppendInt64Element(elems, "wtimeout", int64(wtimeout/time.Millisecond))
+ }
+
+ if len(elems) == 0 {
+ return 0, nil, ErrEmptyWriteConcern
+ }
+
+ return bson.TypeEmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
+}
+
+func (op Operation) addWriteConcern(ctx context.Context, dst []byte, desc description.SelectedServer) ([]byte, error) {
+ if op.MinimumWriteConcernWireVersion > 0 && (desc.WireVersion == nil ||
+ !driverutil.VersionRangeIncludes(*desc.WireVersion, op.MinimumWriteConcernWireVersion)) {
+
return dst, nil
}
wc := op.WriteConcern
@@ -1521,27 +1681,39 @@ func (op Operation) addWriteConcern(dst []byte, desc description.SelectedServer)
return dst, nil
}
- t, data, err := wc.MarshalBSONValue()
- if errors.Is(err, writeconcern.ErrEmptyWriteConcern) {
+ // The specifications for committing a transaction states:
+ //
+ // > if the modified write concern does not include a wtimeout value, drivers
+ // > MUST also apply wtimeout: 10000 to the write concern in order to avoid
+ // > waiting forever (or until a socket timeout) if the majority write concern
+ // > cannot be satisfied.
+ var wtimeout time.Duration
+ if _, ok := ctx.Deadline(); op.Client != nil && op.Timeout == nil && !ok {
+ wtimeout = op.Client.CurrentWTimeout
+ }
+
+ typ, wcBSON, err := MarshalBSONWriteConcern(wc, wtimeout)
+ if errors.Is(err, ErrEmptyWriteConcern) {
return dst, nil
}
+
if err != nil {
return dst, err
}
- return append(bsoncore.AppendHeader(dst, t, "writeConcern"), data...), nil
+ return append(bsoncore.AppendHeader(dst, bsoncore.Type(typ), "writeConcern"), wcBSON...), nil
}
-func (op Operation) addSession(dst []byte, desc description.SelectedServer) ([]byte, error) {
+func (op Operation) addSession(dst []byte, desc description.SelectedServer, retryWrite bool) ([]byte, error) {
client := op.Client
// If the operation is defined for an explicit session but the server
// does not support sessions, then throw an error.
- if client != nil && !client.IsImplicit && desc.SessionTimeoutMinutesPtr == nil {
+ if client != nil && !client.IsImplicit && desc.SessionTimeoutMinutes == nil {
return nil, fmt.Errorf("current topology does not support sessions")
}
- if client == nil || !sessionsSupported(desc.WireVersion) || desc.SessionTimeoutMinutesPtr == nil {
+ if client == nil || !sessionsSupported(desc.WireVersion) || desc.SessionTimeoutMinutes == nil {
return dst, nil
}
if err := client.UpdateUseTime(); err != nil {
@@ -1550,7 +1722,7 @@ func (op Operation) addSession(dst []byte, desc description.SelectedServer) ([]b
dst = bsoncore.AppendDocumentElement(dst, "lsid", client.SessionID)
var addedTxnNumber bool
- if op.Type == Write && client.RetryWrite {
+ if op.Type == Write && retryWrite {
addedTxnNumber = true
dst = bsoncore.AppendInt64Element(dst, "txnNumber", op.Client.TxnNumber)
}
@@ -1572,7 +1744,10 @@ func (op Operation) addClusterTime(dst []byte, desc description.SelectedServer)
if (clock == nil && client == nil) || !sessionsSupported(desc.WireVersion) {
return dst
}
- clusterTime := clock.GetClusterTime()
+ var clusterTime bson.Raw
+ if clock != nil {
+ clusterTime = clock.GetClusterTime()
+ }
if client != nil {
clusterTime = session.MaxClusterTime(clusterTime, client.ClusterTime)
}
@@ -1583,8 +1758,7 @@ func (op Operation) addClusterTime(dst []byte, desc description.SelectedServer)
if err != nil {
return dst
}
- return append(bsoncore.AppendHeader(dst, val.Type, "$clusterTime"), val.Value...)
- // return bsoncore.AppendDocumentElement(dst, "$clusterTime", clusterTime)
+ return append(bsoncore.AppendHeader(dst, bsoncore.Type(val.Type), "$clusterTime"), val.Value...)
}
// calculateMaxTimeMS calculates the value of the 'maxTimeMS' field to potentially append
@@ -1592,56 +1766,22 @@ func (op Operation) addClusterTime(dst []byte, desc description.SelectedServer)
// if the ctx is a Timeout context. If the context is not a Timeout context, it uses the
// operation's MaxTimeMS if set. If no MaxTimeMS is set on the operation, and context is
// not a Timeout context, calculateMaxTimeMS returns 0.
-func (op Operation) calculateMaxTimeMS(ctx context.Context, mon RTTMonitor) (uint64, error) {
- // If CSOT is enabled and we're not omitting the CSOT-calculated maxTimeMS
- // value, then calculate maxTimeMS.
- //
- // This allows commands that do not currently send CSOT-calculated maxTimeMS
- // (e.g. Find and Aggregate) to still use a manually-provided maxTimeMS
- // value.
- //
- // TODO(GODRIVER-2944): Remove or refactor this logic when we add the
- // "timeoutMode" option, which will allow users to opt-in to the
- // CSOT-calculated maxTimeMS values if that's the behavior they want.
- if csot.IsTimeoutContext(ctx) && !op.OmitCSOTMaxTimeMS {
- if deadline, ok := ctx.Deadline(); ok {
- remainingTimeout := time.Until(deadline)
- rtt90 := mon.P90()
- maxTime := remainingTimeout - rtt90
-
- // Always round up to the next millisecond value so we never truncate the calculated
- // maxTimeMS value (e.g. 400 microseconds evaluates to 1ms, not 0ms).
- maxTimeMS := int64((maxTime + (time.Millisecond - 1)) / time.Millisecond)
- if maxTimeMS <= 0 {
- return 0, fmt.Errorf(
- "negative maxTimeMS: remaining time %v until context deadline is less than 90th percentile network round-trip time (%v): %w",
- remainingTimeout,
- mon.Stats(),
- ErrDeadlineWouldBeExceeded)
- }
-
- // The server will return a "BadValue" error if maxTimeMS is greater
- // than the maximum positive int32 value (about 24.9 days). If the
- // user specified a timeout value greater than that, omit maxTimeMS
- // and let the client-side timeout handle cancelling the op if the
- // timeout is ever reached.
- if maxTimeMS > math.MaxInt32 {
- return 0, nil
- }
+func (op Operation) calculateMaxTimeMS(ctx context.Context, rttMin time.Duration, rttStats string) (int64, error) {
+ if op.OmitMaxTimeMS {
+ return 0, nil
+ }
- return uint64(maxTimeMS), nil
- }
- } else if op.MaxTime != nil {
- // Users are not allowed to pass a negative value as MaxTime. A value of 0 would indicate
- // no timeout and is allowed.
- if *op.MaxTime < 0 {
- return 0, ErrNegativeMaxTime
- }
- // Always round up to the next millisecond value so we never truncate the requested
- // MaxTime value (e.g. 400 microseconds evaluates to 1ms, not 0ms).
- return uint64((*op.MaxTime + (time.Millisecond - 1)) / time.Millisecond), nil
+ // Calculate maxTimeMS value to potentially be appended to the wire message.
+ maxTimeMS, ok := driverutil.CalculateMaxTimeMS(ctx, rttMin)
+ if !ok && maxTimeMS <= 0 {
+ return 0, fmt.Errorf(
+ "calculated server-side timeout (%v ms) is less than or equal to 0 (%v): %w",
+ maxTimeMS,
+ rttStats,
+ ErrDeadlineWouldBeExceeded)
}
- return 0, nil
+
+ return maxTimeMS, nil
}
// updateClusterTimes updates the cluster times for the session and cluster clock attached to this
@@ -1683,7 +1823,7 @@ func (op Operation) updateOperationTime(response bsoncore.Document) {
}
t, i := opTimeElem.Timestamp()
- _ = sess.AdvanceOperationTime(&primitive.Timestamp{
+ _ = sess.AdvanceOperationTime(&bson.Timestamp{
T: t,
I: i,
})
@@ -1713,8 +1853,9 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo
// TODO(GODRIVER-2231): Instead of checking if isOutputAggregate and desc.Server.WireVersion.Max < 13, somehow check
// TODO if supplied readPreference was "overwritten" with primary in description.selectForReplicaSet.
- if desc.Server.Kind == description.Standalone || (isOpQuery && desc.Server.Kind != description.Mongos) ||
- op.Type == Write || (op.IsOutputAggregate && desc.Server.WireVersion.Max < 13) {
+ if desc.Server.Kind == description.ServerKindStandalone || (isOpQuery &&
+ desc.Server.Kind != description.ServerKindMongos) ||
+ op.Type == Write || (op.IsOutputAggregate && desc.WireVersion.Max < 13) {
// Don't send read preference for:
// 1. all standalones
// 2. non-mongos when using OP_QUERY
@@ -1731,7 +1872,7 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo
}
if rp == nil {
- if desc.Kind == description.Single && desc.Server.Kind != description.Mongos {
+ if desc.Kind == description.TopologyKindSingle && desc.Server.Kind != description.ServerKindMongos {
doc = bsoncore.AppendStringElement(doc, "mode", "primaryPreferred")
doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
return doc, nil
@@ -1741,10 +1882,10 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo
switch rp.Mode() {
case readpref.PrimaryMode:
- if desc.Server.Kind == description.Mongos {
+ if desc.Server.Kind == description.ServerKindMongos {
return nil, nil
}
- if desc.Kind == description.Single {
+ if desc.Kind == description.TopologyKindSingle {
doc = bsoncore.AppendStringElement(doc, "mode", "primaryPreferred")
doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
return doc, nil
@@ -1761,7 +1902,9 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo
doc = bsoncore.AppendStringElement(doc, "mode", "primaryPreferred")
case readpref.SecondaryPreferredMode:
_, ok := rp.MaxStaleness()
- if desc.Server.Kind == description.Mongos && isOpQuery && !ok && len(rp.TagSets()) == 0 && rp.HedgeEnabled() == nil {
+ if desc.Server.Kind == description.ServerKindMongos && isOpQuery && !ok && len(rp.TagSets()) == 0 &&
+ rp.HedgeEnabled() == nil {
+
return nil, nil
}
doc = bsoncore.AppendStringElement(doc, "mode", "secondaryPreferred")
@@ -1808,7 +1951,7 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo
}
func (op Operation) secondaryOK(desc description.SelectedServer) wiremessage.QueryFlag {
- if desc.Kind == description.Single && desc.Server.Kind != description.Mongos {
+ if desc.Kind == description.TopologyKindSingle && desc.Server.Kind != description.ServerKindMongos {
return wiremessage.SecondaryOK
}
@@ -1878,7 +2021,7 @@ func (Operation) decodeOpReply(wm []byte) opReply {
return reply
}
-func (op Operation) decodeResult(ctx context.Context, opcode wiremessage.OpCode, wm []byte) (bsoncore.Document, error) {
+func (op Operation) decodeResult(opcode wiremessage.OpCode, wm []byte) (bsoncore.Document, error) {
switch opcode {
case wiremessage.OpReply:
reply := op.decodeOpReply(wm)
@@ -1896,7 +2039,7 @@ func (op Operation) decodeResult(ctx context.Context, opcode wiremessage.OpCode,
return nil, NewCommandResponseError("malformed OP_REPLY: invalid document", err)
}
- return rdr, ExtractErrorFromServerResponse(ctx, rdr)
+ return rdr, ExtractErrorFromServerResponse(rdr)
case wiremessage.OpMsg:
_, wm, ok := wiremessage.ReadMsgFlags(wm)
if !ok {
@@ -1932,7 +2075,7 @@ func (op Operation) decodeResult(ctx context.Context, opcode wiremessage.OpCode,
return nil, NewCommandResponseError("malformed OP_MSG: invalid document", err)
}
- return res, ExtractErrorFromServerResponse(ctx, res)
+ return res, ExtractErrorFromServerResponse(res)
default:
return nil, fmt.Errorf("cannot decode result from %s", opcode)
}
@@ -1977,8 +2120,8 @@ func (op Operation) publishStartedEvent(ctx context.Context, info startedInforma
if op.canLogCommandMessage() {
host, port, _ := net.SplitHostPort(info.serverAddress.String())
- redactedCmd := redactStartedInformationCmd(op, info).String()
- formattedCmd := logger.FormatMessage(redactedCmd, op.Logger.MaxDocumentLength)
+ redactedCmd := redactStartedInformationCmd(info)
+ formattedCmd := logger.FormatDocument(redactedCmd, op.Logger.MaxDocumentLength)
op.Logger.Print(logger.LevelDebug,
logger.ComponentCommand,
@@ -2000,14 +2143,13 @@ func (op Operation) publishStartedEvent(ctx context.Context, info startedInforma
if op.canPublishStartedEvent() {
started := &event.CommandStartedEvent{
- Command: redactStartedInformationCmd(op, info),
- DatabaseName: op.Database,
- CommandName: info.cmdName,
- RequestID: int64(info.requestID),
- ConnectionID: info.connID,
- ServerConnectionID: convertInt64PtrToInt32Ptr(info.serverConnID),
- ServerConnectionID64: info.serverConnID,
- ServiceID: info.serviceID,
+ Command: redactStartedInformationCmd(info),
+ DatabaseName: op.Database,
+ CommandName: info.cmdName,
+ RequestID: int64(info.requestID),
+ ConnectionID: info.connID,
+ ServerConnectionID: info.serverConnID,
+ ServiceID: info.serviceID,
}
op.CommandMonitor.Started(ctx, started)
}
@@ -2030,8 +2172,9 @@ func (op Operation) publishFinishedEvent(ctx context.Context, info finishedInfor
if op.canLogCommandMessage() && info.success() {
host, port, _ := net.SplitHostPort(info.serverAddress.String())
- redactedReply := redactFinishedInformationResponse(info).String()
- formattedReply := logger.FormatMessage(redactedReply, op.Logger.MaxDocumentLength)
+ redactedReply := redactFinishedInformationResponse(info)
+
+ formattedReply := logger.FormatDocument(redactedReply, op.Logger.MaxDocumentLength)
op.Logger.Print(logger.LevelDebug,
logger.ComponentCommand,
@@ -2054,7 +2197,7 @@ func (op Operation) publishFinishedEvent(ctx context.Context, info finishedInfor
if op.canLogCommandMessage() && !info.success() {
host, port, _ := net.SplitHostPort(info.serverAddress.String())
- formattedReply := logger.FormatMessage(info.cmdErr.Error(), op.Logger.MaxDocumentLength)
+ formattedReply := logger.FormatString(info.cmdErr.Error(), op.Logger.MaxDocumentLength)
op.Logger.Print(logger.LevelDebug,
logger.ComponentCommand,
@@ -2080,15 +2223,13 @@ func (op Operation) publishFinishedEvent(ctx context.Context, info finishedInfor
}
finished := event.CommandFinishedEvent{
- CommandName: info.cmdName,
- DatabaseName: op.Database,
- RequestID: int64(info.requestID),
- ConnectionID: info.connID,
- Duration: info.duration,
- DurationNanos: info.duration.Nanoseconds(),
- ServerConnectionID: convertInt64PtrToInt32Ptr(info.serverConnID),
- ServerConnectionID64: info.serverConnID,
- ServiceID: info.serviceID,
+ CommandName: info.cmdName,
+ DatabaseName: op.Database,
+ RequestID: int64(info.requestID),
+ ConnectionID: info.connID,
+ Duration: info.duration,
+ ServerConnectionID: info.serverConnID,
+ ServiceID: info.serviceID,
}
if info.success() {
@@ -2102,7 +2243,7 @@ func (op Operation) publishFinishedEvent(ctx context.Context, info finishedInfor
}
failedEvent := &event.CommandFailedEvent{
- Failure: info.cmdErr.Error(),
+ Failure: info.cmdErr,
CommandFinishedEvent: finished,
}
op.CommandMonitor.Failed(ctx, failedEvent)
@@ -2115,5 +2256,25 @@ func sessionsSupported(wireVersion *description.VersionRange) bool {
// retryWritesSupported returns true if this description represents a server that supports retryable writes.
func retryWritesSupported(s description.Server) bool {
- return s.SessionTimeoutMinutesPtr != nil && s.Kind != description.Standalone
+ return s.SessionTimeoutMinutes != nil && s.Kind != description.ServerKindStandalone
+}
+
+// appendDocumentArray will append an array header and document elements in data to dst and return the extended buffer.
+func appendDocumentArray(dst []byte, key string, data []byte) []byte {
+ aidx, dst := bsoncore.AppendArrayElementStart(dst, key)
+ var doc bsoncore.Document
+ var ok bool
+ i := 0
+ for {
+ doc, data, ok = bsoncore.ReadDocument(data)
+ if !ok {
+ break
+ }
+ dst = bsoncore.AppendDocumentElement(dst, strconv.Itoa(i), doc)
+ i++
+ }
+
+ dst, _ = bsoncore.AppendArrayEnd(dst, aidx)
+
+ return dst
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/abort_transaction.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/abort_transaction.go
index aeee53353..2b15056f1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/abort_transaction.go
@@ -10,30 +10,34 @@ import (
"context"
"errors"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// AbortTransaction performs an abortTransaction operation.
type AbortTransaction struct {
- authenticator driver.Authenticator
- recoveryToken bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- serverAPI *driver.ServerAPIOptions
+ authenticator driver.Authenticator
+ recoveryToken bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ serverAPI *driver.ServerAPIOptions
+ logger *logger.Logger
}
// NewAbortTransaction constructs and returns a new AbortTransaction.
@@ -41,9 +45,8 @@ func NewAbortTransaction() *AbortTransaction {
return &AbortTransaction{}
}
-func (at *AbortTransaction) processResponse(driver.ResponseInfo) error {
- var err error
- return err
+func (at *AbortTransaction) processResponse(context.Context, bsoncore.Document, driver.ResponseInfo) error {
+ return nil
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -53,27 +56,28 @@ func (at *AbortTransaction) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: at.command,
- ProcessResponseFn: at.processResponse,
- RetryMode: at.retry,
- Type: driver.Write,
- Client: at.session,
- Clock: at.clock,
- CommandMonitor: at.monitor,
- Crypt: at.crypt,
- Database: at.database,
- Deployment: at.deployment,
- Selector: at.selector,
- WriteConcern: at.writeConcern,
- ServerAPI: at.serverAPI,
- Name: driverutil.AbortTransactionOp,
- Authenticator: at.authenticator,
+ CommandFn: at.command,
+ ProcessResponseFn: at.processResponse,
+ RetryMode: at.retry,
+ Type: driver.Write,
+ Client: at.session,
+ Clock: at.clock,
+ CommandMonitor: at.monitor,
+ MaxAdaptiveRetries: at.maxAdaptiveRetries,
+ EnableOverloadRetargeting: at.enableOverloadRetargeting,
+ Crypt: at.crypt,
+ Database: at.database,
+ Deployment: at.deployment,
+ Selector: at.selector,
+ WriteConcern: at.writeConcern,
+ ServerAPI: at.serverAPI,
+ Name: driverutil.AbortTransactionOp,
+ Authenticator: at.authenticator,
+ Logger: at.logger,
}.Execute(ctx)
-
}
func (at *AbortTransaction) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
-
dst = bsoncore.AppendInt32Element(dst, "abortTransaction", 1)
if at.recoveryToken != nil {
dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", at.recoveryToken)
@@ -192,6 +196,28 @@ func (at *AbortTransaction) Retry(retry driver.RetryMode) *AbortTransaction {
return at
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (at *AbortTransaction) MaxAdaptiveRetries(maxAdaptiveRetries uint) *AbortTransaction {
+ if at == nil {
+ at = new(AbortTransaction)
+ }
+
+ at.maxAdaptiveRetries = maxAdaptiveRetries
+ return at
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (at *AbortTransaction) EnableOverloadRetargeting(enabled bool) *AbortTransaction {
+ if at == nil {
+ at = new(AbortTransaction)
+ }
+
+ at.enableOverloadRetargeting = enabled
+ return at
+}
+
// ServerAPI sets the server API version for this operation.
func (at *AbortTransaction) ServerAPI(serverAPI *driver.ServerAPIOptions) *AbortTransaction {
if at == nil {
@@ -211,3 +237,13 @@ func (at *AbortTransaction) Authenticator(authenticator driver.Authenticator) *A
at.authenticator = authenticator
return at
}
+
+// Logger sets the logger for this operation.
+func (at *AbortTransaction) Logger(logger *logger.Logger) *AbortTransaction {
+ if at == nil {
+ at = new(AbortTransaction)
+ }
+
+ at.logger = logger
+ return at
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/aggregate.go
similarity index 70%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/aggregate.go
index df6b8fa9d..22dbb8087 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/aggregate.go
@@ -11,47 +11,48 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Aggregate represents an aggregate operation.
type Aggregate struct {
- authenticator driver.Authenticator
- allowDiskUse *bool
- batchSize *int32
- bypassDocumentValidation *bool
- collation bsoncore.Document
- comment *string
- hint bsoncore.Value
- maxTime *time.Duration
- pipeline bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- database string
- deployment driver.Deployment
- readConcern *readconcern.ReadConcern
- readPreference *readpref.ReadPref
- retry *driver.RetryMode
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- crypt driver.Crypt
- serverAPI *driver.ServerAPIOptions
- let bsoncore.Document
- hasOutputStage bool
- customOptions map[string]bsoncore.Value
- timeout *time.Duration
- omitCSOTMaxTimeMS bool
+ authenticator driver.Authenticator
+ allowDiskUse *bool
+ batchSize *int32
+ bypassDocumentValidation *bool
+ collation bsoncore.Document
+ comment bsoncore.Value
+ hint bsoncore.Value
+ pipeline bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ database string
+ deployment driver.Deployment
+ readConcern *readconcern.ReadConcern
+ readPreference *readpref.ReadPref
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ crypt driver.Crypt
+ serverAPI *driver.ServerAPIOptions
+ let bsoncore.Document
+ hasOutputStage bool
+ customOptions map[string]bsoncore.Value
+ timeout *time.Duration
+ omitMaxTimeMS bool
+ rawData *bool
result driver.CursorResponse
}
@@ -65,7 +66,6 @@ func NewAggregate(pipeline bsoncore.Document) *Aggregate {
// Result returns the result of executing this operation.
func (a *Aggregate) Result(opts driver.CursorOptions) (*driver.BatchCursor, error) {
-
clientSession := a.session
clock := a.clock
@@ -79,12 +79,13 @@ func (a *Aggregate) ResultCursorResponse() driver.CursorResponse {
return a.result
}
-func (a *Aggregate) processResponse(info driver.ResponseInfo) error {
- var err error
-
- a.result, err = driver.NewCursorResponse(info)
+func (a *Aggregate) processResponse(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ curDoc, err := driver.ExtractCursorDocument(resp)
+ if err != nil {
+ return err
+ }
+ a.result, err = driver.NewCursorResponse(curDoc, info)
return err
-
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -106,62 +107,60 @@ func (a *Aggregate) Execute(ctx context.Context) error {
ReadPreference: a.readPreference,
Type: driver.Read,
RetryMode: a.retry,
+ MaxAdaptiveRetries: a.maxAdaptiveRetries,
+ EnableOverloadRetargeting: a.enableOverloadRetargeting,
Selector: a.selector,
WriteConcern: a.writeConcern,
Crypt: a.crypt,
MinimumWriteConcernWireVersion: 5,
ServerAPI: a.serverAPI,
IsOutputAggregate: a.hasOutputStage,
- MaxTime: a.maxTime,
Timeout: a.timeout,
Name: driverutil.AggregateOp,
- OmitCSOTMaxTimeMS: a.omitCSOTMaxTimeMS,
Authenticator: a.authenticator,
+ OmitMaxTimeMS: a.omitMaxTimeMS,
}.Execute(ctx)
-
}
func (a *Aggregate) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
- header := bsoncore.Value{Type: bsontype.String, Data: bsoncore.AppendString(nil, a.collection)}
+ header := bsoncore.Value{Type: bsoncore.TypeString, Data: bsoncore.AppendString(nil, a.collection)}
if a.collection == "" {
- header = bsoncore.Value{Type: bsontype.Int32, Data: []byte{0x01, 0x00, 0x00, 0x00}}
+ header = bsoncore.Value{Type: bsoncore.TypeInt32, Data: []byte{0x01, 0x00, 0x00, 0x00}}
}
dst = bsoncore.AppendValueElement(dst, "aggregate", header)
cursorIdx, cursorDoc := bsoncore.AppendDocumentStart(nil)
if a.allowDiskUse != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "allowDiskUse", *a.allowDiskUse)
}
if a.batchSize != nil {
cursorDoc = bsoncore.AppendInt32Element(cursorDoc, "batchSize", *a.batchSize)
}
if a.bypassDocumentValidation != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *a.bypassDocumentValidation)
}
if a.collation != nil {
-
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5")
}
dst = bsoncore.AppendDocumentElement(dst, "collation", a.collation)
}
- if a.comment != nil {
-
- dst = bsoncore.AppendStringElement(dst, "comment", *a.comment)
+ if a.comment.Type != bsoncore.Type(0) {
+ dst = bsoncore.AppendValueElement(dst, "comment", a.comment)
}
- if a.hint.Type != bsontype.Type(0) {
-
+ if a.hint.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "hint", a.hint)
}
if a.pipeline != nil {
-
dst = bsoncore.AppendArrayElement(dst, "pipeline", a.pipeline)
}
if a.let != nil {
dst = bsoncore.AppendDocumentElement(dst, "let", a.let)
}
+ // Set rawData for 8.2+ servers.
+ if a.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *a.rawData)
+ }
for optionName, optionValue := range a.customOptions {
dst = bsoncore.AppendValueElement(dst, optionName, optionValue)
}
@@ -201,7 +200,7 @@ func (a *Aggregate) BypassDocumentValidation(bypassDocumentValidation bool) *Agg
return a
}
-// Collation specifies a collation. This option is only valid for server versions 3.4 and above.
+// Collation specifies a collation.
func (a *Aggregate) Collation(collation bsoncore.Document) *Aggregate {
if a == nil {
a = new(Aggregate)
@@ -211,13 +210,13 @@ func (a *Aggregate) Collation(collation bsoncore.Document) *Aggregate {
return a
}
-// Comment specifies an arbitrary string to help trace the operation through the database profiler, currentOp, and logs.
-func (a *Aggregate) Comment(comment string) *Aggregate {
+// Comment sets a value to help trace an operation.
+func (a *Aggregate) Comment(comment bsoncore.Value) *Aggregate {
if a == nil {
a = new(Aggregate)
}
- a.comment = &comment
+ a.comment = comment
return a
}
@@ -231,16 +230,6 @@ func (a *Aggregate) Hint(hint bsoncore.Value) *Aggregate {
return a
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (a *Aggregate) MaxTime(maxTime *time.Duration) *Aggregate {
- if a == nil {
- a = new(Aggregate)
- }
-
- a.maxTime = maxTime
- return a
-}
-
// Pipeline determines how data is transformed for an aggregation.
func (a *Aggregate) Pipeline(pipeline bsoncore.Document) *Aggregate {
if a == nil {
@@ -363,6 +352,28 @@ func (a *Aggregate) Retry(retry driver.RetryMode) *Aggregate {
return a
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (a *Aggregate) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Aggregate {
+ if a == nil {
+ a = new(Aggregate)
+ }
+
+ a.maxAdaptiveRetries = maxAdaptiveRetries
+ return a
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (a *Aggregate) EnableOverloadRetargeting(enabled bool) *Aggregate {
+ if a == nil {
+ a = new(Aggregate)
+ }
+
+ a.enableOverloadRetargeting = enabled
+ return a
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (a *Aggregate) Crypt(crypt driver.Crypt) *Aggregate {
if a == nil {
@@ -424,24 +435,33 @@ func (a *Aggregate) Timeout(timeout *time.Duration) *Aggregate {
return a
}
-// OmitCSOTMaxTimeMS omits the automatically-calculated "maxTimeMS" from the
-// command when CSOT is enabled. It does not effect "maxTimeMS" set by
-// [Aggregate.MaxTime].
-func (a *Aggregate) OmitCSOTMaxTimeMS(omit bool) *Aggregate {
+// Authenticator sets the authenticator to use for this operation.
+func (a *Aggregate) Authenticator(authenticator driver.Authenticator) *Aggregate {
if a == nil {
a = new(Aggregate)
}
- a.omitCSOTMaxTimeMS = omit
+ a.authenticator = authenticator
return a
}
-// Authenticator sets the authenticator to use for this operation.
-func (a *Aggregate) Authenticator(authenticator driver.Authenticator) *Aggregate {
+// OmitMaxTimeMS omits the automatically-calculated "maxTimeMS" from the
+// command.
+func (a *Aggregate) OmitMaxTimeMS(omit bool) *Aggregate {
if a == nil {
a = new(Aggregate)
}
- a.authenticator = authenticator
+ a.omitMaxTimeMS = omit
+ return a
+}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (a *Aggregate) RawData(rawData bool) *Aggregate {
+ if a == nil {
+ a = new(Aggregate)
+ }
+
+ a.rawData = &rawData
return a
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/command.go
similarity index 62%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/command.go
index 64c98ba19..a4f60abf7 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/command.go
@@ -11,34 +11,36 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Command is used to run a generic operation.
type Command struct {
- authenticator driver.Authenticator
- command bsoncore.Document
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- readPreference *readpref.ReadPref
- clock *session.ClusterClock
- session *session.Client
- monitor *event.CommandMonitor
- resultResponse bsoncore.Document
- resultCursor *driver.BatchCursor
- crypt driver.Crypt
- serverAPI *driver.ServerAPIOptions
- createCursor bool
- cursorOpts driver.CursorOptions
- timeout *time.Duration
- logger *logger.Logger
+ authenticator driver.Authenticator
+ command bsoncore.Document
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ readPreference *readpref.ReadPref
+ clock *session.ClusterClock
+ session *session.Client
+ monitor *event.CommandMonitor
+ resultResponse bsoncore.Document
+ resultCursor *driver.BatchCursor
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ crypt driver.Crypt
+ serverAPI *driver.ServerAPIOptions
+ createCursor bool
+ cursorOpts driver.CursorOptions
+ timeout *time.Duration
+ logger *logger.Logger
}
// NewCommand constructs and returns a new Command. Once the operation is executed, the result may only be accessed via
@@ -56,6 +58,9 @@ func NewCursorCommand(command bsoncore.Document, cursorOpts driver.CursorOptions
command: command,
cursorOpts: cursorOpts,
createCursor: true,
+
+ maxAdaptiveRetries: cursorOpts.MaxAdaptiveRetries,
+ enableOverloadRetargeting: cursorOpts.EnableOverloadRetargeting,
}
}
@@ -82,11 +87,15 @@ func (c *Command) Execute(ctx context.Context) error {
CommandFn: func(dst []byte, _ description.SelectedServer) ([]byte, error) {
return append(dst, c.command[4:len(c.command)-1]...), nil
},
- ProcessResponseFn: func(info driver.ResponseInfo) error {
- c.resultResponse = info.ServerResponse
+ ProcessResponseFn: func(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ c.resultResponse = resp
if c.createCursor {
- cursorRes, err := driver.NewCursorResponse(info)
+ curDoc, err := driver.ExtractCursorDocument(resp)
+ if err != nil {
+ return err
+ }
+ cursorRes, err := driver.NewCursorResponse(curDoc, info)
if err != nil {
return err
}
@@ -97,18 +106,20 @@ func (c *Command) Execute(ctx context.Context) error {
return nil
},
- Client: c.session,
- Clock: c.clock,
- CommandMonitor: c.monitor,
- Database: c.database,
- Deployment: c.deployment,
- ReadPreference: c.readPreference,
- Selector: c.selector,
- Crypt: c.crypt,
- ServerAPI: c.serverAPI,
- Timeout: c.timeout,
- Logger: c.logger,
- Authenticator: c.authenticator,
+ Client: c.session,
+ Clock: c.clock,
+ CommandMonitor: c.monitor,
+ Database: c.database,
+ Deployment: c.deployment,
+ ReadPreference: c.readPreference,
+ Selector: c.selector,
+ MaxAdaptiveRetries: c.maxAdaptiveRetries,
+ EnableOverloadRetargeting: c.enableOverloadRetargeting,
+ Crypt: c.crypt,
+ ServerAPI: c.serverAPI,
+ Timeout: c.timeout,
+ Logger: c.logger,
+ Authenticator: c.authenticator,
}.Execute(ctx)
}
@@ -182,6 +193,28 @@ func (c *Command) ServerSelector(selector description.ServerSelector) *Command {
return c
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (c *Command) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Command {
+ if c == nil {
+ c = new(Command)
+ }
+
+ c.maxAdaptiveRetries = maxAdaptiveRetries
+ return c
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (c *Command) EnableOverloadRetargeting(enabled bool) *Command {
+ if c == nil {
+ c = new(Command)
+ }
+
+ c.enableOverloadRetargeting = enabled
+ return c
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (c *Command) Crypt(crypt driver.Crypt) *Command {
if c == nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/commit_transaction.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/commit_transaction.go
index 6b402bdf6..d9a9745d5 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/commit_transaction.go
@@ -9,32 +9,34 @@ package operation
import (
"context"
"errors"
- "time"
-
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// CommitTransaction attempts to commit a transaction.
type CommitTransaction struct {
- authenticator driver.Authenticator
- maxTime *time.Duration
- recoveryToken bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- serverAPI *driver.ServerAPIOptions
+ authenticator driver.Authenticator
+ recoveryToken bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ serverAPI *driver.ServerAPIOptions
+ logger *logger.Logger
}
// NewCommitTransaction constructs and returns a new CommitTransaction.
@@ -42,9 +44,8 @@ func NewCommitTransaction() *CommitTransaction {
return &CommitTransaction{}
}
-func (ct *CommitTransaction) processResponse(driver.ResponseInfo) error {
- var err error
- return err
+func (ct *CommitTransaction) processResponse(context.Context, bsoncore.Document, driver.ResponseInfo) error {
+ return nil
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -54,28 +55,28 @@ func (ct *CommitTransaction) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: ct.command,
- ProcessResponseFn: ct.processResponse,
- RetryMode: ct.retry,
- Type: driver.Write,
- Client: ct.session,
- Clock: ct.clock,
- CommandMonitor: ct.monitor,
- Crypt: ct.crypt,
- Database: ct.database,
- Deployment: ct.deployment,
- MaxTime: ct.maxTime,
- Selector: ct.selector,
- WriteConcern: ct.writeConcern,
- ServerAPI: ct.serverAPI,
- Name: driverutil.CommitTransactionOp,
- Authenticator: ct.authenticator,
+ CommandFn: ct.command,
+ ProcessResponseFn: ct.processResponse,
+ RetryMode: ct.retry,
+ Type: driver.Write,
+ Client: ct.session,
+ Clock: ct.clock,
+ CommandMonitor: ct.monitor,
+ MaxAdaptiveRetries: ct.maxAdaptiveRetries,
+ EnableOverloadRetargeting: ct.enableOverloadRetargeting,
+ Crypt: ct.crypt,
+ Database: ct.database,
+ Deployment: ct.deployment,
+ Selector: ct.selector,
+ WriteConcern: ct.writeConcern,
+ ServerAPI: ct.serverAPI,
+ Name: driverutil.CommitTransactionOp,
+ Authenticator: ct.authenticator,
+ Logger: ct.logger,
}.Execute(ctx)
-
}
func (ct *CommitTransaction) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
-
dst = bsoncore.AppendInt32Element(dst, "commitTransaction", 1)
if ct.recoveryToken != nil {
dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", ct.recoveryToken)
@@ -83,16 +84,6 @@ func (ct *CommitTransaction) command(dst []byte, _ description.SelectedServer) (
return dst, nil
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (ct *CommitTransaction) MaxTime(maxTime *time.Duration) *CommitTransaction {
- if ct == nil {
- ct = new(CommitTransaction)
- }
-
- ct.maxTime = maxTime
- return ct
-}
-
// RecoveryToken sets the recovery token to use when committing or aborting a sharded transaction.
func (ct *CommitTransaction) RecoveryToken(recoveryToken bsoncore.Document) *CommitTransaction {
if ct == nil {
@@ -194,6 +185,28 @@ func (ct *CommitTransaction) Retry(retry driver.RetryMode) *CommitTransaction {
return ct
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (ct *CommitTransaction) MaxAdaptiveRetries(maxAdaptiveRetries uint) *CommitTransaction {
+ if ct == nil {
+ ct = new(CommitTransaction)
+ }
+
+ ct.maxAdaptiveRetries = maxAdaptiveRetries
+ return ct
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (ct *CommitTransaction) EnableOverloadRetargeting(enabled bool) *CommitTransaction {
+ if ct == nil {
+ ct = new(CommitTransaction)
+ }
+
+ ct.enableOverloadRetargeting = enabled
+ return ct
+}
+
// ServerAPI sets the server API version for this operation.
func (ct *CommitTransaction) ServerAPI(serverAPI *driver.ServerAPIOptions) *CommitTransaction {
if ct == nil {
@@ -213,3 +226,13 @@ func (ct *CommitTransaction) Authenticator(authenticator driver.Authenticator) *
ct.authenticator = authenticator
return ct
}
+
+// Logger sets the logger for this operation.
+func (ct *CommitTransaction) Logger(logger *logger.Logger) *CommitTransaction {
+ if ct == nil {
+ ct = new(CommitTransaction)
+ }
+
+ ct.logger = logger
+ return ct
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/count.go
similarity index 63%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/count.go
index eaafc9a24..69e585ebf 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/count.go
@@ -12,37 +12,38 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Count represents a count operation.
type Count struct {
- authenticator driver.Authenticator
- maxTime *time.Duration
- query bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- collection string
- comment bsoncore.Value
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- readConcern *readconcern.ReadConcern
- readPreference *readpref.ReadPref
- selector description.ServerSelector
- retry *driver.RetryMode
- result CountResult
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ query bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ comment bsoncore.Value
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ readConcern *readconcern.ReadConcern
+ readPreference *readpref.ReadPref
+ selector description.ServerSelector
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result CountResult
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
}
// CountResult represents a count result returned by the server.
@@ -99,9 +100,9 @@ func NewCount() *Count {
// Result returns the result of executing this operation.
func (c *Count) Result() CountResult { return c.result }
-func (c *Count) processResponse(info driver.ResponseInfo) error {
+func (c *Count) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- c.result, err = buildCountResult(info.ServerResponse)
+ c.result, err = buildCountResult(resp)
return err
}
@@ -112,26 +113,26 @@ func (c *Count) Execute(ctx context.Context) error {
}
err := driver.Operation{
- CommandFn: c.command,
- ProcessResponseFn: c.processResponse,
- RetryMode: c.retry,
- Type: driver.Read,
- Client: c.session,
- Clock: c.clock,
- CommandMonitor: c.monitor,
- Crypt: c.crypt,
- Database: c.database,
- Deployment: c.deployment,
- MaxTime: c.maxTime,
- ReadConcern: c.readConcern,
- ReadPreference: c.readPreference,
- Selector: c.selector,
- ServerAPI: c.serverAPI,
- Timeout: c.timeout,
- Name: driverutil.CountOp,
- Authenticator: c.authenticator,
+ CommandFn: c.command,
+ ProcessResponseFn: c.processResponse,
+ RetryMode: c.retry,
+ MaxAdaptiveRetries: c.maxAdaptiveRetries,
+ EnableOverloadRetargeting: c.enableOverloadRetargeting,
+ Type: driver.Read,
+ Client: c.session,
+ Clock: c.clock,
+ CommandMonitor: c.monitor,
+ Crypt: c.crypt,
+ Database: c.database,
+ Deployment: c.deployment,
+ ReadConcern: c.readConcern,
+ ReadPreference: c.readPreference,
+ Selector: c.selector,
+ ServerAPI: c.serverAPI,
+ Timeout: c.timeout,
+ Name: driverutil.CountOp,
+ Authenticator: c.authenticator,
}.Execute(ctx)
-
// Swallow error if NamespaceNotFound(26) is returned from aggregate on non-existent namespace
if err != nil {
dErr, ok := err.(driver.Error)
@@ -142,25 +143,19 @@ func (c *Count) Execute(ctx context.Context) error {
return err
}
-func (c *Count) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
+func (c *Count) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "count", c.collection)
if c.query != nil {
dst = bsoncore.AppendDocumentElement(dst, "query", c.query)
}
- if c.comment.Type != bsontype.Type(0) {
+ if c.comment.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "comment", c.comment)
}
- return dst, nil
-}
-
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (c *Count) MaxTime(maxTime *time.Duration) *Count {
- if c == nil {
- c = new(Count)
+ // Set rawData for 8.2+ servers.
+ if c.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *c.rawData)
}
-
- c.maxTime = maxTime
- return c
+ return dst, nil
}
// Query determines what results are returned from find.
@@ -294,6 +289,28 @@ func (c *Count) Retry(retry driver.RetryMode) *Count {
return c
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (c *Count) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Count {
+ if c == nil {
+ c = new(Count)
+ }
+
+ c.maxAdaptiveRetries = maxAdaptiveRetries
+ return c
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (c *Count) EnableOverloadRetargeting(enabled bool) *Count {
+ if c == nil {
+ c = new(Count)
+ }
+
+ c.enableOverloadRetargeting = enabled
+ return c
+}
+
// ServerAPI sets the server API version for this operation.
func (c *Count) ServerAPI(serverAPI *driver.ServerAPIOptions) *Count {
if c == nil {
@@ -323,3 +340,13 @@ func (c *Count) Authenticator(authenticator driver.Authenticator) *Count {
c.authenticator = authenticator
return c
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (c *Count) RawData(rawData bool) *Count {
+ if c == nil {
+ c = new(Count)
+ }
+
+ c.rawData = &rawData
+ return c
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create.go
similarity index 94%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create.go
index 4878e2c77..f9a406dbc 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create.go
@@ -10,12 +10,13 @@ import (
"context"
"errors"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Create represents a create operation.
@@ -56,7 +57,7 @@ func NewCreate(collectionName string) *Create {
}
}
-func (c *Create) processResponse(driver.ResponseInfo) error {
+func (c *Create) processResponse(context.Context, bsoncore.Document, driver.ResponseInfo) error {
return nil
}
@@ -93,7 +94,7 @@ func (c *Create) command(dst []byte, desc description.SelectedServer) ([]byte, e
dst = bsoncore.AppendDocumentElement(dst, "changeStreamPreAndPostImages", c.changeStreamPreAndPostImages)
}
if c.collation != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5")
}
dst = bsoncore.AppendDocumentElement(dst, "collation", c.collation)
@@ -150,7 +151,7 @@ func (c *Create) Capped(capped bool) *Create {
return c
}
-// Collation specifies a collation. This option is only valid for server versions 3.4 and above.
+// Collation specifies a collation.
func (c *Create) Collation(collation bsoncore.Document) *Create {
if c == nil {
c = new(Create)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_indexes.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_indexes.go
similarity index 66%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_indexes.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_indexes.go
index 464c1762d..c4033bc11 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_indexes.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_indexes.go
@@ -12,34 +12,35 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// CreateIndexes performs a createIndexes operation.
type CreateIndexes struct {
- authenticator driver.Authenticator
- commitQuorum bsoncore.Value
- indexes bsoncore.Document
- maxTime *time.Duration
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- result CreateIndexesResult
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ commitQuorum bsoncore.Value
+ indexes bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ result CreateIndexesResult
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
}
// CreateIndexesResult represents a createIndexes result returned by the server.
@@ -93,9 +94,9 @@ func NewCreateIndexes(indexes bsoncore.Document) *CreateIndexes {
// Result returns the result of executing this operation.
func (ci *CreateIndexes) Result() CreateIndexesResult { return ci.result }
-func (ci *CreateIndexes) processResponse(info driver.ResponseInfo) error {
+func (ci *CreateIndexes) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- ci.result, err = buildCreateIndexesResult(info.ServerResponse)
+ ci.result, err = buildCreateIndexesResult(resp)
return err
}
@@ -106,29 +107,29 @@ func (ci *CreateIndexes) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: ci.command,
- ProcessResponseFn: ci.processResponse,
- Client: ci.session,
- Clock: ci.clock,
- CommandMonitor: ci.monitor,
- Crypt: ci.crypt,
- Database: ci.database,
- Deployment: ci.deployment,
- MaxTime: ci.maxTime,
- Selector: ci.selector,
- WriteConcern: ci.writeConcern,
- ServerAPI: ci.serverAPI,
- Timeout: ci.timeout,
- Name: driverutil.CreateIndexesOp,
- Authenticator: ci.authenticator,
+ CommandFn: ci.command,
+ ProcessResponseFn: ci.processResponse,
+ Client: ci.session,
+ Clock: ci.clock,
+ CommandMonitor: ci.monitor,
+ MaxAdaptiveRetries: ci.maxAdaptiveRetries,
+ EnableOverloadRetargeting: ci.enableOverloadRetargeting,
+ Crypt: ci.crypt,
+ Database: ci.database,
+ Deployment: ci.deployment,
+ Selector: ci.selector,
+ WriteConcern: ci.writeConcern,
+ ServerAPI: ci.serverAPI,
+ Timeout: ci.timeout,
+ Name: driverutil.CreateIndexesOp,
+ Authenticator: ci.authenticator,
}.Execute(ctx)
-
}
func (ci *CreateIndexes) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "createIndexes", ci.collection)
- if ci.commitQuorum.Type != bsontype.Type(0) {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(9) {
+ if ci.commitQuorum.Type != bsoncore.Type(0) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 9) {
return nil, errors.New("the 'commitQuorum' command parameter requires a minimum server wire version of 9")
}
dst = bsoncore.AppendValueElement(dst, "commitQuorum", ci.commitQuorum)
@@ -136,6 +137,10 @@ func (ci *CreateIndexes) command(dst []byte, desc description.SelectedServer) ([
if ci.indexes != nil {
dst = bsoncore.AppendArrayElement(dst, "indexes", ci.indexes)
}
+ // Set rawData for 8.2+ servers.
+ if ci.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *ci.rawData)
+ }
return dst, nil
}
@@ -161,16 +166,6 @@ func (ci *CreateIndexes) Indexes(indexes bsoncore.Document) *CreateIndexes {
return ci
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (ci *CreateIndexes) MaxTime(maxTime *time.Duration) *CreateIndexes {
- if ci == nil {
- ci = new(CreateIndexes)
- }
-
- ci.maxTime = maxTime
- return ci
-}
-
// Session sets the session for this operation.
func (ci *CreateIndexes) Session(session *session.Client) *CreateIndexes {
if ci == nil {
@@ -211,6 +206,28 @@ func (ci *CreateIndexes) CommandMonitor(monitor *event.CommandMonitor) *CreateIn
return ci
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (ci *CreateIndexes) MaxAdaptiveRetries(maxAdaptiveRetries uint) *CreateIndexes {
+ if ci == nil {
+ ci = new(CreateIndexes)
+ }
+
+ ci.maxAdaptiveRetries = maxAdaptiveRetries
+ return ci
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (ci *CreateIndexes) EnableOverloadRetargeting(enabled bool) *CreateIndexes {
+ if ci == nil {
+ ci = new(CreateIndexes)
+ }
+
+ ci.enableOverloadRetargeting = enabled
+ return ci
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (ci *CreateIndexes) Crypt(crypt driver.Crypt) *CreateIndexes {
if ci == nil {
@@ -290,3 +307,13 @@ func (ci *CreateIndexes) Authenticator(authenticator driver.Authenticator) *Crea
ci.authenticator = authenticator
return ci
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (ci *CreateIndexes) RawData(rawData bool) *CreateIndexes {
+ if ci == nil {
+ ci = new(CreateIndexes)
+ }
+
+ ci.rawData = &rawData
+ return ci
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_search_indexes.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_search_indexes.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_search_indexes.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_search_indexes.go
index 8185d27fe..84a549740 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create_search_indexes.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_search_indexes.go
@@ -12,12 +12,12 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// CreateSearchIndexes performs a createSearchIndexes operation.
@@ -93,9 +93,9 @@ func NewCreateSearchIndexes(indexes bsoncore.Document) *CreateSearchIndexes {
// Result returns the result of executing this operation.
func (csi *CreateSearchIndexes) Result() CreateSearchIndexesResult { return csi.result }
-func (csi *CreateSearchIndexes) processResponse(info driver.ResponseInfo) error {
+func (csi *CreateSearchIndexes) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- csi.result, err = buildCreateSearchIndexesResult(info.ServerResponse)
+ csi.result, err = buildCreateSearchIndexesResult(resp)
return err
}
@@ -119,7 +119,6 @@ func (csi *CreateSearchIndexes) Execute(ctx context.Context) error {
Timeout: csi.timeout,
Authenticator: csi.authenticator,
}.Execute(ctx)
-
}
func (csi *CreateSearchIndexes) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/delete.go
similarity index 64%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/delete.go
index 4b520a548..1a5e437ac 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/delete.go
@@ -12,39 +12,41 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Delete performs a delete operation
type Delete struct {
- authenticator driver.Authenticator
- comment bsoncore.Value
- deletes []bsoncore.Document
- ordered *bool
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- hint *bool
- result DeleteResult
- serverAPI *driver.ServerAPIOptions
- let bsoncore.Document
- timeout *time.Duration
- logger *logger.Logger
+ authenticator driver.Authenticator
+ comment bsoncore.Value
+ deletes []bsoncore.Document
+ ordered *bool
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ hint *bool
+ result DeleteResult
+ serverAPI *driver.ServerAPIOptions
+ let bsoncore.Document
+ timeout *time.Duration
+ rawData *bool
+ logger *logger.Logger
}
// DeleteResult represents a delete result returned by the server.
@@ -81,8 +83,8 @@ func NewDelete(deletes ...bsoncore.Document) *Delete {
// Result returns the result of executing this operation.
func (d *Delete) Result() DeleteResult { return d.result }
-func (d *Delete) processResponse(info driver.ResponseInfo) error {
- dr, err := buildDeleteResult(info.ServerResponse)
+func (d *Delete) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
+ dr, err := buildDeleteResult(resp)
d.result.N += dr.N
return err
}
@@ -99,38 +101,39 @@ func (d *Delete) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: d.command,
- ProcessResponseFn: d.processResponse,
- Batches: batches,
- RetryMode: d.retry,
- Type: driver.Write,
- Client: d.session,
- Clock: d.clock,
- CommandMonitor: d.monitor,
- Crypt: d.crypt,
- Database: d.database,
- Deployment: d.deployment,
- Selector: d.selector,
- WriteConcern: d.writeConcern,
- ServerAPI: d.serverAPI,
- Timeout: d.timeout,
- Logger: d.logger,
- Name: driverutil.DeleteOp,
- Authenticator: d.authenticator,
+ CommandFn: d.command,
+ ProcessResponseFn: d.processResponse,
+ Batches: batches,
+ RetryMode: d.retry,
+ MaxAdaptiveRetries: d.maxAdaptiveRetries,
+ EnableOverloadRetargeting: d.enableOverloadRetargeting,
+ Type: driver.Write,
+ Client: d.session,
+ Clock: d.clock,
+ CommandMonitor: d.monitor,
+ Crypt: d.crypt,
+ Database: d.database,
+ Deployment: d.deployment,
+ Selector: d.selector,
+ WriteConcern: d.writeConcern,
+ ServerAPI: d.serverAPI,
+ Timeout: d.timeout,
+ Logger: d.logger,
+ Name: driverutil.DeleteOp,
+ Authenticator: d.authenticator,
}.Execute(ctx)
-
}
func (d *Delete) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "delete", d.collection)
- if d.comment.Type != bsontype.Type(0) {
+ if d.comment.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "comment", d.comment)
}
if d.ordered != nil {
dst = bsoncore.AppendBooleanElement(dst, "ordered", *d.ordered)
}
if d.hint != nil && *d.hint {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'hint' command parameter requires a minimum server wire version of 5")
}
if !d.writeConcern.Acknowledged() {
@@ -140,6 +143,10 @@ func (d *Delete) command(dst []byte, desc description.SelectedServer) ([]byte, e
if d.let != nil {
dst = bsoncore.AppendDocumentElement(dst, "let", d.let)
}
+ // Set rawData for 8.2+ servers.
+ if d.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *d.rawData)
+ }
return dst, nil
}
@@ -277,9 +284,30 @@ func (d *Delete) Retry(retry driver.RetryMode) *Delete {
return d
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (d *Delete) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Delete {
+ if d == nil {
+ d = new(Delete)
+ }
+
+ d.maxAdaptiveRetries = maxAdaptiveRetries
+ return d
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (d *Delete) EnableOverloadRetargeting(enabled bool) *Delete {
+ if d == nil {
+ d = new(Delete)
+ }
+
+ d.enableOverloadRetargeting = enabled
+ return d
+}
+
// Hint is a flag to indicate that the update document contains a hint. Hint is only supported by
-// servers >= 4.4. Older servers >= 3.4 will report an error for using the hint option. For servers <
-// 3.4, the driver will return an error if the hint option is used.
+// servers >= 4.4. Older servers will report an error for using the hint option.
func (d *Delete) Hint(hint bool) *Delete {
if d == nil {
d = new(Delete)
@@ -339,3 +367,13 @@ func (d *Delete) Authenticator(authenticator driver.Authenticator) *Delete {
d.authenticator = authenticator
return d
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (d *Delete) RawData(rawData bool) *Delete {
+ if d == nil {
+ d = new(Delete)
+ }
+
+ d.rawData = &rawData
+ return d
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/distinct.go
similarity index 61%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/distinct.go
index 0c39027e7..411eb3cac 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/distinct.go
@@ -11,39 +11,41 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Distinct performs a distinct operation.
type Distinct struct {
- authenticator driver.Authenticator
- collation bsoncore.Document
- key *string
- maxTime *time.Duration
- query bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- collection string
- comment bsoncore.Value
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- readConcern *readconcern.ReadConcern
- readPreference *readpref.ReadPref
- selector description.ServerSelector
- retry *driver.RetryMode
- result DistinctResult
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ collation bsoncore.Document
+ key *string
+ query bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ comment bsoncore.Value
+ hint bsoncore.Value
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ readConcern *readconcern.ReadConcern
+ readPreference *readpref.ReadPref
+ selector description.ServerSelector
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result DistinctResult
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
}
// DistinctResult represents a distinct result returned by the server.
@@ -77,9 +79,9 @@ func NewDistinct(key string, query bsoncore.Document) *Distinct {
// Result returns the result of executing this operation.
func (d *Distinct) Result() DistinctResult { return d.result }
-func (d *Distinct) processResponse(info driver.ResponseInfo) error {
+func (d *Distinct) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- d.result, err = buildDistinctResult(info.ServerResponse)
+ d.result, err = buildDistinctResult(resp)
return err
}
@@ -90,45 +92,52 @@ func (d *Distinct) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: d.command,
- ProcessResponseFn: d.processResponse,
- RetryMode: d.retry,
- Type: driver.Read,
- Client: d.session,
- Clock: d.clock,
- CommandMonitor: d.monitor,
- Crypt: d.crypt,
- Database: d.database,
- Deployment: d.deployment,
- MaxTime: d.maxTime,
- ReadConcern: d.readConcern,
- ReadPreference: d.readPreference,
- Selector: d.selector,
- ServerAPI: d.serverAPI,
- Timeout: d.timeout,
- Name: driverutil.DistinctOp,
- Authenticator: d.authenticator,
+ CommandFn: d.command,
+ ProcessResponseFn: d.processResponse,
+ RetryMode: d.retry,
+ MaxAdaptiveRetries: d.maxAdaptiveRetries,
+ EnableOverloadRetargeting: d.enableOverloadRetargeting,
+ Type: driver.Read,
+ Client: d.session,
+ Clock: d.clock,
+ CommandMonitor: d.monitor,
+ Crypt: d.crypt,
+ Database: d.database,
+ Deployment: d.deployment,
+ ReadConcern: d.readConcern,
+ ReadPreference: d.readPreference,
+ Selector: d.selector,
+ ServerAPI: d.serverAPI,
+ Timeout: d.timeout,
+ Name: driverutil.DistinctOp,
+ Authenticator: d.authenticator,
}.Execute(ctx)
-
}
func (d *Distinct) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "distinct", d.collection)
if d.collation != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5")
}
dst = bsoncore.AppendDocumentElement(dst, "collation", d.collation)
}
- if d.comment.Type != bsontype.Type(0) {
+ if d.comment.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "comment", d.comment)
}
+ if d.hint.Type != bsoncore.Type(0) {
+ dst = bsoncore.AppendValueElement(dst, "hint", d.hint)
+ }
if d.key != nil {
dst = bsoncore.AppendStringElement(dst, "key", *d.key)
}
if d.query != nil {
dst = bsoncore.AppendDocumentElement(dst, "query", d.query)
}
+ // Set rawData for 8.2+ servers.
+ if d.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *d.rawData)
+ }
return dst, nil
}
@@ -152,16 +161,6 @@ func (d *Distinct) Key(key string) *Distinct {
return d
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (d *Distinct) MaxTime(maxTime *time.Duration) *Distinct {
- if d == nil {
- d = new(Distinct)
- }
-
- d.maxTime = maxTime
- return d
-}
-
// Query specifies which documents to return distinct values from.
func (d *Distinct) Query(query bsoncore.Document) *Distinct {
if d == nil {
@@ -212,6 +211,16 @@ func (d *Distinct) Comment(comment bsoncore.Value) *Distinct {
return d
}
+// Hint sets a value to help trace an operation.
+func (d *Distinct) Hint(hint bsoncore.Value) *Distinct {
+ if d == nil {
+ d = new(Distinct)
+ }
+
+ d.hint = hint
+ return d
+}
+
// CommandMonitor sets the monitor to use for APM events.
func (d *Distinct) CommandMonitor(monitor *event.CommandMonitor) *Distinct {
if d == nil {
@@ -293,6 +302,28 @@ func (d *Distinct) Retry(retry driver.RetryMode) *Distinct {
return d
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (d *Distinct) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Distinct {
+ if d == nil {
+ d = new(Distinct)
+ }
+
+ d.maxAdaptiveRetries = maxAdaptiveRetries
+ return d
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (d *Distinct) EnableOverloadRetargeting(enabled bool) *Distinct {
+ if d == nil {
+ d = new(Distinct)
+ }
+
+ d.enableOverloadRetargeting = enabled
+ return d
+}
+
// ServerAPI sets the server API version for this operation.
func (d *Distinct) ServerAPI(serverAPI *driver.ServerAPIOptions) *Distinct {
if d == nil {
@@ -322,3 +353,13 @@ func (d *Distinct) Authenticator(authenticator driver.Authenticator) *Distinct {
d.authenticator = authenticator
return d
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (d *Distinct) RawData(rawData bool) *Distinct {
+ if d == nil {
+ d = new(Distinct)
+ }
+
+ d.rawData = &rawData
+ return d
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_collection.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_collection.go
index 5a32c2f8d..8ebf08f59 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_collection.go
@@ -12,13 +12,13 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// DropCollection performs a drop operation.
@@ -79,9 +79,9 @@ func NewDropCollection() *DropCollection {
// Result returns the result of executing this operation.
func (dc *DropCollection) Result() DropCollectionResult { return dc.result }
-func (dc *DropCollection) processResponse(info driver.ResponseInfo) error {
+func (dc *DropCollection) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- dc.result, err = buildDropCollectionResult(info.ServerResponse)
+ dc.result, err = buildDropCollectionResult(resp)
return err
}
@@ -107,7 +107,6 @@ func (dc *DropCollection) Execute(ctx context.Context) error {
Name: driverutil.DropOp,
Authenticator: dc.authenticator,
}.Execute(ctx)
-
}
func (dc *DropCollection) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_database.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_database.go
index 19956210d..e2a7533b1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_database.go
@@ -10,13 +10,13 @@ import (
"context"
"errors"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// DropDatabase performs a dropDatabase operation
@@ -58,11 +58,9 @@ func (dd *DropDatabase) Execute(ctx context.Context) error {
Name: driverutil.DropDatabaseOp,
Authenticator: dd.authenticator,
}.Execute(ctx)
-
}
func (dd *DropDatabase) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
-
dst = bsoncore.AppendInt32Element(dst, "dropDatabase", 1)
return dst, nil
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_indexes.go
similarity index 61%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_indexes.go
index a22496b1e..76c804551 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_indexes.go
@@ -12,32 +12,34 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// DropIndexes performs an dropIndexes operation.
type DropIndexes struct {
- authenticator driver.Authenticator
- index any
- maxTime *time.Duration
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- result DropIndexesResult
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ index any
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ result DropIndexesResult
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
}
// DropIndexesResult represents a dropIndexes result returned by the server.
@@ -74,9 +76,9 @@ func NewDropIndexes(index any) *DropIndexes {
// Result returns the result of executing this operation.
func (di *DropIndexes) Result() DropIndexesResult { return di.result }
-func (di *DropIndexes) processResponse(info driver.ResponseInfo) error {
+func (di *DropIndexes) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- di.result, err = buildDropIndexesResult(info.ServerResponse)
+ di.result, err = buildDropIndexesResult(resp)
return err
}
@@ -87,26 +89,26 @@ func (di *DropIndexes) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: di.command,
- ProcessResponseFn: di.processResponse,
- Client: di.session,
- Clock: di.clock,
- CommandMonitor: di.monitor,
- Crypt: di.crypt,
- Database: di.database,
- Deployment: di.deployment,
- MaxTime: di.maxTime,
- Selector: di.selector,
- WriteConcern: di.writeConcern,
- ServerAPI: di.serverAPI,
- Timeout: di.timeout,
- Name: driverutil.DropIndexesOp,
- Authenticator: di.authenticator,
+ CommandFn: di.command,
+ ProcessResponseFn: di.processResponse,
+ Client: di.session,
+ Clock: di.clock,
+ CommandMonitor: di.monitor,
+ MaxAdaptiveRetries: di.maxAdaptiveRetries,
+ EnableOverloadRetargeting: di.enableOverloadRetargeting,
+ Crypt: di.crypt,
+ Database: di.database,
+ Deployment: di.deployment,
+ Selector: di.selector,
+ WriteConcern: di.writeConcern,
+ ServerAPI: di.serverAPI,
+ Timeout: di.timeout,
+ Name: driverutil.DropIndexesOp,
+ Authenticator: di.authenticator,
}.Execute(ctx)
-
}
-func (di *DropIndexes) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
+func (di *DropIndexes) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "dropIndexes", di.collection)
switch t := di.index.(type) {
@@ -117,6 +119,10 @@ func (di *DropIndexes) command(dst []byte, _ description.SelectedServer) ([]byte
dst = bsoncore.AppendDocumentElement(dst, "index", t)
}
}
+ // Set rawData for 8.2+ servers.
+ if di.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *di.rawData)
+ }
return dst, nil
}
@@ -131,16 +137,6 @@ func (di *DropIndexes) Index(index any) *DropIndexes {
return di
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (di *DropIndexes) MaxTime(maxTime *time.Duration) *DropIndexes {
- if di == nil {
- di = new(DropIndexes)
- }
-
- di.maxTime = maxTime
- return di
-}
-
// Session sets the session for this operation.
func (di *DropIndexes) Session(session *session.Client) *DropIndexes {
if di == nil {
@@ -181,6 +177,28 @@ func (di *DropIndexes) CommandMonitor(monitor *event.CommandMonitor) *DropIndexe
return di
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (di *DropIndexes) MaxAdaptiveRetries(maxAdaptiveRetries uint) *DropIndexes {
+ if di == nil {
+ di = new(DropIndexes)
+ }
+
+ di.maxAdaptiveRetries = maxAdaptiveRetries
+ return di
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (di *DropIndexes) EnableOverloadRetargeting(enabled bool) *DropIndexes {
+ if di == nil {
+ di = new(DropIndexes)
+ }
+
+ di.enableOverloadRetargeting = enabled
+ return di
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (di *DropIndexes) Crypt(crypt driver.Crypt) *DropIndexes {
if di == nil {
@@ -260,3 +278,13 @@ func (di *DropIndexes) Authenticator(authenticator driver.Authenticator) *DropIn
di.authenticator = authenticator
return di
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (di *DropIndexes) RawData(rawData bool) *DropIndexes {
+ if di == nil {
+ di = new(DropIndexes)
+ }
+
+ di.rawData = &rawData
+ return di
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_search_index.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_search_index.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_search_index.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_search_index.go
index 94e4ddfb0..dd7235664 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_search_index.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_search_index.go
@@ -12,11 +12,11 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// DropSearchIndex performs an dropSearchIndex operation.
@@ -69,9 +69,9 @@ func NewDropSearchIndex(index string) *DropSearchIndex {
// Result returns the result of executing this operation.
func (dsi *DropSearchIndex) Result() DropSearchIndexResult { return dsi.result }
-func (dsi *DropSearchIndex) processResponse(info driver.ResponseInfo) error {
+func (dsi *DropSearchIndex) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- dsi.result, err = buildDropSearchIndexResult(info.ServerResponse)
+ dsi.result, err = buildDropSearchIndexResult(resp)
return err
}
@@ -95,7 +95,6 @@ func (dsi *DropSearchIndex) Execute(ctx context.Context) error {
Timeout: dsi.timeout,
Authenticator: dsi.authenticator,
}.Execute(ctx)
-
}
func (dsi *DropSearchIndex) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/end_sessions.go
similarity index 59%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/end_sessions.go
index 8b24b3d8c..71bba2d91 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/end_sessions.go
@@ -10,26 +10,28 @@ import (
"context"
"errors"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// EndSessions performs an endSessions operation.
type EndSessions struct {
- authenticator driver.Authenticator
- sessionIDs bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- serverAPI *driver.ServerAPIOptions
+ authenticator driver.Authenticator
+ sessionIDs bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ serverAPI *driver.ServerAPIOptions
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
}
// NewEndSessions constructs and returns a new EndSessions.
@@ -39,9 +41,8 @@ func NewEndSessions(sessionIDs bsoncore.Document) *EndSessions {
}
}
-func (es *EndSessions) processResponse(driver.ResponseInfo) error {
- var err error
- return err
+func (es *EndSessions) processResponse(context.Context, bsoncore.Document, driver.ResponseInfo) error {
+ return nil
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -51,20 +52,21 @@ func (es *EndSessions) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: es.command,
- ProcessResponseFn: es.processResponse,
- Client: es.session,
- Clock: es.clock,
- CommandMonitor: es.monitor,
- Crypt: es.crypt,
- Database: es.database,
- Deployment: es.deployment,
- Selector: es.selector,
- ServerAPI: es.serverAPI,
- Name: driverutil.EndSessionsOp,
- Authenticator: es.authenticator,
+ CommandFn: es.command,
+ ProcessResponseFn: es.processResponse,
+ Client: es.session,
+ Clock: es.clock,
+ CommandMonitor: es.monitor,
+ MaxAdaptiveRetries: es.maxAdaptiveRetries,
+ EnableOverloadRetargeting: es.enableOverloadRetargeting,
+ Crypt: es.crypt,
+ Database: es.database,
+ Deployment: es.deployment,
+ Selector: es.selector,
+ ServerAPI: es.serverAPI,
+ Name: driverutil.EndSessionsOp,
+ Authenticator: es.authenticator,
}.Execute(ctx)
-
}
func (es *EndSessions) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
@@ -173,3 +175,25 @@ func (es *EndSessions) Authenticator(authenticator driver.Authenticator) *EndSes
es.authenticator = authenticator
return es
}
+
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (es *EndSessions) MaxAdaptiveRetries(maxAdaptiveRetries uint) *EndSessions {
+ if es == nil {
+ es = new(EndSessions)
+ }
+
+ es.maxAdaptiveRetries = maxAdaptiveRetries
+ return es
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (es *EndSessions) EnableOverloadRetargeting(enabled bool) *EndSessions {
+ if es == nil {
+ es = new(EndSessions)
+ }
+
+ es.enableOverloadRetargeting = enabled
+ return es
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/errors.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/errors.go
similarity index 72%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/errors.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/errors.go
index d13a135ce..f88de0141 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/errors.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/errors.go
@@ -8,6 +8,4 @@ package operation
import "errors"
-var (
- errUnacknowledgedHint = errors.New("the 'hint' command parameter cannot be used with unacknowledged writes")
-)
+var errUnacknowledgedHint = errors.New("the 'hint' command parameter cannot be used with unacknowledged writes")
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find.go
similarity index 68%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find.go
index c71b7d755..23599814b 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find.go
@@ -11,60 +11,61 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Find performs a find operation.
type Find struct {
- authenticator driver.Authenticator
- allowDiskUse *bool
- allowPartialResults *bool
- awaitData *bool
- batchSize *int32
- collation bsoncore.Document
- comment *string
- filter bsoncore.Document
- hint bsoncore.Value
- let bsoncore.Document
- limit *int64
- max bsoncore.Document
- maxTime *time.Duration
- min bsoncore.Document
- noCursorTimeout *bool
- oplogReplay *bool
- projection bsoncore.Document
- returnKey *bool
- showRecordID *bool
- singleBatch *bool
- skip *int64
- snapshot *bool
- sort bsoncore.Document
- tailable *bool
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- readConcern *readconcern.ReadConcern
- readPreference *readpref.ReadPref
- selector description.ServerSelector
- retry *driver.RetryMode
- result driver.CursorResponse
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
- omitCSOTMaxTimeMS bool
- logger *logger.Logger
+ authenticator driver.Authenticator
+ allowDiskUse *bool
+ allowPartialResults *bool
+ awaitData *bool
+ batchSize *int32
+ collation bsoncore.Document
+ comment bsoncore.Value
+ filter bsoncore.Document
+ hint bsoncore.Value
+ let bsoncore.Document
+ limit *int64
+ max bsoncore.Document
+ min bsoncore.Document
+ noCursorTimeout *bool
+ oplogReplay *bool
+ projection bsoncore.Document
+ returnKey *bool
+ showRecordID *bool
+ singleBatch *bool
+ skip *int64
+ snapshot *bool
+ sort bsoncore.Document
+ tailable *bool
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ readConcern *readconcern.ReadConcern
+ readPreference *readpref.ReadPref
+ selector description.ServerSelector
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result driver.CursorResponse
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
+ logger *logger.Logger
+ omitMaxTimeMS bool
}
// NewFind constructs and returns a new Find.
@@ -80,9 +81,12 @@ func (f *Find) Result(opts driver.CursorOptions) (*driver.BatchCursor, error) {
return driver.NewBatchCursor(f.result, f.session, f.clock, opts)
}
-func (f *Find) processResponse(info driver.ResponseInfo) error {
- var err error
- f.result, err = driver.NewCursorResponse(info)
+func (f *Find) processResponse(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ curDoc, err := driver.ExtractCursorDocument(resp)
+ if err != nil {
+ return err
+ }
+ f.result, err = driver.NewCursorResponse(curDoc, info)
return err
}
@@ -93,35 +97,35 @@ func (f *Find) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: f.command,
- ProcessResponseFn: f.processResponse,
- RetryMode: f.retry,
- Type: driver.Read,
- Client: f.session,
- Clock: f.clock,
- CommandMonitor: f.monitor,
- Crypt: f.crypt,
- Database: f.database,
- Deployment: f.deployment,
- MaxTime: f.maxTime,
- ReadConcern: f.readConcern,
- ReadPreference: f.readPreference,
- Selector: f.selector,
- Legacy: driver.LegacyFind,
- ServerAPI: f.serverAPI,
- Timeout: f.timeout,
- Logger: f.logger,
- Name: driverutil.FindOp,
- OmitCSOTMaxTimeMS: f.omitCSOTMaxTimeMS,
- Authenticator: f.authenticator,
+ CommandFn: f.command,
+ ProcessResponseFn: f.processResponse,
+ RetryMode: f.retry,
+ MaxAdaptiveRetries: f.maxAdaptiveRetries,
+ EnableOverloadRetargeting: f.enableOverloadRetargeting,
+ Type: driver.Read,
+ Client: f.session,
+ Clock: f.clock,
+ CommandMonitor: f.monitor,
+ Crypt: f.crypt,
+ Database: f.database,
+ Deployment: f.deployment,
+ ReadConcern: f.readConcern,
+ ReadPreference: f.readPreference,
+ Selector: f.selector,
+ Legacy: driver.LegacyFind,
+ ServerAPI: f.serverAPI,
+ Timeout: f.timeout,
+ Logger: f.logger,
+ Name: driverutil.FindOp,
+ Authenticator: f.authenticator,
+ OmitMaxTimeMS: f.omitMaxTimeMS,
}.Execute(ctx)
-
}
func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "find", f.collection)
if f.allowDiskUse != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(4) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 4) {
return nil, errors.New("the 'allowDiskUse' command parameter requires a minimum server wire version of 4")
}
dst = bsoncore.AppendBooleanElement(dst, "allowDiskUse", *f.allowDiskUse)
@@ -136,18 +140,18 @@ func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, err
dst = bsoncore.AppendInt32Element(dst, "batchSize", *f.batchSize)
}
if f.collation != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5")
}
dst = bsoncore.AppendDocumentElement(dst, "collation", f.collation)
}
- if f.comment != nil {
- dst = bsoncore.AppendStringElement(dst, "comment", *f.comment)
+ if f.comment.Type != bsoncore.Type(0) {
+ dst = bsoncore.AppendValueElement(dst, "comment", f.comment)
}
if f.filter != nil {
dst = bsoncore.AppendDocumentElement(dst, "filter", f.filter)
}
- if f.hint.Type != bsontype.Type(0) {
+ if f.hint.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "hint", f.hint)
}
if f.let != nil {
@@ -192,6 +196,10 @@ func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, err
if f.tailable != nil {
dst = bsoncore.AppendBooleanElement(dst, "tailable", *f.tailable)
}
+ // Set rawData for 8.2+ servers.
+ if f.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *f.rawData)
+ }
return dst, nil
}
@@ -245,13 +253,13 @@ func (f *Find) Collation(collation bsoncore.Document) *Find {
return f
}
-// Comment sets a string to help trace an operation.
-func (f *Find) Comment(comment string) *Find {
+// Comment sets a value to help trace an operation.
+func (f *Find) Comment(comment bsoncore.Value) *Find {
if f == nil {
f = new(Find)
}
- f.comment = &comment
+ f.comment = comment
return f
}
@@ -305,16 +313,6 @@ func (f *Find) Max(max bsoncore.Document) *Find {
return f
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (f *Find) MaxTime(maxTime *time.Duration) *Find {
- if f == nil {
- f = new(Find)
- }
-
- f.maxTime = maxTime
- return f
-}
-
// Min sets an inclusive lower bound for a specific index.
func (f *Find) Min(min bsoncore.Document) *Find {
if f == nil {
@@ -536,35 +534,45 @@ func (f *Find) Retry(retry driver.RetryMode) *Find {
return f
}
-// ServerAPI sets the server API version for this operation.
-func (f *Find) ServerAPI(serverAPI *driver.ServerAPIOptions) *Find {
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (f *Find) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Find {
if f == nil {
f = new(Find)
}
- f.serverAPI = serverAPI
+ f.maxAdaptiveRetries = maxAdaptiveRetries
return f
}
-// Timeout sets the timeout for this operation.
-func (f *Find) Timeout(timeout *time.Duration) *Find {
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (f *Find) EnableOverloadRetargeting(enabled bool) *Find {
if f == nil {
f = new(Find)
}
- f.timeout = timeout
+ f.enableOverloadRetargeting = enabled
return f
}
-// OmitCSOTMaxTimeMS omits the automatically-calculated "maxTimeMS" from the
-// command when CSOT is enabled. It does not effect "maxTimeMS" set by
-// [Find.MaxTime].
-func (f *Find) OmitCSOTMaxTimeMS(omit bool) *Find {
+// ServerAPI sets the server API version for this operation.
+func (f *Find) ServerAPI(serverAPI *driver.ServerAPIOptions) *Find {
if f == nil {
f = new(Find)
}
- f.omitCSOTMaxTimeMS = omit
+ f.serverAPI = serverAPI
+ return f
+}
+
+// Timeout sets the timeout for this operation.
+func (f *Find) Timeout(timeout *time.Duration) *Find {
+ if f == nil {
+ f = new(Find)
+ }
+
+ f.timeout = timeout
return f
}
@@ -587,3 +595,24 @@ func (f *Find) Authenticator(authenticator driver.Authenticator) *Find {
f.authenticator = authenticator
return f
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (f *Find) RawData(rawData bool) *Find {
+ if f == nil {
+ f = new(Find)
+ }
+
+ f.rawData = &rawData
+ return f
+}
+
+// OmitMaxTimeMS omits the automatically-calculated "maxTimeMS" from the
+// command.
+func (f *Find) OmitMaxTimeMS(omit bool) *Find {
+ if f == nil {
+ f = new(Find)
+ }
+
+ f.omitMaxTimeMS = omit
+ return f
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find_and_modify.go
similarity index 72%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find_and_modify.go
index 89f887477..4a2ccd71d 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find_and_modify.go
@@ -12,47 +12,48 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// FindAndModify performs a findAndModify operation.
type FindAndModify struct {
- authenticator driver.Authenticator
- arrayFilters bsoncore.Array
- bypassDocumentValidation *bool
- collation bsoncore.Document
- comment bsoncore.Value
- fields bsoncore.Document
- maxTime *time.Duration
- newDocument *bool
- query bsoncore.Document
- remove *bool
- sort bsoncore.Document
- update bsoncore.Value
- upsert *bool
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- crypt driver.Crypt
- hint bsoncore.Value
- serverAPI *driver.ServerAPIOptions
- let bsoncore.Document
- timeout *time.Duration
- bypassEmptyTsReplacement *bool
+ authenticator driver.Authenticator
+ arrayFilters bsoncore.Array
+ bypassDocumentValidation *bool
+ collation bsoncore.Document
+ comment bsoncore.Value
+ fields bsoncore.Document
+ newDocument *bool
+ query bsoncore.Document
+ remove *bool
+ sort bsoncore.Document
+ update bsoncore.Value
+ upsert *bool
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ crypt driver.Crypt
+ hint bsoncore.Value
+ serverAPI *driver.ServerAPIOptions
+ let bsoncore.Document
+ timeout *time.Duration
+ rawData *bool
+ additionalCmd bson.D
result FindAndModifyResult
}
@@ -62,7 +63,7 @@ type LastErrorObject struct {
// True if an update modified an existing document
UpdatedExisting bool
// Object ID of the upserted document.
- Upserted interface{}
+ Upserted any
}
// FindAndModifyResult represents a findAndModify result returned by the server.
@@ -86,7 +87,7 @@ func buildFindAndModifyResult(response bsoncore.Document) (FindAndModifyResult,
famr.Value, ok = element.Value().DocumentOK()
// The 'value' field returned by a FindAndModify can be null in the case that no document was found.
- if element.Value().Type != bsontype.Null && !ok {
+ if element.Value().Type != bsoncore.TypeNull && !ok {
return famr, fmt.Errorf("response field 'value' is type document or null, but received BSON type %s", element.Value().Type)
}
case "lastErrorObject":
@@ -115,12 +116,11 @@ func NewFindAndModify(query bsoncore.Document) *FindAndModify {
// Result returns the result of executing this operation.
func (fam *FindAndModify) Result() FindAndModifyResult { return fam.result }
-func (fam *FindAndModify) processResponse(info driver.ResponseInfo) error {
+func (fam *FindAndModify) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- fam.result, err = buildFindAndModifyResult(info.ServerResponse)
+ fam.result, err = buildFindAndModifyResult(resp)
return err
-
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -133,78 +133,71 @@ func (fam *FindAndModify) Execute(ctx context.Context) error {
CommandFn: fam.command,
ProcessResponseFn: fam.processResponse,
- RetryMode: fam.retry,
- Type: driver.Write,
- Client: fam.session,
- Clock: fam.clock,
- CommandMonitor: fam.monitor,
- Database: fam.database,
- Deployment: fam.deployment,
- MaxTime: fam.maxTime,
- Selector: fam.selector,
- WriteConcern: fam.writeConcern,
- Crypt: fam.crypt,
- ServerAPI: fam.serverAPI,
- Timeout: fam.timeout,
- Name: driverutil.FindAndModifyOp,
- Authenticator: fam.authenticator,
+ RetryMode: fam.retry,
+ MaxAdaptiveRetries: fam.maxAdaptiveRetries,
+ EnableOverloadRetargeting: fam.enableOverloadRetargeting,
+ Type: driver.Write,
+ Client: fam.session,
+ Clock: fam.clock,
+ CommandMonitor: fam.monitor,
+ Database: fam.database,
+ Deployment: fam.deployment,
+ Selector: fam.selector,
+ WriteConcern: fam.writeConcern,
+ Crypt: fam.crypt,
+ ServerAPI: fam.serverAPI,
+ Timeout: fam.timeout,
+ Name: driverutil.FindAndModifyOp,
+ Authenticator: fam.authenticator,
}.Execute(ctx)
-
}
func (fam *FindAndModify) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "findAndModify", fam.collection)
if fam.arrayFilters != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(6) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 6) {
return nil, errors.New("the 'arrayFilters' command parameter requires a minimum server wire version of 6")
}
dst = bsoncore.AppendArrayElement(dst, "arrayFilters", fam.arrayFilters)
}
if fam.bypassDocumentValidation != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *fam.bypassDocumentValidation)
}
if fam.collation != nil {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'collation' command parameter requires a minimum server wire version of 5")
}
dst = bsoncore.AppendDocumentElement(dst, "collation", fam.collation)
}
- if fam.comment.Type != bsontype.Type(0) {
+ if fam.comment.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "comment", fam.comment)
}
if fam.fields != nil {
-
dst = bsoncore.AppendDocumentElement(dst, "fields", fam.fields)
}
if fam.newDocument != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "new", *fam.newDocument)
}
if fam.query != nil {
-
dst = bsoncore.AppendDocumentElement(dst, "query", fam.query)
}
if fam.remove != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "remove", *fam.remove)
}
if fam.sort != nil {
-
dst = bsoncore.AppendDocumentElement(dst, "sort", fam.sort)
}
if fam.update.Data != nil {
dst = bsoncore.AppendValueElement(dst, "update", fam.update)
}
if fam.upsert != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "upsert", *fam.upsert)
}
- if fam.hint.Type != bsontype.Type(0) {
+ if fam.hint.Type != bsoncore.Type(0) {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(8) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 8) {
return nil, errors.New("the 'hint' command parameter requires a minimum server wire version of 8")
}
if !fam.writeConcern.Acknowledged() {
@@ -215,8 +208,16 @@ func (fam *FindAndModify) command(dst []byte, desc description.SelectedServer) (
if fam.let != nil {
dst = bsoncore.AppendDocumentElement(dst, "let", fam.let)
}
- if fam.bypassEmptyTsReplacement != nil {
- dst = bsoncore.AppendBooleanElement(dst, "bypassEmptyTsReplacement", *fam.bypassEmptyTsReplacement)
+ // Set rawData for 8.2+ servers.
+ if fam.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *fam.rawData)
+ }
+ if len(fam.additionalCmd) > 0 {
+ doc, err := bson.Marshal(fam.additionalCmd)
+ if err != nil {
+ return nil, err
+ }
+ dst = append(dst, doc[4:len(doc)-1]...)
}
return dst, nil
@@ -272,16 +273,6 @@ func (fam *FindAndModify) Fields(fields bsoncore.Document) *FindAndModify {
return fam
}
-// MaxTime specifies the maximum amount of time to allow the operation to run on the server.
-func (fam *FindAndModify) MaxTime(maxTime *time.Duration) *FindAndModify {
- if fam == nil {
- fam = new(FindAndModify)
- }
-
- fam.maxTime = maxTime
- return fam
-}
-
// NewDocument specifies whether to return the modified document or the original. Defaults to false (return original).
func (fam *FindAndModify) NewDocument(newDocument bool) *FindAndModify {
if fam == nil {
@@ -434,6 +425,28 @@ func (fam *FindAndModify) Retry(retry driver.RetryMode) *FindAndModify {
return fam
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (fam *FindAndModify) MaxAdaptiveRetries(maxAdaptiveRetries uint) *FindAndModify {
+ if fam == nil {
+ fam = new(FindAndModify)
+ }
+
+ fam.maxAdaptiveRetries = maxAdaptiveRetries
+ return fam
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (fam *FindAndModify) EnableOverloadRetargeting(enabled bool) *FindAndModify {
+ if fam == nil {
+ fam = new(FindAndModify)
+ }
+
+ fam.enableOverloadRetargeting = enabled
+ return fam
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (fam *FindAndModify) Crypt(crypt driver.Crypt) *FindAndModify {
if fam == nil {
@@ -494,12 +507,22 @@ func (fam *FindAndModify) Authenticator(authenticator driver.Authenticator) *Fin
return fam
}
-// BypassEmptyTsReplacement sets the bypassEmptyTsReplacement to use for this operation.
-func (fam *FindAndModify) BypassEmptyTsReplacement(bypassEmptyTsReplacement bool) *FindAndModify {
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (fam *FindAndModify) RawData(rawData bool) *FindAndModify {
+ if fam == nil {
+ fam = new(FindAndModify)
+ }
+
+ fam.rawData = &rawData
+ return fam
+}
+
+// AdditionalCmd sets additional command fields to be attached.
+func (fam *FindAndModify) AdditionalCmd(d bson.D) *FindAndModify {
if fam == nil {
fam = new(FindAndModify)
}
- fam.bypassEmptyTsReplacement = &bypassEmptyTsReplacement
+ fam.additionalCmd = d
return fam
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/hello.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/hello.go
index 60c99f063..f50a2b2c1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/hello.go
@@ -14,16 +14,17 @@ import (
"strconv"
"strings"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/internal/bsonutil"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/handshake"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/version"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/bsonutil"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/handshake"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/version"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// maxClientMetadataSize is the maximum size of the client metadata document
@@ -47,6 +48,12 @@ type Hello struct {
maxAwaitTimeMS *int64
serverAPI *driver.ServerAPIOptions
loadBalanced bool
+ omitMaxTimeMS bool
+
+ // Fields provided by a library that wraps the Go Driver.
+ outerLibraryName string
+ outerLibraryVersion string
+ outerLibraryPlatform string
res bsoncore.Document
}
@@ -121,9 +128,32 @@ func (h *Hello) LoadBalanced(lb bool) *Hello {
return h
}
+// OuterLibraryName specifies the name of the library wrapping the Go Driver.
+func (h *Hello) OuterLibraryName(name string) *Hello {
+ h.outerLibraryName = name
+
+ return h
+}
+
+// OuterLibraryVersion specifies the version of the library wrapping the Go
+// Driver.
+func (h *Hello) OuterLibraryVersion(version string) *Hello {
+ h.outerLibraryVersion = version
+
+ return h
+}
+
+// OuterLibraryPlatform specifies the platform of the library wrapping the Go
+// Driver.
+func (h *Hello) OuterLibraryPlatform(platform string) *Hello {
+ h.outerLibraryPlatform = platform
+
+ return h
+}
+
// Result returns the result of executing this operation.
func (h *Hello) Result(addr address.Address) description.Server {
- return description.NewServer(addr, bson.Raw(h.res))
+ return driverutil.NewServerDescription(addr, bson.Raw(h.res))
}
const dockerEnvPath = "/.dockerenv"
@@ -245,12 +275,22 @@ func appendClientAppName(dst []byte, name string) ([]byte, error) {
// appendClientDriver appends the driver metadata to dst. It is the
// responsibility of the caller to check that this appending does not cause dst
// to exceed any size limitations.
-func appendClientDriver(dst []byte) ([]byte, error) {
+func appendClientDriver(dst []byte, outerLibraryName, outerLibraryVersion string) ([]byte, error) {
var idx int32
idx, dst = bsoncore.AppendDocumentElementStart(dst, "driver")
- dst = bsoncore.AppendStringElement(dst, "name", driverName)
- dst = bsoncore.AppendStringElement(dst, "version", version.Driver)
+ name := driverName
+ if outerLibraryName != "" {
+ name = name + "|" + outerLibraryName
+ }
+
+ version := version.Driver
+ if outerLibraryVersion != "" {
+ version = version + "|" + outerLibraryVersion
+ }
+
+ dst = bsoncore.AppendStringElement(dst, "name", name)
+ dst = bsoncore.AppendStringElement(dst, "version", version)
return bsoncore.AppendDocumentEnd(dst, idx)
}
@@ -372,8 +412,13 @@ func appendClientOS(dst []byte, omitNonType bool) ([]byte, error) {
// appendClientPlatform appends the platform metadata to dst. It is the
// responsibility of the caller to check that this appending does not cause dst
// to exceed any size limitations.
-func appendClientPlatform(dst []byte) []byte {
- return bsoncore.AppendStringElement(dst, "platform", runtime.Version())
+func appendClientPlatform(dst []byte, outerLibraryPlatform string) []byte {
+ platform := runtime.Version()
+ if outerLibraryPlatform != "" {
+ platform = platform + "|" + outerLibraryPlatform
+ }
+
+ return bsoncore.AppendStringElement(dst, "platform", platform)
}
// encodeClientMetadata encodes the client metadata into a BSON document. maxLen
@@ -410,7 +455,7 @@ func appendClientPlatform(dst []byte) []byte {
// }
// }
// }
-func encodeClientMetadata(appname string, maxLen int) ([]byte, error) {
+func encodeClientMetadata(h *Hello, maxLen int) ([]byte, error) {
dst := make([]byte, 0, maxLen)
omitEnvDoc := false
@@ -424,12 +469,12 @@ retry:
idx, dst = bsoncore.AppendDocumentStart(dst)
var err error
- dst, err = appendClientAppName(dst, appname)
+ dst, err = appendClientAppName(dst, h.appname)
if err != nil {
return nil, err
}
- dst, err = appendClientDriver(dst)
+ dst, err = appendClientDriver(dst, h.outerLibraryName, h.outerLibraryVersion)
if err != nil {
return nil, err
}
@@ -440,7 +485,7 @@ retry:
}
if !truncatePlatform {
- dst = appendClientPlatform(dst)
+ dst = appendClientPlatform(dst, h.outerLibraryPlatform)
}
if !omitEnvDocument {
@@ -517,7 +562,7 @@ func (h *Hello) handshakeCommand(dst []byte, desc description.SelectedServer) ([
}
dst, _ = bsoncore.AppendArrayEnd(dst, idx)
- clientMetadata, _ := encodeClientMetadata(h.appname, maxClientMetadataSize)
+ clientMetadata, _ := encodeClientMetadata(h, maxClientMetadataSize)
// If the client metadata is empty, do not append it to the command.
if len(clientMetadata) > 0 {
@@ -531,7 +576,7 @@ func (h *Hello) handshakeCommand(dst []byte, desc description.SelectedServer) ([
func (h *Hello) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
// Use "hello" if topology is LoadBalanced, API version is declared or server
// has responded with "helloOk". Otherwise, use legacy hello.
- if h.loadBalanced || h.serverAPI != nil || desc.Server.HelloOK {
+ if h.loadBalanced || h.serverAPI != nil || desc.HelloOK {
dst = bsoncore.AppendInt32Element(dst, "hello", 1)
} else {
dst = bsoncore.AppendInt32Element(dst, handshake.LegacyHello, 1)
@@ -554,6 +599,7 @@ func (h *Hello) command(dst []byte, desc description.SelectedServer) ([]byte, er
// loadBalanced=false per the load balancing spec.
dst = bsoncore.AppendBooleanElement(dst, "loadBalanced", true)
}
+ dst = bsoncore.AppendBooleanElement(dst, "backpressure", true)
return dst, nil
}
@@ -568,7 +614,7 @@ func (h *Hello) Execute(ctx context.Context) error {
}
// StreamResponse gets the next streaming Hello response from the server.
-func (h *Hello) StreamResponse(ctx context.Context, conn driver.StreamerConnection) error {
+func (h *Hello) StreamResponse(ctx context.Context, conn *mnet.Connection) error {
return h.createOperation().ExecuteExhaust(ctx, conn)
}
@@ -586,11 +632,12 @@ func (h *Hello) createOperation() driver.Operation {
CommandFn: h.command,
Database: "admin",
Deployment: h.d,
- ProcessResponseFn: func(info driver.ResponseInfo) error {
- h.res = info.ServerResponse
+ ProcessResponseFn: func(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
+ h.res = resp
return nil
},
- ServerAPI: h.serverAPI,
+ ServerAPI: h.serverAPI,
+ OmitMaxTimeMS: h.omitMaxTimeMS,
}
if isLegacyHandshake(h.serverAPI, h.loadBalanced) {
@@ -602,16 +649,16 @@ func (h *Hello) createOperation() driver.Operation {
// GetHandshakeInformation performs the MongoDB handshake for the provided connection and returns the relevant
// information about the server. This function implements the driver.Handshaker interface.
-func (h *Hello) GetHandshakeInformation(ctx context.Context, _ address.Address, c driver.Connection) (driver.HandshakeInformation, error) {
- deployment := driver.SingleConnectionDeployment{C: c}
+func (h *Hello) GetHandshakeInformation(ctx context.Context, _ address.Address, conn *mnet.Connection) (driver.HandshakeInformation, error) {
+ deployment := driver.SingleConnectionDeployment{C: conn}
op := driver.Operation{
Clock: h.clock,
CommandFn: h.handshakeCommand,
Deployment: deployment,
Database: "admin",
- ProcessResponseFn: func(info driver.ResponseInfo) error {
- h.res = info.ServerResponse
+ ProcessResponseFn: func(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
+ h.res = resp
return nil
},
ServerAPI: h.serverAPI,
@@ -626,7 +673,7 @@ func (h *Hello) GetHandshakeInformation(ctx context.Context, _ address.Address,
}
info := driver.HandshakeInformation{
- Description: h.Result(c.Address()),
+ Description: h.Result(conn.Address()),
}
if speculativeAuthenticate, ok := h.res.Lookup("speculativeAuthenticate").DocumentOK(); ok {
info.SpeculativeAuthenticate = speculativeAuthenticate
@@ -647,10 +694,20 @@ func (h *Hello) GetHandshakeInformation(ctx context.Context, _ address.Address,
// FinishHandshake implements the Handshaker interface. This is a no-op function because a non-authenticated connection
// does not do anything besides the initial Hello for a handshake.
-func (h *Hello) FinishHandshake(context.Context, driver.Connection) error {
+func (h *Hello) FinishHandshake(context.Context, *mnet.Connection) error {
return nil
}
+// OmitMaxTimeMS will ensure maxTimMS is not included in the wire message
+// constructed to send a hello request.
+func (h *Hello) OmitMaxTimeMS(val bool) *Hello {
+ if h == nil {
+ h = new(Hello)
+ }
+ h.omitMaxTimeMS = val
+ return h
+}
+
// Authenticator sets the authenticator to use for this operation.
func (h *Hello) Authenticator(authenticator driver.Authenticator) *Hello {
if h == nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_collections.go
similarity index 61%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_collections.go
index 1e39f5bfb..97c81317d 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_collections.go
@@ -11,34 +11,37 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// ListCollections performs a listCollections operation.
type ListCollections struct {
- authenticator driver.Authenticator
- filter bsoncore.Document
- nameOnly *bool
- authorizedCollections *bool
- session *session.Client
- clock *session.ClusterClock
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- readPreference *readpref.ReadPref
- selector description.ServerSelector
- retry *driver.RetryMode
- result driver.CursorResponse
- batchSize *int32
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ filter bsoncore.Document
+ nameOnly *bool
+ authorizedCollections *bool
+ session *session.Client
+ clock *session.ClusterClock
+ monitor *event.CommandMonitor
+ crypt driver.Crypt
+ database string
+ deployment driver.Deployment
+ readPreference *readpref.ReadPref
+ selector description.ServerSelector
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result driver.CursorResponse
+ batchSize *int32
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
}
// NewListCollections constructs and returns a new ListCollections.
@@ -55,9 +58,12 @@ func (lc *ListCollections) Result(opts driver.CursorOptions) (*driver.BatchCurso
return driver.NewBatchCursor(lc.result, lc.session, lc.clock, opts)
}
-func (lc *ListCollections) processResponse(info driver.ResponseInfo) error {
- var err error
- lc.result, err = driver.NewCursorResponse(info)
+func (lc *ListCollections) processResponse(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ curDoc, err := driver.ExtractCursorDocument(resp)
+ if err != nil {
+ return err
+ }
+ lc.result, err = driver.NewCursorResponse(curDoc, info)
return err
}
@@ -68,28 +74,29 @@ func (lc *ListCollections) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: lc.command,
- ProcessResponseFn: lc.processResponse,
- RetryMode: lc.retry,
- Type: driver.Read,
- Client: lc.session,
- Clock: lc.clock,
- CommandMonitor: lc.monitor,
- Crypt: lc.crypt,
- Database: lc.database,
- Deployment: lc.deployment,
- ReadPreference: lc.readPreference,
- Selector: lc.selector,
- Legacy: driver.LegacyListCollections,
- ServerAPI: lc.serverAPI,
- Timeout: lc.timeout,
- Name: driverutil.ListCollectionsOp,
- Authenticator: lc.authenticator,
+ CommandFn: lc.command,
+ ProcessResponseFn: lc.processResponse,
+ RetryMode: lc.retry,
+ MaxAdaptiveRetries: lc.maxAdaptiveRetries,
+ EnableOverloadRetargeting: lc.enableOverloadRetargeting,
+ Type: driver.Read,
+ Client: lc.session,
+ Clock: lc.clock,
+ CommandMonitor: lc.monitor,
+ Crypt: lc.crypt,
+ Database: lc.database,
+ Deployment: lc.deployment,
+ ReadPreference: lc.readPreference,
+ Selector: lc.selector,
+ Legacy: driver.LegacyListCollections,
+ ServerAPI: lc.serverAPI,
+ Timeout: lc.timeout,
+ Name: driverutil.ListCollectionsOp,
+ Authenticator: lc.authenticator,
}.Execute(ctx)
-
}
-func (lc *ListCollections) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
+func (lc *ListCollections) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendInt32Element(dst, "listCollections", 1)
if lc.filter != nil {
dst = bsoncore.AppendDocumentElement(dst, "filter", lc.filter)
@@ -107,6 +114,11 @@ func (lc *ListCollections) command(dst []byte, _ description.SelectedServer) ([]
}
dst = bsoncore.AppendDocumentElement(dst, "cursor", cursorDoc.Build())
+ // Set rawData for 8.2+ servers.
+ if lc.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *lc.rawData)
+ }
+
return dst, nil
}
@@ -232,6 +244,28 @@ func (lc *ListCollections) Retry(retry driver.RetryMode) *ListCollections {
return lc
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (lc *ListCollections) MaxAdaptiveRetries(maxAdaptiveRetries uint) *ListCollections {
+ if lc == nil {
+ lc = new(ListCollections)
+ }
+
+ lc.maxAdaptiveRetries = maxAdaptiveRetries
+ return lc
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (lc *ListCollections) EnableOverloadRetargeting(enabled bool) *ListCollections {
+ if lc == nil {
+ lc = new(ListCollections)
+ }
+
+ lc.enableOverloadRetargeting = enabled
+ return lc
+}
+
// BatchSize specifies the number of documents to return in every batch.
func (lc *ListCollections) BatchSize(batchSize int32) *ListCollections {
if lc == nil {
@@ -271,3 +305,13 @@ func (lc *ListCollections) Authenticator(authenticator driver.Authenticator) *Li
lc.authenticator = authenticator
return lc
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (lc *ListCollections) RawData(rawData bool) *ListCollections {
+ if lc == nil {
+ lc = new(ListCollections)
+ }
+
+ lc.rawData = &rawData
+ return lc
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_databases.go
similarity index 74%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_databases.go
index 3df171e37..f66d60684 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_databases.go
@@ -12,33 +12,35 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// ListDatabases performs a listDatabases operation.
type ListDatabases struct {
- authenticator driver.Authenticator
- filter bsoncore.Document
- authorizedDatabases *bool
- nameOnly *bool
- session *session.Client
- clock *session.ClusterClock
- monitor *event.CommandMonitor
- database string
- deployment driver.Deployment
- readPreference *readpref.ReadPref
- retry *driver.RetryMode
- selector description.ServerSelector
- crypt driver.Crypt
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ filter bsoncore.Document
+ authorizedDatabases *bool
+ nameOnly *bool
+ session *session.Client
+ clock *session.ClusterClock
+ monitor *event.CommandMonitor
+ database string
+ deployment driver.Deployment
+ readPreference *readpref.ReadPref
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ selector description.ServerSelector
+ crypt driver.Crypt
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
result ListDatabasesResult
}
@@ -135,12 +137,11 @@ func NewListDatabases(filter bsoncore.Document) *ListDatabases {
// Result returns the result of executing this operation.
func (ld *ListDatabases) Result() ListDatabasesResult { return ld.result }
-func (ld *ListDatabases) processResponse(info driver.ResponseInfo) error {
+func (ld *ListDatabases) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- ld.result, err = buildListDatabasesResult(info.ServerResponse)
+ ld.result, err = buildListDatabasesResult(resp)
return err
-
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -153,36 +154,34 @@ func (ld *ListDatabases) Execute(ctx context.Context) error {
CommandFn: ld.command,
ProcessResponseFn: ld.processResponse,
- Client: ld.session,
- Clock: ld.clock,
- CommandMonitor: ld.monitor,
- Database: ld.database,
- Deployment: ld.deployment,
- ReadPreference: ld.readPreference,
- RetryMode: ld.retry,
- Type: driver.Read,
- Selector: ld.selector,
- Crypt: ld.crypt,
- ServerAPI: ld.serverAPI,
- Timeout: ld.timeout,
- Name: driverutil.ListDatabasesOp,
- Authenticator: ld.authenticator,
+ Client: ld.session,
+ Clock: ld.clock,
+ CommandMonitor: ld.monitor,
+ Database: ld.database,
+ Deployment: ld.deployment,
+ ReadPreference: ld.readPreference,
+ RetryMode: ld.retry,
+ MaxAdaptiveRetries: ld.maxAdaptiveRetries,
+ EnableOverloadRetargeting: ld.enableOverloadRetargeting,
+ Type: driver.Read,
+ Selector: ld.selector,
+ Crypt: ld.crypt,
+ ServerAPI: ld.serverAPI,
+ Timeout: ld.timeout,
+ Name: driverutil.ListDatabasesOp,
+ Authenticator: ld.authenticator,
}.Execute(ctx)
-
}
func (ld *ListDatabases) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendInt32Element(dst, "listDatabases", 1)
if ld.filter != nil {
-
dst = bsoncore.AppendDocumentElement(dst, "filter", ld.filter)
}
if ld.nameOnly != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "nameOnly", *ld.nameOnly)
}
if ld.authorizedDatabases != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "authorizedDatabases", *ld.authorizedDatabases)
}
@@ -300,6 +299,28 @@ func (ld *ListDatabases) Retry(retry driver.RetryMode) *ListDatabases {
return ld
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (ld *ListDatabases) MaxAdaptiveRetries(maxAdaptiveRetries uint) *ListDatabases {
+ if ld == nil {
+ ld = new(ListDatabases)
+ }
+
+ ld.maxAdaptiveRetries = maxAdaptiveRetries
+ return ld
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (ld *ListDatabases) EnableOverloadRetargeting(enabled bool) *ListDatabases {
+ if ld == nil {
+ ld = new(ListDatabases)
+ }
+
+ ld.enableOverloadRetargeting = enabled
+ return ld
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (ld *ListDatabases) Crypt(crypt driver.Crypt) *ListDatabases {
if ld == nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_indexes.go
similarity index 60%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_indexes.go
index 433344f30..1eea4e640 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_indexes.go
@@ -11,30 +11,32 @@ import (
"errors"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// ListIndexes performs a listIndexes operation.
type ListIndexes struct {
- authenticator driver.Authenticator
- batchSize *int32
- maxTime *time.Duration
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- retry *driver.RetryMode
- crypt driver.Crypt
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
+ authenticator driver.Authenticator
+ batchSize *int32
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ database string
+ deployment driver.Deployment
+ selector description.ServerSelector
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ crypt driver.Crypt
+ serverAPI *driver.ServerAPIOptions
+ timeout *time.Duration
+ rawData *bool
result driver.CursorResponse
}
@@ -46,7 +48,6 @@ func NewListIndexes() *ListIndexes {
// Result returns the result of executing this operation.
func (li *ListIndexes) Result(opts driver.CursorOptions) (*driver.BatchCursor, error) {
-
clientSession := li.session
clock := li.clock
@@ -54,12 +55,13 @@ func (li *ListIndexes) Result(opts driver.CursorOptions) (*driver.BatchCursor, e
return driver.NewBatchCursor(li.result, clientSession, clock, opts)
}
-func (li *ListIndexes) processResponse(info driver.ResponseInfo) error {
- var err error
-
- li.result, err = driver.NewCursorResponse(info)
+func (li *ListIndexes) processResponse(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ curDoc, err := driver.ExtractCursorDocument(resp)
+ if err != nil {
+ return err
+ }
+ li.result, err = driver.NewCursorResponse(curDoc, info)
return err
-
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -72,35 +74,38 @@ func (li *ListIndexes) Execute(ctx context.Context) error {
CommandFn: li.command,
ProcessResponseFn: li.processResponse,
- Client: li.session,
- Clock: li.clock,
- CommandMonitor: li.monitor,
- Database: li.database,
- Deployment: li.deployment,
- MaxTime: li.maxTime,
- Selector: li.selector,
- Crypt: li.crypt,
- Legacy: driver.LegacyListIndexes,
- RetryMode: li.retry,
- Type: driver.Read,
- ServerAPI: li.serverAPI,
- Timeout: li.timeout,
- Name: driverutil.ListIndexesOp,
- Authenticator: li.authenticator,
+ Client: li.session,
+ Clock: li.clock,
+ CommandMonitor: li.monitor,
+ Database: li.database,
+ Deployment: li.deployment,
+ Selector: li.selector,
+ Crypt: li.crypt,
+ Legacy: driver.LegacyListIndexes,
+ RetryMode: li.retry,
+ MaxAdaptiveRetries: li.maxAdaptiveRetries,
+ EnableOverloadRetargeting: li.enableOverloadRetargeting,
+ Type: driver.Read,
+ ServerAPI: li.serverAPI,
+ Timeout: li.timeout,
+ Name: driverutil.ListIndexesOp,
+ Authenticator: li.authenticator,
}.Execute(ctx)
-
}
-func (li *ListIndexes) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
+func (li *ListIndexes) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "listIndexes", li.collection)
cursorIdx, cursorDoc := bsoncore.AppendDocumentStart(nil)
if li.batchSize != nil {
-
cursorDoc = bsoncore.AppendInt32Element(cursorDoc, "batchSize", *li.batchSize)
}
cursorDoc, _ = bsoncore.AppendDocumentEnd(cursorDoc, cursorIdx)
dst = bsoncore.AppendDocumentElement(dst, "cursor", cursorDoc)
+ // Set rawData for 8.2+ servers.
+ if li.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *li.rawData)
+ }
return dst, nil
}
@@ -115,16 +120,6 @@ func (li *ListIndexes) BatchSize(batchSize int32) *ListIndexes {
return li
}
-// MaxTime specifies the maximum amount of time to allow the query to run on the server.
-func (li *ListIndexes) MaxTime(maxTime *time.Duration) *ListIndexes {
- if li == nil {
- li = new(ListIndexes)
- }
-
- li.maxTime = maxTime
- return li
-}
-
// Session sets the session for this operation.
func (li *ListIndexes) Session(session *session.Client) *ListIndexes {
if li == nil {
@@ -206,6 +201,28 @@ func (li *ListIndexes) Retry(retry driver.RetryMode) *ListIndexes {
return li
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (li *ListIndexes) MaxAdaptiveRetries(maxAdaptiveRetries uint) *ListIndexes {
+ if li == nil {
+ li = new(ListIndexes)
+ }
+
+ li.maxAdaptiveRetries = maxAdaptiveRetries
+ return li
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (li *ListIndexes) EnableOverloadRetargeting(enabled bool) *ListIndexes {
+ if li == nil {
+ li = new(ListIndexes)
+ }
+
+ li.enableOverloadRetargeting = enabled
+ return li
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (li *ListIndexes) Crypt(crypt driver.Crypt) *ListIndexes {
if li == nil {
@@ -245,3 +262,13 @@ func (li *ListIndexes) Authenticator(authenticator driver.Authenticator) *ListIn
li.authenticator = authenticator
return li
}
+
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (li *ListIndexes) RawData(rawData bool) *ListIndexes {
+ if li == nil {
+ li = new(ListIndexes)
+ }
+
+ li.rawData = &rawData
+ return li
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update.go
similarity index 67%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update.go
index a33c67ee2..f4bae20d3 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update.go
@@ -12,49 +12,51 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// Update performs an update operation.
type Update struct {
- authenticator driver.Authenticator
- bypassDocumentValidation *bool
- comment bsoncore.Value
- ordered *bool
- updates []bsoncore.Document
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- database string
- deployment driver.Deployment
- hint *bool
- arrayFilters *bool
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- result UpdateResult
- crypt driver.Crypt
- serverAPI *driver.ServerAPIOptions
- let bsoncore.Document
- timeout *time.Duration
- bypassEmptyTsReplacement *bool
- logger *logger.Logger
+ authenticator driver.Authenticator
+ bypassDocumentValidation *bool
+ comment bsoncore.Value
+ ordered *bool
+ updates []bsoncore.Document
+ session *session.Client
+ clock *session.ClusterClock
+ collection string
+ monitor *event.CommandMonitor
+ database string
+ deployment driver.Deployment
+ hint *bool
+ arrayFilters *bool
+ selector description.ServerSelector
+ writeConcern *writeconcern.WriteConcern
+ retry *driver.RetryMode
+ maxAdaptiveRetries uint
+ enableOverloadRetargeting bool
+ result UpdateResult
+ crypt driver.Crypt
+ serverAPI *driver.ServerAPIOptions
+ let bsoncore.Document
+ timeout *time.Duration
+ rawData *bool
+ additionalCmd bson.D
+ logger *logger.Logger
}
// Upsert contains the information for an upsert in an Update operation.
type Upsert struct {
Index int64
- ID interface{} `bson:"_id"`
+ ID any `bson:"_id"`
}
// UpdateResult contains information for the result of an Update operation.
@@ -125,8 +127,8 @@ func NewUpdate(updates ...bsoncore.Document) *Update {
// Result returns the result of executing this operation.
func (u *Update) Result() UpdateResult { return u.result }
-func (u *Update) processResponse(info driver.ResponseInfo) error {
- ur, err := buildUpdateResult(info.ServerResponse)
+func (u *Update) processResponse(_ context.Context, resp bsoncore.Document, info driver.ResponseInfo) error {
+ ur, err := buildUpdateResult(resp)
u.result.N += ur.N
u.result.NModified += ur.NModified
@@ -137,7 +139,6 @@ func (u *Update) processResponse(info driver.ResponseInfo) error {
}
u.result.Upserted = append(u.result.Upserted, ur.Upserted...)
return err
-
}
// Execute runs this operations and returns an error if the operation did not execute successfully.
@@ -152,45 +153,45 @@ func (u *Update) Execute(ctx context.Context) error {
}
return driver.Operation{
- CommandFn: u.command,
- ProcessResponseFn: u.processResponse,
- Batches: batches,
- RetryMode: u.retry,
- Type: driver.Write,
- Client: u.session,
- Clock: u.clock,
- CommandMonitor: u.monitor,
- Database: u.database,
- Deployment: u.deployment,
- Selector: u.selector,
- WriteConcern: u.writeConcern,
- Crypt: u.crypt,
- ServerAPI: u.serverAPI,
- Timeout: u.timeout,
- Logger: u.logger,
- Name: driverutil.UpdateOp,
- Authenticator: u.authenticator,
+ CommandFn: u.command,
+ ProcessResponseFn: u.processResponse,
+ Batches: batches,
+ RetryMode: u.retry,
+ MaxAdaptiveRetries: u.maxAdaptiveRetries,
+ EnableOverloadRetargeting: u.enableOverloadRetargeting,
+ Type: driver.Write,
+ Client: u.session,
+ Clock: u.clock,
+ CommandMonitor: u.monitor,
+ Database: u.database,
+ Deployment: u.deployment,
+ Selector: u.selector,
+ WriteConcern: u.writeConcern,
+ Crypt: u.crypt,
+ ServerAPI: u.serverAPI,
+ Timeout: u.timeout,
+ Logger: u.logger,
+ Name: driverutil.UpdateOp,
+ Authenticator: u.authenticator,
}.Execute(ctx)
-
}
func (u *Update) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
dst = bsoncore.AppendStringElement(dst, "update", u.collection)
if u.bypassDocumentValidation != nil &&
- (desc.WireVersion != nil && desc.WireVersion.Includes(4)) {
+ (desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 4)) {
dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *u.bypassDocumentValidation)
}
- if u.comment.Type != bsontype.Type(0) {
+ if u.comment.Type != bsoncore.Type(0) {
dst = bsoncore.AppendValueElement(dst, "comment", u.comment)
}
if u.ordered != nil {
-
dst = bsoncore.AppendBooleanElement(dst, "ordered", *u.ordered)
}
if u.hint != nil && *u.hint {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 5) {
return nil, errors.New("the 'hint' command parameter requires a minimum server wire version of 5")
}
if !u.writeConcern.Acknowledged() {
@@ -198,22 +199,29 @@ func (u *Update) command(dst []byte, desc description.SelectedServer) ([]byte, e
}
}
if u.arrayFilters != nil && *u.arrayFilters {
- if desc.WireVersion == nil || !desc.WireVersion.Includes(6) {
+ if desc.WireVersion == nil || !driverutil.VersionRangeIncludes(*desc.WireVersion, 6) {
return nil, errors.New("the 'arrayFilters' command parameter requires a minimum server wire version of 6")
}
}
if u.let != nil {
dst = bsoncore.AppendDocumentElement(dst, "let", u.let)
}
- if u.bypassEmptyTsReplacement != nil {
- dst = bsoncore.AppendBooleanElement(dst, "bypassEmptyTsReplacement", *u.bypassEmptyTsReplacement)
+ // Set rawData for 8.2+ servers.
+ if u.rawData != nil && desc.WireVersion != nil && driverutil.VersionRangeIncludes(*desc.WireVersion, 27) {
+ dst = bsoncore.AppendBooleanElement(dst, "rawData", *u.rawData)
+ }
+ if len(u.additionalCmd) > 0 {
+ doc, err := bson.Marshal(u.additionalCmd)
+ if err != nil {
+ return nil, err
+ }
+ dst = append(dst, doc[4:len(doc)-1]...)
}
return dst, nil
}
-// BypassDocumentValidation allows the operation to opt-out of document level validation. Valid
-// for server versions >= 3.2. For servers < 3.2, this setting is ignored.
+// BypassDocumentValidation allows the operation to opt-out of document level validation.
func (u *Update) BypassDocumentValidation(bypassDocumentValidation bool) *Update {
if u == nil {
u = new(Update)
@@ -224,8 +232,7 @@ func (u *Update) BypassDocumentValidation(bypassDocumentValidation bool) *Update
}
// Hint is a flag to indicate that the update document contains a hint. Hint is only supported by
-// servers >= 4.2. Older servers >= 3.4 will report an error for using the hint option. For servers <
-// 3.4, the driver will return an error if the hint option is used.
+// servers >= 4.2. Older servers will report an error for using the hint option.
func (u *Update) Hint(hint bool) *Update {
if u == nil {
u = new(Update)
@@ -235,8 +242,7 @@ func (u *Update) Hint(hint bool) *Update {
return u
}
-// ArrayFilters is a flag to indicate that the update document contains an arrayFilters field. This option is only
-// supported on server versions 3.6 and higher. For servers < 3.6, the driver will return an error.
+// ArrayFilters is a flag to indicate that the update document contains an arrayFilters field.
func (u *Update) ArrayFilters(arrayFilters bool) *Update {
if u == nil {
u = new(Update)
@@ -371,6 +377,28 @@ func (u *Update) Retry(retry driver.RetryMode) *Update {
return u
}
+// MaxAdaptiveRetries specifies the maximum number of times the driver should retry operations
+// that fail with a server side overload error.
+func (u *Update) MaxAdaptiveRetries(maxAdaptiveRetries uint) *Update {
+ if u == nil {
+ u = new(Update)
+ }
+
+ u.maxAdaptiveRetries = maxAdaptiveRetries
+ return u
+}
+
+// EnableOverloadRetargeting specifies whether the driver adds the previously failed server's address
+// to the list of deprioritized server addresses
+func (u *Update) EnableOverloadRetargeting(enabled bool) *Update {
+ if u == nil {
+ u = new(Update)
+ }
+
+ u.enableOverloadRetargeting = enabled
+ return u
+}
+
// Crypt sets the Crypt object to use for automatic encryption and decryption.
func (u *Update) Crypt(crypt driver.Crypt) *Update {
if u == nil {
@@ -431,12 +459,22 @@ func (u *Update) Authenticator(authenticator driver.Authenticator) *Update {
return u
}
-// BypassEmptyTsReplacement sets the bypassEmptyTsReplacement to use for this operation.
-func (u *Update) BypassEmptyTsReplacement(bypassEmptyTsReplacement bool) *Update {
+// RawData sets the rawData to access timeseries data in the compressed format.
+func (u *Update) RawData(rawData bool) *Update {
+ if u == nil {
+ u = new(Update)
+ }
+
+ u.rawData = &rawData
+ return u
+}
+
+// AdditionalCmd sets additional command fields to be attached.
+func (u *Update) AdditionalCmd(d bson.D) *Update {
if u == nil {
u = new(Update)
}
- u.bypassEmptyTsReplacement = &bypassEmptyTsReplacement
+ u.additionalCmd = d
return u
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update_search_index.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update_search_index.go
similarity index 93%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update_search_index.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update_search_index.go
index c63e048f2..b215a9ba8 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update_search_index.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update_search_index.go
@@ -12,11 +12,11 @@ import (
"fmt"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
// UpdateSearchIndex performs a updateSearchIndex operation.
@@ -71,9 +71,9 @@ func NewUpdateSearchIndex(index string, definition bsoncore.Document) *UpdateSea
// Result returns the result of executing this operation.
func (usi *UpdateSearchIndex) Result() UpdateSearchIndexResult { return usi.result }
-func (usi *UpdateSearchIndex) processResponse(info driver.ResponseInfo) error {
+func (usi *UpdateSearchIndex) processResponse(_ context.Context, resp bsoncore.Document, _ driver.ResponseInfo) error {
var err error
- usi.result, err = buildUpdateSearchIndexResult(info.ServerResponse)
+ usi.result, err = buildUpdateSearchIndexResult(resp)
return err
}
@@ -97,7 +97,6 @@ func (usi *UpdateSearchIndex) Execute(ctx context.Context) error {
Timeout: usi.timeout,
Authenticator: usi.authenticator,
}.Execute(ctx)
-
}
func (usi *UpdateSearchIndex) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation_exhaust.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation_exhaust.go
similarity index 79%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation_exhaust.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation_exhaust.go
index e0879de31..a643040d7 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation_exhaust.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation_exhaust.go
@@ -9,11 +9,13 @@ package driver
import (
"context"
"errors"
+
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
)
// ExecuteExhaust reads a response from the provided StreamerConnection. This will error if the connection's
// CurrentlyStreaming function returns false.
-func (op Operation) ExecuteExhaust(ctx context.Context, conn StreamerConnection) error {
+func (op Operation) ExecuteExhaust(ctx context.Context, conn *mnet.Connection) error {
if !conn.CurrentlyStreaming() {
return errors.New("exhaust read must be done with a connection that is currently streaming")
}
@@ -25,10 +27,9 @@ func (op Operation) ExecuteExhaust(ctx context.Context, conn StreamerConnection)
if op.ProcessResponseFn != nil {
// Server, ConnectionDescription, and CurrentIndex are unused in this mode.
info := ResponseInfo{
- ServerResponse: res,
- Connection: conn,
+ Connection: conn,
}
- if err = op.ProcessResponseFn(info); err != nil {
+ if err = op.ProcessResponseFn(ctx, res, info); err != nil {
return err
}
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/serverapioptions.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/serverapioptions.go
similarity index 91%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/serverapioptions.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/serverapioptions.go
index a033cf126..941a41085 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/serverapioptions.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/serverapioptions.go
@@ -10,8 +10,8 @@ package driver
// Only to be used in testing.
const TestServerAPIVersion = "1"
-// ServerAPIOptions represents options used to configure the API version sent to the server
-// when running commands.
+// ServerAPIOptions represents arguments used to configure the API version sent
+// to the server when running commands.
type ServerAPIOptions struct {
ServerAPIVersion string
Strict *bool
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/client_session.go
similarity index 82%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/client_session.go
index eff27bfe3..b06d7dce0 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/client_session.go
@@ -4,22 +4,21 @@
// 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 session // import "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+package session
import (
- "context"
"errors"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/uuid"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/uuid"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
)
// ErrSessionEnded is returned when a client session is used after a call to endSession().
@@ -58,6 +57,8 @@ const (
Aborted
)
+const defaultWriteConcernTimeout = 10_000 * time.Millisecond
+
// String implements the fmt.Stringer interface.
func (s TransactionState) String() string {
switch s {
@@ -76,28 +77,15 @@ func (s TransactionState) String() string {
}
}
+var _ mnet.Pinner = (LoadBalancedTransactionConnection)(nil)
+
// LoadBalancedTransactionConnection represents a connection that's pinned by a ClientSession because it's being used
// to execute a transaction when running against a load balancer. This interface is a copy of driver.PinnedConnection
// and exists to be able to pin transactions to a connection without causing an import cycle.
type LoadBalancedTransactionConnection interface {
- // Functions copied over from driver.Connection.
- WriteWireMessage(context.Context, []byte) error
- ReadWireMessage(ctx context.Context) ([]byte, error)
- Description() description.Server
- Close() error
- ID() string
- ServerConnectionID() *int64
- DriverConnectionID() uint64 // TODO(GODRIVER-2824): change type to int64.
- Address() address.Address
- Stale() bool
- OIDCTokenGenID() uint64
- SetOIDCTokenGenID(uint64)
-
- // Functions copied over from driver.PinnedConnection that are not part of Connection or Expirable.
- PinToCursor() error
- PinToTransaction() error
- UnpinFromCursor() error
- UnpinFromTransaction() error
+ mnet.ReadWriteCloser
+ mnet.Describer
+ mnet.Pinner
}
// Client is a session for clients to run commands.
@@ -106,35 +94,38 @@ type Client struct {
ClientID uuid.UUID
ClusterTime bson.Raw
Consistent bool // causal consistency
- OperationTime *primitive.Timestamp
+ OperationTime *bson.Timestamp
IsImplicit bool
Terminated bool
RetryingCommit bool
Committing bool
Aborting bool
- RetryWrite bool
- RetryRead bool
Snapshot bool
+ // SnapshotTime is the atClusterTime value for snapshot reads. This field is
+ // left immutable once set for the lifetime of the session. This guards
+ // against users updating custom snapshot times during transactions which
+ // could lead to a write conflict.
+ SnapshotTime bson.Timestamp
+ SnapshotTimeSet bool
+
// options for the current transaction
// most recently set by transactionopt
- CurrentRc *readconcern.ReadConcern
- CurrentRp *readpref.ReadPref
- CurrentWc *writeconcern.WriteConcern
- CurrentMct *time.Duration
+ CurrentRc *readconcern.ReadConcern
+ CurrentRp *readpref.ReadPref
+ CurrentWc *writeconcern.WriteConcern
+ CurrentWTimeout time.Duration
// default transaction options
- transactionRc *readconcern.ReadConcern
- transactionRp *readpref.ReadPref
- transactionWc *writeconcern.WriteConcern
- transactionMaxCommitTime *time.Duration
+ transactionRc *readconcern.ReadConcern
+ transactionRp *readpref.ReadPref
+ transactionWc *writeconcern.WriteConcern
pool *Pool
TransactionState TransactionState
- PinnedServer *description.Server
+ PinnedServerAddr *address.Address
RecoveryToken bson.Raw
PinnedConnection LoadBalancedTransactionConnection
- SnapshotTime *primitive.Timestamp
}
func getClusterTime(clusterTime bson.Raw) (uint32, uint32) {
@@ -204,12 +195,13 @@ func NewClientSession(pool *Pool, clientID uuid.UUID, opts ...*ClientOptions) (*
if mergedOpts.DefaultWriteConcern != nil {
c.transactionWc = mergedOpts.DefaultWriteConcern
}
- if mergedOpts.DefaultMaxCommitTime != nil {
- c.transactionMaxCommitTime = mergedOpts.DefaultMaxCommitTime
- }
if mergedOpts.Snapshot != nil {
c.Snapshot = *mergedOpts.Snapshot
}
+ if mergedOpts.SnapshotTime != nil {
+ c.SnapshotTime = *mergedOpts.SnapshotTime
+ c.SnapshotTimeSet = true
+ }
// For explicit sessions, the default for causalConsistency is true, unless Snapshot is
// enabled, then it's false. Set the default and then allow any explicit causalConsistency
@@ -223,6 +215,10 @@ func NewClientSession(pool *Pool, clientID uuid.UUID, opts ...*ClientOptions) (*
return nil, errors.New("causal consistency and snapshot cannot both be set for a session")
}
+ if c.SnapshotTimeSet && !c.Snapshot {
+ return nil, errors.New("snapshotTime cannot be set when snapshot is false")
+ }
+
if err := c.SetServer(); err != nil {
return nil, err
}
@@ -247,7 +243,7 @@ func (c *Client) AdvanceClusterTime(clusterTime bson.Raw) error {
}
// AdvanceOperationTime updates the session's operation time.
-func (c *Client) AdvanceOperationTime(opTime *primitive.Timestamp) error {
+func (c *Client) AdvanceOperationTime(opTime *bson.Timestamp) error {
if c.Terminated {
return ErrSessionEnded
}
@@ -291,9 +287,13 @@ func (c *Client) UpdateRecoveryToken(response bson.Raw) {
c.RecoveryToken = token.Document()
}
-// UpdateSnapshotTime updates the session's value for the atClusterTime field of ReadConcern.
+// UpdateSnapshotTime updates the session's value for the atClusterTime field of
+// ReadConcern.
func (c *Client) UpdateSnapshotTime(response bsoncore.Document) {
- if c == nil {
+ if c == nil || c.SnapshotTimeSet {
+ // Do nothing if session is nil or snapshot time is already set. The driver
+ // sends the same atClusterTime for all operations in a snapshot session so
+ // resetting is a potentially dangerous redundancy.
return
}
@@ -309,10 +309,11 @@ func (c *Client) UpdateSnapshotTime(response bsoncore.Document) {
}
t, i := ssTimeElem.Timestamp()
- c.SnapshotTime = &primitive.Timestamp{
+ c.SnapshotTime = bson.Timestamp{
T: t,
I: i,
}
+ c.SnapshotTimeSet = true
}
// ClearPinnedResources clears the pinned server and/or connection associated with the session.
@@ -321,7 +322,7 @@ func (c *Client) ClearPinnedResources() error {
return nil
}
- c.PinnedServer = nil
+ c.PinnedServerAddr = nil
if c.PinnedConnection != nil {
if err := c.PinnedConnection.UnpinFromTransaction(); err != nil {
return err
@@ -414,7 +415,6 @@ func (c *Client) StartTransaction(opts *TransactionOptions) error {
c.CurrentRc = opts.ReadConcern
c.CurrentRp = opts.ReadPreference
c.CurrentWc = opts.WriteConcern
- c.CurrentMct = opts.MaxCommitTime
}
if c.CurrentRc == nil {
@@ -429,11 +429,7 @@ func (c *Client) StartTransaction(opts *TransactionOptions) error {
c.CurrentWc = c.transactionWc
}
- if c.CurrentMct == nil {
- c.CurrentMct = c.transactionMaxCommitTime
- }
-
- if !writeconcern.AckWrite(c.CurrentWc) {
+ if !c.CurrentWc.Acknowledged() {
_ = c.clearTransactionOpts()
return ErrUnackWCUnsupported
}
@@ -445,9 +441,10 @@ func (c *Client) StartTransaction(opts *TransactionOptions) error {
// CheckCommitTransaction checks to see if allowed to commit transaction and returns
// an error if not allowed.
func (c *Client) CheckCommitTransaction() error {
- if c.TransactionState == None {
+ switch c.TransactionState {
+ case None:
return ErrNoTransactStarted
- } else if c.TransactionState == Aborted {
+ case Aborted:
return ErrCommitAfterAbort
}
return nil
@@ -464,27 +461,33 @@ func (c *Client) CommitTransaction() error {
return nil
}
-// UpdateCommitTransactionWriteConcern will set the write concern to majority and potentially set a
-// w timeout of 10 seconds. This should be called after a commit transaction operation fails with a
-// retryable error or after a successful commit transaction operation.
+// UpdateCommitTransactionWriteConcern will set the write concern to majority.
+// This should be called after a commit transaction operation fails with a
+// retryable error or after a successful commit transaction operation
+//
+// Per the transaction specifications, when commitTransaction is retried, if
+// the modified write concern does not include a "wtimeout" value, drivers
+// MUST apply "wtimeout: 10000" to the write concern in order to avoid waiting
+// forever (oruntil a socket timeout) if the majority write concern cannot be
+// satisfied. This field abstracts that functionality. For more information,
+// see SPEC-1185.
func (c *Client) UpdateCommitTransactionWriteConcern() {
- wc := c.CurrentWc
- timeout := 10 * time.Second
- if wc != nil && wc.GetWTimeout() != 0 {
- timeout = wc.GetWTimeout()
+ c.CurrentWc = &writeconcern.WriteConcern{
+ W: "majority",
}
- c.CurrentWc = wc.WithOptions(writeconcern.WMajority(), writeconcern.WTimeout(timeout))
+
+ c.CurrentWTimeout = defaultWriteConcernTimeout
}
// CheckAbortTransaction checks to see if allowed to abort transaction and returns
// an error if not allowed.
func (c *Client) CheckAbortTransaction() error {
- switch {
- case c.TransactionState == None:
+ switch c.TransactionState {
+ case None:
return ErrNoTransactStarted
- case c.TransactionState == Committed:
+ case Committed:
return ErrAbortAfterCommit
- case c.TransactionState == Aborted:
+ case Aborted:
return ErrAbortTwice
}
return nil
@@ -523,13 +526,14 @@ func (c *Client) ApplyCommand(desc description.Server) error {
// Do not change state if committing after already committed
return nil
}
- if c.TransactionState == Starting {
+ switch c.TransactionState {
+ case Starting:
c.TransactionState = InProgress
// If this is in a transaction and the server is a mongos, pin it
- if desc.Kind == description.Mongos {
- c.PinnedServer = &desc
+ if desc.Kind == description.ServerKindMongos {
+ c.PinnedServerAddr = &desc.Addr
}
- } else if c.TransactionState == Committed || c.TransactionState == Aborted {
+ case Committed, Aborted:
c.TransactionState = None
return c.clearTransactionOpts()
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/cluster_clock.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/cluster_clock.go
similarity index 95%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/cluster_clock.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/cluster_clock.go
index 961f2274e..9f6c14c21 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/cluster_clock.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/cluster_clock.go
@@ -9,7 +9,7 @@ package session
import (
"sync"
- "go.mongodb.org/mongo-driver/bson"
+ "go.mongodb.org/mongo-driver/v2/bson"
)
// ClusterClock represents a logical clock for keeping track of cluster time.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/doc.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/doc.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/doc.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/options.go
similarity index 82%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/options.go
index ee7c301d6..3c4abfcce 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/options.go
@@ -7,11 +7,10 @@
package session
import (
- "time"
-
- "go.mongodb.org/mongo-driver/mongo/readconcern"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/mongo/readconcern"
+ "go.mongodb.org/mongo-driver/v2/mongo/readpref"
+ "go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
)
// ClientOptions represents all possible options for creating a client session.
@@ -20,8 +19,8 @@ type ClientOptions struct {
DefaultReadConcern *readconcern.ReadConcern
DefaultWriteConcern *writeconcern.WriteConcern
DefaultReadPreference *readpref.ReadPref
- DefaultMaxCommitTime *time.Duration
Snapshot *bool
+ SnapshotTime *bson.Timestamp
}
// TransactionOptions represents all possible options for starting a transaction in a session.
@@ -29,7 +28,6 @@ type TransactionOptions struct {
ReadConcern *readconcern.ReadConcern
WriteConcern *writeconcern.WriteConcern
ReadPreference *readpref.ReadPref
- MaxCommitTime *time.Duration
}
func mergeClientOptions(opts ...*ClientOptions) *ClientOptions {
@@ -50,12 +48,12 @@ func mergeClientOptions(opts ...*ClientOptions) *ClientOptions {
if opt.DefaultWriteConcern != nil {
c.DefaultWriteConcern = opt.DefaultWriteConcern
}
- if opt.DefaultMaxCommitTime != nil {
- c.DefaultMaxCommitTime = opt.DefaultMaxCommitTime
- }
if opt.Snapshot != nil {
c.Snapshot = opt.Snapshot
}
+ if opt.SnapshotTime != nil {
+ c.SnapshotTime = opt.SnapshotTime
+ }
}
return c
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/server_session.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/server_session.go
similarity index 89%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/server_session.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/server_session.go
index b1e45552a..7d9c00213 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/server_session.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/server_session.go
@@ -9,9 +9,9 @@ package session
import (
"time"
- "go.mongodb.org/mongo-driver/internal/uuid"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/internal/uuid"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
// Server is an open session with the server.
@@ -27,7 +27,7 @@ type Server struct {
func (ss *Server) expired(topoDesc topologyDescription) bool {
// There is no server monitoring in LB mode, so we do not track session timeout minutes from server hello responses
// and never consider sessions to be expired.
- if topoDesc.kind == description.LoadBalanced {
+ if topoDesc.kind == description.TopologyKindLoadBalanced {
return false
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/session_pool.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/session_pool.go
similarity index 96%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/session_pool.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/session_pool.go
index 7336f5451..df9330307 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/session_pool.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/session_pool.go
@@ -10,8 +10,8 @@ import (
"sync"
"sync/atomic"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
// Node represents a server session in a linked list
@@ -65,7 +65,7 @@ func (p *Pool) updateTimeout() {
case newDesc := <-p.descChan:
p.latestTopology = topologyDescription{
kind: newDesc.Kind,
- timeoutMinutes: newDesc.SessionTimeoutMinutesPtr,
+ timeoutMinutes: newDesc.SessionTimeoutMinutes,
}
default:
// no new description waiting
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/DESIGN.md b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/DESIGN.md
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/DESIGN.md
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/DESIGN.md
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection.go
similarity index 76%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection.go
index bad00e745..85b87a73d 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection.go
@@ -9,6 +9,7 @@ package topology
import (
"context"
"crypto/tls"
+ "crypto/x509"
"encoding/binary"
"errors"
"fmt"
@@ -19,13 +20,14 @@ import (
"sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/internal/csot"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/ocsp"
- "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)
// Connection state constants.
@@ -45,6 +47,30 @@ var (
func nextConnectionID() uint64 { return atomic.AddUint64(&globalConnectionID, 1) }
+func wrapConnectionError(connErr ConnectionError) error {
+ var dnsErr *net.DNSError
+ if errors.As(connErr.Wrapped, &dnsErr) {
+ return connErr
+ }
+ // x509 errors are returned as values by the crypto/tls package
+ var hostErr x509.HostnameError
+ if errors.As(connErr.Wrapped, &hostErr) {
+ return connErr
+ }
+ var certErr x509.CertificateInvalidError
+ if errors.As(connErr.Wrapped, &certErr) {
+ return connErr
+ }
+ var unknownCAErr x509.UnknownAuthorityError
+ if errors.As(connErr.Wrapped, &unknownCAErr) {
+ return connErr
+ }
+ return driver.Error{
+ Labels: []string{driver.ErrSystemOverloadedError, driver.ErrRetryableError, driver.NetworkError},
+ Wrapped: connErr,
+ }
+}
+
type connection struct {
// state must be accessed using the atomic package and should be at the beginning of the struct.
// - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG
@@ -56,8 +82,6 @@ type connection struct {
addr address.Address
idleTimeout time.Duration
idleStart atomic.Value // Stores a time.Time
- readTimeout time.Duration
- writeTimeout time.Duration
desc description.Server
helloRTT time.Duration
compressor wiremessage.CompressorID
@@ -65,28 +89,26 @@ type connection struct {
zstdLevel int
connectDone chan struct{}
config *connectionConfig
- cancelConnectContext context.CancelFunc
connectContextMade chan struct{}
canStream bool
currentlyStreaming bool
- connectContextMutex sync.Mutex
- cancellationListener cancellationListener
- serverConnectionID *int64 // the server's ID for this client's connection
+ cancellationListener contextListener
+ connectListener contextListener // Cancels blocking ops during connect
+ serverConnectionID *int64 // the server's ID for this client's connection
+ prevCanceled atomic.Value
// pool related fields
pool *pool
- // TODO(GODRIVER-2824): change driverConnectionID type to int64.
- driverConnectionID uint64
+ driverConnectionID int64
generation uint64
+ // oidcTokenGenID is the monotonic generation ID for OIDC tokens, used to invalidate
+ // accessTokens in the OIDC authenticator cache.
+ oidcTokenGenID uint64
// awaitRemainingBytes indicates the size of server response that was not completely
// read before returning the connection to the pool.
awaitRemainingBytes *int32
-
- // oidcTokenGenID is the monotonic generation ID for OIDC tokens, used to invalidate
- // accessTokens in the OIDC authenticator cache.
- oidcTokenGenID uint64
}
// newConnection handles the creation of a connection. It does not connect the connection.
@@ -99,12 +121,11 @@ func newConnection(addr address.Address, opts ...ConnectionOption) *connection {
id: id,
addr: addr,
idleTimeout: cfg.idleTimeout,
- readTimeout: cfg.readTimeout,
- writeTimeout: cfg.writeTimeout,
connectDone: make(chan struct{}),
config: cfg,
connectContextMade: make(chan struct{}),
- cancellationListener: newCancellListener(),
+ cancellationListener: newContextDoneListener(),
+ connectListener: newNonBlockingContextDoneListener(),
}
// Connections to non-load balanced deployments should eagerly set the generation numbers so errors encountered
// at any point during connection establishment can be processed without the connection being considered stale.
@@ -134,7 +155,7 @@ func (c *connection) hasGenerationNumber() bool {
// For LB clusters, we set the generation after the initial handshake, so we know it's set if the connection
// description has been updated to reflect that it's behind an LB.
- return c.desc.LoadBalanced()
+ return driverutil.IsServerLoadBalanced(c.desc)
}
func configureTLS(ctx context.Context,
@@ -178,6 +199,7 @@ func (c *connection) connect(ctx context.Context) (err error) {
return nil
}
+ defer c.closeConnectContext()
defer close(c.connectDone)
// If connect returns an error, set the connection status as disconnected and close the
@@ -202,37 +224,20 @@ func (c *connection) connect(ctx context.Context) (err error) {
// cancellation still applies but with an added timeout to ensure the connectTimeoutMS option is applied to socket
// establishment and the TLS handshake as a whole. This is created outside of the connectContextMutex lock to avoid
// holding the lock longer than necessary.
- c.connectContextMutex.Lock()
- var handshakeCtx context.Context
- handshakeCtx, c.cancelConnectContext = context.WithCancel(ctx)
- c.connectContextMutex.Unlock()
-
- dialCtx := handshakeCtx
- var dialCancel context.CancelFunc
- if c.config.connectTimeout != 0 {
- dialCtx, dialCancel = context.WithTimeout(handshakeCtx, c.config.connectTimeout)
- defer dialCancel()
- }
-
- defer func() {
- var cancelFn context.CancelFunc
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
- c.connectContextMutex.Lock()
- cancelFn = c.cancelConnectContext
- c.cancelConnectContext = nil
- c.connectContextMutex.Unlock()
+ go func() {
+ defer cancel()
- if cancelFn != nil {
- cancelFn()
- }
+ c.connectListener.Listen(ctx, func() {})
}()
- close(c.connectContextMade)
-
// Assign the result of DialContext to a temporary net.Conn to ensure that c.nc is not set in an error case.
- tempNc, err := c.config.dialer.DialContext(dialCtx, c.addr.Network(), c.addr.String())
+ tempNc, err := c.config.dialer.DialContext(ctx, c.addr.Network(), c.addr.String())
if err != nil {
- return ConnectionError{Wrapped: err, init: true}
+ connErr := ConnectionError{Wrapped: err, init: true, message: fmt.Sprintf("failed to connect to %s", c.addr)}
+ return wrapConnectionError(connErr)
}
c.nc = tempNc
@@ -246,9 +251,10 @@ func (c *connection) connect(ctx context.Context) (err error) {
DisableEndpointChecking: c.config.disableOCSPEndpointCheck,
HTTPClient: c.config.httpClient,
}
- tlsNc, err := configureTLS(dialCtx, c.config.tlsConnectionSource, c.nc, c.addr, tlsConfig, ocspOpts)
+ tlsNc, err := configureTLS(ctx, c.config.tlsConnectionSource, c.nc, c.addr, tlsConfig, ocspOpts)
if err != nil {
- return ConnectionError{Wrapped: err, init: true}
+ connErr := ConnectionError{Wrapped: err, init: true, message: fmt.Sprintf("failed to configure TLS for %s", c.addr)}
+ return wrapConnectionError(connErr)
}
c.nc = tlsNc
}
@@ -261,36 +267,38 @@ func (c *connection) connect(ctx context.Context) (err error) {
var handshakeInfo driver.HandshakeInformation
handshakeStartTime := time.Now()
- handshakeConn := initConnection{c}
- handshakeInfo, err = handshaker.GetHandshakeInformation(handshakeCtx, c.addr, handshakeConn)
- if err == nil {
- // We only need to retain the Description field as the connection's description. The authentication-related
- // fields in handshakeInfo are tracked by the handshaker if necessary.
- c.desc = handshakeInfo.Description
- c.serverConnectionID = handshakeInfo.ServerConnectionID
- c.helloRTT = time.Since(handshakeStartTime)
-
- // If the application has indicated that the cluster is load balanced, ensure the server has included serviceId
- // in its handshake response to signal that it knows it's behind an LB as well.
- if c.config.loadBalanced && c.desc.ServiceID == nil {
- err = errLoadBalancedStateMismatch
- }
+
+ iconn := initConnection{c}
+ handshakeConn := mnet.NewConnection(iconn)
+
+ handshakeInfo, err = handshaker.GetHandshakeInformation(ctx, c.addr, handshakeConn)
+ if err != nil {
+ connErr := ConnectionError{Wrapped: err, init: true}
+ return wrapConnectionError(connErr)
}
- if err == nil {
- // For load-balanced connections, the generation number depends on the service ID, which isn't known until the
- // initial MongoDB handshake is done. To account for this, we don't attempt to set the connection's generation
- // number unless GetHandshakeInformation succeeds.
- if c.config.loadBalanced {
- c.setGenerationNumber()
- }
- // If we successfully finished the first part of the handshake and verified LB state, continue with the rest of
- // the handshake.
- err = handshaker.FinishHandshake(handshakeCtx, handshakeConn)
+ // We only need to retain the Description field as the connection's description. The authentication-related
+ // fields in handshakeInfo are tracked by the handshaker if necessary.
+ c.desc = handshakeInfo.Description
+ c.serverConnectionID = handshakeInfo.ServerConnectionID
+ c.helloRTT = time.Since(handshakeStartTime)
+
+ // If the application has indicated that the cluster is load balanced, ensure the server has included serviceId
+ // in its handshake response to signal that it knows it's behind an LB as well.
+ if c.config.loadBalanced && c.desc.ServiceID == nil {
+ return ConnectionError{Wrapped: errLoadBalancedStateMismatch, init: true}
}
- // We have a failed handshake here
- if err != nil {
+ // For load-balanced connections, the generation number depends on the service ID, which isn't known until the
+ // initial MongoDB handshake is done. To account for this, we don't attempt to set the connection's generation
+ // number unless GetHandshakeInformation succeeds.
+ if c.config.loadBalanced {
+ c.setGenerationNumber()
+ }
+
+ // If we successfully finished the first part of the handshake and verified LB state, continue with the rest of
+ // the handshake. Authentication errors are not connection establishment errors and do not get backpressure labels.
+ if err = handshaker.FinishHandshake(ctx, handshakeConn); err != nil {
return ConnectionError{Wrapped: err, init: true}
}
@@ -332,16 +340,8 @@ func (c *connection) wait() {
}
func (c *connection) closeConnectContext() {
- <-c.connectContextMade
- var cancelFn context.CancelFunc
-
- c.connectContextMutex.Lock()
- cancelFn = c.cancelConnectContext
- c.cancelConnectContext = nil
- c.connectContextMutex.Unlock()
-
- if cancelFn != nil {
- cancelFn()
+ if c.connectListener != nil {
+ c.connectListener.StopListening()
}
}
@@ -365,7 +365,10 @@ func transformNetworkError(ctx context.Context, originalError error, contextDead
return originalError
}
if netErr, ok := originalError.(net.Error); ok && netErr.Timeout() {
- return fmt.Errorf("%w: %s", context.DeadlineExceeded, originalError.Error())
+ return fmt.Errorf("%w: %s: %s",
+ context.DeadlineExceeded,
+ "client timed out waiting for server response",
+ originalError.Error())
}
return originalError
@@ -380,24 +383,15 @@ func (c *connection) writeWireMessage(ctx context.Context, wm []byte) error {
}
}
- var deadline time.Time
- if c.writeTimeout != 0 {
- deadline = time.Now().Add(c.writeTimeout)
- }
-
- var contextDeadlineUsed bool
- if dl, ok := ctx.Deadline(); ok && (deadline.IsZero() || dl.Before(deadline)) {
- contextDeadlineUsed = true
- deadline = dl
- }
-
+ deadline, contextDeadlineUsed := ctx.Deadline()
if err := c.nc.SetWriteDeadline(deadline); err != nil {
return ConnectionError{ConnectionID: c.id, Wrapped: err, message: "failed to set write deadline"}
}
err = c.write(ctx, wm)
if err != nil {
- c.close()
+ _ = c.close()
+
return ConnectionError{
ConnectionID: c.id,
Wrapped: transformNetworkError(ctx, err, contextDeadlineUsed),
@@ -434,17 +428,7 @@ func (c *connection) readWireMessage(ctx context.Context) ([]byte, error) {
}
}
- var deadline time.Time
- if c.readTimeout != 0 {
- deadline = time.Now().Add(c.readTimeout)
- }
-
- var contextDeadlineUsed bool
- if dl, ok := ctx.Deadline(); ok && (deadline.IsZero() || dl.Before(deadline)) {
- contextDeadlineUsed = true
- deadline = dl
- }
-
+ deadline, contextDeadlineUsed := ctx.Deadline()
if err := c.nc.SetReadDeadline(deadline); err != nil {
return nil, ConnectionError{ConnectionID: c.id, Wrapped: err, message: "failed to set read deadline"}
}
@@ -452,15 +436,12 @@ func (c *connection) readWireMessage(ctx context.Context) ([]byte, error) {
dst, errMsg, err := c.read(ctx)
if err != nil {
if c.awaitRemainingBytes == nil {
- // If the connection was not marked as awaiting response, use the
- // pre-CSOT behavior and close the connection because we don't know
- // if there are other bytes left to read.
- c.close()
+ // If the connection was not marked as awaiting response, close the
+ // connection because we don't know what the connection state is.
+ _ = c.close()
}
+
message := errMsg
- if errors.Is(err, io.EOF) {
- message = "socket was unexpectedly closed"
- }
return nil, ConnectionError{
ConnectionID: c.id,
Wrapped: transformNetworkError(ctx, err, contextDeadlineUsed),
@@ -505,12 +486,11 @@ func (c *connection) read(ctx context.Context) (bytesRead []byte, errMsg string,
}()
isCSOTTimeout := func(err error) bool {
- // If the error was a timeout error and CSOT is enabled, instead of
- // closing the connection mark it as awaiting response so the pool
- // can read the response before making it available to other
- // operations.
+ // If the error was a timeout error, instead of closing the
+ // connection mark it as awaiting response so the pool can read the
+ // response before making it available to other operations.
nerr := net.Error(nil)
- return errors.As(err, &nerr) && nerr.Timeout() && csot.IsTimeoutContext(ctx)
+ return errors.As(err, &nerr) && nerr.Timeout()
}
// We use an array here because it only costs 4 bytes on the stack and means we'll only need to
@@ -548,6 +528,12 @@ func (c *connection) read(ctx context.Context) (bytesRead []byte, errMsg string,
}
func (c *connection) close() error {
+ // Stop any blocking operations occurring in connect(), but await closing the
+ // connections directly before closing the connection context. This ensures
+ // that closing a connection will manifest as an io.EOF error, avoiding
+ // non-deterministic connection closure errors.
+ defer c.closeConnectContext()
+
// Overwrite the connection state as the first step so only the first close call will execute.
if !atomic.CompareAndSwapInt64(&c.state, connConnected, connDisconnected) {
return nil
@@ -593,15 +579,12 @@ func (c *connection) getCurrentlyStreaming() bool {
return c.currentlyStreaming
}
-func (c *connection) setSocketTimeout(timeout time.Duration) {
- c.readTimeout = timeout
- c.writeTimeout = timeout
-}
+func (c *connection) previousCanceled() bool {
+ if val := c.prevCanceled.Load(); val != nil {
+ return val.(bool)
+ }
-// DriverConnectionID returns the driver connection ID.
-// TODO(GODRIVER-2824): change return type to int64.
-func (c *connection) DriverConnectionID() uint64 {
- return c.driverConnectionID
+ return false
}
func (c *connection) ID() string {
@@ -612,6 +595,11 @@ func (c *connection) ServerConnectionID() *int64 {
return c.serverConnectionID
}
+// DriverConnectionID returns the driver connection ID.
+func (c *connection) DriverConnectionID() int64 {
+ return c.driverConnectionID
+}
+
func (c *connection) OIDCTokenGenID() uint64 {
return c.oidcTokenGenID
}
@@ -625,14 +613,17 @@ func (c *connection) SetOIDCTokenGenID(genID uint64) {
// *connection to a Handshaker.
type initConnection struct{ *connection }
-var _ driver.Connection = initConnection{}
-var _ driver.StreamerConnection = initConnection{}
+var (
+ _ mnet.ReadWriteCloser = initConnection{}
+ _ mnet.Describer = initConnection{}
+ _ mnet.Streamer = initConnection{}
+)
func (c initConnection) Description() description.Server {
if c.connection == nil {
return description.Server{}
}
- return c.connection.desc
+ return c.desc
}
func (c initConnection) Close() error { return nil }
func (c initConnection) ID() string { return c.id }
@@ -644,18 +635,23 @@ func (c initConnection) LocalAddress() address.Address {
}
return address.Address(c.nc.LocalAddr().String())
}
-func (c initConnection) WriteWireMessage(ctx context.Context, wm []byte) error {
+
+func (c initConnection) Write(ctx context.Context, wm []byte) error {
return c.writeWireMessage(ctx, wm)
}
-func (c initConnection) ReadWireMessage(ctx context.Context) ([]byte, error) {
+
+func (c initConnection) Read(ctx context.Context) ([]byte, error) {
return c.readWireMessage(ctx)
}
+
func (c initConnection) SetStreaming(streaming bool) {
c.setStreaming(streaming)
}
+
func (c initConnection) CurrentlyStreaming() bool {
return c.getCurrentlyStreaming()
}
+
func (c initConnection) SupportsStreaming() bool {
return c.canStream
}
@@ -677,12 +673,16 @@ type Connection struct {
mu sync.RWMutex
}
-var _ driver.Connection = (*Connection)(nil)
-var _ driver.Expirable = (*Connection)(nil)
-var _ driver.PinnedConnection = (*Connection)(nil)
+var (
+ _ mnet.ReadWriteCloser = (*Connection)(nil)
+ _ mnet.Describer = (*Connection)(nil)
+ _ mnet.Compressor = (*Connection)(nil)
+ _ mnet.Pinner = (*Connection)(nil)
+ _ driver.Expirable = (*Connection)(nil)
+)
-// WriteWireMessage handles writing a wire message to the underlying connection.
-func (c *Connection) WriteWireMessage(ctx context.Context, wm []byte) error {
+// Write handles writing a wire message to the underlying connection.
+func (c *Connection) Write(ctx context.Context, wm []byte) error {
c.mu.RLock()
defer c.mu.RUnlock()
if c.connection == nil {
@@ -691,9 +691,9 @@ func (c *Connection) WriteWireMessage(ctx context.Context, wm []byte) error {
return c.connection.writeWireMessage(ctx, wm)
}
-// ReadWireMessage handles reading a wire message from the underlying connection. The dst parameter
-// will be overwritten with the new wire message.
-func (c *Connection) ReadWireMessage(ctx context.Context) ([]byte, error) {
+// Read handles reading a wire message from the underlying connection. The dst
+// parameter will be overwritten with the new wire message.
+func (c *Connection) Read(ctx context.Context) ([]byte, error) {
c.mu.RLock()
defer c.mu.RUnlock()
if c.connection == nil {
@@ -886,8 +886,10 @@ func (c *Connection) unpin(reason string) error {
}
// DriverConnectionID returns the driver connection ID.
-// TODO(GODRIVER-2824): change return type to int64.
-func (c *Connection) DriverConnectionID() uint64 {
+func (c *Connection) DriverConnectionID() int64 {
+ if c.connection == nil {
+ return 0
+ }
return c.connection.DriverConnectionID()
}
@@ -900,47 +902,3 @@ func (c *Connection) OIDCTokenGenID() uint64 {
func (c *Connection) SetOIDCTokenGenID(genID uint64) {
c.oidcTokenGenID = genID
}
-
-// TODO: Naming?
-
-// cancellListener listens for context cancellation and notifies listeners via a
-// callback function.
-type cancellListener struct {
- aborted bool
- done chan struct{}
-}
-
-// newCancellListener constructs a cancellListener.
-func newCancellListener() *cancellListener {
- return &cancellListener{
- done: make(chan struct{}),
- }
-}
-
-// Listen blocks until the provided context is cancelled or listening is aborted
-// via the StopListening function. If this detects that the context has been
-// cancelled (i.e. errors.Is(ctx.Err(), context.Canceled), the provided callback is
-// called to abort in-progress work. Even if the context expires, this function
-// will block until StopListening is called.
-func (c *cancellListener) Listen(ctx context.Context, abortFn func()) {
- c.aborted = false
-
- select {
- case <-ctx.Done():
- if errors.Is(ctx.Err(), context.Canceled) {
- c.aborted = true
- abortFn()
- }
-
- <-c.done
- case <-c.done:
- }
-}
-
-// StopListening stops the in-progress Listen call. This blocks if there is no
-// in-progress Listen call. This function will return true if the provided abort
-// callback was called when listening for cancellation on the previous context.
-func (c *cancellListener) StopListening() bool {
- c.done <- struct{}{}
- return c.aborted
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_legacy.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_legacy.go
similarity index 100%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_legacy.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_legacy.go
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_options.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_options.go
index 43e6f3f50..6a53da7b6 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_options.go
@@ -13,11 +13,11 @@ import (
"net/http"
"time"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/httputil"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/ocsp"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/httputil"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp"
)
// Dialer is used to make network connections.
@@ -45,16 +45,13 @@ var DefaultDialer Dialer = &net.Dialer{}
type Handshaker = driver.Handshaker
// generationNumberFn is a callback type used by a connection to fetch its generation number given its service ID.
-type generationNumberFn func(serviceID *primitive.ObjectID) uint64
+type generationNumberFn func(serviceID *bson.ObjectID) uint64
type connectionConfig struct {
- connectTimeout time.Duration
dialer Dialer
handshaker Handshaker
idleTimeout time.Duration
cmdMonitor *event.CommandMonitor
- readTimeout time.Duration
- writeTimeout time.Duration
tlsConfig *tls.Config
httpClient *http.Client
compressors []string
@@ -69,7 +66,6 @@ type connectionConfig struct {
func newConnectionConfig(opts ...ConnectionOption) *connectionConfig {
cfg := &connectionConfig{
- connectTimeout: 30 * time.Second,
dialer: nil,
tlsConnectionSource: defaultTLSConnectionSource,
httpClient: httputil.DefaultHTTPClient,
@@ -107,14 +103,6 @@ func WithCompressors(fn func([]string) []string) ConnectionOption {
}
}
-// WithConnectTimeout configures the maximum amount of time a dial will wait for a
-// Connect to complete. The default is 30 seconds.
-func WithConnectTimeout(fn func(time.Duration) time.Duration) ConnectionOption {
- return func(c *connectionConfig) {
- c.connectTimeout = fn(c.connectTimeout)
- }
-}
-
// WithDialer configures the Dialer to use when making a new connection to MongoDB.
func WithDialer(fn func(Dialer) Dialer) ConnectionOption {
return func(c *connectionConfig) {
@@ -137,20 +125,6 @@ func WithIdleTimeout(fn func(time.Duration) time.Duration) ConnectionOption {
}
}
-// WithReadTimeout configures the maximum read time for a connection.
-func WithReadTimeout(fn func(time.Duration) time.Duration) ConnectionOption {
- return func(c *connectionConfig) {
- c.readTimeout = fn(c.readTimeout)
- }
-}
-
-// WithWriteTimeout configures the maximum write time for a connection.
-func WithWriteTimeout(fn func(time.Duration) time.Duration) ConnectionOption {
- return func(c *connectionConfig) {
- c.writeTimeout = fn(c.writeTimeout)
- }
-}
-
// WithTLSConfig configures the TLS options for a connection.
func WithTLSConfig(fn func(*tls.Config) *tls.Config) ConnectionOption {
return func(c *connectionConfig) {
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/context_listener.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/context_listener.go
new file mode 100644
index 000000000..99c252c87
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/context_listener.go
@@ -0,0 +1,91 @@
+// 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 topology
+
+import (
+ "context"
+ "errors"
+ "sync/atomic"
+)
+
+type contextListener interface {
+ Listen(context.Context, func())
+ StopListening() bool
+}
+
+// contextDoneListener listens for context-ending eventsand notifies listeners
+// via a callback function.
+type contextDoneListener struct {
+ aborted atomic.Value
+ done chan struct{}
+ blockOnDone bool
+}
+
+var _ contextListener = &contextDoneListener{}
+
+// newContextDoneListener constructs a contextDoneListener that will block
+// when a context is done until StopListening is called.
+func newContextDoneListener() *contextDoneListener {
+ return &contextDoneListener{
+ done: make(chan struct{}),
+ blockOnDone: true,
+ }
+}
+
+// newNonBlockingContextDoneLIstener constructs a contextDoneListener that
+// will not block when a context is done. In this case there are two ways to
+// unblock the listener: a finished context or a call to StopListening.
+func newNonBlockingContextDoneListener() *contextDoneListener {
+ return &contextDoneListener{
+ done: make(chan struct{}),
+ blockOnDone: false,
+ }
+}
+
+// Listen blocks until the provided context is cancelled or listening is aborted
+// via the StopListening function. If this detects that the context has been
+// cancelled (i.e. errors.Is(ctx.Err(), context.Canceled), the provided callback
+// is called to abort in-progress work. If blockOnDone is true, this function
+// will block until StopListening is called, even if the context expires.
+func (c *contextDoneListener) Listen(ctx context.Context, abortFn func()) {
+ c.aborted.Store(false)
+
+ select {
+ case <-ctx.Done():
+ if errors.Is(ctx.Err(), context.Canceled) {
+ c.aborted.Store(true)
+
+ abortFn()
+ }
+
+ if c.blockOnDone {
+ <-c.done
+ }
+ case <-c.done:
+ }
+}
+
+// StopListening stops the in-progress Listen call. If blockOnDone is true, then
+// this blocks if there is no in-progress Listen call. This function will return
+// true if the provided abort callback was called when listening for
+// cancellation on the previous context.
+func (c *contextDoneListener) StopListening() bool {
+ if c.blockOnDone {
+ c.done <- struct{}{}
+ } else {
+ select {
+ case c.done <- struct{}{}:
+ default:
+ }
+ }
+
+ if aborted := c.aborted.Load(); aborted != nil {
+ return aborted.(bool)
+ }
+
+ return false
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/diff.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/diff.go
similarity index 86%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/diff.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/diff.go
index b9bf2c14c..eddd334ee 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/diff.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/diff.go
@@ -6,7 +6,7 @@
package topology
-import "go.mongodb.org/mongo-driver/mongo/description"
+import "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
// hostlistDiff is the difference between a topology and a host list.
type hostlistDiff struct {
@@ -45,15 +45,15 @@ type topologyDiff struct {
}
// diffTopology compares the two topology descriptions and returns the difference.
-func diffTopology(old, new description.Topology) topologyDiff {
+func diffTopology(oldtopo, newtopo description.Topology) topologyDiff {
var diff topologyDiff
oldServers := make(map[string]bool)
- for _, s := range old.Servers {
+ for _, s := range oldtopo.Servers {
oldServers[s.Addr.String()] = true
}
- for _, s := range new.Servers {
+ for _, s := range newtopo.Servers {
addr := s.Addr.String()
if oldServers[addr] {
delete(oldServers, addr)
@@ -62,7 +62,7 @@ func diffTopology(old, new description.Topology) topologyDiff {
}
}
- for _, s := range old.Servers {
+ for _, s := range oldtopo.Servers {
addr := s.Addr.String()
if oldServers[addr] {
diff.Removed = append(diff.Removed, s)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/errors.go
similarity index 77%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/errors.go
index a6630aae7..dee194154 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/errors.go
@@ -10,11 +10,17 @@ import (
"context"
"errors"
"fmt"
+ "io"
+ "net"
+ "os"
+ "strings"
"time"
- "go.mongodb.org/mongo-driver/mongo/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
+var _ error = ConnectionError{}
+
// ConnectionError represents a connection error.
type ConnectionError struct {
ConnectionID string
@@ -28,21 +34,28 @@ type ConnectionError struct {
// Error implements the error interface.
func (e ConnectionError) Error() string {
- message := e.message
+ var messages []string
if e.init {
- fullMsg := "error occurred during connection handshake"
- if message != "" {
- fullMsg = fmt.Sprintf("%s: %s", fullMsg, message)
- }
- message = fullMsg
+ messages = append(messages, "error occurred during connection handshake")
}
- if e.Wrapped != nil && message != "" {
- return fmt.Sprintf("connection(%s) %s: %s", e.ConnectionID, message, e.Wrapped.Error())
+ if e.message != "" {
+ messages = append(messages, e.message)
}
if e.Wrapped != nil {
- return fmt.Sprintf("connection(%s) %s", e.ConnectionID, e.Wrapped.Error())
+ if errors.Is(e.Wrapped, io.EOF) {
+ messages = append(messages, "connection closed unexpectedly by the other side")
+ }
+ if errors.Is(e.Wrapped, os.ErrDeadlineExceeded) {
+ messages = append(messages, "client timed out waiting for server response")
+ } else if err, ok := e.Wrapped.(net.Error); ok && err.Timeout() {
+ messages = append(messages, "client timed out waiting for server response")
+ }
+ messages = append(messages, e.Wrapped.Error())
+ }
+ if len(messages) > 0 {
+ return fmt.Sprintf("connection(%s) %s", e.ConnectionID, strings.Join(messages, ": "))
}
- return fmt.Sprintf("connection(%s) %s", e.ConnectionID, message)
+ return fmt.Sprintf("connection(%s)", e.ConnectionID)
}
// Unwrap returns the underlying error.
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/fsm.go
similarity index 78%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/fsm.go
index 1d097b65c..7e96b3c34 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/fsm.go
@@ -11,23 +11,24 @@ import (
"fmt"
"sync/atomic"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/internal/ptrutil"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/ptrutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)
var (
// MinSupportedMongoDBVersion is the version string for the lowest MongoDB version supported by the driver.
- MinSupportedMongoDBVersion = "3.6"
+ MinSupportedMongoDBVersion = "4.2"
// SupportedWireVersions is the range of wire versions supported by the driver.
- SupportedWireVersions = description.NewVersionRange(6, 25)
+ SupportedWireVersions = driverutil.NewVersionRange(driverutil.MinWireVersion, driverutil.MaxWireVersion)
)
type fsm struct {
description.Topology
- maxElectionID primitive.ObjectID
+ maxElectionID bson.ObjectID
maxSetVersion uint32
compatible atomic.Value
compatibilityErr error
@@ -39,6 +40,14 @@ func newFSM() *fsm {
return &f
}
+// isServerDataBearing returns true if the server is a data bearing server.
+func isServerDataBearing(srv description.Server) bool {
+ return srv.Kind == description.ServerKindRSPrimary ||
+ srv.Kind == description.ServerKindRSSecondary ||
+ srv.Kind == description.ServerKindMongos ||
+ srv.Kind == description.ServerKindStandalone
+}
+
// selectFSMSessionTimeout selects the timeout to return for the topology's
// finite state machine. If the logicalSessionTimeoutMinutes on the FSM exists
// and the server is data-bearing, then we determine this value by returning
@@ -54,8 +63,8 @@ func newFSM() *fsm {
// still do not have a timeout. This function chooses the lowest of the existing
// timeouts.
func selectFSMSessionTimeout(f *fsm, s description.Server) *int64 {
- oldMinutes := f.SessionTimeoutMinutesPtr
- comp := ptrutil.CompareInt64(oldMinutes, s.SessionTimeoutMinutesPtr)
+ oldMinutes := f.SessionTimeoutMinutes
+ comp := ptrutil.CompareInt64(oldMinutes, s.SessionTimeoutMinutes)
// If the server is data-bearing and the current timeout exists and is
// either:
@@ -64,8 +73,8 @@ func selectFSMSessionTimeout(f *fsm, s description.Server) *int64 {
// 2. non-nil while the server timeout is nil
//
// then return the server timeout.
- if s.DataBearing() && (comp == 1 || comp == 2) {
- return s.SessionTimeoutMinutesPtr
+ if isServerDataBearing(s) && (comp == 1 || comp == 2) {
+ return s.SessionTimeoutMinutes
}
// If the current timeout exists and the server is not data-bearing OR
@@ -75,22 +84,22 @@ func selectFSMSessionTimeout(f *fsm, s description.Server) *int64 {
return oldMinutes
}
- timeout := s.SessionTimeoutMinutesPtr
+ timeout := s.SessionTimeoutMinutes
for _, server := range f.Servers {
// If the server is not data-bearing, then we do not consider
// it's timeout whether set or not.
- if !server.DataBearing() {
+ if !isServerDataBearing(server) {
continue
}
- srvTimeout := server.SessionTimeoutMinutesPtr
+ srvTimeout := server.SessionTimeoutMinutes
comp := ptrutil.CompareInt64(timeout, srvTimeout)
if comp <= 0 { // timeout <= srvTimout
continue
}
- timeout = server.SessionTimeoutMinutesPtr
+ timeout = server.SessionTimeoutMinutes
}
return timeout
@@ -116,11 +125,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser
SetName: f.SetName,
}
- f.Topology.SessionTimeoutMinutesPtr = serverTimeoutMinutes
-
- if serverTimeoutMinutes != nil {
- f.SessionTimeoutMinutes = uint32(*serverTimeoutMinutes)
- }
+ f.SessionTimeoutMinutes = serverTimeoutMinutes
if _, ok := f.findServer(s.Addr); !ok {
return f.Topology, s
@@ -130,13 +135,13 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser
switch f.Kind {
case description.Unknown:
updatedDesc = f.applyToUnknown(s)
- case description.Sharded:
+ case description.TopologyKindSharded:
updatedDesc = f.applyToSharded(s)
- case description.ReplicaSetNoPrimary:
+ case description.TopologyKindReplicaSetNoPrimary:
updatedDesc = f.applyToReplicaSetNoPrimary(s)
- case description.ReplicaSetWithPrimary:
+ case description.TopologyKindReplicaSetWithPrimary:
updatedDesc = f.applyToReplicaSetWithPrimary(s)
- case description.Single:
+ case description.TopologyKindSingle:
updatedDesc = f.applyToSingle(s)
}
@@ -152,7 +157,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser
SupportedWireVersions.Min,
MinSupportedMongoDBVersion,
)
- f.Topology.CompatibilityErr = f.compatibilityErr
+ f.CompatibilityErr = f.compatibilityErr
return f.Topology, s
}
@@ -164,7 +169,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser
server.WireVersion.Min,
SupportedWireVersions.Max,
)
- f.Topology.CompatibilityErr = f.compatibilityErr
+ f.CompatibilityErr = f.compatibilityErr
return f.Topology, s
}
}
@@ -178,13 +183,13 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser
func (f *fsm) applyToReplicaSetNoPrimary(s description.Server) description.Server {
switch s.Kind {
- case description.Standalone, description.Mongos:
+ case description.ServerKindStandalone, description.ServerKindMongos:
f.removeServerByAddr(s.Addr)
- case description.RSPrimary:
+ case description.ServerKindRSPrimary:
f.updateRSFromPrimary(s)
- case description.RSSecondary, description.RSArbiter, description.RSMember:
+ case description.ServerKindRSSecondary, description.ServerKindRSArbiter, description.ServerKindRSMember:
f.updateRSWithoutPrimary(s)
- case description.Unknown, description.RSGhost:
+ case description.Unknown, description.ServerKindRSGhost:
f.replaceServer(s)
}
@@ -193,14 +198,14 @@ func (f *fsm) applyToReplicaSetNoPrimary(s description.Server) description.Serve
func (f *fsm) applyToReplicaSetWithPrimary(s description.Server) description.Server {
switch s.Kind {
- case description.Standalone, description.Mongos:
+ case description.ServerKindStandalone, description.ServerKindMongos:
f.removeServerByAddr(s.Addr)
f.checkIfHasPrimary()
- case description.RSPrimary:
+ case description.ServerKindRSPrimary:
f.updateRSFromPrimary(s)
- case description.RSSecondary, description.RSArbiter, description.RSMember:
+ case description.ServerKindRSSecondary, description.ServerKindRSArbiter, description.ServerKindRSMember:
f.updateRSWithPrimaryFromMember(s)
- case description.Unknown, description.RSGhost:
+ case description.Unknown, description.ServerKindRSGhost:
f.replaceServer(s)
f.checkIfHasPrimary()
}
@@ -210,9 +215,11 @@ func (f *fsm) applyToReplicaSetWithPrimary(s description.Server) description.Ser
func (f *fsm) applyToSharded(s description.Server) description.Server {
switch s.Kind {
- case description.Mongos, description.Unknown:
+ case description.ServerKindMongos, description.Unknown:
f.replaceServer(s)
- case description.Standalone, description.RSPrimary, description.RSSecondary, description.RSArbiter, description.RSMember, description.RSGhost:
+ case description.ServerKindStandalone, description.ServerKindRSPrimary,
+ description.ServerKindRSSecondary, description.ServerKindRSArbiter, description.ServerKindRSMember,
+ description.ServerKindRSGhost:
f.removeServerByAddr(s.Addr)
}
@@ -223,14 +230,15 @@ func (f *fsm) applyToSingle(s description.Server) description.Server {
switch s.Kind {
case description.Unknown:
f.replaceServer(s)
- case description.Standalone, description.Mongos:
+ case description.ServerKindStandalone, description.ServerKindMongos:
if f.SetName != "" {
f.removeServerByAddr(s.Addr)
return s
}
f.replaceServer(s)
- case description.RSPrimary, description.RSSecondary, description.RSArbiter, description.RSMember, description.RSGhost:
+ case description.ServerKindRSPrimary, description.ServerKindRSSecondary,
+ description.ServerKindRSArbiter, description.ServerKindRSMember, description.ServerKindRSGhost:
// A replica set name can be provided when creating a direct connection. In this case, if the set name returned
// by the hello response doesn't match up with the one provided during configuration, the server description
// is replaced with a default Unknown description.
@@ -252,17 +260,17 @@ func (f *fsm) applyToSingle(s description.Server) description.Server {
func (f *fsm) applyToUnknown(s description.Server) description.Server {
switch s.Kind {
- case description.Mongos:
- f.setKind(description.Sharded)
+ case description.ServerKindMongos:
+ f.setKind(description.TopologyKindSharded)
f.replaceServer(s)
- case description.RSPrimary:
+ case description.ServerKindRSPrimary:
f.updateRSFromPrimary(s)
- case description.RSSecondary, description.RSArbiter, description.RSMember:
- f.setKind(description.ReplicaSetNoPrimary)
+ case description.ServerKindRSSecondary, description.ServerKindRSArbiter, description.ServerKindRSMember:
+ f.setKind(description.TopologyKindReplicaSetNoPrimary)
f.updateRSWithoutPrimary(s)
- case description.Standalone:
+ case description.ServerKindStandalone:
f.updateUnknownWithStandalone(s)
- case description.Unknown, description.RSGhost:
+ case description.Unknown, description.ServerKindRSGhost:
f.replaceServer(s)
}
@@ -271,9 +279,9 @@ func (f *fsm) applyToUnknown(s description.Server) description.Server {
func (f *fsm) checkIfHasPrimary() {
if _, ok := f.findPrimary(); ok {
- f.setKind(description.ReplicaSetWithPrimary)
+ f.setKind(description.TopologyKindReplicaSetWithPrimary)
} else {
- f.setKind(description.ReplicaSetNoPrimary)
+ f.setKind(description.TopologyKindReplicaSetNoPrimary)
}
}
@@ -399,7 +407,7 @@ func (f *fsm) updateRSWithPrimaryFromMember(s description.Server) {
f.replaceServer(s)
if _, ok := f.findPrimary(); !ok {
- f.setKind(description.ReplicaSetNoPrimary)
+ f.setKind(description.TopologyKindReplicaSetNoPrimary)
}
}
@@ -431,7 +439,7 @@ func (f *fsm) updateUnknownWithStandalone(s description.Server) {
return
}
- f.setKind(description.Single)
+ f.setKind(description.TopologyKindSingle)
f.replaceServer(s)
}
@@ -443,7 +451,7 @@ func (f *fsm) addServer(addr address.Address) {
func (f *fsm) findPrimary() (int, bool) {
for i, s := range f.Servers {
- if s.Kind == description.RSPrimary {
+ if s.Kind == description.ServerKindRSPrimary {
return i, true
}
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool.go
similarity index 92%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool.go
index 45b0b7d9b..796fcd566 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool.go
@@ -15,11 +15,11 @@ import (
"sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
)
// Connection pool state constants.
@@ -78,7 +78,8 @@ type poolConfig struct {
LoadBalanced bool
PoolMonitor *event.PoolMonitor
Logger *logger.Logger
- handshakeErrFn func(error, uint64, *primitive.ObjectID)
+ handshakeErrFn func(error, uint64, *bson.ObjectID)
+ ConnectTimeout time.Duration
}
type pool struct {
@@ -87,7 +88,7 @@ type pool struct {
// - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG
// - suggested layout: https://go101.org/article/memory-layout.html
- nextID uint64 // nextID is the next pool ID for a new connection.
+ nextID int64 // nextID is the next pool ID for a new connection.
pinnedCursorConnections uint64
pinnedTransactionConnections uint64
@@ -101,7 +102,7 @@ type pool struct {
// handshakeErrFn is used to handle any errors that happen during connection establishment and
// handshaking.
- handshakeErrFn func(error, uint64, *primitive.ObjectID)
+ handshakeErrFn func(error, uint64, *bson.ObjectID)
connOpts []ConnectionOption
generation *poolGenerationMap
@@ -119,13 +120,14 @@ type pool struct {
// to the state of the guarded values must be made while holding the lock to prevent undefined
// behavior in the createConnections() waiting logic.
createConnectionsCond *sync.Cond
- cancelBackgroundCtx context.CancelFunc // cancelBackgroundCtx is called to signal background goroutines to stop.
- conns map[uint64]*connection // conns holds all currently open connections.
- newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections.
-
- idleMu sync.Mutex // idleMu guards idleConns, idleConnWait
- idleConns []*connection // idleConns holds all idle connections.
- idleConnWait wantConnQueue // idleConnWait holds all wantConn requests for idle connections.
+ cancelBackgroundCtx context.CancelFunc // cancelBackgroundCtx is called to signal background goroutines to stop.
+ conns map[int64]*connection // conns holds all currently open connections.
+ newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections.
+
+ idleMu sync.Mutex // idleMu guards idleConns, idleConnWait
+ idleConns []*connection // idleConns holds all idle connections.
+ idleConnWait wantConnQueue // idleConnWait holds all wantConn requests for idle connections.
+ connectTimeout time.Duration
}
// getState returns the current state of the pool. Callers must not hold the stateMu lock.
@@ -141,7 +143,7 @@ func mustLogPoolMessage(pool *pool) bool {
logger.LevelDebug, logger.ComponentConnection)
}
-func logPoolMessage(pool *pool, msg string, keysAndValues ...interface{}) {
+func logPoolMessage(pool *pool, msg string, keysAndValues ...any) {
host, port, err := net.SplitHostPort(pool.address.String())
if err != nil {
host = pool.address.String()
@@ -156,7 +158,6 @@ func logPoolMessage(pool *pool, msg string, keysAndValues ...interface{}) {
ServerHost: host,
ServerPort: port,
}, keysAndValues...)...)
-
}
type reason struct {
@@ -221,8 +222,9 @@ func newPool(config poolConfig, connOpts ...ConnectionOption) *pool {
maintainReady: make(chan struct{}, 1),
backgroundDone: &sync.WaitGroup{},
createConnectionsCond: sync.NewCond(&sync.Mutex{}),
- conns: make(map[uint64]*connection, config.MaxPoolSize),
+ conns: make(map[int64]*connection, config.MaxPoolSize),
idleConns: make([]*connection, 0, config.MaxPoolSize),
+ connectTimeout: config.ConnectTimeout,
}
// minSize must not exceed maxSize if maxSize is not 0
if pool.maxSize != 0 && pool.minSize > pool.maxSize {
@@ -263,7 +265,7 @@ func newPool(config poolConfig, connOpts ...ConnectionOption) *pool {
if pool.monitor != nil {
pool.monitor.Event(&event.PoolEvent{
- Type: event.PoolCreated,
+ Type: event.ConnectionPoolCreated,
PoolOptions: &event.MonitorPoolOptions{
MaxPoolSize: config.MaxPoolSize,
MinPoolSize: config.MinPoolSize,
@@ -306,7 +308,7 @@ func (p *pool) ready() error {
// "pool ready" event is always sent before maintain() starts creating connections.
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.PoolReady,
+ Type: event.ConnectionPoolReady,
Address: p.address.String(),
})
}
@@ -417,7 +419,7 @@ func (p *pool) close(ctx context.Context) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.PoolClosedEvent,
+ Type: event.ConnectionPoolClosed,
Address: p.address.String(),
})
}
@@ -464,7 +466,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
// TODO checkout.
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetStarted,
+ Type: event.ConnectionCheckOutStarted,
Address: p.address.String(),
})
}
@@ -492,7 +494,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetFailed,
+ Type: event.ConnectionCheckOutFailed,
Address: p.address.String(),
Duration: duration,
Reason: event.ReasonPoolClosed,
@@ -500,7 +502,19 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
}
return nil, ErrPoolClosed
case poolPaused:
- err := poolClearedError{err: p.lastClearErr, address: p.address}
+ // Wrap poolCleared in a driver.Error so we can add the
+ // "TransientTransactionError" label. This will add
+ // "TransientTransactionError" to all poolClearedError instances, not
+ // just those that happened during transactions. While that behavior is
+ // different than other places we add "TransientTransactionError", it is
+ // consistent with the Transactions specification and simplifies the
+ // code.
+ pcErr := poolClearedError{err: p.lastClearErr, address: p.address}
+ err := driver.Error{
+ Message: pcErr.Error(),
+ Labels: []string{driver.TransientTransactionError},
+ Wrapped: pcErr,
+ }
p.stateMu.RUnlock()
duration := time.Since(start)
@@ -515,10 +529,10 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetFailed,
+ Type: event.ConnectionCheckOutFailed,
Address: p.address.String(),
- Duration: duration,
Reason: event.ReasonConnectionErrored,
+ Duration: duration,
Error: err,
})
}
@@ -561,7 +575,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetFailed,
+ Type: event.ConnectionCheckOutFailed,
Address: p.address.String(),
Duration: duration,
Reason: event.ReasonConnectionErrored,
@@ -583,7 +597,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetSucceeded,
+ Type: event.ConnectionCheckedOut,
Address: p.address.String(),
ConnectionID: w.conn.driverConnectionID,
Duration: duration,
@@ -616,7 +630,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetFailed,
+ Type: event.ConnectionCheckOutFailed,
Address: p.address.String(),
Duration: duration,
Reason: event.ReasonConnectionErrored,
@@ -639,7 +653,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetSucceeded,
+ Type: event.ConnectionCheckedOut,
Address: p.address.String(),
ConnectionID: w.conn.driverConnectionID,
Duration: duration,
@@ -661,7 +675,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.GetFailed,
+ Type: event.ConnectionCheckOutFailed,
Address: p.address.String(),
Duration: duration,
Reason: event.ReasonTimedOut,
@@ -705,7 +719,7 @@ func (p *pool) closeConnection(conn *connection) error {
return nil
}
-func (p *pool) getGenerationForNewConnection(serviceID *primitive.ObjectID) uint64 {
+func (p *pool) getGenerationForNewConnection(serviceID *bson.ObjectID) uint64 {
return p.generation.addConnection(serviceID)
}
@@ -769,11 +783,11 @@ func (p *pool) removeConnection(conn *connection, reason reason, err error) erro
var (
// BGReadTimeout is the maximum amount of the to wait when trying to read
// the server reply on a connection after an operation timed out. The
- // default is 1 second.
+ // default is 400ms.
//
// Deprecated: BGReadTimeout is intended for internal use only and may be
// removed or modified at any time.
- BGReadTimeout = 1 * time.Second
+ BGReadTimeout = 400 * time.Millisecond
// BGReadCallback is a callback for monitoring the behavior of the
// background-read-on-timeout connection preserving mechanism.
@@ -783,10 +797,9 @@ var (
BGReadCallback func(addr string, start, read time.Time, errs []error, connClosed bool)
)
-// bgRead sets a new read deadline on the provided connection (1 second in the
-// future) and tries to read any bytes returned by the server. If successful, it
-// checks the connection into the provided pool. If there are any errors, it
-// closes the connection.
+// bgRead sets a new read deadline on the provided connection and tries to read
+// any bytes returned by the server. If successful, it checks the connection
+// into the provided pool. If there are any errors, it closes the connection.
//
// It calls the package-global BGReadCallback function, if set, with the
// address, timings, and any errors that occurred.
@@ -865,7 +878,7 @@ func (p *pool) checkIn(conn *connection) error {
if p.monitor != nil {
p.monitor.Event(&event.PoolEvent{
- Type: event.ConnectionReturned,
+ Type: event.ConnectionCheckedIn,
ConnectionID: conn.driverConnectionID,
Address: conn.addr.String(),
})
@@ -949,12 +962,12 @@ func (p *pool) checkInNoEvent(conn *connection) error {
}
// clear calls clearImpl internally with a false interruptAllConnections value.
-func (p *pool) clear(err error, serviceID *primitive.ObjectID) {
+func (p *pool) clear(err error, serviceID *bson.ObjectID) {
p.clearImpl(err, serviceID, false)
}
// clearAll does same as the "clear" method but interrupts all connections.
-func (p *pool) clearAll(err error, serviceID *primitive.ObjectID) {
+func (p *pool) clearAll(err error, serviceID *bson.ObjectID) {
p.clearImpl(err, serviceID, true)
}
@@ -978,7 +991,7 @@ func (p *pool) interruptConnections(conns []*connection) {
// mode).
// If interruptAllConnections is true, this function calls interruptConnections to interrupt all
// non-idle connections.
-func (p *pool) clearImpl(err error, serviceID *primitive.ObjectID, interruptAllConnections bool) {
+func (p *pool) clearImpl(err error, serviceID *bson.ObjectID, interruptAllConnections bool) {
if p.getState() == poolClosed {
return
}
@@ -1014,7 +1027,7 @@ func (p *pool) clearImpl(err error, serviceID *primitive.ObjectID, interruptAllC
if sendEvent && p.monitor != nil {
event := &event.PoolEvent{
- Type: event.PoolCleared,
+ Type: event.ConnectionPoolCleared,
Address: p.address.String(),
ServiceID: serviceID,
Interruption: interruptAllConnections,
@@ -1177,7 +1190,7 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
conn := newConnection(p.address, p.connOpts...)
conn.pool = p
- conn.driverConnectionID = atomic.AddUint64(&p.nextID, 1)
+ conn.driverConnectionID = atomic.AddInt64(&p.nextID, 1)
p.conns[conn.driverConnectionID] = conn
return w, conn, true
@@ -1206,9 +1219,26 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
}
start := time.Now()
- // Pass the createConnections context to connect to allow pool close to cancel connection
- // establishment so shutdown doesn't block indefinitely if connectTimeout=0.
- err := conn.connect(ctx)
+ // Pass the createConnections context to connect to allow pool close to
+ // cancel connection establishment so shutdown doesn't block indefinitely if
+ // connectTimeout=0.
+ //
+ // Per the specifications, an explicit value of connectTimeout=0 means the
+ // timeout is "infinite".
+
+ var cancel context.CancelFunc
+
+ connctx := context.Background()
+ if p.connectTimeout != 0 {
+ connctx, cancel = context.WithTimeout(ctx, p.connectTimeout)
+ }
+
+ err := conn.connect(connctx)
+
+ if cancel != nil {
+ cancel()
+ }
+
if err != nil {
w.tryDeliver(nil, err)
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool_generation_counter.go
similarity index 77%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool_generation_counter.go
index dd10c0ce7..dec4c699f 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool_generation_counter.go
@@ -10,7 +10,7 @@ import (
"sync"
"sync/atomic"
- "go.mongodb.org/mongo-driver/bson/primitive"
+ "go.mongodb.org/mongo-driver/v2/bson"
)
// Pool generation state constants.
@@ -27,23 +27,23 @@ type generationStats struct {
}
// poolGenerationMap tracks the version for each service ID present in a pool. For deployments that are not behind a
-// load balancer, there is only one service ID: primitive.NilObjectID. For load-balanced deployments, each server behind
+// load balancer, there is only one service ID: bson.NilObjectID. For load-balanced deployments, each server behind
// the load balancer will have a unique service ID.
type poolGenerationMap struct {
// state must be accessed using the atomic package and should be at the beginning of the struct.
// - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG
// - suggested layout: https://go101.org/article/memory-layout.html
state int64
- generationMap map[primitive.ObjectID]*generationStats
+ generationMap map[bson.ObjectID]*generationStats
sync.Mutex
}
func newPoolGenerationMap() *poolGenerationMap {
pgm := &poolGenerationMap{
- generationMap: make(map[primitive.ObjectID]*generationStats),
+ generationMap: make(map[bson.ObjectID]*generationStats),
}
- pgm.generationMap[primitive.NilObjectID] = &generationStats{}
+ pgm.generationMap[bson.NilObjectID] = &generationStats{}
return pgm
}
@@ -57,7 +57,7 @@ func (p *poolGenerationMap) disconnect() {
// addConnection increments the connection count for the generation associated with the given service ID and returns the
// generation number for the connection.
-func (p *poolGenerationMap) addConnection(serviceIDPtr *primitive.ObjectID) uint64 {
+func (p *poolGenerationMap) addConnection(serviceIDPtr *bson.ObjectID) uint64 {
serviceID := getServiceID(serviceIDPtr)
p.Lock()
defer p.Unlock()
@@ -77,7 +77,7 @@ func (p *poolGenerationMap) addConnection(serviceIDPtr *primitive.ObjectID) uint
return 0
}
-func (p *poolGenerationMap) removeConnection(serviceIDPtr *primitive.ObjectID) {
+func (p *poolGenerationMap) removeConnection(serviceIDPtr *bson.ObjectID) {
serviceID := getServiceID(serviceIDPtr)
p.Lock()
defer p.Unlock()
@@ -96,7 +96,7 @@ func (p *poolGenerationMap) removeConnection(serviceIDPtr *primitive.ObjectID) {
}
}
-func (p *poolGenerationMap) clear(serviceIDPtr *primitive.ObjectID) {
+func (p *poolGenerationMap) clear(serviceIDPtr *bson.ObjectID) {
serviceID := getServiceID(serviceIDPtr)
p.Lock()
defer p.Unlock()
@@ -106,7 +106,7 @@ func (p *poolGenerationMap) clear(serviceIDPtr *primitive.ObjectID) {
}
}
-func (p *poolGenerationMap) stale(serviceIDPtr *primitive.ObjectID, knownGeneration uint64) bool {
+func (p *poolGenerationMap) stale(serviceIDPtr *bson.ObjectID, knownGeneration uint64) bool {
// If the map has been disconnected, all connections should be considered stale to ensure that they're closed.
if atomic.LoadInt64(&p.state) == generationDisconnected {
return true
@@ -118,7 +118,7 @@ func (p *poolGenerationMap) stale(serviceIDPtr *primitive.ObjectID, knownGenerat
return false
}
-func (p *poolGenerationMap) getGeneration(serviceIDPtr *primitive.ObjectID) (uint64, bool) {
+func (p *poolGenerationMap) getGeneration(serviceIDPtr *bson.ObjectID) (uint64, bool) {
serviceID := getServiceID(serviceIDPtr)
p.Lock()
defer p.Unlock()
@@ -129,7 +129,7 @@ func (p *poolGenerationMap) getGeneration(serviceIDPtr *primitive.ObjectID) (uin
return 0, false
}
-func (p *poolGenerationMap) getNumConns(serviceIDPtr *primitive.ObjectID) uint64 {
+func (p *poolGenerationMap) getNumConns(serviceIDPtr *bson.ObjectID) uint64 {
serviceID := getServiceID(serviceIDPtr)
p.Lock()
defer p.Unlock()
@@ -140,9 +140,9 @@ func (p *poolGenerationMap) getNumConns(serviceIDPtr *primitive.ObjectID) uint64
return 0
}
-func getServiceID(oid *primitive.ObjectID) primitive.ObjectID {
+func getServiceID(oid *bson.ObjectID) bson.ObjectID {
if oid == nil {
- return primitive.NilObjectID
+ return bson.NilObjectID
}
return *oid
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/rtt_monitor.go
similarity index 57%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/rtt_monitor.go
index cc37db59d..042ca04b1 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/rtt_monitor.go
@@ -7,21 +7,21 @@
package topology
import (
+ "container/list"
"context"
"fmt"
- "math"
"sync"
"time"
- "github.com/montanaflynn/stats"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
)
const (
- rttAlphaValue = 0.2
- minSamples = 10
- maxSamples = 500
+ rttAlphaValue = 0.2
+ minRTTSamplesForMovingMin = 2
+ maxRTTSamplesForMovingMin = 10
)
type rttConfig struct {
@@ -29,13 +29,10 @@ type rttConfig struct {
// the operation takes longer than the interval.
interval time.Duration
- // The timeout applied to running the "hello" operation. If the timeout is reached while running
- // the operation, the RTT sample is discarded. The default is 1 minute.
- timeout time.Duration
-
minRTTWindow time.Duration
createConnectionFn func() *connection
- createOperationFn func(driver.Connection) *operation.Hello
+ connectTimeout time.Duration
+ createOperationFn func(*mnet.Connection) *operation.Hello
}
type rttMonitor struct {
@@ -44,13 +41,14 @@ type rttMonitor struct {
// connMu guards connecting and disconnecting. This is necessary since
// disconnecting will await the cancellation of a started connection. The
// use case for rttMonitor.connect needs to be goroutine safe.
- connMu sync.Mutex
- samples []time.Duration
- offset int
- minRTT time.Duration
- rtt90 time.Duration
- averageRTT time.Duration
- averageRTTSet bool
+ connMu sync.Mutex
+ averageRTT time.Duration
+ averageRTTSet bool
+ movingMin *list.List
+ minRTT time.Duration
+ stddevRTT time.Duration
+ stddevSum float64
+ callsToAppendMovingMin int
closeWg sync.WaitGroup
cfg *rttConfig
@@ -66,15 +64,12 @@ func newRTTMonitor(cfg *rttConfig) *rttMonitor {
}
ctx, cancel := context.WithCancel(context.Background())
- // Determine the number of samples we need to keep to store the minWindow of RTT durations. The
- // number of samples must be between [10, 500].
- numSamples := int(math.Max(minSamples, math.Min(maxSamples, float64((cfg.minRTTWindow)/cfg.interval))))
return &rttMonitor{
- samples: make([]time.Duration, numSamples),
- cfg: cfg,
- ctx: ctx,
- cancelFn: cancel,
+ cfg: cfg,
+ ctx: ctx,
+ cancelFn: cancel,
+ movingMin: list.New(),
}
}
@@ -120,14 +115,18 @@ func (r *rttMonitor) start() {
for {
conn = r.cfg.createConnectionFn()
- err := conn.connect(r.ctx)
+
+ ctx, cancel := context.WithTimeout(r.ctx, r.cfg.connectTimeout)
+
+ err := conn.connect(ctx)
+ cancel()
// Add an RTT sample from the new connection handshake and start a runHellos() loop if we
// successfully established the new connection. Otherwise, close the connection and try to
// create another new connection.
if err == nil {
- r.addSample(conn.helloRTT)
r.runHellos(conn)
+ r.addSample(conn.helloRTT)
}
// Close any connection here because we're either about to try to create another new
@@ -166,14 +165,12 @@ func (r *rttMonitor) runHellos(conn *connection) {
// server or a proxy stops responding to requests on the RTT connection but does not close
// the TCP socket, effectively creating an operation that will never complete. We expect
// that "connectTimeoutMS" provides at least enough time for a single round trip.
- timeout := r.cfg.timeout
- if timeout <= 0 {
- timeout = conn.config.connectTimeout
- }
- ctx, cancel := context.WithTimeout(r.ctx, timeout)
+ ctx, cancel := context.WithTimeout(r.ctx, r.cfg.connectTimeout)
start := time.Now()
- err := r.cfg.createOperationFn(initConnection{conn}).Execute(ctx)
+ iconn := mnet.NewConnection(initConnection{conn})
+
+ err := r.cfg.createOperationFn(iconn).Execute(ctx)
cancel()
if err != nil {
return
@@ -185,85 +182,91 @@ func (r *rttMonitor) runHellos(conn *connection) {
}
}
-// reset sets the average and min RTT to 0. This should only be called from the server monitor when an error
-// occurs during a server check. Errors in the RTT monitor should not reset the RTTs.
+// reset sets the average, min, and stddev RTT to 0. This should only be called from the server monitor
+// when an error occurs during a server check. Errors in the RTT monitor should not reset the RTTs.
func (r *rttMonitor) reset() {
r.mu.Lock()
defer r.mu.Unlock()
- for i := range r.samples {
- r.samples[i] = 0
- }
- r.offset = 0
- r.minRTT = 0
- r.rtt90 = 0
+ r.movingMin = list.New()
r.averageRTT = 0
r.averageRTTSet = false
+ r.stddevSum = 0
+ r.callsToAppendMovingMin = 0
}
-func (r *rttMonitor) addSample(rtt time.Duration) {
- // Lock for the duration of this method. We're doing compuationally inexpensive work very infrequently, so lock
- // contention isn't expected.
- r.mu.Lock()
- defer r.mu.Unlock()
-
- r.samples[r.offset] = rtt
- r.offset = (r.offset + 1) % len(r.samples)
- // Set the minRTT and 90th percentile RTT of all collected samples. Require at least 10 samples before
- // setting these to prevent noisy samples on startup from artificially increasing RTT and to allow the
- // calculation of a 90th percentile.
- r.minRTT = min(r.samples, minSamples)
- r.rtt90 = percentile(90.0, r.samples, minSamples)
+// appendMovingMin will append the RTT to the movingMin list which tracks a
+// minimum RTT within the last "minRTTSamplesForMovingMin" RTT samples.
+func (r *rttMonitor) appendMovingMin(rtt time.Duration) {
+ r.callsToAppendMovingMin++
- if !r.averageRTTSet {
- r.averageRTT = rtt
- r.averageRTTSet = true
+ if r.movingMin == nil || rtt < 0 {
return
}
- r.averageRTT = time.Duration(rttAlphaValue*float64(rtt) + (1-rttAlphaValue)*float64(r.averageRTT))
-}
+ if r.movingMin.Len() == maxRTTSamplesForMovingMin {
+ r.movingMin.Remove(r.movingMin.Front())
+ }
-// min returns the minimum value of the slice of duration samples. Zero values are not considered
-// samples and are ignored. If no samples or fewer than minSamples are found in the slice, min
-// returns 0.
-func min(samples []time.Duration, minSamples int) time.Duration {
- count := 0
- min := time.Duration(math.MaxInt64)
- for _, d := range samples {
- if d > 0 {
- count++
- }
- if d > 0 && d < min {
- min = d
- }
+ r.movingMin.PushBack(rtt)
+
+ // Collect a sum of stddevs over maxRTTSamplesForMovingMin calls, ignore if calls are less than max
+ if r.callsToAppendMovingMin >= maxRTTSamplesForMovingMin {
+ stddev := standardDeviationList(r.movingMin)
+ r.stddevSum += stddev
}
- if count == 0 || count < minSamples {
+}
+
+// min will return the minimum value in the movingMin list.
+func (r *rttMonitor) min() time.Duration {
+ if r.movingMin == nil || r.movingMin.Len() < minRTTSamplesForMovingMin {
return 0
}
- return min
-}
-// percentile returns the specified percentile value of the slice of duration samples. Zero values
-// are not considered samples and are ignored. If no samples or fewer than minSamples are found
-// in the slice, percentile returns 0.
-func percentile(perc float64, samples []time.Duration, minSamples int) time.Duration {
- // Convert Durations to float64s.
- floatSamples := make([]float64, 0, len(samples))
- for _, sample := range samples {
- if sample > 0 {
- floatSamples = append(floatSamples, float64(sample))
+ var min time.Duration
+ for e := r.movingMin.Front(); e != nil; e = e.Next() {
+ val := e.Value.(time.Duration)
+
+ if min == 0 || val < min {
+ min = val
}
}
- if len(floatSamples) == 0 || len(floatSamples) < minSamples {
+
+ return min
+}
+
+// stddev will return the current moving stddev.
+func (r *rttMonitor) stddev() time.Duration {
+ var stddev time.Duration
+
+ if r.callsToAppendMovingMin < maxRTTSamplesForMovingMin {
return 0
}
- p, err := stats.Percentile(floatSamples, perc)
- if err != nil {
- panic(fmt.Errorf("x/mongo/driver/topology: error calculating %f percentile RTT: %w for samples:\n%v", perc, err, floatSamples))
+ // Get the number of times stddev was updated and calculate the average stddev
+ frequency := (r.callsToAppendMovingMin + 1) - maxRTTSamplesForMovingMin
+ stddev = time.Duration(r.stddevSum / float64(frequency))
+
+ return stddev
+}
+
+func (r *rttMonitor) addSample(rtt time.Duration) {
+ // Lock for the duration of this method. We're doing compuationally inexpensive work very infrequently, so lock
+ // contention isn't expected.
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ r.appendMovingMin(rtt)
+ r.minRTT = r.min()
+ r.stddevRTT = r.stddev()
+
+ if !r.averageRTTSet {
+ r.averageRTT = rtt
+ r.averageRTTSet = true
+ return
}
- return time.Duration(p)
+
+ r.averageRTT = time.Duration(rttAlphaValue*float64(rtt) + (1-rttAlphaValue)*float64(r.averageRTT))
}
// EWMA returns the exponentially weighted moving average observed round-trip time.
@@ -282,44 +285,14 @@ func (r *rttMonitor) Min() time.Duration {
return r.minRTT
}
-// P90 returns the 90th percentile observed round-trip time over the window period.
-func (r *rttMonitor) P90() time.Duration {
- r.mu.RLock()
- defer r.mu.RUnlock()
-
- return r.rtt90
-}
-
// Stats returns stringified stats of the current state of the monitor.
func (r *rttMonitor) Stats() string {
r.mu.RLock()
defer r.mu.RUnlock()
- // Calculate standard deviation and average (non-EWMA) of samples.
- var sum float64
- floatSamples := make([]float64, 0, len(r.samples))
- for _, sample := range r.samples {
- if sample > 0 {
- floatSamples = append(floatSamples, float64(sample))
- sum += float64(sample)
- }
- }
-
- var avg, stdDev float64
- if len(floatSamples) > 0 {
- avg = sum / float64(len(floatSamples))
-
- var err error
- stdDev, err = stats.StandardDeviation(floatSamples)
- if err != nil {
- panic(fmt.Errorf("x/mongo/driver/topology: error calculating standard deviation RTT: %w for samples:\n%v", err, floatSamples))
- }
- }
-
return fmt.Sprintf(
- "network round-trip time stats: avg: %v, min: %v, 90th pct: %v, stddev: %v",
- time.Duration(avg),
+ "network round-trip time stats: moving avg: %v, min: %v, moving stddev: %v",
+ r.averageRTT,
r.minRTT,
- r.rtt90,
- time.Duration(stdDev))
+ r.stddevRTT)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server.go
similarity index 74%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server.go
index 062363267..ff69b60dd 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server.go
@@ -15,20 +15,22 @@ import (
"sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
)
-const minHeartbeatInterval = 500 * time.Millisecond
-const wireVersion42 = 8 // Wire version for MongoDB 4.2
+const (
+ minHeartbeatInterval = 500 * time.Millisecond
+ wireVersion42 = 8 // Wire version for MongoDB 4.2
+)
// Server state constants.
const (
@@ -50,6 +52,27 @@ func serverStateString(state int64) string {
return ""
}
+// newServerDescriptionFromError creates a new unknown server description with
+// the given parameters.
+func newServerDescriptionFromError(
+ addr address.Address,
+ err error,
+ tv *description.TopologyVersion,
+) description.Server {
+ return description.Server{
+ Addr: addr,
+ LastError: err,
+ Kind: description.Unknown,
+ TopologyVersion: tv,
+ }
+}
+
+// newDefaultServerDescription creates a new unknown server description with the
+// given address.
+func newDefaultServerDescription(addr address.Address) description.Server {
+ return newServerDescriptionFromError(addr, nil, nil)
+}
+
var (
// ErrServerClosed occurs when an attempt to Get a connection is made after
// the server has been closed.
@@ -59,7 +82,7 @@ var (
ErrServerConnected = errors.New("server is connected")
errCheckCancelled = errors.New("server check cancelled")
- emptyDescription = description.NewDefaultServer("")
+ emptyDescription = newDefaultServerDescription("")
)
// SelectedServer represents a specific server that was selected during server selection.
@@ -104,7 +127,7 @@ type Server struct {
// description related fields
desc atomic.Value // holds a description.Server
updateTopologyCallback atomic.Value
- topologyID primitive.ObjectID
+ topologyID bson.ObjectID
// subscriber related fields
subLock sync.Mutex
@@ -112,16 +135,12 @@ type Server struct {
currentSubscriberID uint64
subscriptionsClosed bool
- // heartbeat and cancellation related fields
- // globalCtx should be created in NewServer and cancelled in Disconnect to signal that the server is shutting down.
- // heartbeatCtx should be used for individual heartbeats and should be a child of globalCtx so that it will be
- // cancelled automatically during shutdown.
- heartbeatLock sync.Mutex
- conn *connection
- globalCtx context.Context
- globalCtxCancel context.CancelFunc
- heartbeatCtx context.Context
- heartbeatCtxCancel context.CancelFunc
+ conn *connection
+
+ // Calling StopListening on the heartbeatListner will cancel the context
+ // passed to the heartbeat check. This will result in the current connection
+ // being closed.
+ heartbeatListener contextListener
processErrorLock sync.Mutex
rttMonitor *rttMonitor
@@ -138,10 +157,11 @@ type updateTopologyCallback func(description.Server) description.Server
func ConnectServer(
addr address.Address,
updateCallback updateTopologyCallback,
- topologyID primitive.ObjectID,
+ topologyID bson.ObjectID,
+ connectTimeout time.Duration,
opts ...ServerOption,
) (*Server, error) {
- srvr := NewServer(addr, topologyID, opts...)
+ srvr := NewServer(addr, topologyID, connectTimeout, opts...)
err := srvr.Connect(updateCallback)
if err != nil {
return nil, err
@@ -151,9 +171,14 @@ func ConnectServer(
// NewServer creates a new server. The mongodb server at the address will be monitored
// on an internal monitoring goroutine.
-func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...ServerOption) *Server {
- cfg := newServerConfig(opts...)
- globalCtx, globalCtxCancel := context.WithCancel(context.Background())
+func NewServer(
+ addr address.Address,
+ topologyID bson.ObjectID,
+ connectTimeout time.Duration,
+ opts ...ServerOption,
+) *Server {
+ cfg := newServerConfig(connectTimeout, opts...)
+
s := &Server{
state: serverDisconnected,
@@ -166,16 +191,16 @@ func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...Serv
topologyID: topologyID,
- subscribers: make(map[uint64]chan description.Server),
- globalCtx: globalCtx,
- globalCtxCancel: globalCtxCancel,
+ subscribers: make(map[uint64]chan description.Server),
+ heartbeatListener: newNonBlockingContextDoneListener(),
}
- s.desc.Store(description.NewDefaultServer(addr))
+ s.desc.Store(newDefaultServerDescription(addr))
rttCfg := &rttConfig{
interval: cfg.heartbeatInterval,
minRTTWindow: 5 * time.Minute,
createConnectionFn: s.createConnection,
createOperationFn: s.createBaseOperation,
+ connectTimeout: connectTimeout,
}
s.rttMonitor = newRTTMonitor(rttCfg)
@@ -190,6 +215,7 @@ func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...Serv
PoolMonitor: cfg.poolMonitor,
Logger: cfg.logger,
handshakeErrFn: s.ProcessHandshakeError,
+ ConnectTimeout: connectTimeout,
}
connectionOpts := copyConnectionOpts(cfg.connectionOpts)
@@ -204,14 +230,14 @@ func mustLogServerMessage(srv *Server) bool {
logger.LevelDebug, logger.ComponentTopology)
}
-func logServerMessage(srv *Server, msg string, keysAndValues ...interface{}) {
+func logServerMessage(srv *Server, msg string, keysAndValues ...any) {
serverHost, serverPort, err := net.SplitHostPort(srv.address.String())
if err != nil {
serverHost = srv.address.String()
serverPort = ""
}
- var driverConnectionID uint64
+ var driverConnectionID int64
var serverConnectionID *int64
if srv.conn != nil {
@@ -239,10 +265,10 @@ func (s *Server) Connect(updateCallback updateTopologyCallback) error {
return ErrServerConnected
}
- desc := description.NewDefaultServer(s.address)
+ desc := newDefaultServerDescription(s.address)
if s.cfg.loadBalanced {
// LBs automatically start off with kind LoadBalancer because there is no monitoring routine for state changes.
- desc.Kind = description.LoadBalancer
+ desc.Kind = description.ServerKindLoadBalancer
}
s.desc.Store(desc)
s.updateTopologyCallback.Store(updateCallback)
@@ -278,13 +304,9 @@ func (s *Server) Disconnect(ctx context.Context) error {
s.updateTopologyCallback.Store((updateTopologyCallback)(nil))
- // Cancel the global context so any new contexts created from it will be automatically cancelled. Close the done
- // channel so the update() routine will know that it can stop. Cancel any in-progress monitoring checks at the end.
- // The done channel is closed before cancelling the check so the update routine() will immediately detect that it
- // can stop rather than trying to create new connections until the read from done succeeds.
- s.globalCtxCancel()
close(s.done)
- s.cancelCheck()
+
+ s.heartbeatListener.StopListening()
s.pool.close(ctx)
@@ -296,7 +318,7 @@ func (s *Server) Disconnect(ctx context.Context) error {
}
// Connection gets a connection to the server.
-func (s *Server) Connection(ctx context.Context) (driver.Connection, error) {
+func (s *Server) Connection(ctx context.Context) (*mnet.Connection, error) {
if atomic.LoadInt64(&s.state) != serverConnected {
return nil, ErrServerClosed
}
@@ -311,7 +333,7 @@ func (s *Server) Connection(ctx context.Context) (driver.Connection, error) {
return nil, err
}
- return &Connection{
+ serverConn := &Connection{
connection: conn,
cleanupServerFn: func() {
// Decrement the operation count whenever the caller is done with the connection. Note
@@ -322,12 +344,14 @@ func (s *Server) Connection(ctx context.Context) (driver.Connection, error) {
// make the server much less selectable.
atomic.AddInt64(&s.operationCount, -1)
},
- }, nil
+ }
+
+ return mnet.NewConnection(serverConn), nil
}
// ProcessHandshakeError implements SDAM error handling for errors that occur before a connection
// finishes handshaking.
-func (s *Server) ProcessHandshakeError(err error, startingGenerationNumber uint64, serviceID *primitive.ObjectID) {
+func (s *Server) ProcessHandshakeError(err error, startingGenerationNumber uint64, serviceID *bson.ObjectID) {
// Ignore the error if the server is behind a load balancer but the service ID is unknown. This indicates that the
// error happened when dialing the connection or during the MongoDB handshake, so we don't know the service ID to
// use for clearing the pool.
@@ -346,6 +370,12 @@ func (s *Server) ProcessHandshakeError(err error, startingGenerationNumber uint6
return
}
+ // Do not clear the pool when backpressure error label applied.
+ var de driver.Error
+ if errors.As(err, &de) && de.HasErrorLabel(driver.ErrSystemOverloadedError) {
+ return
+ }
+
// Must hold the processErrorLock while updating the server description and clearing the pool.
// Not holding the lock leads to possible out-of-order processing of pool.clear() and
// pool.ready() calls from concurrent server description updates.
@@ -355,9 +385,9 @@ func (s *Server) ProcessHandshakeError(err error, startingGenerationNumber uint6
// Since the only kind of ConnectionError we receive from pool.Get will be an initialization error, we should set
// the description.Server appropriately. The description should not have a TopologyVersion because the staleness
// checking logic above has already determined that this description is not stale.
- s.updateDescription(description.NewServerFromError(s.address, wrappedConnErr, nil))
+ s.updateDescription(newServerDescriptionFromError(s.address, wrappedConnErr, nil))
s.pool.clear(err, serviceID)
- s.cancelCheck()
+ s.heartbeatListener.StopListening()
}
// Description returns a description of the server as of the last heartbeat.
@@ -372,7 +402,7 @@ func (s *Server) SelectedDescription() description.SelectedServer {
sdesc := s.Description()
return description.SelectedServer{
Server: sdesc,
- Kind: description.Single,
+ Kind: description.TopologyKindSingle,
}
}
@@ -430,7 +460,7 @@ func getWriteConcernErrorForProcessing(err error) (*driver.WriteConcernError, bo
}
// ProcessError handles SDAM error handling and implements driver.ErrorProcessor.
-func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessErrorResult {
+func (s *Server) ProcessError(err error, describer mnet.Describer) driver.ProcessErrorResult {
// Ignore nil errors.
if err == nil {
return driver.NoChange
@@ -441,7 +471,7 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
// the pool generation to increment. Processing errors for stale connections could result in
// handling the same error root cause multiple times (e.g. a temporary network interrupt causing
// all connections to the same server to return errors).
- if conn.Stale() {
+ if describer.Stale() {
return driver.NoChange
}
@@ -454,7 +484,7 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
// Get the wire version and service ID from the connection description because they will never
// change for the lifetime of a connection and can possibly be different between connections to
// the same server.
- connDesc := conn.Description()
+ connDesc := describer.Description()
wireVersion := connDesc.WireVersion
serviceID := connDesc.ServiceID
@@ -474,7 +504,7 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
// TODO(GODRIVER-2841): Remove this logic once we set the Server description when we create
// TODO application connections because then the Server's topology version will always be the
// TODO latest known.
- if tv := connDesc.TopologyVersion; tv != nil && topologyVersion.CompareToIncoming(tv) < 0 {
+ if tv := connDesc.TopologyVersion; tv != nil && driverutil.CompareTopologyVersions(topologyVersion, tv) < 0 {
topologyVersion = tv
}
@@ -482,12 +512,12 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
// These errors can be reported as a command error or a write concern error.
if cerr, ok := err.(driver.Error); ok && (cerr.NodeIsRecovering() || cerr.NotPrimary()) {
// Ignore errors that came from when the database was on a previous topology version.
- if topologyVersion.CompareToIncoming(cerr.TopologyVersion) >= 0 {
+ if driverutil.CompareTopologyVersions(topologyVersion, cerr.TopologyVersion) >= 0 {
return driver.NoChange
}
// updates description to unknown
- s.updateDescription(description.NewServerFromError(s.address, err, cerr.TopologyVersion))
+ s.updateDescription(newServerDescriptionFromError(s.address, err, cerr.TopologyVersion))
s.RequestImmediateCheck()
res := driver.ServerMarkedUnknown
@@ -501,12 +531,12 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
}
if wcerr, ok := getWriteConcernErrorForProcessing(err); ok {
// Ignore errors that came from when the database was on a previous topology version.
- if topologyVersion.CompareToIncoming(wcerr.TopologyVersion) >= 0 {
+ if driverutil.CompareTopologyVersions(topologyVersion, wcerr.TopologyVersion) >= 0 {
return driver.NoChange
}
// updates description to unknown
- s.updateDescription(description.NewServerFromError(s.address, err, wcerr.TopologyVersion))
+ s.updateDescription(newServerDescriptionFromError(s.address, err, wcerr.TopologyVersion))
s.RequestImmediateCheck()
res := driver.ServerMarkedUnknown
@@ -534,12 +564,66 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE
// For a non-timeout network error, we clear the pool, set the description to Unknown, and cancel the in-progress
// monitoring check. The check is cancelled last to avoid a post-cancellation reconnect racing with
// updateDescription.
- s.updateDescription(description.NewServerFromError(s.address, err, nil))
+ s.updateDescription(newServerDescriptionFromError(s.address, err, nil))
s.pool.clear(err, serviceID)
- s.cancelCheck()
+ s.heartbeatListener.StopListening()
return driver.ConnectionPoolCleared
}
+type serverChecker interface {
+ check(ctx context.Context) (description.Server, error)
+}
+
+var _ serverChecker = &Server{}
+
+// checkServerWithSignal will run the server heartbeat check, canceling if the
+// sig channel's buffer is emptied or is closed.
+func checkServerWithSignal(
+ checker serverChecker,
+ conn *connection,
+ listener contextListener,
+) (description.Server, error) {
+ // Create a context for the blocking operations associated with checking the
+ // status of a server.
+ //
+ // The Server Monitoring spec already mandates that drivers set and
+ // dynamically update the read/write timeout of the dedicated connections
+ // used in monitoring threads, so we rely on that to time out commands
+ // rather than adding complexity to the behavior of timeoutMS.
+ ctx, cancel := context.WithCancel(context.Background())
+
+ defer listener.StopListening()
+ defer cancel()
+
+ go func(conn *connection) {
+ defer cancel()
+
+ var aborted bool
+ listener.Listen(ctx, func() {
+ aborted = true
+ })
+
+ // Close the connection if the listener was stopped before
+ // checkServerWithSignal terminates.
+ if !aborted {
+ if conn == nil {
+ return
+ }
+
+ // If the connection exists, we need to wait for it to be connected
+ // because conn.connect() and conn.close() cannot be called concurrently.
+ // If the connection wasn't successfully opened, its state was set back
+ // to disconnected, so calling conn.close() will be a no-op.
+ conn.closeConnectContext()
+ conn.wait()
+ conn.prevCanceled.Store(true)
+ _ = conn.close()
+ }
+ }(conn)
+
+ return checker.check(ctx)
+}
+
// update handle performing heartbeats and updating any subscribers of the
// newest description.Server retrieved.
func (s *Server) update() {
@@ -551,7 +635,9 @@ func (s *Server) update() {
checkNow := s.checkNow
done := s.done
- defer logUnexpectedFailure(s.cfg.logger, "Encountered unexpected failure updating server")
+ defer func() {
+ _ = recover()
+ }()
closeServer := func() {
s.subLock.Lock()
@@ -562,8 +648,6 @@ func (s *Server) update() {
s.subscriptionsClosed = true
s.subLock.Unlock()
- // We don't need to take s.heartbeatLock here because closeServer is called synchronously when the select checks
- // below detect that the server is being closed, so we can be sure that the connection isn't being used.
if s.conn != nil {
_ = s.conn.close()
}
@@ -601,8 +685,9 @@ func (s *Server) update() {
previousDescription := s.Description()
- // Perform the next check.
- desc, err := s.check()
+ desc, err := checkServerWithSignal(s, s.conn, s.heartbeatListener)
+
+ // The only error returned from checkServerWithSignal is errCheckCancelled.
if errors.Is(err, errCheckCancelled) {
if atomic.LoadInt64(&s.state) != serverConnected {
continue
@@ -687,7 +772,10 @@ func (s *Server) updateDescription(desc description.Server) {
return
}
- defer logUnexpectedFailure(s.cfg.logger, "Encountered unexpected failure updating server description")
+ defer func() {
+ // ¯\_(ツ)_/¯
+ _ = recover()
+ }()
// Anytime we update the server description to something other than "unknown", set the pool to
// "ready". Do this before updating the description so that connections can be checked out as
@@ -725,14 +813,19 @@ func (s *Server) updateDescription(desc description.Server) {
func (s *Server) createConnection() *connection {
opts := copyConnectionOpts(s.cfg.connectionOpts)
opts = append(opts,
- WithConnectTimeout(func(time.Duration) time.Duration { return s.cfg.heartbeatTimeout }),
- WithReadTimeout(func(time.Duration) time.Duration { return s.cfg.heartbeatTimeout }),
- WithWriteTimeout(func(time.Duration) time.Duration { return s.cfg.heartbeatTimeout }),
- // We override whatever handshaker is currently attached to the options with a basic
- // one because need to make sure we don't do auth.
WithHandshaker(func(Handshaker) Handshaker {
- return operation.NewHello().AppName(s.cfg.appname).Compressors(s.cfg.compressionOpts).
+ handshaker := operation.NewHello().AppName(s.cfg.appname).Compressors(s.cfg.compressionOpts).
ServerAPI(s.cfg.serverAPI)
+
+ if s.cfg.driverInfo != nil {
+ driverInfo := s.cfg.driverInfo.Load()
+ if driverInfo != nil {
+ handshaker = handshaker.OuterLibraryName(driverInfo.Name).OuterLibraryVersion(driverInfo.Version).
+ OuterLibraryPlatform(driverInfo.Platform)
+ }
+ }
+
+ return handshaker
}),
// Override any monitors specified in options with nil to avoid monitoring heartbeats.
WithMonitor(func(*event.CommandMonitor) *event.CommandMonitor { return nil }),
@@ -747,54 +840,24 @@ func copyConnectionOpts(opts []ConnectionOption) []ConnectionOption {
return optsCopy
}
-func (s *Server) setupHeartbeatConnection() error {
+func (s *Server) setupHeartbeatConnection(ctx context.Context) error {
conn := s.createConnection()
- // Take the lock when assigning the context and connection because they're accessed by cancelCheck.
- s.heartbeatLock.Lock()
- if s.heartbeatCtxCancel != nil {
- // Ensure the previous context is cancelled to avoid a leak.
- s.heartbeatCtxCancel()
- }
- s.heartbeatCtx, s.heartbeatCtxCancel = context.WithCancel(s.globalCtx)
s.conn = conn
- s.heartbeatLock.Unlock()
- return s.conn.connect(s.heartbeatCtx)
-}
+ if s.cfg.connectTimeout != 0 {
+ var cancelFn context.CancelFunc
+ ctx, cancelFn = context.WithTimeout(ctx, s.cfg.connectTimeout)
-// cancelCheck cancels in-progress connection dials and reads. It does not set any fields on the server.
-func (s *Server) cancelCheck() {
- var conn *connection
-
- // Take heartbeatLock for mutual exclusion with the checks in the update function.
- s.heartbeatLock.Lock()
- if s.heartbeatCtx != nil {
- s.heartbeatCtxCancel()
+ defer cancelFn()
}
- conn = s.conn
- s.heartbeatLock.Unlock()
- if conn == nil {
- return
- }
-
- // If the connection exists, we need to wait for it to be connected because conn.connect() and
- // conn.close() cannot be called concurrently. If the connection wasn't successfully opened, its
- // state was set back to disconnected, so calling conn.close() will be a no-op.
- conn.closeConnectContext()
- conn.wait()
- _ = conn.close()
-}
-
-func (s *Server) checkWasCancelled() bool {
- return s.heartbeatCtx.Err() != nil
+ return s.conn.connect(ctx)
}
-func (s *Server) createBaseOperation(conn driver.Connection) *operation.Hello {
+func (s *Server) createBaseOperation(conn *mnet.Connection) *operation.Hello {
return operation.
NewHello().
- ClusterClock(s.cfg.clock).
Deployment(driver.SingleConnectionDeployment{C: conn}).
ServerAPI(s.cfg.serverAPI)
}
@@ -814,24 +877,119 @@ func isStreamable(srv *Server) bool {
return srv.Description().Kind != description.Unknown && srv.Description().TopologyVersion != nil
}
-func (s *Server) check() (description.Server, error) {
+func (s *Server) streamable() bool {
+ return isStreamingEnabled(s) && isStreamable(s)
+}
+
+// getHeartbeatTimeout will return the maximum allowable duration for streaming
+// or polling a hello command during server monitoring.
+func getHeartbeatTimeout(srv *Server) time.Duration {
+ if srv.conn.getCurrentlyStreaming() || srv.streamable() {
+ // If connectTimeoutMS=0, the operation timeout should be infinite.
+ // Otherwise, it is connectTimeoutMS + heartbeatFrequencyMS to account for
+ // the fact that the query will block for heartbeatFrequencyMS
+ // server-side.
+ streamingTO := srv.cfg.connectTimeout
+ if streamingTO != 0 {
+ streamingTO += srv.cfg.heartbeatInterval
+ }
+
+ return streamingTO
+ }
+
+ // The server doesn't support the awaitable protocol. Set the timeout to
+ // connectTimeoutMS and execute a regular heartbeat without any additional
+ // parameters.
+ return srv.cfg.connectTimeout
+}
+
+// withHeartbeatTimeout will apply the appropriate timeout to the parent context
+// for server monitoring.
+func withHeartbeatTimeout(parent context.Context, srv *Server) (context.Context, context.CancelFunc) {
+ var cancel context.CancelFunc
+
+ timeout := getHeartbeatTimeout(srv)
+ if timeout == 0 {
+ return parent, cancel
+ }
+
+ return context.WithTimeout(parent, timeout)
+}
+
+// doHandshake will construct the hello operation use to execute a handshake
+// between the client and a server. Depending on the configuration and version,
+// this function will either poll, stream, or resume streaming.
+func doHandshake(ctx context.Context, srv *Server) (description.Server, error) {
+ heartbeatConn := mnet.NewConnection(initConnection{srv.conn})
+ handshakeOp := srv.createBaseOperation(heartbeatConn)
+
+ // Using timeoutMS in the monitoring and RTT calculation threads would require
+ // another special case in the code that derives maxTimeMS from timeoutMS
+ // because the awaitable hello requests sent to 4.4+ servers already have a
+ // maxAwaitTimeMS field. Adding maxTimeMS also does not help for non-awaitable
+ // hello commands because we expect them to execute quickly on the server. The
+ // Server Monitoring spec already mandates that drivers set and dynamically
+ // update the read/write timeout of the dedicated connections used in
+ // monitoring threads, so we rely on that to time out commands rather than
+ // adding complexity to the behavior of timeoutMS.
+ handshakeOp = handshakeOp.OmitMaxTimeMS(true)
+
+ // Apply monitoring timeout.
+ ctx, cancel := withHeartbeatTimeout(ctx, srv)
+ defer cancel()
+
+ // If we are currently streaming, get more data and return the result.
+ if srv.conn.getCurrentlyStreaming() {
+ if err := handshakeOp.StreamResponse(ctx, heartbeatConn); err != nil {
+ return description.Server{}, err
+ }
+
+ return handshakeOp.Result(srv.address), nil
+ }
+
+ // If the server supports streaming, update it so the next handshake streams
+ // the response.
+ if srv.streamable() {
+ srv.conn.setCanStream(true)
+
+ maxAwaitTimeMS := int64(srv.cfg.heartbeatInterval) / 1e6
+
+ handshakeOp = handshakeOp.
+ TopologyVersion(srv.Description().TopologyVersion).
+ MaxAwaitTimeMS(maxAwaitTimeMS)
+ }
+
+ // Perform the handshake.
+ if err := handshakeOp.Execute(ctx); err != nil {
+ return description.Server{}, err
+ }
+
+ return handshakeOp.Result(srv.address), nil
+}
+
+func (s *Server) check(ctx context.Context) (description.Server, error) {
var descPtr *description.Server
var err error
- var duration time.Duration
+ var execDuration time.Duration
start := time.Now()
+ var previousCanceled bool
+ if s.conn != nil {
+ previousCanceled = s.conn.previousCanceled()
+ }
+
// Create a new connection if this is the first check, the connection was closed after an error during the previous
// check, or the previous check was cancelled.
- if s.conn == nil || s.conn.closed() || s.checkWasCancelled() {
+ if s.conn == nil || s.conn.closed() || previousCanceled {
connID := "0"
if s.conn != nil {
connID = s.conn.ID()
}
s.publishServerHeartbeatStartedEvent(connID, false)
// Create a new connection and add it's handshake RTT as a sample.
- err = s.setupHeartbeatConnection()
- duration = time.Since(start)
+ err = s.setupHeartbeatConnection(ctx)
+ execDuration = time.Since(start)
connID = "0"
if s.conn != nil {
connID = s.conn.ID()
@@ -840,85 +998,56 @@ func (s *Server) check() (description.Server, error) {
// Use the description from the connection handshake as the value for this check.
s.rttMonitor.addSample(s.conn.helloRTT)
descPtr = &s.conn.desc
- s.publishServerHeartbeatSucceededEvent(connID, duration, s.conn.desc, false)
+ s.publishServerHeartbeatSucceededEvent(connID, execDuration, s.conn.desc, false)
} else {
err = unwrapConnectionError(err)
- s.publishServerHeartbeatFailedEvent(connID, duration, err, false)
+ s.publishServerHeartbeatFailedEvent(connID, execDuration, err, false)
}
} else {
- // An existing connection is being used. Use the server description properties to execute the right heartbeat.
+ // An existing connection is being used. Use the server description
+ // properties to execute the right heartbeat.
- // Wrap conn in a type that implements driver.StreamerConnection.
- heartbeatConn := initConnection{s.conn}
- baseOperation := s.createBaseOperation(heartbeatConn)
- previousDescription := s.Description()
streamable := isStreamingEnabled(s) && isStreamable(s)
s.publishServerHeartbeatStartedEvent(s.conn.ID(), s.conn.getCurrentlyStreaming() || streamable)
- switch {
- case s.conn.getCurrentlyStreaming():
- // The connection is already in a streaming state, so we stream the next response.
- err = baseOperation.StreamResponse(s.heartbeatCtx, heartbeatConn)
- case streamable:
- // The server supports the streamable protocol. Set the socket timeout to
- // connectTimeoutMS+heartbeatFrequencyMS and execute an awaitable hello request. Set conn.canStream so
- // the wire message will advertise streaming support to the server.
-
- // Calculation for maxAwaitTimeMS is taken from time.Duration.Milliseconds (added in Go 1.13).
- maxAwaitTimeMS := int64(s.cfg.heartbeatInterval) / 1e6
- // If connectTimeoutMS=0, the socket timeout should be infinite. Otherwise, it is connectTimeoutMS +
- // heartbeatFrequencyMS to account for the fact that the query will block for heartbeatFrequencyMS
- // server-side.
- socketTimeout := s.cfg.heartbeatTimeout
- if socketTimeout != 0 {
- socketTimeout += s.cfg.heartbeatInterval
- }
- s.conn.setSocketTimeout(socketTimeout)
- baseOperation = baseOperation.TopologyVersion(previousDescription.TopologyVersion).
- MaxAwaitTimeMS(maxAwaitTimeMS)
- s.conn.setCanStream(true)
- err = baseOperation.Execute(s.heartbeatCtx)
- default:
- // The server doesn't support the awaitable protocol. Set the socket timeout to connectTimeoutMS and
- // execute a regular heartbeat without any additional parameters.
-
- s.conn.setSocketTimeout(s.cfg.heartbeatTimeout)
- err = baseOperation.Execute(s.heartbeatCtx)
- }
+ var tempDesc description.Server
+ tempDesc, err = doHandshake(ctx, s) // Perform a handshake with the server
- duration = time.Since(start)
+ execDuration = time.Since(start)
// We need to record an RTT sample in the polling case so that if the server
// is < 4.4, or if polling is specified by the user, then the
// RTT-short-circuit feature of CSOT is not disabled.
if !streamable {
- s.rttMonitor.addSample(duration)
+ s.rttMonitor.addSample(execDuration)
}
if err == nil {
- tempDesc := baseOperation.Result(s.address)
descPtr = &tempDesc
- s.publishServerHeartbeatSucceededEvent(s.conn.ID(), duration, tempDesc, s.conn.getCurrentlyStreaming() || streamable)
+ s.publishServerHeartbeatSucceededEvent(s.conn.ID(), execDuration,
+ tempDesc, s.conn.getCurrentlyStreaming() || streamable)
} else {
// Close the connection here rather than below so we ensure we're not closing a connection that wasn't
// successfully created.
if s.conn != nil {
_ = s.conn.close()
}
- s.publishServerHeartbeatFailedEvent(s.conn.ID(), duration, err, s.conn.getCurrentlyStreaming() || streamable)
+ s.publishServerHeartbeatFailedEvent(s.conn.ID(), execDuration, err, s.conn.getCurrentlyStreaming() || streamable)
}
}
if descPtr != nil {
- // The check was successful. Set the average RTT and the 90th percentile RTT and return.
+ // The check was successful. Set the average RTT and return.
desc := *descPtr
- desc = desc.SetAverageRTT(s.rttMonitor.EWMA())
+ desc.AverageRTT = s.rttMonitor.EWMA()
+ desc.AverageRTTSet = true
desc.HeartbeatInterval = s.cfg.heartbeatInterval
+
return desc, nil
}
- if s.checkWasCancelled() {
+ if previousCanceled {
// If the previous check was cancelled, we don't want to clear the pool. Return a sentinel error so the caller
// will know that an actual error didn't occur.
return emptyDescription, errCheckCancelled
@@ -928,7 +1057,7 @@ func (s *Server) check() (description.Server, error) {
// be cleared, but only after the description has already been updated, so that is handled by the caller.
topologyVersion := extractTopologyVersion(err)
s.rttMonitor.reset()
- return description.NewServerFromError(s.address, err, topologyVersion), nil
+ return newServerDescriptionFromError(s.address, err, topologyVersion), nil
}
func extractTopologyVersion(err error) *description.TopologyVersion {
@@ -1049,11 +1178,10 @@ func (s *Server) publishServerHeartbeatSucceededEvent(connectionID string,
await bool,
) {
serverHeartbeatSucceeded := &event.ServerHeartbeatSucceededEvent{
- DurationNanos: duration.Nanoseconds(),
- Duration: duration,
- Reply: desc,
- ConnectionID: connectionID,
- Awaited: await,
+ Duration: duration,
+ Reply: newEventServerDescription(desc),
+ ConnectionID: connectionID,
+ Awaited: await,
}
if s != nil && s.cfg.serverMonitor != nil && s.cfg.serverMonitor.ServerHeartbeatSucceeded != nil {
@@ -1089,11 +1217,10 @@ func (s *Server) publishServerHeartbeatFailedEvent(connectionID string,
await bool,
) {
serverHeartbeatFailed := &event.ServerHeartbeatFailedEvent{
- DurationNanos: duration.Nanoseconds(),
- Duration: duration,
- Failure: err,
- ConnectionID: connectionID,
- Awaited: await,
+ Duration: duration,
+ Failure: err,
+ ConnectionID: connectionID,
+ Awaited: await,
}
if s != nil && s.cfg.serverMonitor != nil && s.cfg.serverMonitor.ServerHeartbeatFailed != nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server_options.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server_options.go
index 4504a2535..297cafc70 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server_options.go
@@ -7,18 +7,19 @@
package topology
import (
+ "sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/bsoncodec"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
-var defaultRegistry = bson.NewRegistryBuilder().Build()
+var defaultRegistry = bson.NewRegistry()
type serverConfig struct {
clock *session.ClusterClock
@@ -26,13 +27,14 @@ type serverConfig struct {
connectionOpts []ConnectionOption
appname string
heartbeatInterval time.Duration
- heartbeatTimeout time.Duration
+ connectTimeout time.Duration
serverMonitoringMode string
serverMonitor *event.ServerMonitor
- registry *bsoncodec.Registry
+ registry *bson.Registry
monitoringDisabled bool
serverAPI *driver.ServerAPIOptions
loadBalanced bool
+ driverInfo *atomic.Pointer[options.DriverInfo]
// Connection pool options.
maxConns uint64
@@ -44,10 +46,10 @@ type serverConfig struct {
poolMaintainInterval time.Duration
}
-func newServerConfig(opts ...ServerOption) *serverConfig {
+func newServerConfig(connectTimeout time.Duration, opts ...ServerOption) *serverConfig {
cfg := &serverConfig{
heartbeatInterval: 10 * time.Second,
- heartbeatTimeout: 10 * time.Second,
+ connectTimeout: connectTimeout,
registry: defaultRegistry,
}
@@ -66,8 +68,8 @@ type ServerOption func(*serverConfig)
// ServerAPIFromServerOptions will return the server API options if they have been functionally set on the ServerOption
// slice.
-func ServerAPIFromServerOptions(opts []ServerOption) *driver.ServerAPIOptions {
- return newServerConfig(opts...).serverAPI
+func ServerAPIFromServerOptions(connectTimeout time.Duration, opts []ServerOption) *driver.ServerAPIOptions {
+ return newServerConfig(connectTimeout, opts...).serverAPI
}
func withMonitoringDisabled(fn func(bool) bool) ServerOption {
@@ -97,18 +99,19 @@ func WithServerAppName(fn func(string) string) ServerOption {
}
}
-// WithHeartbeatInterval configures a server's heartbeat interval.
-func WithHeartbeatInterval(fn func(time.Duration) time.Duration) ServerOption {
+// WithDriverInfo sets at atomic pointer to the server configuration, which will
+// be used to create the "driver" section on handshake commands. An atomic
+// pointer is used so that the driver info can be updated concurrently.
+func WithDriverInfo(info *atomic.Pointer[options.DriverInfo]) ServerOption {
return func(cfg *serverConfig) {
- cfg.heartbeatInterval = fn(cfg.heartbeatInterval)
+ cfg.driverInfo = info
}
}
-// WithHeartbeatTimeout configures how long to wait for a heartbeat socket to
-// connection.
-func WithHeartbeatTimeout(fn func(time.Duration) time.Duration) ServerOption {
+// WithHeartbeatInterval configures a server's heartbeat interval.
+func WithHeartbeatInterval(fn func(time.Duration) time.Duration) ServerOption {
return func(cfg *serverConfig) {
- cfg.heartbeatTimeout = fn(cfg.heartbeatTimeout)
+ cfg.heartbeatInterval = fn(cfg.heartbeatInterval)
}
}
@@ -178,7 +181,7 @@ func WithClock(fn func(clock *session.ClusterClock) *session.ClusterClock) Serve
// WithRegistry configures the registry for the server to use when creating
// cursors.
-func WithRegistry(fn func(*bsoncodec.Registry) *bsoncodec.Registry) ServerOption {
+func WithRegistry(fn func(*bson.Registry) *bson.Registry) ServerOption {
return func(cfg *serverConfig) {
cfg.registry = fn(cfg.registry)
}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/stats.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/stats.go
new file mode 100644
index 000000000..62062de56
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/stats.go
@@ -0,0 +1,33 @@
+// Copyright (C) MongoDB, Inc. 2024-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 topology
+
+import (
+ "container/list"
+ "math"
+ "time"
+)
+
+func standardDeviationList(l *list.List) float64 {
+ if l.Len() == 0 {
+ return 0
+ }
+
+ var mean, variance float64
+ count := 0.0
+
+ for el := l.Front(); el != nil; el = el.Next() {
+ count++
+ sample := float64(el.Value.(time.Duration))
+
+ delta := sample - mean
+ mean += delta / count
+ variance += delta * (sample - mean)
+ }
+
+ return math.Sqrt(variance / count)
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_16.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_16.go
index 387f2ec04..dad53d010 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_16.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build !go1.17
-// +build !go1.17
package topology
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_17.go
similarity index 98%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_17.go
index c9822e060..8306c6c43 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_17.go
@@ -5,7 +5,6 @@
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//go:build go1.17
-// +build go1.17
package topology
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology.go
similarity index 83%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology.go
index 0fb913d21..5504595a6 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology.go
@@ -17,7 +17,7 @@
// workings of service discovery and monitoring to allow low level applications
// to have fine grained control, while hiding most of the detailed
// implementation of the algorithms.
-package topology // import "go.mongodb.org/mongo-driver/x/mongo/driver/topology"
+package topology
import (
"context"
@@ -30,16 +30,17 @@ import (
"sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/internal/randutil"
- "go.mongodb.org/mongo-driver/mongo/address"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
- "go.mongodb.org/mongo-driver/x/mongo/driver/dns"
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/driverutil"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/internal/randutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/address"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns"
)
// Topology state constants.
@@ -62,10 +63,6 @@ var ErrTopologyClosed = errors.New("topology is closed")
// already connected Topology.
var ErrTopologyConnected = errors.New("topology is connected or connecting")
-// ErrServerSelectionTimeout is returned from server selection when the server
-// selection process took longer than allowed by the timeout.
-var ErrServerSelectionTimeout = errors.New("server selection timeout")
-
// MonitorMode represents the way in which a server is monitored.
type MonitorMode uint8
@@ -117,7 +114,7 @@ type Topology struct {
serversClosed bool
servers map[address.Address]*Server
- id primitive.ObjectID
+ id bson.ObjectID
}
var (
@@ -125,18 +122,6 @@ var (
_ driver.Subscriber = &Topology{}
)
-type serverSelectionState struct {
- selector description.ServerSelector
- timeoutChan <-chan time.Time
-}
-
-func newServerSelectionState(selector description.ServerSelector, timeoutChan <-chan time.Time) serverSelectionState {
- return serverSelectionState{
- selector: selector,
- timeoutChan: timeoutChan,
- }
-}
-
// New creates a new topology. A "nil" config is interpreted as the default configuration.
func New(cfg *Config) (*Topology, error) {
if cfg == nil {
@@ -156,11 +141,11 @@ func New(cfg *Config) (*Topology, error) {
subscribers: make(map[uint64]chan description.Topology),
servers: make(map[address.Address]*Server),
dnsResolver: dns.DefaultResolver,
- id: primitive.NewObjectID(),
+ id: bson.NewObjectID(),
}
t.desc.Store(description.Topology{})
t.updateCallback = func(desc description.Server) description.Server {
- return t.apply(context.TODO(), desc)
+ return t.apply(context.Background(), desc)
}
if t.cfg.URI != "" {
@@ -182,7 +167,7 @@ func mustLogTopologyMessage(topo *Topology, level logger.Level) bool {
level, logger.ComponentTopology)
}
-func logTopologyMessage(topo *Topology, level logger.Level, msg string, keysAndValues ...interface{}) {
+func logTopologyMessage(topo *Topology, level logger.Level, msg string, keysAndValues ...any) {
topo.cfg.logger.Print(level,
logger.ComponentTopology,
msg,
@@ -233,7 +218,7 @@ func logServerSelection(
level logger.Level,
msg string,
srvSelector description.ServerSelector,
- keysAndValues ...interface{},
+ keysAndValues ...any,
) {
var srvSelectorString string
@@ -285,32 +270,6 @@ func logServerSelectionFailed(
logger.KeyFailure, err.Error())
}
-// logUnexpectedFailure is a defer-recover function for logging unexpected
-// failures encountered while maintaining a topology.
-//
-// Most topology maintenance actions, such as updating a server, should not take
-// down a client's application. This function provides a best-effort to log
-// unexpected failures. If the logger passed to this function is nil, then the
-// recovery will be silent.
-func logUnexpectedFailure(log *logger.Logger, msg string, callbacks ...func()) {
- r := recover()
- if r == nil {
- return
- }
-
- defer func() {
- for _, clbk := range callbacks {
- clbk()
- }
- }()
-
- if log == nil {
- return
- }
-
- log.Print(logger.LevelInfo, logger.ComponentTopology, fmt.Sprintf("%s: %v", msg, r))
-}
-
// Connect initializes a Topology and starts the monitoring process. This function
// must be called to properly monitor the topology.
func (t *Topology) Connect() error {
@@ -326,17 +285,17 @@ func (t *Topology) Connect() error {
// specified, in which case the initial type is Single.
if t.cfg.ReplicaSetName != "" {
t.fsm.SetName = t.cfg.ReplicaSetName
- t.fsm.Kind = description.ReplicaSetNoPrimary
+ t.fsm.Kind = description.TopologyKindReplicaSetNoPrimary
}
// A direct connection unconditionally sets the topology type to Single.
if t.cfg.Mode == SingleMode {
- t.fsm.Kind = description.Single
+ t.fsm.Kind = description.TopologyKindSingle
}
for _, a := range t.cfg.SeedList {
addr := address.Address(a).Canonicalize()
- t.fsm.Servers = append(t.fsm.Servers, description.NewDefaultServer(addr))
+ t.fsm.Servers = append(t.fsm.Servers, newServerDescriptionFromError(addr, nil, nil))
}
switch {
@@ -347,7 +306,7 @@ func (t *Topology) Connect() error {
// monitoring routines in this mode, so we have to mock state changes.
// Transition from Unknown with no servers to LoadBalanced with a single Unknown server.
- t.fsm.Kind = description.LoadBalanced
+ t.fsm.Kind = description.TopologyKindLoadBalanced
t.publishTopologyDescriptionChangedEvent(description.Topology{}, t.fsm.Topology)
addr := address.Address(t.cfg.SeedList[0]).Canonicalize()
@@ -372,12 +331,8 @@ func (t *Topology) Connect() error {
// server monitoring goroutines.
newDesc := description.Topology{
- Kind: t.fsm.Kind,
- Servers: t.fsm.Servers,
- SessionTimeoutMinutesPtr: t.fsm.SessionTimeoutMinutesPtr,
-
- // TODO(GODRIVER-2885): This field can be removed once
- // legacy SessionTimeoutMinutes is removed.
+ Kind: t.fsm.Kind,
+ Servers: t.fsm.Servers,
SessionTimeoutMinutes: t.fsm.SessionTimeoutMinutes,
}
t.desc.Store(newDesc)
@@ -450,7 +405,10 @@ func (t *Topology) Disconnect(ctx context.Context) error {
t.pollingwg.Wait()
}
- t.desc.Store(description.Topology{})
+ oldDesc := t.fsm.Topology
+ t.fsm = newFSM()
+ t.desc.Store(t.fsm.Topology)
+ t.publishTopologyDescriptionChangedEvent(oldDesc, t.fsm.Topology)
atomic.StoreInt64(&t.state, topologyDisconnected)
t.publishTopologyClosedEvent()
@@ -532,9 +490,8 @@ func (t *Topology) RequestImmediateCheck() {
t.serversLock.Unlock()
}
-// SelectServer selects a server with given a selector. SelectServer complies with the
-// server selection spec, and will time out after serverSelectionTimeout or when the
-// parent context is done.
+// SelectServer selects a server with given a selector, returning the remaining
+// computedServerSelectionTimeout.
func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelector) (driver.Server, error) {
if atomic.LoadInt64(&t.state) != topologyConnected {
if mustLogServerSelection(t, logger.LevelDebug) {
@@ -543,17 +500,9 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect
return nil, ErrTopologyClosed
}
- var ssTimeoutCh <-chan time.Time
-
- if t.cfg.ServerSelectionTimeout > 0 {
- ssTimeout := time.NewTimer(t.cfg.ServerSelectionTimeout)
- ssTimeoutCh = ssTimeout.C
- defer ssTimeout.Stop()
- }
var doneOnce bool
var sub *driver.Subscription
- selectionState := newServerSelectionState(ss, ssTimeoutCh)
// Record the start time.
startTime := time.Now()
@@ -568,7 +517,7 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect
// for the first pass, select a server from the current description.
// this improves selection speed for up-to-date topology descriptions.
- suitable, selectErr = t.selectServerFromDescription(t.Description(), selectionState)
+ suitable, selectErr = t.selectServerFromDescription(t.Description(), ss)
doneOnce = true
} else {
// if the first pass didn't select a server, the previous description did not contain a suitable server, so
@@ -586,7 +535,7 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect
defer func() { _ = t.Unsubscribe(sub) }()
}
- suitable, selectErr = t.selectServerFromSubscription(ctx, sub.Updates, selectionState)
+ suitable, selectErr = t.selectServerFromSubscription(ctx, sub.Updates, ss)
}
if selectErr != nil {
if mustLogServerSelection(t, logger.LevelDebug) {
@@ -600,10 +549,10 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect
// try again if there are no servers available
if mustLogServerSelection(t, logger.LevelInfo) {
elapsed := time.Since(startTime)
- remainingTimeMS := t.cfg.ServerSelectionTimeout - elapsed
+ remainingTime := t.cfg.ServerSelectionTimeout - elapsed
logServerSelection(ctx, t, logger.LevelInfo, logger.ServerSelectionWaiting, ss,
- logger.KeyRemainingTimeMS, remainingTimeMS.Milliseconds())
+ logger.KeyRemainingTimeMS, remainingTime.Milliseconds())
}
continue
@@ -733,20 +682,20 @@ func (t *Topology) FindServer(selected description.Server) (*SelectedServer, err
// selectServerFromSubscription loops until a topology description is available for server selection. It returns
// when the given context expires, server selection timeout is reached, or a description containing a selectable
// server is available.
-func (t *Topology) selectServerFromSubscription(ctx context.Context, subscriptionCh <-chan description.Topology,
- selectionState serverSelectionState) ([]description.Server, error) {
-
+func (t *Topology) selectServerFromSubscription(
+ ctx context.Context,
+ subscriptionCh <-chan description.Topology,
+ srvSelector description.ServerSelector,
+) ([]description.Server, error) {
current := t.Description()
for {
select {
case <-ctx.Done():
return nil, ServerSelectionError{Wrapped: ctx.Err(), Desc: current}
- case <-selectionState.timeoutChan:
- return nil, ServerSelectionError{Wrapped: ErrServerSelectionTimeout, Desc: current}
case current = <-subscriptionCh:
}
- suitable, err := t.selectServerFromDescription(current, selectionState)
+ suitable, err := t.selectServerFromDescription(current, srvSelector)
if err != nil {
return nil, err
}
@@ -759,9 +708,10 @@ func (t *Topology) selectServerFromSubscription(ctx context.Context, subscriptio
}
// selectServerFromDescription process the given topology description and returns a slice of suitable servers.
-func (t *Topology) selectServerFromDescription(desc description.Topology,
- selectionState serverSelectionState) ([]description.Server, error) {
-
+func (t *Topology) selectServerFromDescription(
+ desc description.Topology,
+ srvSelector description.ServerSelector,
+) ([]description.Server, error) {
// Unlike selectServerFromSubscription, this code path does not check ctx.Done or selectionState.timeoutChan because
// selecting a server from a description is not a blocking operation.
@@ -772,7 +722,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
// If the topology kind is LoadBalanced, the LB is the only server and it is always considered selectable. The
// selectors exported by the driver should already return the LB as a candidate, so this but this check ensures that
// the LB is always selectable even if a user of the low-level driver provides a custom selector.
- if desc.Kind == description.LoadBalanced {
+ if desc.Kind == description.TopologyKindLoadBalanced {
return desc.Servers, nil
}
@@ -788,7 +738,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
allowed[i] = desc.Servers[idx]
}
- suitable, err := selectionState.selector.SelectServer(desc, allowed)
+ suitable, err := srvSelector.SelectServer(desc, allowed)
if err != nil {
return nil, ServerSelectionError{Wrapped: err, Desc: desc}
}
@@ -798,18 +748,19 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
func (t *Topology) pollSRVRecords(hosts string) {
defer t.pollingwg.Done()
- serverConfig := newServerConfig(t.cfg.ServerOpts...)
+ serverConfig := newServerConfig(t.cfg.ConnectTimeout, t.cfg.ServerOpts...)
heartbeatInterval := serverConfig.heartbeatInterval
pollTicker := time.NewTicker(t.rescanSRVInterval)
defer pollTicker.Stop()
t.pollHeartbeatTime.Store(false)
var doneOnce bool
- defer logUnexpectedFailure(t.cfg.logger, "Encountered unexpected failure polling SRV records", func() {
- if !doneOnce {
+ defer func() {
+ // ¯\_(ツ)_/¯
+ if r := recover(); r != nil && !doneOnce {
<-t.pollingDone
}
- })
+ }()
for {
select {
@@ -819,7 +770,7 @@ func (t *Topology) pollSRVRecords(hosts string) {
return
}
topoKind := t.Description().Kind
- if !(topoKind == description.Unknown || topoKind == description.Sharded) {
+ if topoKind != description.Unknown && topoKind != description.TopologyKindSharded {
break
}
@@ -848,6 +799,38 @@ func (t *Topology) pollSRVRecords(hosts string) {
doneOnce = true
}
+// equalTopologies compares two topology descriptions and returns true if they
+// are equal.
+func equalTopologies(topo1, topo2 description.Topology) bool {
+ if topo1.Kind != topo2.Kind {
+ return false
+ }
+
+ topoServers := make(map[string]description.Server, len(topo1.Servers))
+ for _, s := range topo1.Servers {
+ topoServers[s.Addr.String()] = s
+ }
+
+ otherServers := make(map[string]description.Server, len(topo2.Servers))
+ for _, s := range topo2.Servers {
+ otherServers[s.Addr.String()] = s
+ }
+
+ if len(topoServers) != len(otherServers) {
+ return false
+ }
+
+ for _, server := range topoServers {
+ otherServer := otherServers[server.Addr.String()]
+
+ if !driverutil.EqualServers(server, otherServer) {
+ return false
+ }
+ }
+
+ return true
+}
+
func (t *Topology) processSRVResults(parsedHosts []string) bool {
t.serversLock.Lock()
defer t.serversLock.Unlock()
@@ -898,17 +881,13 @@ func (t *Topology) processSRVResults(parsedHosts []string) bool {
// store new description
newDesc := description.Topology{
- Kind: t.fsm.Kind,
- Servers: t.fsm.Servers,
- SessionTimeoutMinutesPtr: t.fsm.SessionTimeoutMinutesPtr,
-
- // TODO(GODRIVER-2885): This field can be removed once legacy
- // SessionTimeoutMinutes is removed.
+ Kind: t.fsm.Kind,
+ Servers: t.fsm.Servers,
SessionTimeoutMinutes: t.fsm.SessionTimeoutMinutes,
}
t.desc.Store(newDesc)
- if !prev.Equal(newDesc) {
+ if !equalTopologies(prev, newDesc) {
t.publishTopologyDescriptionChangedEvent(prev, newDesc)
}
@@ -939,14 +918,14 @@ func (t *Topology) apply(ctx context.Context, desc description.Server) descripti
prev := t.fsm.Topology
oldDesc := t.fsm.Servers[ind]
- if oldDesc.TopologyVersion.CompareToIncoming(desc.TopologyVersion) > 0 {
+ if driverutil.CompareTopologyVersions(oldDesc.TopologyVersion, desc.TopologyVersion) > 0 {
return oldDesc
}
var current description.Topology
current, desc = t.fsm.apply(desc)
- if !oldDesc.Equal(desc) {
+ if !driverutil.EqualServers(oldDesc, desc) {
t.publishServerDescriptionChangedEvent(oldDesc, desc)
}
@@ -969,7 +948,7 @@ func (t *Topology) apply(ctx context.Context, desc description.Server) descripti
}
t.desc.Store(current)
- if !prev.Equal(current) {
+ if !equalTopologies(prev, current) {
t.publishTopologyDescriptionChangedEvent(prev, current)
}
@@ -992,7 +971,7 @@ func (t *Topology) addServer(addr address.Address) error {
return nil
}
- svr, err := ConnectServer(addr, t.updateCallback, t.id, t.cfg.ServerOpts...)
+ svr, err := ConnectServer(addr, t.updateCallback, t.id, t.cfg.ConnectTimeout, t.cfg.ServerOpts...)
if err != nil {
return err
}
@@ -1020,8 +999,8 @@ func (t *Topology) publishServerDescriptionChangedEvent(prev description.Server,
serverDescriptionChanged := &event.ServerDescriptionChangedEvent{
Address: current.Addr,
TopologyID: t.id,
- PreviousDescription: prev,
- NewDescription: current,
+ PreviousDescription: newEventServerDescription(prev),
+ NewDescription: newEventServerDescription(current),
}
if t.cfg.ServerMonitor != nil && t.cfg.ServerMonitor.ServerDescriptionChanged != nil {
@@ -1059,8 +1038,8 @@ func (t *Topology) publishServerClosedEvent(addr address.Address) {
func (t *Topology) publishTopologyDescriptionChangedEvent(prev description.Topology, current description.Topology) {
topologyDescriptionChanged := &event.TopologyDescriptionChangedEvent{
TopologyID: t.id,
- PreviousDescription: prev,
- NewDescription: current,
+ PreviousDescription: newEventServerTopology(prev),
+ NewDescription: newEventServerTopology(current),
}
if t.cfg.ServerMonitor != nil && t.cfg.ServerMonitor.TopologyDescriptionChanged != nil {
@@ -1103,3 +1082,70 @@ func (t *Topology) publishTopologyClosedEvent() {
logTopologyMessage(t, logger.LevelDebug, logger.TopologyClosed)
}
}
+
+// GetServerSelectionTimeout returns the server selection timeout defined on
+// the client options.
+func (t *Topology) GetServerSelectionTimeout() time.Duration {
+ if t.cfg == nil {
+ return 0
+ }
+
+ return t.cfg.ServerSelectionTimeout
+}
+
+func newEventServerDescription(srv description.Server) event.ServerDescription {
+ evtSrv := event.ServerDescription{
+ Addr: srv.Addr,
+ Arbiters: srv.Arbiters,
+ Compression: srv.Compression,
+ CanonicalAddr: srv.CanonicalAddr,
+ ElectionID: srv.ElectionID,
+ IsCryptd: srv.IsCryptd,
+ HelloOK: srv.HelloOK,
+ Hosts: srv.Hosts,
+ Kind: srv.Kind.String(),
+ LastWriteTime: srv.LastWriteTime,
+ MaxBatchCount: srv.MaxBatchCount,
+ MaxDocumentSize: srv.MaxDocumentSize,
+ MaxMessageSize: srv.MaxMessageSize,
+ Members: srv.Members,
+ Passive: srv.Passive,
+ Passives: srv.Passives,
+ Primary: srv.Primary,
+ ReadOnly: srv.ReadOnly,
+ ServiceID: srv.ServiceID,
+ SessionTimeoutMinutes: srv.SessionTimeoutMinutes,
+ SetName: srv.SetName,
+ SetVersion: srv.SetVersion,
+ Tags: srv.Tags,
+ }
+
+ if srv.WireVersion != nil {
+ evtSrv.MaxWireVersion = srv.WireVersion.Max
+ evtSrv.MinWireVersion = srv.WireVersion.Min
+ }
+
+ if srv.TopologyVersion != nil {
+ evtSrv.TopologyVersionProcessID = srv.TopologyVersion.ProcessID
+ evtSrv.TopologyVersionCounter = srv.TopologyVersion.Counter
+ }
+
+ return evtSrv
+}
+
+func newEventServerTopology(topo description.Topology) event.TopologyDescription {
+ evtSrvs := make([]event.ServerDescription, len(topo.Servers))
+ for idx, srv := range topo.Servers {
+ evtSrvs[idx] = newEventServerDescription(srv)
+ }
+
+ evtTopo := event.TopologyDescription{
+ Servers: evtSrvs,
+ SetName: topo.SetName,
+ Kind: topo.Kind.String(),
+ SessionTimeoutMinutes: topo.SessionTimeoutMinutes,
+ CompatibilityErr: topo.CompatibilityErr,
+ }
+
+ return evtTopo
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology_options.go
similarity index 51%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology_options.go
index 2c0518a54..d65fdf56a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology_options.go
@@ -11,20 +11,25 @@ import (
"crypto/tls"
"fmt"
"net/http"
+ "sync/atomic"
"time"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/options"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/auth"
- "go.mongodb.org/mongo-driver/x/mongo/driver/ocsp"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
+ "go.mongodb.org/mongo-driver/v2/event"
+ "go.mongodb.org/mongo-driver/v2/internal/logger"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
)
-const defaultServerSelectionTimeout = 30 * time.Second
+const (
+ defaultServerSelectionTimeout = 30 * time.Second
+ defaultConnectionTimeout = 30 * time.Second
+)
// Config is used to construct a topology.
type Config struct {
@@ -33,6 +38,8 @@ type Config struct {
SeedList []string
ServerOpts []ServerOption
URI string
+ ConnectTimeout time.Duration
+ Timeout *time.Duration
ServerSelectionTimeout time.Duration
ServerMonitor *event.ServerMonitor
SRVMaxHosts int
@@ -41,14 +48,15 @@ type Config struct {
logger *logger.Logger
}
-// ConvertToDriverAPIOptions converts a options.ServerAPIOptions instance to a driver.ServerAPIOptions.
-func ConvertToDriverAPIOptions(s *options.ServerAPIOptions) *driver.ServerAPIOptions {
- driverOpts := driver.NewServerAPIOptions(string(s.ServerAPIVersion))
- if s.Strict != nil {
- driverOpts.SetStrict(*s.Strict)
+// ConvertToDriverAPIOptions converts a given ServerAPIOptions object from the
+// options package to a ServerAPIOptions object from the driver package.
+func ConvertToDriverAPIOptions(opts *options.ServerAPIOptions) *driver.ServerAPIOptions {
+ driverOpts := driver.NewServerAPIOptions(string(opts.ServerAPIVersion))
+ if opts.Strict != nil {
+ driverOpts.SetStrict(*opts.Strict)
}
- if s.DeprecationErrors != nil {
- driverOpts.SetDeprecationErrors(*s.DeprecationErrors)
+ if opts.DeprecationErrors != nil {
+ driverOpts.SetDeprecationErrors(*opts.DeprecationErrors)
}
return driverOpts
}
@@ -119,46 +127,90 @@ func ConvertCreds(cred *options.Credential) *driver.Cred {
}
// NewConfig will translate data from client options into a topology config for
-// building non-default deployments.
-func NewConfig(co *options.ClientOptions, clock *session.ClusterClock) (*Config, error) {
+// building non-default deployments. Server and topology options are not honored
+// if a custom deployment is used.
+func NewConfig(opts *options.ClientOptions, clock *session.ClusterClock) (*Config, error) {
var authenticator driver.Authenticator
var err error
- if co.Auth != nil {
+ if opts.Auth != nil {
authenticator, err = auth.CreateAuthenticator(
- co.Auth.AuthMechanism,
- ConvertCreds(co.Auth),
- co.HTTPClient,
+ opts.Auth.AuthMechanism,
+ ConvertCreds(opts.Auth),
+ opts.HTTPClient,
)
if err != nil {
return nil, fmt.Errorf("error creating authenticator: %w", err)
}
}
- return NewConfigWithAuthenticator(co, clock, authenticator)
+ return NewAuthenticatorConfig(authenticator,
+ WithAuthConfigClock(clock),
+ WithAuthConfigClientOptions(opts),
+ )
+}
+
+type authConfigOptions struct {
+ clock *session.ClusterClock
+ opts *options.ClientOptions
+ driverInfo *atomic.Pointer[options.DriverInfo]
+}
+
+// AuthConfigOption is a function that configures authConfigOptions.
+type AuthConfigOption func(*authConfigOptions)
+
+// WithAuthConfigClock sets the cluster clock in authConfigOptions.
+func WithAuthConfigClock(clock *session.ClusterClock) AuthConfigOption {
+ return func(co *authConfigOptions) {
+ co.clock = clock
+ }
+}
+
+// WithAuthConfigClientOptions sets the client options in authConfigOptions.
+func WithAuthConfigClientOptions(opts *options.ClientOptions) AuthConfigOption {
+ return func(co *authConfigOptions) {
+ co.opts = opts
+ }
}
-// NewConfigWithAuthenticator will translate data from client options into a
+// WithAuthConfigDriverInfo sets the driver info in authConfigOptions.
+func WithAuthConfigDriverInfo(driverInfo *atomic.Pointer[options.DriverInfo]) AuthConfigOption {
+ return func(co *authConfigOptions) {
+ co.driverInfo = driverInfo
+ }
+}
+
+// NewAuthenticatorConfig will translate data from client options into a
// topology config for building non-default deployments. Server and topology
// options are not honored if a custom deployment is used. It uses a passed in
// authenticator to authenticate the connection.
-func NewConfigWithAuthenticator(
- co *options.ClientOptions,
- clock *session.ClusterClock,
- authenticator driver.Authenticator,
-) (*Config, error) {
+func NewAuthenticatorConfig(authenticator driver.Authenticator, clientOpts ...AuthConfigOption) (*Config, error) {
+ settings := authConfigOptions{}
+ for _, apply := range clientOpts {
+ apply(&settings)
+ }
+
+ opts := settings.opts
+ clock := settings.clock
+ driverInfo := settings.driverInfo
+
var serverAPI *driver.ServerAPIOptions
- if err := co.Validate(); err != nil {
+ if err := opts.Validate(); err != nil {
return nil, err
}
var connOpts []ConnectionOption
var serverOpts []ServerOption
- cfgp := &Config{}
+ cfgp := &Config{
+ Timeout: opts.Timeout,
+ }
// Set the default "ServerSelectionTimeout" to 30 seconds.
cfgp.ServerSelectionTimeout = defaultServerSelectionTimeout
+ // Set the default "ConnectionTimeout" to 30 seconds.
+ cfgp.ConnectTimeout = defaultConnectionTimeout
+
// Set the default "SeedList" to localhost.
cfgp.SeedList = []string{"localhost:27017"}
@@ -166,36 +218,41 @@ func NewConfigWithAuthenticator(
// ServerAPIOptions need to be handled early as other client and server options below reference
// c.serverAPI and serverOpts.serverAPI.
- if co.ServerAPIOptions != nil {
- serverAPI = ConvertToDriverAPIOptions(co.ServerAPIOptions)
+ if opts.ServerAPIOptions != nil {
+ serverAPI = ConvertToDriverAPIOptions(opts.ServerAPIOptions)
serverOpts = append(serverOpts, WithServerAPI(func(*driver.ServerAPIOptions) *driver.ServerAPIOptions {
return serverAPI
}))
}
- cfgp.URI = co.GetURI()
+ cfgp.URI = opts.GetURI()
- if co.SRVServiceName != nil {
- cfgp.SRVServiceName = *co.SRVServiceName
+ if opts.SRVServiceName != nil {
+ cfgp.SRVServiceName = *opts.SRVServiceName
}
- if co.SRVMaxHosts != nil {
- cfgp.SRVMaxHosts = *co.SRVMaxHosts
+ if opts.SRVMaxHosts != nil {
+ cfgp.SRVMaxHosts = *opts.SRVMaxHosts
}
// AppName
var appName string
- if co.AppName != nil {
- appName = *co.AppName
+ if opts.AppName != nil {
+ appName = *opts.AppName
serverOpts = append(serverOpts, WithServerAppName(func(string) string {
return appName
}))
}
+
+ if driverInfo != nil {
+ serverOpts = append(serverOpts, WithDriverInfo(driverInfo))
+ }
+
// Compressors & ZlibLevel
var comps []string
- if len(co.Compressors) > 0 {
- comps = co.Compressors
+ if len(opts.Compressors) > 0 {
+ comps = opts.Compressors
connOpts = append(connOpts, WithCompressors(
func(compressors []string) []string {
@@ -207,11 +264,11 @@ func NewConfigWithAuthenticator(
switch comp {
case "zlib":
connOpts = append(connOpts, WithZlibLevel(func(*int) *int {
- return co.ZlibLevel
+ return opts.ZlibLevel
}))
case "zstd":
connOpts = append(connOpts, WithZstdLevel(func(*int) *int {
- return co.ZstdLevel
+ return opts.ZstdLevel
}))
}
}
@@ -222,158 +279,165 @@ func NewConfigWithAuthenticator(
}
var loadBalanced bool
- if co.LoadBalanced != nil {
- loadBalanced = *co.LoadBalanced
+ if opts.LoadBalanced != nil {
+ loadBalanced = *opts.LoadBalanced
}
// Handshaker
var handshaker func(driver.Handshaker) driver.Handshaker
if authenticator != nil {
- handshakeOpts := &auth.HandshakeOptions{
- AppName: appName,
- Authenticator: authenticator,
- Compressors: comps,
- ServerAPI: serverAPI,
- LoadBalanced: loadBalanced,
- ClusterClock: clock,
- }
+ handshaker = func(driver.Handshaker) driver.Handshaker {
+ handshakeOpts := &auth.HandshakeOptions{
+ AppName: appName,
+ Authenticator: authenticator,
+ Compressors: comps,
+ ServerAPI: serverAPI,
+ LoadBalanced: loadBalanced,
+ ClusterClock: clock,
+ }
- if co.Auth.AuthMechanism == "" {
- // Required for SASL mechanism negotiation during handshake
- handshakeOpts.DBUser = co.Auth.AuthSource + "." + co.Auth.Username
- }
- if co.AuthenticateToAnything != nil && *co.AuthenticateToAnything {
- // Authenticate arbiters
- handshakeOpts.PerformAuthentication = func(description.Server) bool {
- return true
+ if opts.Auth.AuthMechanism == "" {
+ // Required for SASL mechanism negotiation during handshake
+ handshakeOpts.DBUser = opts.Auth.AuthSource + "." + opts.Auth.Username
+ }
+
+ if auth, ok := optionsutil.Value(opts.Custom, "authenticateToAnything").(bool); ok && auth {
+ // Authenticate arbiters
+ handshakeOpts.PerformAuthentication = func(_ description.Server) bool {
+ return true
+ }
+ }
+
+ if driverInfo != nil {
+ if di := driverInfo.Load(); di != nil {
+ handshakeOpts.OuterLibraryName = di.Name
+ handshakeOpts.OuterLibraryVersion = di.Version
+ handshakeOpts.OuterLibraryPlatform = di.Platform
+ }
}
- }
- handshaker = func(driver.Handshaker) driver.Handshaker {
return auth.Handshaker(nil, handshakeOpts)
}
} else {
handshaker = func(driver.Handshaker) driver.Handshaker {
- return operation.NewHello().
+ op := operation.NewHello().
AppName(appName).
Compressors(comps).
ClusterClock(clock).
ServerAPI(serverAPI).
LoadBalanced(loadBalanced)
+
+ if driverInfo != nil {
+ if di := driverInfo.Load(); di != nil {
+ op = op.OuterLibraryName(di.Name).
+ OuterLibraryVersion(di.Version).
+ OuterLibraryPlatform(di.Platform)
+ }
+ }
+
+ return op
}
}
connOpts = append(connOpts, WithHandshaker(handshaker))
- // ConnectTimeout
- if co.ConnectTimeout != nil {
- serverOpts = append(serverOpts, WithHeartbeatTimeout(
- func(time.Duration) time.Duration { return *co.ConnectTimeout },
- ))
- connOpts = append(connOpts, WithConnectTimeout(
- func(time.Duration) time.Duration { return *co.ConnectTimeout },
- ))
- }
+
// Dialer
- if co.Dialer != nil {
+ if opts.Dialer != nil {
connOpts = append(connOpts, WithDialer(
- func(Dialer) Dialer { return co.Dialer },
+ func(Dialer) Dialer { return opts.Dialer },
))
}
// Direct
- if co.Direct != nil && *co.Direct {
+ if opts.Direct != nil && *opts.Direct {
cfgp.Mode = SingleMode
}
// HeartbeatInterval
- if co.HeartbeatInterval != nil {
+ if opts.HeartbeatInterval != nil {
serverOpts = append(serverOpts, WithHeartbeatInterval(
- func(time.Duration) time.Duration { return *co.HeartbeatInterval },
+ func(time.Duration) time.Duration { return *opts.HeartbeatInterval },
))
}
// Hosts
cfgp.SeedList = []string{"localhost:27017"} // default host
- if len(co.Hosts) > 0 {
- cfgp.SeedList = co.Hosts
+ if len(opts.Hosts) > 0 {
+ cfgp.SeedList = opts.Hosts
}
// MaxConIdleTime
- if co.MaxConnIdleTime != nil {
+ if opts.MaxConnIdleTime != nil {
serverOpts = append(serverOpts, WithConnectionPoolMaxIdleTime(
- func(time.Duration) time.Duration { return *co.MaxConnIdleTime },
+ func(time.Duration) time.Duration { return *opts.MaxConnIdleTime },
))
}
// MaxPoolSize
- if co.MaxPoolSize != nil {
+ if opts.MaxPoolSize != nil {
serverOpts = append(
serverOpts,
- WithMaxConnections(func(uint64) uint64 { return *co.MaxPoolSize }),
+ WithMaxConnections(func(uint64) uint64 { return *opts.MaxPoolSize }),
)
}
// MinPoolSize
- if co.MinPoolSize != nil {
+ if opts.MinPoolSize != nil {
serverOpts = append(
serverOpts,
- WithMinConnections(func(uint64) uint64 { return *co.MinPoolSize }),
+ WithMinConnections(func(uint64) uint64 { return *opts.MinPoolSize }),
)
}
// MaxConnecting
- if co.MaxConnecting != nil {
+ if opts.MaxConnecting != nil {
serverOpts = append(
serverOpts,
- WithMaxConnecting(func(uint64) uint64 { return *co.MaxConnecting }),
+ WithMaxConnecting(func(uint64) uint64 { return *opts.MaxConnecting }),
)
}
// PoolMonitor
- if co.PoolMonitor != nil {
+ if opts.PoolMonitor != nil {
serverOpts = append(
serverOpts,
- WithConnectionPoolMonitor(func(*event.PoolMonitor) *event.PoolMonitor { return co.PoolMonitor }),
+ WithConnectionPoolMonitor(func(*event.PoolMonitor) *event.PoolMonitor { return opts.PoolMonitor }),
)
}
// Monitor
- if co.Monitor != nil {
+ if opts.Monitor != nil {
connOpts = append(connOpts, WithMonitor(
- func(*event.CommandMonitor) *event.CommandMonitor { return co.Monitor },
+ func(*event.CommandMonitor) *event.CommandMonitor { return opts.Monitor },
))
}
// ServerMonitor
- if co.ServerMonitor != nil {
+ if opts.ServerMonitor != nil {
serverOpts = append(
serverOpts,
- WithServerMonitor(func(*event.ServerMonitor) *event.ServerMonitor { return co.ServerMonitor }),
+ WithServerMonitor(func(*event.ServerMonitor) *event.ServerMonitor { return opts.ServerMonitor }),
)
- cfgp.ServerMonitor = co.ServerMonitor
+ cfgp.ServerMonitor = opts.ServerMonitor
}
// ReplicaSet
- if co.ReplicaSet != nil {
- cfgp.ReplicaSetName = *co.ReplicaSet
+ if opts.ReplicaSet != nil {
+ cfgp.ReplicaSetName = *opts.ReplicaSet
}
// ServerSelectionTimeout
- if co.ServerSelectionTimeout != nil {
- cfgp.ServerSelectionTimeout = *co.ServerSelectionTimeout
+ if opts.ServerSelectionTimeout != nil {
+ cfgp.ServerSelectionTimeout = *opts.ServerSelectionTimeout
}
- // SocketTimeout
- if co.SocketTimeout != nil {
- connOpts = append(
- connOpts,
- WithReadTimeout(func(time.Duration) time.Duration { return *co.SocketTimeout }),
- WithWriteTimeout(func(time.Duration) time.Duration { return *co.SocketTimeout }),
- )
+ // ConnectionTimeout
+ if opts.ConnectTimeout != nil {
+ cfgp.ConnectTimeout = *opts.ConnectTimeout
}
// TLSConfig
- if co.TLSConfig != nil {
+ if opts.TLSConfig != nil {
connOpts = append(connOpts, WithTLSConfig(
func(*tls.Config) *tls.Config {
- return co.TLSConfig
+ return opts.TLSConfig
},
))
}
// HTTP Client
- if co.HTTPClient != nil {
+ if opts.HTTPClient != nil {
connOpts = append(connOpts, WithHTTPClient(
func(*http.Client) *http.Client {
- return co.HTTPClient
+ return opts.HTTPClient
},
))
}
@@ -386,28 +450,28 @@ func NewConfigWithAuthenticator(
)
// Disable communication with external OCSP responders.
- if co.DisableOCSPEndpointCheck != nil {
+ if opts.DisableOCSPEndpointCheck != nil {
connOpts = append(
connOpts,
- WithDisableOCSPEndpointCheck(func(bool) bool { return *co.DisableOCSPEndpointCheck }),
+ WithDisableOCSPEndpointCheck(func(bool) bool { return *opts.DisableOCSPEndpointCheck }),
)
}
// LoadBalanced
- if co.LoadBalanced != nil {
- cfgp.LoadBalanced = *co.LoadBalanced
+ if opts.LoadBalanced != nil {
+ cfgp.LoadBalanced = *opts.LoadBalanced
serverOpts = append(
serverOpts,
- WithServerLoadBalanced(func(bool) bool { return *co.LoadBalanced }),
+ WithServerLoadBalanced(func(bool) bool { return *opts.LoadBalanced }),
)
connOpts = append(
connOpts,
- WithConnectionLoadBalanced(func(bool) bool { return *co.LoadBalanced }),
+ WithConnectionLoadBalanced(func(bool) bool { return *opts.LoadBalanced }),
)
}
- lgr, err := newLogger(co.LoggerOptions)
+ lgr, err := newLogger(opts.LoggerOptions)
if err != nil {
return nil, err
}
@@ -415,7 +479,7 @@ func NewConfigWithAuthenticator(
serverOpts = append(
serverOpts,
withLogger(func() *logger.Logger { return lgr }),
- withServerMonitoringMode(co.ServerMonitoringMode),
+ withServerMonitoringMode(opts.ServerMonitoringMode),
)
cfgp.logger = lgr
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage/wiremessage.go
similarity index 84%
rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go
rename to vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage/wiremessage.go
index 424d025cf..465fad097 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage/wiremessage.go
@@ -14,12 +14,11 @@
package wiremessage
import (
- "bytes"
- "encoding/binary"
"strings"
"sync/atomic"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+ "go.mongodb.org/mongo-driver/v2/internal/binaryutil"
+ "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
)
// WireMessage represents a MongoDB wire message in binary form.
@@ -219,18 +218,18 @@ const (
// starts in dst and the updated slice.
func AppendHeaderStart(dst []byte, reqid, respto int32, opcode OpCode) (index int32, b []byte) {
index, dst = bsoncore.ReserveLength(dst)
- dst = appendi32(dst, reqid)
- dst = appendi32(dst, respto)
- dst = appendi32(dst, int32(opcode))
+ dst = binaryutil.Append32(dst, reqid)
+ dst = binaryutil.Append32(dst, respto)
+ dst = binaryutil.Append32(dst, opcode)
return index, dst
}
// AppendHeader appends a header to dst.
func AppendHeader(dst []byte, length, reqid, respto int32, opcode OpCode) []byte {
- dst = appendi32(dst, length)
- dst = appendi32(dst, reqid)
- dst = appendi32(dst, respto)
- dst = appendi32(dst, int32(opcode))
+ dst = binaryutil.Append32(dst, length)
+ dst = binaryutil.Append32(dst, reqid)
+ dst = binaryutil.Append32(dst, respto)
+ dst = binaryutil.Append32(dst, opcode)
return dst
}
@@ -240,26 +239,27 @@ func ReadHeader(src []byte) (length, requestID, responseTo int32, opcode OpCode,
return 0, 0, 0, 0, src, false
}
- length = readi32unsafe(src)
- requestID = readi32unsafe(src[4:])
- responseTo = readi32unsafe(src[8:])
- opcode = OpCode(readi32unsafe(src[12:]))
+ length, _, _ = binaryutil.ReadI32(src)
+ requestID, _, _ = binaryutil.ReadI32(src[4:])
+ responseTo, _, _ = binaryutil.ReadI32(src[8:])
+ opcodeVal, _, _ := binaryutil.ReadI32(src[12:])
+ opcode = OpCode(opcodeVal)
return length, requestID, responseTo, opcode, src[16:], true
}
// AppendQueryFlags appends the flags for an OP_QUERY wire message.
func AppendQueryFlags(dst []byte, flags QueryFlag) []byte {
- return appendi32(dst, int32(flags))
+ return binaryutil.Append32(dst, flags)
}
// AppendMsgFlags appends the flags for an OP_MSG wire message.
func AppendMsgFlags(dst []byte, flags MsgFlag) []byte {
- return appendi32(dst, int32(flags))
+ return binaryutil.Append32(dst, flags)
}
// AppendReplyFlags appends the flags for an OP_REPLY wire message.
func AppendReplyFlags(dst []byte, flags ReplyFlag) []byte {
- return appendi32(dst, int32(flags))
+ return binaryutil.Append32(dst, flags)
}
// AppendMsgSectionType appends the section type to dst.
@@ -274,37 +274,39 @@ func AppendQueryFullCollectionName(dst []byte, ns string) []byte {
// AppendQueryNumberToSkip appends the number to skip to dst.
func AppendQueryNumberToSkip(dst []byte, skip int32) []byte {
- return appendi32(dst, skip)
+ return binaryutil.Append32(dst, skip)
}
// AppendQueryNumberToReturn appends the number to return to dst.
func AppendQueryNumberToReturn(dst []byte, nor int32) []byte {
- return appendi32(dst, nor)
+ return binaryutil.Append32(dst, nor)
}
// AppendReplyCursorID appends the cursor ID to dst.
func AppendReplyCursorID(dst []byte, id int64) []byte {
- return appendi64(dst, id)
+ return binaryutil.Append64(dst, id)
}
// AppendReplyStartingFrom appends the starting from field to dst.
func AppendReplyStartingFrom(dst []byte, sf int32) []byte {
- return appendi32(dst, sf)
+ return binaryutil.Append32(dst, sf)
}
// AppendReplyNumberReturned appends the number returned to dst.
func AppendReplyNumberReturned(dst []byte, nr int32) []byte {
- return appendi32(dst, nr)
+ return binaryutil.Append32(dst, nr)
}
// AppendCompressedOriginalOpCode appends the original opcode to dst.
func AppendCompressedOriginalOpCode(dst []byte, opcode OpCode) []byte {
- return appendi32(dst, int32(opcode))
+ return binaryutil.Append32(dst, opcode)
}
// AppendCompressedUncompressedSize appends the uncompressed size of a
// compressed wiremessage to dst.
-func AppendCompressedUncompressedSize(dst []byte, size int32) []byte { return appendi32(dst, size) }
+func AppendCompressedUncompressedSize(dst []byte, size int32) []byte {
+ return binaryutil.Append32(dst, size)
+}
// AppendCompressedCompressorID appends the ID of the compressor to dst.
func AppendCompressedCompressorID(dst []byte, id CompressorID) []byte {
@@ -316,7 +318,7 @@ func AppendCompressedCompressedMessage(dst []byte, msg []byte) []byte { return a
// AppendGetMoreZero appends the zero field to dst.
func AppendGetMoreZero(dst []byte) []byte {
- return appendi32(dst, 0)
+ return binaryutil.Append32(dst, int32(0))
}
// AppendGetMoreFullCollectionName appends the fullCollectionName field to dst.
@@ -326,43 +328,46 @@ func AppendGetMoreFullCollectionName(dst []byte, ns string) []byte {
// AppendGetMoreNumberToReturn appends the numberToReturn field to dst.
func AppendGetMoreNumberToReturn(dst []byte, numToReturn int32) []byte {
- return appendi32(dst, numToReturn)
+ return binaryutil.Append32(dst, numToReturn)
}
// AppendGetMoreCursorID appends the cursorID field to dst.
func AppendGetMoreCursorID(dst []byte, cursorID int64) []byte {
- return appendi64(dst, cursorID)
+ return binaryutil.Append64(dst, cursorID)
}
// AppendKillCursorsZero appends the zero field to dst.
func AppendKillCursorsZero(dst []byte) []byte {
- return appendi32(dst, 0)
+ return binaryutil.Append32(dst, int32(0))
}
// AppendKillCursorsNumberIDs appends the numberOfCursorIDs field to dst.
func AppendKillCursorsNumberIDs(dst []byte, numIDs int32) []byte {
- return appendi32(dst, numIDs)
+ return binaryutil.Append32(dst, numIDs)
}
// AppendKillCursorsCursorIDs appends each the cursorIDs field to dst.
func AppendKillCursorsCursorIDs(dst []byte, cursors []int64) []byte {
for _, cursor := range cursors {
- dst = appendi64(dst, cursor)
+ dst = binaryutil.Append64(dst, cursor)
}
return dst
}
// ReadMsgFlags reads the OP_MSG flags from src.
func ReadMsgFlags(src []byte) (flags MsgFlag, rem []byte, ok bool) {
- i32, rem, ok := readi32(src)
+ i32, rem, ok := binaryutil.ReadI32(src)
return MsgFlag(i32), rem, ok
}
// IsMsgMoreToCome returns if the provided wire message is an OP_MSG with the more to come flag set.
func IsMsgMoreToCome(wm []byte) bool {
- return len(wm) >= 20 &&
- OpCode(readi32unsafe(wm[12:16])) == OpMsg &&
- MsgFlag(readi32unsafe(wm[16:20]))&MoreToCome == MoreToCome
+ if len(wm) < 20 {
+ return false
+ }
+ opcode, _, _ := binaryutil.ReadI32(wm[12:16])
+ flag, _, _ := binaryutil.ReadI32(wm[16:20])
+ return OpCode(opcode) == OpMsg && MsgFlag(flag)&MoreToCome == MoreToCome
}
// ReadMsgSectionType reads the section type from src.
@@ -405,8 +410,8 @@ func ReadMsgSectionDocumentSequence(src []byte) (identifier string, docs []bsonc
// ReadMsgSectionRawDocumentSequence reads an identifier and document sequence from src and returns the raw document
// sequence data.
func ReadMsgSectionRawDocumentSequence(src []byte) (identifier string, data []byte, rem []byte, ok bool) {
- length, rem, ok := readi32(src)
- if !ok || int(length) > len(src) || length-4 < 0 {
+ length, rem, ok := binaryutil.ReadI32(src)
+ if !ok || int(length) > len(src) || length < 4 {
return "", nil, src, false
}
@@ -414,7 +419,7 @@ func ReadMsgSectionRawDocumentSequence(src []byte) (identifier string, data []by
// rest will be the rest of the wire message after this document sequence.
rem, rest := rem[:length-4], rem[length-4:]
- identifier, rem, ok = readcstring(rem)
+ identifier, rem, ok = binaryutil.ReadCString(rem)
if !ok {
return "", nil, src, false
}
@@ -424,7 +429,7 @@ func ReadMsgSectionRawDocumentSequence(src []byte) (identifier string, data []by
// ReadMsgChecksum reads a checksum from src.
func ReadMsgChecksum(src []byte) (checksum uint32, rem []byte, ok bool) {
- i32, rem, ok := readi32(src)
+ i32, rem, ok := binaryutil.ReadI32(src)
return uint32(i32), rem, ok
}
@@ -433,7 +438,7 @@ func ReadMsgChecksum(src []byte) (checksum uint32, rem []byte, ok bool) {
// Deprecated: Construct wiremessages with OpMsg and use the ReadMsg* functions
// instead.
func ReadQueryFlags(src []byte) (flags QueryFlag, rem []byte, ok bool) {
- i32, rem, ok := readi32(src)
+ i32, rem, ok := binaryutil.ReadI32(src)
return QueryFlag(i32), rem, ok
}
@@ -442,7 +447,7 @@ func ReadQueryFlags(src []byte) (flags QueryFlag, rem []byte, ok bool) {
// Deprecated: Construct wiremessages with OpMsg and use the ReadMsg* functions
// instead.
func ReadQueryFullCollectionName(src []byte) (collname string, rem []byte, ok bool) {
- return readcstring(src)
+ return binaryutil.ReadCString(src)
}
// ReadQueryNumberToSkip reads the number to skip from src.
@@ -450,7 +455,7 @@ func ReadQueryFullCollectionName(src []byte) (collname string, rem []byte, ok bo
// Deprecated: Construct wiremessages with OpMsg and use the ReadMsg* functions
// instead.
func ReadQueryNumberToSkip(src []byte) (nts int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadQueryNumberToReturn reads the number to return from src.
@@ -458,7 +463,7 @@ func ReadQueryNumberToSkip(src []byte) (nts int32, rem []byte, ok bool) {
// Deprecated: Construct wiremessages with OpMsg and use the ReadMsg* functions
// instead.
func ReadQueryNumberToReturn(src []byte) (ntr int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadQueryQuery reads the query from src.
@@ -479,23 +484,23 @@ func ReadQueryReturnFieldsSelector(src []byte) (rfs bsoncore.Document, rem []byt
// ReadReplyFlags reads OP_REPLY flags from src.
func ReadReplyFlags(src []byte) (flags ReplyFlag, rem []byte, ok bool) {
- i32, rem, ok := readi32(src)
+ i32, rem, ok := binaryutil.ReadI32(src)
return ReplyFlag(i32), rem, ok
}
// ReadReplyCursorID reads a cursor ID from src.
func ReadReplyCursorID(src []byte) (cursorID int64, rem []byte, ok bool) {
- return readi64(src)
+ return binaryutil.ReadI64(src)
}
// ReadReplyStartingFrom reads the starting from src.
func ReadReplyStartingFrom(src []byte) (startingFrom int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadReplyNumberReturned reads the numbered returned from src.
func ReadReplyNumberReturned(src []byte) (numberReturned int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadReplyDocuments reads as many documents as possible from src
@@ -521,14 +526,14 @@ func ReadReplyDocument(src []byte) (doc bsoncore.Document, rem []byte, ok bool)
// ReadCompressedOriginalOpCode reads the original opcode from src.
func ReadCompressedOriginalOpCode(src []byte) (opcode OpCode, rem []byte, ok bool) {
- i32, rem, ok := readi32(src)
+ i32, rem, ok := binaryutil.ReadI32(src)
return OpCode(i32), rem, ok
}
// ReadCompressedUncompressedSize reads the uncompressed size of a
// compressed wiremessage to dst.
func ReadCompressedUncompressedSize(src []byte) (size int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadCompressedCompressorID reads the ID of the compressor to dst.
@@ -539,25 +544,14 @@ func ReadCompressedCompressorID(src []byte) (id CompressorID, rem []byte, ok boo
return CompressorID(src[0]), src[1:], true
}
-// ReadCompressedCompressedMessage reads the compressed wiremessage to dst.
-//
-// Deprecated: This function is not required by the Go Driver and will be
-// removed in the 2.0 release.
-func ReadCompressedCompressedMessage(src []byte, length int32) (msg []byte, rem []byte, ok bool) {
- if len(src) < int(length) || length < 0 {
- return nil, src, false
- }
- return src[:length], src[length:], true
-}
-
// ReadKillCursorsZero reads the zero field from src.
func ReadKillCursorsZero(src []byte) (zero int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadKillCursorsNumberIDs reads the numberOfCursorIDs field from src.
func ReadKillCursorsNumberIDs(src []byte) (numIDs int32, rem []byte, ok bool) {
- return readi32(src)
+ return binaryutil.ReadI32(src)
}
// ReadKillCursorsCursorIDs reads numIDs cursor IDs from src.
@@ -565,7 +559,7 @@ func ReadKillCursorsCursorIDs(src []byte, numIDs int32) (cursorIDs []int64, rem
var i int32
var id int64
for i = 0; i < numIDs; i++ {
- id, src, ok = readi64(src)
+ id, src, ok = binaryutil.ReadI64(src)
if !ok {
return cursorIDs, src, false
}
@@ -575,45 +569,7 @@ func ReadKillCursorsCursorIDs(src []byte, numIDs int32) (cursorIDs []int64, rem
return cursorIDs, src, true
}
-func appendi32(dst []byte, x int32) []byte {
- b := []byte{0, 0, 0, 0}
- binary.LittleEndian.PutUint32(b, uint32(x))
- return append(dst, b...)
-}
-
-func appendi64(dst []byte, x int64) []byte {
- b := []byte{0, 0, 0, 0, 0, 0, 0, 0}
- binary.LittleEndian.PutUint64(b, uint64(x))
- return append(dst, b...)
-}
-
func appendCString(b []byte, str string) []byte {
b = append(b, str...)
return append(b, 0x00)
}
-
-func readi32(src []byte) (int32, []byte, bool) {
- if len(src) < 4 {
- return 0, src, false
- }
- return readi32unsafe(src), src[4:], true
-}
-
-func readi32unsafe(src []byte) int32 {
- return int32(binary.LittleEndian.Uint32(src))
-}
-
-func readi64(src []byte) (int64, []byte, bool) {
- if len(src) < 8 {
- return 0, src, false
- }
- return int64(binary.LittleEndian.Uint64(src)), src[8:], true
-}
-
-func readcstring(src []byte) (string, []byte, bool) {
- idx := bytes.IndexByte(src, 0x00)
- if idx < 0 {
- return "", src, false
- }
- return string(src[:idx]), src[idx+1:], true
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions/options.go b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions/options.go
new file mode 100644
index 000000000..c3a0938eb
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions/options.go
@@ -0,0 +1,589 @@
+// Copyright (C) MongoDB, Inc. 2025-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 xoptions
+
+import (
+ "fmt"
+
+ "go.mongodb.org/mongo-driver/v2/bson"
+ "go.mongodb.org/mongo-driver/v2/internal/optionsutil"
+ "go.mongodb.org/mongo-driver/v2/mongo/options"
+ "go.mongodb.org/mongo-driver/v2/x/mongo/driver"
+)
+
+// SetInternalClientOptions sets internal options for ClientOptions.
+func SetInternalClientOptions(opts *options.ClientOptions, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "crypt":
+ c, ok := option.(driver.Crypt)
+ if !ok {
+ return typeErrFunc("driver.Crypt")
+ }
+ opts.Crypt = c
+ case "deployment":
+ d, ok := option.(driver.Deployment)
+ if !ok {
+ return typeErrFunc("driver.Deployment")
+ }
+ opts.Deployment = d
+ case "authenticateToAnything":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ opts.Custom = optionsutil.WithValue(opts.Custom, key, b)
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalAggregateOptions sets internal options for AggregateOptions.
+func SetInternalAggregateOptions(a *options.AggregateOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.AggregateOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalBulkWriteOptions sets internal options for BulkWriteOptions.
+func SetInternalBulkWriteOptions(a *options.BulkWriteOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.BulkWriteOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.BulkWriteOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalClientBulkWriteOptions sets internal options for ClientBulkWriteOptions.
+func SetInternalClientBulkWriteOptions(a *options.ClientBulkWriteOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ClientBulkWriteOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ClientBulkWriteOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalCountOptions sets internal options for CountOptions.
+func SetInternalCountOptions(a *options.CountOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.CountOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalCreateIndexesOptions sets internal options for CreateIndexesOptions.
+func SetInternalCreateIndexesOptions(a *options.CreateIndexesOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.CreateIndexesOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalDeleteOneOptions sets internal options for DeleteOneOptions.
+func SetInternalDeleteOneOptions(a *options.DeleteOneOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.DeleteOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalDeleteManyOptions sets internal options for DeleteManyOptions.
+func SetInternalDeleteManyOptions(a *options.DeleteManyOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.DeleteManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalDistinctOptions sets internal options for DistinctOptions.
+func SetInternalDistinctOptions(a *options.DistinctOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.DistinctOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalDropIndexesOptions sets internal options for DropIndexesOptions.
+func SetInternalDropIndexesOptions(a *options.DropIndexesOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.DropIndexesOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalEstimatedDocumentCountOptions sets internal options for EstimatedDocumentCountOptions.
+func SetInternalEstimatedDocumentCountOptions(a *options.EstimatedDocumentCountOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.EstimatedDocumentCountOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalFindOptions sets internal options for FindOptions.
+func SetInternalFindOptions(a *options.FindOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalFindOneOptions sets internal options for FindOneOptions.
+func SetInternalFindOneOptions(a *options.FindOneOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalFindOneAndDeleteOptions sets internal options for FindOneAndDeleteOptions.
+func SetInternalFindOneAndDeleteOptions(a *options.FindOneAndDeleteOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneAndDeleteOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalFindOneAndReplaceOptions sets internal options for FindOneAndReplaceOptions.
+func SetInternalFindOneAndReplaceOptions(a *options.FindOneAndReplaceOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneAndReplaceOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneAndReplaceOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalFindOneAndUpdateOptions sets internal options for FindOneAndUpdateOptions.
+func SetInternalFindOneAndUpdateOptions(a *options.FindOneAndUpdateOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneAndUpdateOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.FindOneAndUpdateOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalInsertManyOptions sets internal options for InsertManyOptions.
+func SetInternalInsertManyOptions(a *options.InsertManyOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.InsertManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.InsertManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalInsertOneOptions sets internal options for InsertOneOptions.
+func SetInternalInsertOneOptions(a *options.InsertOneOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.InsertOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.InsertOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalListCollectionsOptions sets internal options for ListCollectionsOptions.
+func SetInternalListCollectionsOptions(a *options.ListCollectionsOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ListCollectionsOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalListIndexesOptions sets internal options for ListIndexesOptions.
+func SetInternalListIndexesOptions(a *options.ListIndexesOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ListIndexesOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalReplaceOptions sets internal options for ReplaceOptions.
+func SetInternalReplaceOptions(a *options.ReplaceOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ReplaceOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.ReplaceOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalUpdateManyOptions sets internal options for UpdateManyOptions.
+func SetInternalUpdateManyOptions(a *options.UpdateManyOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.UpdateManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.UpdateManyOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
+
+// SetInternalUpdateOneOptions sets internal options for UpdateOneOptions.
+func SetInternalUpdateOneOptions(a *options.UpdateOneOptionsBuilder, key string, option any) error {
+ typeErrFunc := func(t string) error {
+ return fmt.Errorf("unexpected type for %q: %T is not %s", key, option, t)
+ }
+ switch key {
+ case "rawData":
+ b, ok := option.(bool)
+ if !ok {
+ return typeErrFunc("bool")
+ }
+ a.Opts = append(a.Opts, func(opts *options.UpdateOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
+ return nil
+ })
+ case "addCommandFields":
+ d, ok := option.(bson.D)
+ if !ok {
+ return typeErrFunc("bson.D")
+ }
+ a.Opts = append(a.Opts, func(opts *options.UpdateOneOptions) error {
+ opts.Internal = optionsutil.WithValue(opts.Internal, key, d)
+ return nil
+ })
+ default:
+ return fmt.Errorf("unsupported option: %q", key)
+ }
+ return nil
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go
deleted file mode 100644
index e35bd0cd9..000000000
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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 bsoncore
-
-import (
- "errors"
- "io"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
-)
-
-// DocumentSequenceStyle is used to represent how a document sequence is laid out in a slice of
-// bytes.
-type DocumentSequenceStyle uint32
-
-// These constants are the valid styles for a DocumentSequence.
-const (
- _ DocumentSequenceStyle = iota
- SequenceStyle
- ArrayStyle
-)
-
-// DocumentSequence represents a sequence of documents. The Style field indicates how the documents
-// are laid out inside of the Data field.
-type DocumentSequence struct {
- Style DocumentSequenceStyle
- Data []byte
- Pos int
-}
-
-// ErrCorruptedDocument is returned when a full document couldn't be read from the sequence.
-var ErrCorruptedDocument = errors.New("invalid DocumentSequence: corrupted document")
-
-// ErrNonDocument is returned when a DocumentSequence contains a non-document BSON value.
-var ErrNonDocument = errors.New("invalid DocumentSequence: a non-document value was found in sequence")
-
-// ErrInvalidDocumentSequenceStyle is returned when an unknown DocumentSequenceStyle is set on a
-// DocumentSequence.
-var ErrInvalidDocumentSequenceStyle = errors.New("invalid DocumentSequenceStyle")
-
-// DocumentCount returns the number of documents in the sequence.
-func (ds *DocumentSequence) DocumentCount() int {
- if ds == nil {
- return 0
- }
- switch ds.Style {
- case SequenceStyle:
- var count int
- var ok bool
- rem := ds.Data
- for len(rem) > 0 {
- _, rem, ok = ReadDocument(rem)
- if !ok {
- return 0
- }
- count++
- }
- return count
- case ArrayStyle:
- _, rem, ok := ReadLength(ds.Data)
- if !ok {
- return 0
- }
-
- var count int
- for len(rem) > 1 {
- _, rem, ok = ReadElement(rem)
- if !ok {
- return 0
- }
- count++
- }
- return count
- default:
- return 0
- }
-}
-
-// Empty returns true if the sequence is empty. It always returns true for unknown sequence styles.
-func (ds *DocumentSequence) Empty() bool {
- if ds == nil {
- return true
- }
-
- switch ds.Style {
- case SequenceStyle:
- return len(ds.Data) == 0
- case ArrayStyle:
- return len(ds.Data) <= 5
- default:
- return true
- }
-}
-
-// ResetIterator resets the iteration point for the Next method to the beginning of the document
-// sequence.
-func (ds *DocumentSequence) ResetIterator() {
- if ds == nil {
- return
- }
- ds.Pos = 0
-}
-
-// Documents returns a slice of the documents. If nil either the Data field is also nil or could not
-// be properly read.
-func (ds *DocumentSequence) Documents() ([]Document, error) {
- if ds == nil {
- return nil, nil
- }
- switch ds.Style {
- case SequenceStyle:
- rem := ds.Data
- var docs []Document
- var doc Document
- var ok bool
- for {
- doc, rem, ok = ReadDocument(rem)
- if !ok {
- if len(rem) == 0 {
- break
- }
- return nil, ErrCorruptedDocument
- }
- docs = append(docs, doc)
- }
- return docs, nil
- case ArrayStyle:
- if len(ds.Data) == 0 {
- return nil, nil
- }
- vals, err := Document(ds.Data).Values()
- if err != nil {
- return nil, ErrCorruptedDocument
- }
- docs := make([]Document, 0, len(vals))
- for _, v := range vals {
- if v.Type != bsontype.EmbeddedDocument {
- return nil, ErrNonDocument
- }
- docs = append(docs, v.Data)
- }
- return docs, nil
- default:
- return nil, ErrInvalidDocumentSequenceStyle
- }
-}
-
-// Next retrieves the next document from this sequence and returns it. This method will return
-// io.EOF when it has reached the end of the sequence.
-func (ds *DocumentSequence) Next() (Document, error) {
- if ds == nil || ds.Pos >= len(ds.Data) {
- return nil, io.EOF
- }
- switch ds.Style {
- case SequenceStyle:
- doc, _, ok := ReadDocument(ds.Data[ds.Pos:])
- if !ok {
- return nil, ErrCorruptedDocument
- }
- ds.Pos += len(doc)
- return doc, nil
- case ArrayStyle:
- if ds.Pos < 4 {
- if len(ds.Data) < 4 {
- return nil, ErrCorruptedDocument
- }
- ds.Pos = 4 // Skip the length of the document
- }
- if len(ds.Data[ds.Pos:]) == 1 && ds.Data[ds.Pos] == 0x00 {
- return nil, io.EOF // At the end of the document
- }
- elem, _, ok := ReadElement(ds.Data[ds.Pos:])
- if !ok {
- return nil, ErrCorruptedDocument
- }
- ds.Pos += len(elem)
- val := elem.Value()
- if val.Type != bsontype.EmbeddedDocument {
- return nil, ErrNonDocument
- }
- return val.Data, nil
- default:
- return nil, ErrInvalidDocumentSequenceStyle
- }
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbcr.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbcr.go
deleted file mode 100644
index 1861956b7..000000000
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbcr.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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 auth
-
-import (
- "context"
- "fmt"
- "io"
- "net/http"
-
- // Ignore gosec warning "Blocklisted import crypto/md5: weak cryptographic primitive". We need
- // to use MD5 here to implement the MONGODB-CR specification.
- /* #nosec G501 */
- "crypto/md5"
-
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/operation"
-)
-
-// MONGODBCR is the mechanism name for MONGODB-CR.
-//
-// The MONGODB-CR authentication mechanism is deprecated in MongoDB 3.6 and removed in
-// MongoDB 4.0.
-const MONGODBCR = "MONGODB-CR"
-
-func newMongoDBCRAuthenticator(cred *Cred, _ *http.Client) (Authenticator, error) {
- source := cred.Source
- if source == "" {
- source = "admin"
- }
- return &MongoDBCRAuthenticator{
- DB: source,
- Username: cred.Username,
- Password: cred.Password,
- }, nil
-}
-
-// MongoDBCRAuthenticator uses the MONGODB-CR algorithm to authenticate a connection.
-//
-// The MONGODB-CR authentication mechanism is deprecated in MongoDB 3.6 and removed in
-// MongoDB 4.0.
-type MongoDBCRAuthenticator struct {
- DB string
- Username string
- Password string
-}
-
-// Auth authenticates the connection.
-//
-// The MONGODB-CR authentication mechanism is deprecated in MongoDB 3.6 and removed in
-// MongoDB 4.0.
-func (a *MongoDBCRAuthenticator) Auth(ctx context.Context, cfg *Config) error {
-
- db := a.DB
- if db == "" {
- db = defaultAuthDB
- }
-
- doc := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendInt32Element(nil, "getnonce", 1))
- cmd := operation.NewCommand(doc).
- Database(db).
- Deployment(driver.SingleConnectionDeployment{cfg.Connection}).
- ClusterClock(cfg.ClusterClock).
- ServerAPI(cfg.ServerAPI)
- err := cmd.Execute(ctx)
- if err != nil {
- return newError(err, MONGODBCR)
- }
- rdr := cmd.Result()
-
- var getNonceResult struct {
- Nonce string `bson:"nonce"`
- }
-
- err = bson.Unmarshal(rdr, &getNonceResult)
- if err != nil {
- return newAuthError("unmarshal error", err)
- }
-
- doc = bsoncore.BuildDocumentFromElements(nil,
- bsoncore.AppendInt32Element(nil, "authenticate", 1),
- bsoncore.AppendStringElement(nil, "user", a.Username),
- bsoncore.AppendStringElement(nil, "nonce", getNonceResult.Nonce),
- bsoncore.AppendStringElement(nil, "key", a.createKey(getNonceResult.Nonce)),
- )
- cmd = operation.NewCommand(doc).
- Database(db).
- Deployment(driver.SingleConnectionDeployment{cfg.Connection}).
- ClusterClock(cfg.ClusterClock).
- ServerAPI(cfg.ServerAPI)
- err = cmd.Execute(ctx)
- if err != nil {
- return newError(err, MONGODBCR)
- }
-
- return nil
-}
-
-// Reauth reauthenticates the connection.
-func (a *MongoDBCRAuthenticator) Reauth(_ context.Context, _ *driver.AuthConfig) error {
- return newAuthError("MONGODB-CR does not support reauthentication", nil)
-}
-
-func (a *MongoDBCRAuthenticator) createKey(nonce string) string {
- // Ignore gosec warning "Use of weak cryptographic primitive". We need to use MD5 here to
- // implement the MONGODB-CR specification.
- /* #nosec G401 */
- h := md5.New()
-
- _, _ = io.WriteString(h, nonce)
- _, _ = io.WriteString(h, a.Username)
- _, _ = io.WriteString(h, mongoPasswordDigest(a.Username, a.Password))
- return fmt.Sprintf("%x", h.Sum(nil))
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batches.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batches.go
deleted file mode 100644
index be430afa1..000000000
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batches.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-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 driver
-
-import (
- "errors"
-
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
-
-// ErrDocumentTooLarge occurs when a document that is larger than the maximum size accepted by a
-// server is passed to an insert command.
-var ErrDocumentTooLarge = errors.New("an inserted document is too large")
-
-// Batches contains the necessary information to batch split an operation. This is only used for write
-// operations.
-type Batches struct {
- Identifier string
- Documents []bsoncore.Document
- Current []bsoncore.Document
- Ordered *bool
-}
-
-// Valid returns true if Batches contains both an identifier and the length of Documents is greater
-// than zero.
-func (b *Batches) Valid() bool { return b != nil && b.Identifier != "" && len(b.Documents) > 0 }
-
-// ClearBatch clears the Current batch. This must be called before AdvanceBatch will advance to the
-// next batch.
-func (b *Batches) ClearBatch() { b.Current = b.Current[:0] }
-
-// AdvanceBatch splits the next batch using maxCount and targetBatchSize. This method will do nothing if
-// the current batch has not been cleared. We do this so that when this is called during execute we
-// can call it without first needing to check if we already have a batch, which makes the code
-// simpler and makes retrying easier.
-// The maxDocSize parameter is used to check that any one document is not too large. If the first document is bigger
-// than targetBatchSize but smaller than maxDocSize, a batch of size 1 containing that document will be created.
-func (b *Batches) AdvanceBatch(maxCount, targetBatchSize, maxDocSize int) error {
- if len(b.Current) > 0 {
- return nil
- }
-
- if maxCount <= 0 {
- maxCount = 1
- }
-
- splitAfter := 0
- size := 0
- for i, doc := range b.Documents {
- if i == maxCount {
- break
- }
- if len(doc) > maxDocSize {
- return ErrDocumentTooLarge
- }
- if size+len(doc) > targetBatchSize {
- break
- }
-
- size += len(doc)
- splitAfter++
- }
-
- // if there are no documents, take the first one.
- // this can happen if there is a document that is smaller than maxDocSize but greater than targetBatchSize.
- if splitAfter == 0 {
- splitAfter = 1
- }
-
- b.Current, b.Documents = b.Documents[:splitAfter], b.Documents[splitAfter:]
- return nil
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_options.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_options.go
deleted file mode 100644
index d800bc8db..000000000
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_options.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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 (
- "net/http"
-
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
-
-// MongoCryptOptions specifies options to configure a MongoCrypt instance.
-type MongoCryptOptions struct {
- KmsProviders bsoncore.Document
- LocalSchemaMap map[string]bsoncore.Document
- BypassQueryAnalysis bool
- EncryptedFieldsMap map[string]bsoncore.Document
- CryptSharedLibDisabled bool
- CryptSharedLibOverridePath string
- HTTPClient *http.Client
-}
-
-// MongoCrypt creates a new MongoCryptOptions instance.
-func MongoCrypt() *MongoCryptOptions {
- return &MongoCryptOptions{}
-}
-
-// SetKmsProviders specifies the KMS providers map.
-func (mo *MongoCryptOptions) SetKmsProviders(kmsProviders bsoncore.Document) *MongoCryptOptions {
- mo.KmsProviders = kmsProviders
- return mo
-}
-
-// SetLocalSchemaMap specifies the local schema map.
-func (mo *MongoCryptOptions) SetLocalSchemaMap(localSchemaMap map[string]bsoncore.Document) *MongoCryptOptions {
- mo.LocalSchemaMap = localSchemaMap
- return mo
-}
-
-// SetBypassQueryAnalysis skips the NeedMongoMarkings state.
-func (mo *MongoCryptOptions) SetBypassQueryAnalysis(bypassQueryAnalysis bool) *MongoCryptOptions {
- mo.BypassQueryAnalysis = bypassQueryAnalysis
- return mo
-}
-
-// SetEncryptedFieldsMap specifies the encrypted fields map.
-func (mo *MongoCryptOptions) SetEncryptedFieldsMap(efcMap map[string]bsoncore.Document) *MongoCryptOptions {
- mo.EncryptedFieldsMap = efcMap
- return mo
-}
-
-// SetCryptSharedLibDisabled explicitly disables loading the crypt_shared library if set to true.
-func (mo *MongoCryptOptions) SetCryptSharedLibDisabled(disabled bool) *MongoCryptOptions {
- mo.CryptSharedLibDisabled = disabled
- return mo
-}
-
-// SetCryptSharedLibOverridePath sets the override path to the crypt_shared library file. Setting
-// an override path disables the default operating system dynamic library search path.
-func (mo *MongoCryptOptions) SetCryptSharedLibOverridePath(path string) *MongoCryptOptions {
- mo.CryptSharedLibOverridePath = path
- return mo
-}
-
-// SetHTTPClient sets the http client.
-func (mo *MongoCryptOptions) SetHTTPClient(httpClient *http.Client) *MongoCryptOptions {
- mo.HTTPClient = httpClient
- return mo
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go
deleted file mode 100644
index eea285b40..000000000
--- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2019-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 operation
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/event"
- "go.mongodb.org/mongo-driver/internal/driverutil"
- "go.mongodb.org/mongo-driver/internal/logger"
- "go.mongodb.org/mongo-driver/mongo/description"
- "go.mongodb.org/mongo-driver/mongo/writeconcern"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- "go.mongodb.org/mongo-driver/x/mongo/driver"
- "go.mongodb.org/mongo-driver/x/mongo/driver/session"
-)
-
-// Insert performs an insert operation.
-type Insert struct {
- authenticator driver.Authenticator
- bypassDocumentValidation *bool
- comment bsoncore.Value
- documents []bsoncore.Document
- ordered *bool
- session *session.Client
- clock *session.ClusterClock
- collection string
- monitor *event.CommandMonitor
- crypt driver.Crypt
- database string
- deployment driver.Deployment
- selector description.ServerSelector
- writeConcern *writeconcern.WriteConcern
- retry *driver.RetryMode
- result InsertResult
- serverAPI *driver.ServerAPIOptions
- timeout *time.Duration
- bypassEmptyTsReplacement *bool
- logger *logger.Logger
-}
-
-// InsertResult represents an insert result returned by the server.
-type InsertResult struct {
- // Number of documents successfully inserted.
- N int64
-}
-
-func buildInsertResult(response bsoncore.Document) (InsertResult, error) {
- elements, err := response.Elements()
- if err != nil {
- return InsertResult{}, err
- }
- ir := InsertResult{}
- for _, element := range elements {
- if element.Key() == "n" {
- var ok bool
- ir.N, ok = element.Value().AsInt64OK()
- if !ok {
- return ir, fmt.Errorf("response field 'n' is type int32 or int64, but received BSON type %s", element.Value().Type)
- }
- }
- }
- return ir, nil
-}
-
-// NewInsert constructs and returns a new Insert.
-func NewInsert(documents ...bsoncore.Document) *Insert {
- return &Insert{
- documents: documents,
- }
-}
-
-// Result returns the result of executing this operation.
-func (i *Insert) Result() InsertResult { return i.result }
-
-func (i *Insert) processResponse(info driver.ResponseInfo) error {
- ir, err := buildInsertResult(info.ServerResponse)
- i.result.N += ir.N
- return err
-}
-
-// Execute runs this operations and returns an error if the operation did not execute successfully.
-func (i *Insert) Execute(ctx context.Context) error {
- if i.deployment == nil {
- return errors.New("the Insert operation must have a Deployment set before Execute can be called")
- }
- batches := &driver.Batches{
- Identifier: "documents",
- Documents: i.documents,
- Ordered: i.ordered,
- }
-
- return driver.Operation{
- CommandFn: i.command,
- ProcessResponseFn: i.processResponse,
- Batches: batches,
- RetryMode: i.retry,
- Type: driver.Write,
- Client: i.session,
- Clock: i.clock,
- CommandMonitor: i.monitor,
- Crypt: i.crypt,
- Database: i.database,
- Deployment: i.deployment,
- Selector: i.selector,
- WriteConcern: i.writeConcern,
- ServerAPI: i.serverAPI,
- Timeout: i.timeout,
- Logger: i.logger,
- Name: driverutil.InsertOp,
- Authenticator: i.authenticator,
- }.Execute(ctx)
-
-}
-
-func (i *Insert) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
- dst = bsoncore.AppendStringElement(dst, "insert", i.collection)
- if i.bypassDocumentValidation != nil && (desc.WireVersion != nil && desc.WireVersion.Includes(4)) {
- dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *i.bypassDocumentValidation)
- }
- if i.comment.Type != bsontype.Type(0) {
- dst = bsoncore.AppendValueElement(dst, "comment", i.comment)
- }
- if i.ordered != nil {
- dst = bsoncore.AppendBooleanElement(dst, "ordered", *i.ordered)
- }
- if i.bypassEmptyTsReplacement != nil {
- dst = bsoncore.AppendBooleanElement(dst, "bypassEmptyTsReplacement", *i.bypassEmptyTsReplacement)
- }
- return dst, nil
-}
-
-// BypassDocumentValidation allows the operation to opt-out of document level validation. Valid
-// for server versions >= 3.2. For servers < 3.2, this setting is ignored.
-func (i *Insert) BypassDocumentValidation(bypassDocumentValidation bool) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.bypassDocumentValidation = &bypassDocumentValidation
- return i
-}
-
-// Comment sets a value to help trace an operation.
-func (i *Insert) Comment(comment bsoncore.Value) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.comment = comment
- return i
-}
-
-// Documents adds documents to this operation that will be inserted when this operation is
-// executed.
-func (i *Insert) Documents(documents ...bsoncore.Document) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.documents = documents
- return i
-}
-
-// Ordered sets ordered. If true, when a write fails, the operation will return the error, when
-// false write failures do not stop execution of the operation.
-func (i *Insert) Ordered(ordered bool) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.ordered = &ordered
- return i
-}
-
-// Session sets the session for this operation.
-func (i *Insert) Session(session *session.Client) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.session = session
- return i
-}
-
-// ClusterClock sets the cluster clock for this operation.
-func (i *Insert) ClusterClock(clock *session.ClusterClock) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.clock = clock
- return i
-}
-
-// Collection sets the collection that this command will run against.
-func (i *Insert) Collection(collection string) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.collection = collection
- return i
-}
-
-// CommandMonitor sets the monitor to use for APM events.
-func (i *Insert) CommandMonitor(monitor *event.CommandMonitor) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.monitor = monitor
- return i
-}
-
-// Crypt sets the Crypt object to use for automatic encryption and decryption.
-func (i *Insert) Crypt(crypt driver.Crypt) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.crypt = crypt
- return i
-}
-
-// Database sets the database to run this operation against.
-func (i *Insert) Database(database string) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.database = database
- return i
-}
-
-// Deployment sets the deployment to use for this operation.
-func (i *Insert) Deployment(deployment driver.Deployment) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.deployment = deployment
- return i
-}
-
-// ServerSelector sets the selector used to retrieve a server.
-func (i *Insert) ServerSelector(selector description.ServerSelector) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.selector = selector
- return i
-}
-
-// WriteConcern sets the write concern for this operation.
-func (i *Insert) WriteConcern(writeConcern *writeconcern.WriteConcern) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.writeConcern = writeConcern
- return i
-}
-
-// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based
-// on how the operation is set.
-func (i *Insert) Retry(retry driver.RetryMode) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.retry = &retry
- return i
-}
-
-// ServerAPI sets the server API version for this operation.
-func (i *Insert) ServerAPI(serverAPI *driver.ServerAPIOptions) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.serverAPI = serverAPI
- return i
-}
-
-// Timeout sets the timeout for this operation.
-func (i *Insert) Timeout(timeout *time.Duration) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.timeout = timeout
- return i
-}
-
-// Logger sets the logger for this operation.
-func (i *Insert) Logger(logger *logger.Logger) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.logger = logger
- return i
-}
-
-// Authenticator sets the authenticator to use for this operation.
-func (i *Insert) Authenticator(authenticator driver.Authenticator) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.authenticator = authenticator
- return i
-}
-
-// BypassEmptyTsReplacement sets the bypassEmptyTsReplacement to use for this operation.
-func (i *Insert) BypassEmptyTsReplacement(bypassEmptyTsReplacement bool) *Insert {
- if i == nil {
- i = new(Insert)
- }
-
- i.bypassEmptyTsReplacement = &bypassEmptyTsReplacement
- return i
-}
diff --git a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go
new file mode 100644
index 000000000..233b8b62c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go
@@ -0,0 +1,50 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import (
+ "errors"
+ "unicode/utf16"
+)
+
+// bmpString returns s encoded in UCS-2 with a zero terminator.
+func bmpString(s string) ([]byte, error) {
+ // References:
+ // https://tools.ietf.org/html/rfc7292#appendix-B.1
+ // https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
+ // - non-BMP characters are encoded in UTF 16 by using a surrogate pair of 16-bit codes
+ // EncodeRune returns 0xfffd if the rune does not need special encoding
+ // - the above RFC provides the info that BMPStrings are NULL terminated.
+
+ ret := make([]byte, 0, 2*len(s)+2)
+
+ for _, r := range s {
+ if t, _ := utf16.EncodeRune(r); t != 0xfffd {
+ return nil, errors.New("pkcs12: string contains characters that cannot be encoded in UCS-2")
+ }
+ ret = append(ret, byte(r/256), byte(r%256))
+ }
+
+ return append(ret, 0, 0), nil
+}
+
+func decodeBMPString(bmpString []byte) (string, error) {
+ if len(bmpString)%2 != 0 {
+ return "", errors.New("pkcs12: odd-length BMP string")
+ }
+
+ // strip terminator if present
+ if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 {
+ bmpString = bmpString[:l-2]
+ }
+
+ s := make([]uint16, 0, len(bmpString)/2)
+ for len(bmpString) > 0 {
+ s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1]))
+ bmpString = bmpString[2:]
+ }
+
+ return string(utf16.Decode(s)), nil
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/crypto.go b/vendor/golang.org/x/crypto/pkcs12/crypto.go
new file mode 100644
index 000000000..212538cb5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/crypto.go
@@ -0,0 +1,131 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/des"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "errors"
+
+ "golang.org/x/crypto/pkcs12/internal/rc2"
+)
+
+var (
+ oidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3})
+ oidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6})
+)
+
+// pbeCipher is an abstraction of a PKCS#12 cipher.
+type pbeCipher interface {
+ // create returns a cipher.Block given a key.
+ create(key []byte) (cipher.Block, error)
+ // deriveKey returns a key derived from the given password and salt.
+ deriveKey(salt, password []byte, iterations int) []byte
+ // deriveIV returns an IV derived from the given password and salt.
+ deriveIV(salt, password []byte, iterations int) []byte
+}
+
+type shaWithTripleDESCBC struct{}
+
+func (shaWithTripleDESCBC) create(key []byte) (cipher.Block, error) {
+ return des.NewTripleDESCipher(key)
+}
+
+func (shaWithTripleDESCBC) deriveKey(salt, password []byte, iterations int) []byte {
+ return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 24)
+}
+
+func (shaWithTripleDESCBC) deriveIV(salt, password []byte, iterations int) []byte {
+ return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8)
+}
+
+type shaWith40BitRC2CBC struct{}
+
+func (shaWith40BitRC2CBC) create(key []byte) (cipher.Block, error) {
+ return rc2.New(key, len(key)*8)
+}
+
+func (shaWith40BitRC2CBC) deriveKey(salt, password []byte, iterations int) []byte {
+ return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 5)
+}
+
+func (shaWith40BitRC2CBC) deriveIV(salt, password []byte, iterations int) []byte {
+ return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8)
+}
+
+type pbeParams struct {
+ Salt []byte
+ Iterations int
+}
+
+func pbDecrypterFor(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, int, error) {
+ var cipherType pbeCipher
+
+ switch {
+ case algorithm.Algorithm.Equal(oidPBEWithSHAAnd3KeyTripleDESCBC):
+ cipherType = shaWithTripleDESCBC{}
+ case algorithm.Algorithm.Equal(oidPBEWithSHAAnd40BitRC2CBC):
+ cipherType = shaWith40BitRC2CBC{}
+ default:
+ return nil, 0, NotImplementedError("algorithm " + algorithm.Algorithm.String() + " is not supported")
+ }
+
+ var params pbeParams
+ if err := unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil {
+ return nil, 0, err
+ }
+
+ key := cipherType.deriveKey(params.Salt, password, params.Iterations)
+ iv := cipherType.deriveIV(params.Salt, password, params.Iterations)
+
+ block, err := cipherType.create(key)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ return cipher.NewCBCDecrypter(block, iv), block.BlockSize(), nil
+}
+
+func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error) {
+ cbc, blockSize, err := pbDecrypterFor(info.Algorithm(), password)
+ if err != nil {
+ return nil, err
+ }
+
+ encrypted := info.Data()
+ if len(encrypted) == 0 {
+ return nil, errors.New("pkcs12: empty encrypted data")
+ }
+ if len(encrypted)%blockSize != 0 {
+ return nil, errors.New("pkcs12: input is not a multiple of the block size")
+ }
+ decrypted = make([]byte, len(encrypted))
+ cbc.CryptBlocks(decrypted, encrypted)
+
+ psLen := int(decrypted[len(decrypted)-1])
+ if psLen == 0 || psLen > blockSize {
+ return nil, ErrDecryption
+ }
+
+ if len(decrypted) < psLen {
+ return nil, ErrDecryption
+ }
+ ps := decrypted[len(decrypted)-psLen:]
+ decrypted = decrypted[:len(decrypted)-psLen]
+ if !bytes.Equal(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) {
+ return nil, ErrDecryption
+ }
+
+ return
+}
+
+// decryptable abstracts an object that contains ciphertext.
+type decryptable interface {
+ Algorithm() pkix.AlgorithmIdentifier
+ Data() []byte
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/errors.go b/vendor/golang.org/x/crypto/pkcs12/errors.go
new file mode 100644
index 000000000..7377ce6fb
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/errors.go
@@ -0,0 +1,23 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import "errors"
+
+var (
+ // ErrDecryption represents a failure to decrypt the input.
+ ErrDecryption = errors.New("pkcs12: decryption error, incorrect padding")
+
+ // ErrIncorrectPassword is returned when an incorrect password is detected.
+ // Usually, P12/PFX data is signed to be able to verify the password.
+ ErrIncorrectPassword = errors.New("pkcs12: decryption password incorrect")
+)
+
+// NotImplementedError indicates that the input is not currently supported.
+type NotImplementedError string
+
+func (e NotImplementedError) Error() string {
+ return "pkcs12: " + string(e)
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go
new file mode 100644
index 000000000..05de9cc2c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go
@@ -0,0 +1,268 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package rc2 implements the RC2 cipher
+/*
+https://www.ietf.org/rfc/rfc2268.txt
+http://people.csail.mit.edu/rivest/pubs/KRRR98.pdf
+
+This code is licensed under the MIT license.
+*/
+package rc2
+
+import (
+ "crypto/cipher"
+ "encoding/binary"
+ "math/bits"
+)
+
+// The rc2 block size in bytes
+const BlockSize = 8
+
+type rc2Cipher struct {
+ k [64]uint16
+}
+
+// New returns a new rc2 cipher with the given key and effective key length t1
+func New(key []byte, t1 int) (cipher.Block, error) {
+ // TODO(dgryski): error checking for key length
+ return &rc2Cipher{
+ k: expandKey(key, t1),
+ }, nil
+}
+
+func (*rc2Cipher) BlockSize() int { return BlockSize }
+
+var piTable = [256]byte{
+ 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
+ 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
+ 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
+ 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
+ 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
+ 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
+ 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
+ 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
+ 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
+ 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
+ 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
+ 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
+ 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
+ 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
+ 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
+ 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad,
+}
+
+func expandKey(key []byte, t1 int) [64]uint16 {
+
+ l := make([]byte, 128)
+ copy(l, key)
+
+ var t = len(key)
+ var t8 = (t1 + 7) / 8
+ var tm = byte(255 % uint(1<<(8+uint(t1)-8*uint(t8))))
+
+ for i := len(key); i < 128; i++ {
+ l[i] = piTable[l[i-1]+l[uint8(i-t)]]
+ }
+
+ l[128-t8] = piTable[l[128-t8]&tm]
+
+ for i := 127 - t8; i >= 0; i-- {
+ l[i] = piTable[l[i+1]^l[i+t8]]
+ }
+
+ var k [64]uint16
+
+ for i := range k {
+ k[i] = uint16(l[2*i]) + uint16(l[2*i+1])*256
+ }
+
+ return k
+}
+
+func (c *rc2Cipher) Encrypt(dst, src []byte) {
+
+ r0 := binary.LittleEndian.Uint16(src[0:])
+ r1 := binary.LittleEndian.Uint16(src[2:])
+ r2 := binary.LittleEndian.Uint16(src[4:])
+ r3 := binary.LittleEndian.Uint16(src[6:])
+
+ var j int
+
+ for j <= 16 {
+ // mix r0
+ r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
+ r0 = bits.RotateLeft16(r0, 1)
+ j++
+
+ // mix r1
+ r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
+ r1 = bits.RotateLeft16(r1, 2)
+ j++
+
+ // mix r2
+ r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
+ r2 = bits.RotateLeft16(r2, 3)
+ j++
+
+ // mix r3
+ r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
+ r3 = bits.RotateLeft16(r3, 5)
+ j++
+
+ }
+
+ r0 = r0 + c.k[r3&63]
+ r1 = r1 + c.k[r0&63]
+ r2 = r2 + c.k[r1&63]
+ r3 = r3 + c.k[r2&63]
+
+ for j <= 40 {
+ // mix r0
+ r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
+ r0 = bits.RotateLeft16(r0, 1)
+ j++
+
+ // mix r1
+ r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
+ r1 = bits.RotateLeft16(r1, 2)
+ j++
+
+ // mix r2
+ r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
+ r2 = bits.RotateLeft16(r2, 3)
+ j++
+
+ // mix r3
+ r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
+ r3 = bits.RotateLeft16(r3, 5)
+ j++
+
+ }
+
+ r0 = r0 + c.k[r3&63]
+ r1 = r1 + c.k[r0&63]
+ r2 = r2 + c.k[r1&63]
+ r3 = r3 + c.k[r2&63]
+
+ for j <= 60 {
+ // mix r0
+ r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
+ r0 = bits.RotateLeft16(r0, 1)
+ j++
+
+ // mix r1
+ r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
+ r1 = bits.RotateLeft16(r1, 2)
+ j++
+
+ // mix r2
+ r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
+ r2 = bits.RotateLeft16(r2, 3)
+ j++
+
+ // mix r3
+ r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
+ r3 = bits.RotateLeft16(r3, 5)
+ j++
+ }
+
+ binary.LittleEndian.PutUint16(dst[0:], r0)
+ binary.LittleEndian.PutUint16(dst[2:], r1)
+ binary.LittleEndian.PutUint16(dst[4:], r2)
+ binary.LittleEndian.PutUint16(dst[6:], r3)
+}
+
+func (c *rc2Cipher) Decrypt(dst, src []byte) {
+
+ r0 := binary.LittleEndian.Uint16(src[0:])
+ r1 := binary.LittleEndian.Uint16(src[2:])
+ r2 := binary.LittleEndian.Uint16(src[4:])
+ r3 := binary.LittleEndian.Uint16(src[6:])
+
+ j := 63
+
+ for j >= 44 {
+ // unmix r3
+ r3 = bits.RotateLeft16(r3, 16-5)
+ r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
+ j--
+
+ // unmix r2
+ r2 = bits.RotateLeft16(r2, 16-3)
+ r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
+ j--
+
+ // unmix r1
+ r1 = bits.RotateLeft16(r1, 16-2)
+ r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
+ j--
+
+ // unmix r0
+ r0 = bits.RotateLeft16(r0, 16-1)
+ r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
+ j--
+ }
+
+ r3 = r3 - c.k[r2&63]
+ r2 = r2 - c.k[r1&63]
+ r1 = r1 - c.k[r0&63]
+ r0 = r0 - c.k[r3&63]
+
+ for j >= 20 {
+ // unmix r3
+ r3 = bits.RotateLeft16(r3, 16-5)
+ r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
+ j--
+
+ // unmix r2
+ r2 = bits.RotateLeft16(r2, 16-3)
+ r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
+ j--
+
+ // unmix r1
+ r1 = bits.RotateLeft16(r1, 16-2)
+ r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
+ j--
+
+ // unmix r0
+ r0 = bits.RotateLeft16(r0, 16-1)
+ r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
+ j--
+
+ }
+
+ r3 = r3 - c.k[r2&63]
+ r2 = r2 - c.k[r1&63]
+ r1 = r1 - c.k[r0&63]
+ r0 = r0 - c.k[r3&63]
+
+ for j >= 0 {
+ // unmix r3
+ r3 = bits.RotateLeft16(r3, 16-5)
+ r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
+ j--
+
+ // unmix r2
+ r2 = bits.RotateLeft16(r2, 16-3)
+ r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
+ j--
+
+ // unmix r1
+ r1 = bits.RotateLeft16(r1, 16-2)
+ r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
+ j--
+
+ // unmix r0
+ r0 = bits.RotateLeft16(r0, 16-1)
+ r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
+ j--
+
+ }
+
+ binary.LittleEndian.PutUint16(dst[0:], r0)
+ binary.LittleEndian.PutUint16(dst[2:], r1)
+ binary.LittleEndian.PutUint16(dst[4:], r2)
+ binary.LittleEndian.PutUint16(dst[6:], r3)
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/mac.go b/vendor/golang.org/x/crypto/pkcs12/mac.go
new file mode 100644
index 000000000..5f38aa7de
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/mac.go
@@ -0,0 +1,45 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import (
+ "crypto/hmac"
+ "crypto/sha1"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+)
+
+type macData struct {
+ Mac digestInfo
+ MacSalt []byte
+ Iterations int `asn1:"optional,default:1"`
+}
+
+// from PKCS#7:
+type digestInfo struct {
+ Algorithm pkix.AlgorithmIdentifier
+ Digest []byte
+}
+
+var (
+ oidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26})
+)
+
+func verifyMac(macData *macData, message, password []byte) error {
+ if !macData.Mac.Algorithm.Algorithm.Equal(oidSHA1) {
+ return NotImplementedError("unknown digest algorithm: " + macData.Mac.Algorithm.Algorithm.String())
+ }
+
+ key := pbkdf(sha1Sum, 20, 64, macData.MacSalt, password, macData.Iterations, 3, 20)
+
+ mac := hmac.New(sha1.New, key)
+ mac.Write(message)
+ expectedMAC := mac.Sum(nil)
+
+ if !hmac.Equal(macData.Mac.Digest, expectedMAC) {
+ return ErrIncorrectPassword
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/pbkdf.go b/vendor/golang.org/x/crypto/pkcs12/pbkdf.go
new file mode 100644
index 000000000..5c419d41e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/pbkdf.go
@@ -0,0 +1,170 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import (
+ "bytes"
+ "crypto/sha1"
+ "math/big"
+)
+
+var (
+ one = big.NewInt(1)
+)
+
+// sha1Sum returns the SHA-1 hash of in.
+func sha1Sum(in []byte) []byte {
+ sum := sha1.Sum(in)
+ return sum[:]
+}
+
+// fillWithRepeats returns v*ceiling(len(pattern) / v) bytes consisting of
+// repeats of pattern.
+func fillWithRepeats(pattern []byte, v int) []byte {
+ if len(pattern) == 0 {
+ return nil
+ }
+ outputLen := v * ((len(pattern) + v - 1) / v)
+ return bytes.Repeat(pattern, (outputLen+len(pattern)-1)/len(pattern))[:outputLen]
+}
+
+func pbkdf(hash func([]byte) []byte, u, v int, salt, password []byte, r int, ID byte, size int) (key []byte) {
+ // implementation of https://tools.ietf.org/html/rfc7292#appendix-B.2 , RFC text verbatim in comments
+
+ // Let H be a hash function built around a compression function f:
+
+ // Z_2^u x Z_2^v -> Z_2^u
+
+ // (that is, H has a chaining variable and output of length u bits, and
+ // the message input to the compression function of H is v bits). The
+ // values for u and v are as follows:
+
+ // HASH FUNCTION VALUE u VALUE v
+ // MD2, MD5 128 512
+ // SHA-1 160 512
+ // SHA-224 224 512
+ // SHA-256 256 512
+ // SHA-384 384 1024
+ // SHA-512 512 1024
+ // SHA-512/224 224 1024
+ // SHA-512/256 256 1024
+
+ // Furthermore, let r be the iteration count.
+
+ // We assume here that u and v are both multiples of 8, as are the
+ // lengths of the password and salt strings (which we denote by p and s,
+ // respectively) and the number n of pseudorandom bits required. In
+ // addition, u and v are of course non-zero.
+
+ // For information on security considerations for MD5 [19], see [25] and
+ // [1], and on those for MD2, see [18].
+
+ // The following procedure can be used to produce pseudorandom bits for
+ // a particular "purpose" that is identified by a byte called "ID".
+ // This standard specifies 3 different values for the ID byte:
+
+ // 1. If ID=1, then the pseudorandom bits being produced are to be used
+ // as key material for performing encryption or decryption.
+
+ // 2. If ID=2, then the pseudorandom bits being produced are to be used
+ // as an IV (Initial Value) for encryption or decryption.
+
+ // 3. If ID=3, then the pseudorandom bits being produced are to be used
+ // as an integrity key for MACing.
+
+ // 1. Construct a string, D (the "diversifier"), by concatenating v/8
+ // copies of ID.
+ var D []byte
+ for i := 0; i < v; i++ {
+ D = append(D, ID)
+ }
+
+ // 2. Concatenate copies of the salt together to create a string S of
+ // length v(ceiling(s/v)) bits (the final copy of the salt may be
+ // truncated to create S). Note that if the salt is the empty
+ // string, then so is S.
+
+ S := fillWithRepeats(salt, v)
+
+ // 3. Concatenate copies of the password together to create a string P
+ // of length v(ceiling(p/v)) bits (the final copy of the password
+ // may be truncated to create P). Note that if the password is the
+ // empty string, then so is P.
+
+ P := fillWithRepeats(password, v)
+
+ // 4. Set I=S||P to be the concatenation of S and P.
+ I := append(S, P...)
+
+ // 5. Set c=ceiling(n/u).
+ c := (size + u - 1) / u
+
+ // 6. For i=1, 2, ..., c, do the following:
+ A := make([]byte, c*20)
+ var IjBuf []byte
+ for i := 0; i < c; i++ {
+ // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1,
+ // H(H(H(... H(D||I))))
+ Ai := hash(append(D, I...))
+ for j := 1; j < r; j++ {
+ Ai = hash(Ai)
+ }
+ copy(A[i*20:], Ai[:])
+
+ if i < c-1 { // skip on last iteration
+ // B. Concatenate copies of Ai to create a string B of length v
+ // bits (the final copy of Ai may be truncated to create B).
+ var B []byte
+ for len(B) < v {
+ B = append(B, Ai[:]...)
+ }
+ B = B[:v]
+
+ // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit
+ // blocks, where k=ceiling(s/v)+ceiling(p/v), modify I by
+ // setting I_j=(I_j+B+1) mod 2^v for each j.
+ {
+ Bbi := new(big.Int).SetBytes(B)
+ Ij := new(big.Int)
+
+ for j := 0; j < len(I)/v; j++ {
+ Ij.SetBytes(I[j*v : (j+1)*v])
+ Ij.Add(Ij, Bbi)
+ Ij.Add(Ij, one)
+ Ijb := Ij.Bytes()
+ // We expect Ijb to be exactly v bytes,
+ // if it is longer or shorter we must
+ // adjust it accordingly.
+ if len(Ijb) > v {
+ Ijb = Ijb[len(Ijb)-v:]
+ }
+ if len(Ijb) < v {
+ if IjBuf == nil {
+ IjBuf = make([]byte, v)
+ }
+ bytesShort := v - len(Ijb)
+ for i := 0; i < bytesShort; i++ {
+ IjBuf[i] = 0
+ }
+ copy(IjBuf[bytesShort:], Ijb)
+ Ijb = IjBuf
+ }
+ copy(I[j*v:(j+1)*v], Ijb)
+ }
+ }
+ }
+ }
+ // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom
+ // bit string, A.
+
+ // 8. Use the first n bits of A as the output of this entire process.
+ return A[:size]
+
+ // If the above process is being used to generate a DES key, the process
+ // should be used to create 64 random bits, and the key's parity bits
+ // should be set after the 64 bits have been produced. Similar concerns
+ // hold for 2-key and 3-key triple-DES keys, for CDMF keys, and for any
+ // similar keys with parity bits "built into them".
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go
new file mode 100644
index 000000000..374d9facf
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go
@@ -0,0 +1,364 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkcs12 implements some of PKCS#12.
+//
+// This implementation is distilled from [RFC 7292] and referenced documents.
+// It is intended for decoding P12/PFX-stored certificates and keys for use
+// with the crypto/tls package.
+//
+// The pkcs12 package is [frozen] and is not accepting new features.
+// If it's missing functionality you need, consider an alternative like
+// software.sslmate.com/src/go-pkcs12.
+//
+// [RFC 7292]: https://datatracker.ietf.org/doc/html/rfc7292
+// [frozen]: https://go.dev/wiki/Frozen
+package pkcs12
+
+import (
+ "crypto/ecdsa"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "encoding/hex"
+ "encoding/pem"
+ "errors"
+)
+
+var (
+ oidDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 1})
+ oidEncryptedDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 6})
+
+ oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20})
+ oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21})
+ oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1})
+
+ errUnknownAttributeOID = errors.New("pkcs12: unknown attribute OID")
+)
+
+type pfxPdu struct {
+ Version int
+ AuthSafe contentInfo
+ MacData macData `asn1:"optional"`
+}
+
+type contentInfo struct {
+ ContentType asn1.ObjectIdentifier
+ Content asn1.RawValue `asn1:"tag:0,explicit,optional"`
+}
+
+type encryptedData struct {
+ Version int
+ EncryptedContentInfo encryptedContentInfo
+}
+
+type encryptedContentInfo struct {
+ ContentType asn1.ObjectIdentifier
+ ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
+ EncryptedContent []byte `asn1:"tag:0,optional"`
+}
+
+func (i encryptedContentInfo) Algorithm() pkix.AlgorithmIdentifier {
+ return i.ContentEncryptionAlgorithm
+}
+
+func (i encryptedContentInfo) Data() []byte { return i.EncryptedContent }
+
+type safeBag struct {
+ Id asn1.ObjectIdentifier
+ Value asn1.RawValue `asn1:"tag:0,explicit"`
+ Attributes []pkcs12Attribute `asn1:"set,optional"`
+}
+
+type pkcs12Attribute struct {
+ Id asn1.ObjectIdentifier
+ Value asn1.RawValue `asn1:"set"`
+}
+
+type encryptedPrivateKeyInfo struct {
+ AlgorithmIdentifier pkix.AlgorithmIdentifier
+ EncryptedData []byte
+}
+
+func (i encryptedPrivateKeyInfo) Algorithm() pkix.AlgorithmIdentifier {
+ return i.AlgorithmIdentifier
+}
+
+func (i encryptedPrivateKeyInfo) Data() []byte {
+ return i.EncryptedData
+}
+
+// PEM block types
+const (
+ certificateType = "CERTIFICATE"
+ privateKeyType = "PRIVATE KEY"
+)
+
+// unmarshal calls asn1.Unmarshal, but also returns an error if there is any
+// trailing data after unmarshaling.
+func unmarshal(in []byte, out interface{}) error {
+ trailing, err := asn1.Unmarshal(in, out)
+ if err != nil {
+ return err
+ }
+ if len(trailing) != 0 {
+ return errors.New("pkcs12: trailing data found")
+ }
+ return nil
+}
+
+// ToPEM converts all "safe bags" contained in pfxData to PEM blocks.
+// Unknown attributes are discarded.
+//
+// Note that although the returned PEM blocks for private keys have type
+// "PRIVATE KEY", the bytes are not encoded according to PKCS #8, but according
+// to PKCS #1 for RSA keys and SEC 1 for ECDSA keys.
+func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) {
+ encodedPassword, err := bmpString(password)
+ if err != nil {
+ return nil, ErrIncorrectPassword
+ }
+
+ bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword)
+
+ if err != nil {
+ return nil, err
+ }
+
+ blocks := make([]*pem.Block, 0, len(bags))
+ for _, bag := range bags {
+ block, err := convertBag(&bag, encodedPassword)
+ if err != nil {
+ return nil, err
+ }
+ blocks = append(blocks, block)
+ }
+
+ return blocks, nil
+}
+
+func convertBag(bag *safeBag, password []byte) (*pem.Block, error) {
+ block := &pem.Block{
+ Headers: make(map[string]string),
+ }
+
+ for _, attribute := range bag.Attributes {
+ k, v, err := convertAttribute(&attribute)
+ if err == errUnknownAttributeOID {
+ continue
+ }
+ if err != nil {
+ return nil, err
+ }
+ block.Headers[k] = v
+ }
+
+ switch {
+ case bag.Id.Equal(oidCertBag):
+ block.Type = certificateType
+ certsData, err := decodeCertBag(bag.Value.Bytes)
+ if err != nil {
+ return nil, err
+ }
+ block.Bytes = certsData
+ case bag.Id.Equal(oidPKCS8ShroundedKeyBag):
+ block.Type = privateKeyType
+
+ key, err := decodePkcs8ShroudedKeyBag(bag.Value.Bytes, password)
+ if err != nil {
+ return nil, err
+ }
+
+ switch key := key.(type) {
+ case *rsa.PrivateKey:
+ block.Bytes = x509.MarshalPKCS1PrivateKey(key)
+ case *ecdsa.PrivateKey:
+ block.Bytes, err = x509.MarshalECPrivateKey(key)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, errors.New("found unknown private key type in PKCS#8 wrapping")
+ }
+ default:
+ return nil, errors.New("don't know how to convert a safe bag of type " + bag.Id.String())
+ }
+ return block, nil
+}
+
+func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error) {
+ isString := false
+
+ switch {
+ case attribute.Id.Equal(oidFriendlyName):
+ key = "friendlyName"
+ isString = true
+ case attribute.Id.Equal(oidLocalKeyID):
+ key = "localKeyId"
+ case attribute.Id.Equal(oidMicrosoftCSPName):
+ // This key is chosen to match OpenSSL.
+ key = "Microsoft CSP Name"
+ isString = true
+ default:
+ return "", "", errUnknownAttributeOID
+ }
+
+ if isString {
+ if err := unmarshal(attribute.Value.Bytes, &attribute.Value); err != nil {
+ return "", "", err
+ }
+ if value, err = decodeBMPString(attribute.Value.Bytes); err != nil {
+ return "", "", err
+ }
+ } else {
+ var id []byte
+ if err := unmarshal(attribute.Value.Bytes, &id); err != nil {
+ return "", "", err
+ }
+ value = hex.EncodeToString(id)
+ }
+
+ return key, value, nil
+}
+
+// Decode extracts a certificate and private key from pfxData. This function
+// assumes that there is only one certificate and only one private key in the
+// pfxData; if there are more use ToPEM instead.
+func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) {
+ encodedPassword, err := bmpString(password)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if len(bags) != 2 {
+ err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU")
+ return
+ }
+
+ for _, bag := range bags {
+ switch {
+ case bag.Id.Equal(oidCertBag):
+ if certificate != nil {
+ err = errors.New("pkcs12: expected exactly one certificate bag")
+ }
+
+ certsData, err := decodeCertBag(bag.Value.Bytes)
+ if err != nil {
+ return nil, nil, err
+ }
+ certs, err := x509.ParseCertificates(certsData)
+ if err != nil {
+ return nil, nil, err
+ }
+ if len(certs) != 1 {
+ err = errors.New("pkcs12: expected exactly one certificate in the certBag")
+ return nil, nil, err
+ }
+ certificate = certs[0]
+
+ case bag.Id.Equal(oidPKCS8ShroundedKeyBag):
+ if privateKey != nil {
+ err = errors.New("pkcs12: expected exactly one key bag")
+ return nil, nil, err
+ }
+
+ if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil {
+ return nil, nil, err
+ }
+ }
+ }
+
+ if certificate == nil {
+ return nil, nil, errors.New("pkcs12: certificate missing")
+ }
+ if privateKey == nil {
+ return nil, nil, errors.New("pkcs12: private key missing")
+ }
+
+ return
+}
+
+func getSafeContents(p12Data, password []byte) (bags []safeBag, updatedPassword []byte, err error) {
+ pfx := new(pfxPdu)
+ if err := unmarshal(p12Data, pfx); err != nil {
+ return nil, nil, errors.New("pkcs12: error reading P12 data: " + err.Error())
+ }
+
+ if pfx.Version != 3 {
+ return nil, nil, NotImplementedError("can only decode v3 PFX PDU's")
+ }
+
+ if !pfx.AuthSafe.ContentType.Equal(oidDataContentType) {
+ return nil, nil, NotImplementedError("only password-protected PFX is implemented")
+ }
+
+ // unmarshal the explicit bytes in the content for type 'data'
+ if err := unmarshal(pfx.AuthSafe.Content.Bytes, &pfx.AuthSafe.Content); err != nil {
+ return nil, nil, err
+ }
+
+ if len(pfx.MacData.Mac.Algorithm.Algorithm) == 0 {
+ return nil, nil, errors.New("pkcs12: no MAC in data")
+ }
+
+ if err := verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password); err != nil {
+ if err == ErrIncorrectPassword && len(password) == 2 && password[0] == 0 && password[1] == 0 {
+ // some implementations use an empty byte array
+ // for the empty string password try one more
+ // time with empty-empty password
+ password = nil
+ err = verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password)
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+
+ var authenticatedSafe []contentInfo
+ if err := unmarshal(pfx.AuthSafe.Content.Bytes, &authenticatedSafe); err != nil {
+ return nil, nil, err
+ }
+
+ if len(authenticatedSafe) != 2 {
+ return nil, nil, NotImplementedError("expected exactly two items in the authenticated safe")
+ }
+
+ for _, ci := range authenticatedSafe {
+ var data []byte
+
+ switch {
+ case ci.ContentType.Equal(oidDataContentType):
+ if err := unmarshal(ci.Content.Bytes, &data); err != nil {
+ return nil, nil, err
+ }
+ case ci.ContentType.Equal(oidEncryptedDataContentType):
+ var encryptedData encryptedData
+ if err := unmarshal(ci.Content.Bytes, &encryptedData); err != nil {
+ return nil, nil, err
+ }
+ if encryptedData.Version != 0 {
+ return nil, nil, NotImplementedError("only version 0 of EncryptedData is supported")
+ }
+ if data, err = pbDecrypt(encryptedData.EncryptedContentInfo, password); err != nil {
+ return nil, nil, err
+ }
+ default:
+ return nil, nil, NotImplementedError("only data and encryptedData content types are supported in authenticated safe")
+ }
+
+ var safeContents []safeBag
+ if err := unmarshal(data, &safeContents); err != nil {
+ return nil, nil, err
+ }
+ bags = append(bags, safeContents...)
+ }
+
+ return bags, password, nil
+}
diff --git a/vendor/golang.org/x/crypto/pkcs12/safebags.go b/vendor/golang.org/x/crypto/pkcs12/safebags.go
new file mode 100644
index 000000000..def1f7b98
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pkcs12/safebags.go
@@ -0,0 +1,57 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs12
+
+import (
+ "crypto/x509"
+ "encoding/asn1"
+ "errors"
+)
+
+var (
+ // see https://tools.ietf.org/html/rfc7292#appendix-D
+ oidCertTypeX509Certificate = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 22, 1})
+ oidPKCS8ShroundedKeyBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 2})
+ oidCertBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 3})
+)
+
+type certBag struct {
+ Id asn1.ObjectIdentifier
+ Data []byte `asn1:"tag:0,explicit"`
+}
+
+func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{}, err error) {
+ pkinfo := new(encryptedPrivateKeyInfo)
+ if err = unmarshal(asn1Data, pkinfo); err != nil {
+ return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error())
+ }
+
+ pkData, err := pbDecrypt(pkinfo, password)
+ if err != nil {
+ return nil, errors.New("pkcs12: error decrypting PKCS#8 shrouded key bag: " + err.Error())
+ }
+
+ ret := new(asn1.RawValue)
+ if err = unmarshal(pkData, ret); err != nil {
+ return nil, errors.New("pkcs12: error unmarshaling decrypted private key: " + err.Error())
+ }
+
+ if privateKey, err = x509.ParsePKCS8PrivateKey(pkData); err != nil {
+ return nil, errors.New("pkcs12: error parsing PKCS#8 private key: " + err.Error())
+ }
+
+ return privateKey, nil
+}
+
+func decodeCertBag(asn1Data []byte) (x509Certificates []byte, err error) {
+ bag := new(certBag)
+ if err := unmarshal(asn1Data, bag); err != nil {
+ return nil, errors.New("pkcs12: error decoding cert bag: " + err.Error())
+ }
+ if !bag.Id.Equal(oidCertTypeX509Certificate) {
+ return nil, NotImplementedError("only X509 certificates are supported")
+ }
+ return bag.Data, nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
deleted file mode 100644
index a4d1919a9..000000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Deprecated: this package moved to golang.org/x/term.
-package terminal
-
-import (
- "io"
-
- "golang.org/x/term"
-)
-
-// EscapeCodes contains escape sequences that can be written to the terminal in
-// order to achieve different styles of text.
-type EscapeCodes = term.EscapeCodes
-
-// Terminal contains the state for running a VT100 terminal that is capable of
-// reading lines of input.
-type Terminal = term.Terminal
-
-// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
-// a local terminal, that terminal must first have been put into raw mode.
-// prompt is a string that is written at the start of each input line (i.e.
-// "> ").
-func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
- return term.NewTerminal(c, prompt)
-}
-
-// ErrPasteIndicator may be returned from ReadLine as the error, in addition
-// to valid line data. It indicates that bracketed paste mode is enabled and
-// that the returned line consists only of pasted data. Programs may wish to
-// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = term.ErrPasteIndicator
-
-// State contains the state of a terminal.
-type State = term.State
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
- return term.IsTerminal(fd)
-}
-
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
- return term.ReadPassword(fd)
-}
-
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
- return term.MakeRaw(fd)
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, oldState *State) error {
- return term.Restore(fd, oldState)
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
- return term.GetState(fd)
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
- return term.GetSize(fd)
-}
diff --git a/vendor/golang.org/x/exp/maps/maps.go b/vendor/golang.org/x/exp/maps/maps.go
new file mode 100644
index 000000000..4a9747ef4
--- /dev/null
+++ b/vendor/golang.org/x/exp/maps/maps.go
@@ -0,0 +1,86 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package maps defines various functions useful with maps of any type.
+package maps
+
+import "maps"
+
+// Keys returns the keys of the map m.
+// The keys will be in an indeterminate order.
+//
+// The simplest true equivalent using the standard library is:
+//
+// slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m))
+func Keys[M ~map[K]V, K comparable, V any](m M) []K {
+
+ r := make([]K, 0, len(m))
+ for k := range m {
+ r = append(r, k)
+ }
+ return r
+}
+
+// Values returns the values of the map m.
+// The values will be in an indeterminate order.
+//
+// The simplest true equivalent using the standard library is:
+//
+// slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m))
+func Values[M ~map[K]V, K comparable, V any](m M) []V {
+
+ r := make([]V, 0, len(m))
+ for _, v := range m {
+ r = append(r, v)
+ }
+ return r
+}
+
+// Equal reports whether two maps contain the same key/value pairs.
+// Values are compared using ==.
+//
+//go:fix inline
+func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
+ return maps.Equal(m1, m2)
+}
+
+// EqualFunc is like Equal, but compares values using eq.
+// Keys are still compared with ==.
+//
+//go:fix inline
+func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
+ return maps.EqualFunc(m1, m2, eq)
+}
+
+// Clear removes all entries from m, leaving it empty.
+//
+//go:fix inline
+func Clear[M ~map[K]V, K comparable, V any](m M) {
+ clear(m)
+}
+
+// Clone returns a copy of m. This is a shallow clone:
+// the new keys and values are set using ordinary assignment.
+//
+//go:fix inline
+func Clone[M ~map[K]V, K comparable, V any](m M) M {
+ return maps.Clone(m)
+}
+
+// Copy copies all key/value pairs in src adding them to dst.
+// When a key in src is already present in dst,
+// the value in dst will be overwritten by the value associated
+// with the key in src.
+//
+//go:fix inline
+func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
+ maps.Copy(dst, src)
+}
+
+// DeleteFunc deletes any key/value pairs from m for which del returns true.
+//
+//go:fix inline
+func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
+ maps.DeleteFunc(m, del)
+}
diff --git a/vendor/golang.org/x/text/cases/cases.go b/vendor/golang.org/x/text/cases/cases.go
new file mode 100644
index 000000000..752cdf031
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/cases.go
@@ -0,0 +1,162 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go gen_trieval.go
+
+// Package cases provides general and language-specific case mappers.
+package cases // import "golang.org/x/text/cases"
+
+import (
+ "golang.org/x/text/language"
+ "golang.org/x/text/transform"
+)
+
+// References:
+// - Unicode Reference Manual Chapter 3.13, 4.2, and 5.18.
+// - https://www.unicode.org/reports/tr29/
+// - https://www.unicode.org/Public/6.3.0/ucd/CaseFolding.txt
+// - https://www.unicode.org/Public/6.3.0/ucd/SpecialCasing.txt
+// - https://www.unicode.org/Public/6.3.0/ucd/DerivedCoreProperties.txt
+// - https://www.unicode.org/Public/6.3.0/ucd/auxiliary/WordBreakProperty.txt
+// - https://www.unicode.org/Public/6.3.0/ucd/auxiliary/WordBreakTest.txt
+// - http://userguide.icu-project.org/transforms/casemappings
+
+// TODO:
+// - Case folding
+// - Wide and Narrow?
+// - Segmenter option for title casing.
+// - ASCII fast paths
+// - Encode Soft-Dotted property within trie somehow.
+
+// A Caser transforms given input to a certain case. It implements
+// transform.Transformer.
+//
+// A Caser may be stateful and should therefore not be shared between
+// goroutines.
+type Caser struct {
+ t transform.SpanningTransformer
+}
+
+// Bytes returns a new byte slice with the result of converting b to the case
+// form implemented by c.
+func (c Caser) Bytes(b []byte) []byte {
+ b, _, _ = transform.Bytes(c.t, b)
+ return b
+}
+
+// String returns a string with the result of transforming s to the case form
+// implemented by c.
+func (c Caser) String(s string) string {
+ s, _, _ = transform.String(c.t, s)
+ return s
+}
+
+// Reset resets the Caser to be reused for new input after a previous call to
+// Transform.
+func (c Caser) Reset() { c.t.Reset() }
+
+// Transform implements the transform.Transformer interface and transforms the
+// given input to the case form implemented by c.
+func (c Caser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ return c.t.Transform(dst, src, atEOF)
+}
+
+// Span implements the transform.SpanningTransformer interface.
+func (c Caser) Span(src []byte, atEOF bool) (n int, err error) {
+ return c.t.Span(src, atEOF)
+}
+
+// Upper returns a Caser for language-specific uppercasing.
+func Upper(t language.Tag, opts ...Option) Caser {
+ return Caser{makeUpper(t, getOpts(opts...))}
+}
+
+// Lower returns a Caser for language-specific lowercasing.
+func Lower(t language.Tag, opts ...Option) Caser {
+ return Caser{makeLower(t, getOpts(opts...))}
+}
+
+// Title returns a Caser for language-specific title casing. It uses an
+// approximation of the default Unicode Word Break algorithm.
+func Title(t language.Tag, opts ...Option) Caser {
+ return Caser{makeTitle(t, getOpts(opts...))}
+}
+
+// Fold returns a Caser that implements Unicode case folding. The returned Caser
+// is stateless and safe to use concurrently by multiple goroutines.
+//
+// Case folding does not normalize the input and may not preserve a normal form.
+// Use the collate or search package for more convenient and linguistically
+// sound comparisons. Use golang.org/x/text/secure/precis for string comparisons
+// where security aspects are a concern.
+func Fold(opts ...Option) Caser {
+ return Caser{makeFold(getOpts(opts...))}
+}
+
+// An Option is used to modify the behavior of a Caser.
+type Option func(o options) options
+
+// TODO: consider these options to take a boolean as well, like FinalSigma.
+// The advantage of using this approach is that other providers of a lower-case
+// algorithm could set different defaults by prefixing a user-provided slice
+// of options with their own. This is handy, for instance, for the precis
+// package which would override the default to not handle the Greek final sigma.
+
+var (
+ // NoLower disables the lowercasing of non-leading letters for a title
+ // caser.
+ NoLower Option = noLower
+
+ // Compact omits mappings in case folding for characters that would grow the
+ // input. (Unimplemented.)
+ Compact Option = compact
+)
+
+// TODO: option to preserve a normal form, if applicable?
+
+type options struct {
+ noLower bool
+ simple bool
+
+ // TODO: segmenter, max ignorable, alternative versions, etc.
+
+ ignoreFinalSigma bool
+}
+
+func getOpts(o ...Option) (res options) {
+ for _, f := range o {
+ res = f(res)
+ }
+ return
+}
+
+func noLower(o options) options {
+ o.noLower = true
+ return o
+}
+
+func compact(o options) options {
+ o.simple = true
+ return o
+}
+
+// HandleFinalSigma specifies whether the special handling of Greek final sigma
+// should be enabled. Unicode prescribes handling the Greek final sigma for all
+// locales, but standards like IDNA and PRECIS override this default.
+func HandleFinalSigma(enable bool) Option {
+ if enable {
+ return handleFinalSigma
+ }
+ return ignoreFinalSigma
+}
+
+func ignoreFinalSigma(o options) options {
+ o.ignoreFinalSigma = true
+ return o
+}
+
+func handleFinalSigma(o options) options {
+ o.ignoreFinalSigma = false
+ return o
+}
diff --git a/vendor/golang.org/x/text/cases/context.go b/vendor/golang.org/x/text/cases/context.go
new file mode 100644
index 000000000..e9aa9e193
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/context.go
@@ -0,0 +1,376 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cases
+
+import "golang.org/x/text/transform"
+
+// A context is used for iterating over source bytes, fetching case info and
+// writing to a destination buffer.
+//
+// Casing operations may need more than one rune of context to decide how a rune
+// should be cased. Casing implementations should call checkpoint on context
+// whenever it is known to be safe to return the runes processed so far.
+//
+// It is recommended for implementations to not allow for more than 30 case
+// ignorables as lookahead (analogous to the limit in norm) and to use state if
+// unbounded lookahead is needed for cased runes.
+type context struct {
+ dst, src []byte
+ atEOF bool
+
+ pDst int // pDst points past the last written rune in dst.
+ pSrc int // pSrc points to the start of the currently scanned rune.
+
+ // checkpoints safe to return in Transform, where nDst <= pDst and nSrc <= pSrc.
+ nDst, nSrc int
+ err error
+
+ sz int // size of current rune
+ info info // case information of currently scanned rune
+
+ // State preserved across calls to Transform.
+ isMidWord bool // false if next cased letter needs to be title-cased.
+}
+
+func (c *context) Reset() {
+ c.isMidWord = false
+}
+
+// ret returns the return values for the Transform method. It checks whether
+// there were insufficient bytes in src to complete and introduces an error
+// accordingly, if necessary.
+func (c *context) ret() (nDst, nSrc int, err error) {
+ if c.err != nil || c.nSrc == len(c.src) {
+ return c.nDst, c.nSrc, c.err
+ }
+ // This point is only reached by mappers if there was no short destination
+ // buffer. This means that the source buffer was exhausted and that c.sz was
+ // set to 0 by next.
+ if c.atEOF && c.pSrc == len(c.src) {
+ return c.pDst, c.pSrc, nil
+ }
+ return c.nDst, c.nSrc, transform.ErrShortSrc
+}
+
+// retSpan returns the return values for the Span method. It checks whether
+// there were insufficient bytes in src to complete and introduces an error
+// accordingly, if necessary.
+func (c *context) retSpan() (n int, err error) {
+ _, nSrc, err := c.ret()
+ return nSrc, err
+}
+
+// checkpoint sets the return value buffer points for Transform to the current
+// positions.
+func (c *context) checkpoint() {
+ if c.err == nil {
+ c.nDst, c.nSrc = c.pDst, c.pSrc+c.sz
+ }
+}
+
+// unreadRune causes the last rune read by next to be reread on the next
+// invocation of next. Only one unreadRune may be called after a call to next.
+func (c *context) unreadRune() {
+ c.sz = 0
+}
+
+func (c *context) next() bool {
+ c.pSrc += c.sz
+ if c.pSrc == len(c.src) || c.err != nil {
+ c.info, c.sz = 0, 0
+ return false
+ }
+ v, sz := trie.lookup(c.src[c.pSrc:])
+ c.info, c.sz = info(v), sz
+ if c.sz == 0 {
+ if c.atEOF {
+ // A zero size means we have an incomplete rune. If we are atEOF,
+ // this means it is an illegal rune, which we will consume one
+ // byte at a time.
+ c.sz = 1
+ } else {
+ c.err = transform.ErrShortSrc
+ return false
+ }
+ }
+ return true
+}
+
+// writeBytes adds bytes to dst.
+func (c *context) writeBytes(b []byte) bool {
+ if len(c.dst)-c.pDst < len(b) {
+ c.err = transform.ErrShortDst
+ return false
+ }
+ // This loop is faster than using copy.
+ for _, ch := range b {
+ c.dst[c.pDst] = ch
+ c.pDst++
+ }
+ return true
+}
+
+// writeString writes the given string to dst.
+func (c *context) writeString(s string) bool {
+ if len(c.dst)-c.pDst < len(s) {
+ c.err = transform.ErrShortDst
+ return false
+ }
+ // This loop is faster than using copy.
+ for i := 0; i < len(s); i++ {
+ c.dst[c.pDst] = s[i]
+ c.pDst++
+ }
+ return true
+}
+
+// copy writes the current rune to dst.
+func (c *context) copy() bool {
+ return c.writeBytes(c.src[c.pSrc : c.pSrc+c.sz])
+}
+
+// copyXOR copies the current rune to dst and modifies it by applying the XOR
+// pattern of the case info. It is the responsibility of the caller to ensure
+// that this is a rune with a XOR pattern defined.
+func (c *context) copyXOR() bool {
+ if !c.copy() {
+ return false
+ }
+ if c.info&xorIndexBit == 0 {
+ // Fast path for 6-bit XOR pattern, which covers most cases.
+ c.dst[c.pDst-1] ^= byte(c.info >> xorShift)
+ } else {
+ // Interpret XOR bits as an index.
+ // TODO: test performance for unrolling this loop. Verify that we have
+ // at least two bytes and at most three.
+ idx := c.info >> xorShift
+ for p := c.pDst - 1; ; p-- {
+ c.dst[p] ^= xorData[idx]
+ idx--
+ if xorData[idx] == 0 {
+ break
+ }
+ }
+ }
+ return true
+}
+
+// hasPrefix returns true if src[pSrc:] starts with the given string.
+func (c *context) hasPrefix(s string) bool {
+ b := c.src[c.pSrc:]
+ if len(b) < len(s) {
+ return false
+ }
+ for i, c := range b[:len(s)] {
+ if c != s[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// caseType returns an info with only the case bits, normalized to either
+// cLower, cUpper, cTitle or cUncased.
+func (c *context) caseType() info {
+ cm := c.info & 0x7
+ if cm < 4 {
+ return cm
+ }
+ if cm >= cXORCase {
+ // xor the last bit of the rune with the case type bits.
+ b := c.src[c.pSrc+c.sz-1]
+ return info(b&1) ^ cm&0x3
+ }
+ if cm == cIgnorableCased {
+ return cLower
+ }
+ return cUncased
+}
+
+// lower writes the lowercase version of the current rune to dst.
+func lower(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cLower {
+ return c.copy()
+ }
+ if c.info&exceptionBit == 0 {
+ return c.copyXOR()
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ offset := 2 + e[0]&lengthMask // size of header + fold string
+ if nLower := (e[1] >> lengthBits) & lengthMask; nLower != noChange {
+ return c.writeString(e[offset : offset+nLower])
+ }
+ return c.copy()
+}
+
+func isLower(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cLower {
+ return true
+ }
+ if c.info&exceptionBit == 0 {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ if nLower := (e[1] >> lengthBits) & lengthMask; nLower != noChange {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ return true
+}
+
+// upper writes the uppercase version of the current rune to dst.
+func upper(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cUpper {
+ return c.copy()
+ }
+ if c.info&exceptionBit == 0 {
+ return c.copyXOR()
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ offset := 2 + e[0]&lengthMask // size of header + fold string
+ // Get length of first special case mapping.
+ n := (e[1] >> lengthBits) & lengthMask
+ if ct == cTitle {
+ // The first special case mapping is for lower. Set n to the second.
+ if n == noChange {
+ n = 0
+ }
+ n, e = e[1]&lengthMask, e[n:]
+ }
+ if n != noChange {
+ return c.writeString(e[offset : offset+n])
+ }
+ return c.copy()
+}
+
+// isUpper writes the isUppercase version of the current rune to dst.
+func isUpper(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cUpper {
+ return true
+ }
+ if c.info&exceptionBit == 0 {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ // Get length of first special case mapping.
+ n := (e[1] >> lengthBits) & lengthMask
+ if ct == cTitle {
+ n = e[1] & lengthMask
+ }
+ if n != noChange {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ return true
+}
+
+// title writes the title case version of the current rune to dst.
+func title(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cTitle {
+ return c.copy()
+ }
+ if c.info&exceptionBit == 0 {
+ if ct == cLower {
+ return c.copyXOR()
+ }
+ return c.copy()
+ }
+ // Get the exception data.
+ e := exceptions[c.info>>exceptionShift:]
+ offset := 2 + e[0]&lengthMask // size of header + fold string
+
+ nFirst := (e[1] >> lengthBits) & lengthMask
+ if nTitle := e[1] & lengthMask; nTitle != noChange {
+ if nFirst != noChange {
+ e = e[nFirst:]
+ }
+ return c.writeString(e[offset : offset+nTitle])
+ }
+ if ct == cLower && nFirst != noChange {
+ // Use the uppercase version instead.
+ return c.writeString(e[offset : offset+nFirst])
+ }
+ // Already in correct case.
+ return c.copy()
+}
+
+// isTitle reports whether the current rune is in title case.
+func isTitle(c *context) bool {
+ ct := c.caseType()
+ if c.info&hasMappingMask == 0 || ct == cTitle {
+ return true
+ }
+ if c.info&exceptionBit == 0 {
+ if ct == cLower {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ return true
+ }
+ // Get the exception data.
+ e := exceptions[c.info>>exceptionShift:]
+ if nTitle := e[1] & lengthMask; nTitle != noChange {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ nFirst := (e[1] >> lengthBits) & lengthMask
+ if ct == cLower && nFirst != noChange {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ return true
+}
+
+// foldFull writes the foldFull version of the current rune to dst.
+func foldFull(c *context) bool {
+ if c.info&hasMappingMask == 0 {
+ return c.copy()
+ }
+ ct := c.caseType()
+ if c.info&exceptionBit == 0 {
+ if ct != cLower || c.info&inverseFoldBit != 0 {
+ return c.copyXOR()
+ }
+ return c.copy()
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ n := e[0] & lengthMask
+ if n == 0 {
+ if ct == cLower {
+ return c.copy()
+ }
+ n = (e[1] >> lengthBits) & lengthMask
+ }
+ return c.writeString(e[2 : 2+n])
+}
+
+// isFoldFull reports whether the current run is mapped to foldFull
+func isFoldFull(c *context) bool {
+ if c.info&hasMappingMask == 0 {
+ return true
+ }
+ ct := c.caseType()
+ if c.info&exceptionBit == 0 {
+ if ct != cLower || c.info&inverseFoldBit != 0 {
+ c.err = transform.ErrEndOfSpan
+ return false
+ }
+ return true
+ }
+ e := exceptions[c.info>>exceptionShift:]
+ n := e[0] & lengthMask
+ if n == 0 && ct == cLower {
+ return true
+ }
+ c.err = transform.ErrEndOfSpan
+ return false
+}
diff --git a/vendor/golang.org/x/text/cases/fold.go b/vendor/golang.org/x/text/cases/fold.go
new file mode 100644
index 000000000..85cc434fa
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/fold.go
@@ -0,0 +1,34 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cases
+
+import "golang.org/x/text/transform"
+
+type caseFolder struct{ transform.NopResetter }
+
+// caseFolder implements the Transformer interface for doing case folding.
+func (t *caseFolder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ c := context{dst: dst, src: src, atEOF: atEOF}
+ for c.next() {
+ foldFull(&c)
+ c.checkpoint()
+ }
+ return c.ret()
+}
+
+func (t *caseFolder) Span(src []byte, atEOF bool) (n int, err error) {
+ c := context{src: src, atEOF: atEOF}
+ for c.next() && isFoldFull(&c) {
+ c.checkpoint()
+ }
+ return c.retSpan()
+}
+
+func makeFold(o options) transform.SpanningTransformer {
+ // TODO: Special case folding, through option Language, Special/Turkic, or
+ // both.
+ // TODO: Implement Compact options.
+ return &caseFolder{}
+}
diff --git a/vendor/golang.org/x/text/cases/icu.go b/vendor/golang.org/x/text/cases/icu.go
new file mode 100644
index 000000000..db7c237cc
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/icu.go
@@ -0,0 +1,61 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build icu
+
+package cases
+
+// Ideally these functions would be defined in a test file, but go test doesn't
+// allow CGO in tests. The build tag should ensure either way that these
+// functions will not end up in the package.
+
+// TODO: Ensure that the correct ICU version is set.
+
+/*
+#cgo LDFLAGS: -licui18n.57 -licuuc.57
+#include
+#include
+#include
+#include
+#include
+*/
+import "C"
+
+import "unsafe"
+
+func doICU(tag, caser, input string) string {
+ err := C.UErrorCode(0)
+ loc := C.CString(tag)
+ cm := C.ucasemap_open(loc, C.uint32_t(0), &err)
+
+ buf := make([]byte, len(input)*4)
+ dst := (*C.char)(unsafe.Pointer(&buf[0]))
+ src := C.CString(input)
+
+ cn := C.int32_t(0)
+
+ switch caser {
+ case "fold":
+ cn = C.ucasemap_utf8FoldCase(cm,
+ dst, C.int32_t(len(buf)),
+ src, C.int32_t(len(input)),
+ &err)
+ case "lower":
+ cn = C.ucasemap_utf8ToLower(cm,
+ dst, C.int32_t(len(buf)),
+ src, C.int32_t(len(input)),
+ &err)
+ case "upper":
+ cn = C.ucasemap_utf8ToUpper(cm,
+ dst, C.int32_t(len(buf)),
+ src, C.int32_t(len(input)),
+ &err)
+ case "title":
+ cn = C.ucasemap_utf8ToTitle(cm,
+ dst, C.int32_t(len(buf)),
+ src, C.int32_t(len(input)),
+ &err)
+ }
+ return string(buf[:cn])
+}
diff --git a/vendor/golang.org/x/text/cases/info.go b/vendor/golang.org/x/text/cases/info.go
new file mode 100644
index 000000000..87a7c3e95
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/info.go
@@ -0,0 +1,82 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cases
+
+func (c info) cccVal() info {
+ if c&exceptionBit != 0 {
+ return info(exceptions[c>>exceptionShift]) & cccMask
+ }
+ return c & cccMask
+}
+
+func (c info) cccType() info {
+ ccc := c.cccVal()
+ if ccc <= cccZero {
+ return cccZero
+ }
+ return ccc
+}
+
+// TODO: Implement full Unicode breaking algorithm:
+// 1) Implement breaking in separate package.
+// 2) Use the breaker here.
+// 3) Compare table size and performance of using the more generic breaker.
+//
+// Note that we can extend the current algorithm to be much more accurate. This
+// only makes sense, though, if the performance and/or space penalty of using
+// the generic breaker is big. Extra data will only be needed for non-cased
+// runes, which means there are sufficient bits left in the caseType.
+// ICU prohibits breaking in such cases as well.
+
+// For the purpose of title casing we use an approximation of the Unicode Word
+// Breaking algorithm defined in Annex #29:
+// https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table.
+//
+// For our approximation, we group the Word Break types into the following
+// categories, with associated rules:
+//
+// 1) Letter:
+// ALetter, Hebrew_Letter, Numeric, ExtendNumLet, Extend, Format_FE, ZWJ.
+// Rule: Never break between consecutive runes of this category.
+//
+// 2) Mid:
+// MidLetter, MidNumLet, Single_Quote.
+// (Cf. case-ignorable: MidLetter, MidNumLet, Single_Quote or cat is Mn,
+// Me, Cf, Lm or Sk).
+// Rule: Don't break between Letter and Mid, but break between two Mids.
+//
+// 3) Break:
+// Any other category: NewLine, MidNum, CR, LF, Double_Quote, Katakana, and
+// Other.
+// These categories should always result in a break between two cased letters.
+// Rule: Always break.
+//
+// Note 1: the Katakana and MidNum categories can, in esoteric cases, result in
+// preventing a break between two cased letters. For now we will ignore this
+// (e.g. [ALetter] [ExtendNumLet] [Katakana] [ExtendNumLet] [ALetter] and
+// [ALetter] [Numeric] [MidNum] [Numeric] [ALetter].)
+//
+// Note 2: the rule for Mid is very approximate, but works in most cases. To
+// improve, we could store the categories in the trie value and use a FA to
+// manage breaks. See TODO comment above.
+//
+// Note 3: according to the spec, it is possible for the Extend category to
+// introduce breaks between other categories grouped in Letter. However, this
+// is undesirable for our purposes. ICU prevents breaks in such cases as well.
+
+// isBreak returns whether this rune should introduce a break.
+func (c info) isBreak() bool {
+ return c.cccVal() == cccBreak
+}
+
+// isLetter returns whether the rune is of break type ALetter, Hebrew_Letter,
+// Numeric, ExtendNumLet, or Extend.
+func (c info) isLetter() bool {
+ ccc := c.cccVal()
+ if ccc == cccZero {
+ return !c.isCaseIgnorable()
+ }
+ return ccc != cccBreak
+}
diff --git a/vendor/golang.org/x/text/cases/map.go b/vendor/golang.org/x/text/cases/map.go
new file mode 100644
index 000000000..0f7c6a14b
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/map.go
@@ -0,0 +1,816 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cases
+
+// This file contains the definitions of case mappings for all supported
+// languages. The rules for the language-specific tailorings were taken and
+// modified from the CLDR transform definitions in common/transforms.
+
+import (
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "golang.org/x/text/internal"
+ "golang.org/x/text/language"
+ "golang.org/x/text/transform"
+ "golang.org/x/text/unicode/norm"
+)
+
+// A mapFunc takes a context set to the current rune and writes the mapped
+// version to the same context. It may advance the context to the next rune. It
+// returns whether a checkpoint is possible: whether the pDst bytes written to
+// dst so far won't need changing as we see more source bytes.
+type mapFunc func(*context) bool
+
+// A spanFunc takes a context set to the current rune and returns whether this
+// rune would be altered when written to the output. It may advance the context
+// to the next rune. It returns whether a checkpoint is possible.
+type spanFunc func(*context) bool
+
+// maxIgnorable defines the maximum number of ignorables to consider for
+// lookahead operations.
+const maxIgnorable = 30
+
+// supported lists the language tags for which we have tailorings.
+const supported = "und af az el lt nl tr"
+
+func init() {
+ tags := []language.Tag{}
+ for _, s := range strings.Split(supported, " ") {
+ tags = append(tags, language.MustParse(s))
+ }
+ matcher = internal.NewInheritanceMatcher(tags)
+ Supported = language.NewCoverage(tags)
+}
+
+var (
+ matcher *internal.InheritanceMatcher
+
+ Supported language.Coverage
+
+ // We keep the following lists separate, instead of having a single per-
+ // language struct, to give the compiler a chance to remove unused code.
+
+ // Some uppercase mappers are stateless, so we can precompute the
+ // Transformers and save a bit on runtime allocations.
+ upperFunc = []struct {
+ upper mapFunc
+ span spanFunc
+ }{
+ {nil, nil}, // und
+ {nil, nil}, // af
+ {aztrUpper(upper), isUpper}, // az
+ {elUpper, noSpan}, // el
+ {ltUpper(upper), noSpan}, // lt
+ {nil, nil}, // nl
+ {aztrUpper(upper), isUpper}, // tr
+ }
+
+ undUpper transform.SpanningTransformer = &undUpperCaser{}
+ undLower transform.SpanningTransformer = &undLowerCaser{}
+ undLowerIgnoreSigma transform.SpanningTransformer = &undLowerIgnoreSigmaCaser{}
+
+ lowerFunc = []mapFunc{
+ nil, // und
+ nil, // af
+ aztrLower, // az
+ nil, // el
+ ltLower, // lt
+ nil, // nl
+ aztrLower, // tr
+ }
+
+ titleInfos = []struct {
+ title mapFunc
+ lower mapFunc
+ titleSpan spanFunc
+ rewrite func(*context)
+ }{
+ {title, lower, isTitle, nil}, // und
+ {title, lower, isTitle, afnlRewrite}, // af
+ {aztrUpper(title), aztrLower, isTitle, nil}, // az
+ {title, lower, isTitle, nil}, // el
+ {ltUpper(title), ltLower, noSpan, nil}, // lt
+ {nlTitle, lower, nlTitleSpan, afnlRewrite}, // nl
+ {aztrUpper(title), aztrLower, isTitle, nil}, // tr
+ }
+)
+
+func makeUpper(t language.Tag, o options) transform.SpanningTransformer {
+ _, i, _ := matcher.Match(t)
+ f := upperFunc[i].upper
+ if f == nil {
+ return undUpper
+ }
+ return &simpleCaser{f: f, span: upperFunc[i].span}
+}
+
+func makeLower(t language.Tag, o options) transform.SpanningTransformer {
+ _, i, _ := matcher.Match(t)
+ f := lowerFunc[i]
+ if f == nil {
+ if o.ignoreFinalSigma {
+ return undLowerIgnoreSigma
+ }
+ return undLower
+ }
+ if o.ignoreFinalSigma {
+ return &simpleCaser{f: f, span: isLower}
+ }
+ return &lowerCaser{
+ first: f,
+ midWord: finalSigma(f),
+ }
+}
+
+func makeTitle(t language.Tag, o options) transform.SpanningTransformer {
+ _, i, _ := matcher.Match(t)
+ x := &titleInfos[i]
+ lower := x.lower
+ if o.noLower {
+ lower = (*context).copy
+ } else if !o.ignoreFinalSigma {
+ lower = finalSigma(lower)
+ }
+ return &titleCaser{
+ title: x.title,
+ lower: lower,
+ titleSpan: x.titleSpan,
+ rewrite: x.rewrite,
+ }
+}
+
+func noSpan(c *context) bool {
+ c.err = transform.ErrEndOfSpan
+ return false
+}
+
+// TODO: consider a similar special case for the fast majority lower case. This
+// is a bit more involved so will require some more precise benchmarking to
+// justify it.
+
+type undUpperCaser struct{ transform.NopResetter }
+
+// undUpperCaser implements the Transformer interface for doing an upper case
+// mapping for the root locale (und). It eliminates the need for an allocation
+// as it prevents escaping by not using function pointers.
+func (t undUpperCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ c := context{dst: dst, src: src, atEOF: atEOF}
+ for c.next() {
+ upper(&c)
+ c.checkpoint()
+ }
+ return c.ret()
+}
+
+func (t undUpperCaser) Span(src []byte, atEOF bool) (n int, err error) {
+ c := context{src: src, atEOF: atEOF}
+ for c.next() && isUpper(&c) {
+ c.checkpoint()
+ }
+ return c.retSpan()
+}
+
+// undLowerIgnoreSigmaCaser implements the Transformer interface for doing
+// a lower case mapping for the root locale (und) ignoring final sigma
+// handling. This casing algorithm is used in some performance-critical packages
+// like secure/precis and x/net/http/idna, which warrants its special-casing.
+type undLowerIgnoreSigmaCaser struct{ transform.NopResetter }
+
+func (t undLowerIgnoreSigmaCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ c := context{dst: dst, src: src, atEOF: atEOF}
+ for c.next() && lower(&c) {
+ c.checkpoint()
+ }
+ return c.ret()
+
+}
+
+// Span implements a generic lower-casing. This is possible as isLower works
+// for all lowercasing variants. All lowercase variants only vary in how they
+// transform a non-lowercase letter. They will never change an already lowercase
+// letter. In addition, there is no state.
+func (t undLowerIgnoreSigmaCaser) Span(src []byte, atEOF bool) (n int, err error) {
+ c := context{src: src, atEOF: atEOF}
+ for c.next() && isLower(&c) {
+ c.checkpoint()
+ }
+ return c.retSpan()
+}
+
+type simpleCaser struct {
+ context
+ f mapFunc
+ span spanFunc
+}
+
+// simpleCaser implements the Transformer interface for doing a case operation
+// on a rune-by-rune basis.
+func (t *simpleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ c := context{dst: dst, src: src, atEOF: atEOF}
+ for c.next() && t.f(&c) {
+ c.checkpoint()
+ }
+ return c.ret()
+}
+
+func (t *simpleCaser) Span(src []byte, atEOF bool) (n int, err error) {
+ c := context{src: src, atEOF: atEOF}
+ for c.next() && t.span(&c) {
+ c.checkpoint()
+ }
+ return c.retSpan()
+}
+
+// undLowerCaser implements the Transformer interface for doing a lower case
+// mapping for the root locale (und) ignoring final sigma handling. This casing
+// algorithm is used in some performance-critical packages like secure/precis
+// and x/net/http/idna, which warrants its special-casing.
+type undLowerCaser struct{ transform.NopResetter }
+
+func (t undLowerCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ c := context{dst: dst, src: src, atEOF: atEOF}
+
+ for isInterWord := true; c.next(); {
+ if isInterWord {
+ if c.info.isCased() {
+ if !lower(&c) {
+ break
+ }
+ isInterWord = false
+ } else if !c.copy() {
+ break
+ }
+ } else {
+ if c.info.isNotCasedAndNotCaseIgnorable() {
+ if !c.copy() {
+ break
+ }
+ isInterWord = true
+ } else if !c.hasPrefix("Σ") {
+ if !lower(&c) {
+ break
+ }
+ } else if !finalSigmaBody(&c) {
+ break
+ }
+ }
+ c.checkpoint()
+ }
+ return c.ret()
+}
+
+func (t undLowerCaser) Span(src []byte, atEOF bool) (n int, err error) {
+ c := context{src: src, atEOF: atEOF}
+ for c.next() && isLower(&c) {
+ c.checkpoint()
+ }
+ return c.retSpan()
+}
+
+// lowerCaser implements the Transformer interface. The default Unicode lower
+// casing requires different treatment for the first and subsequent characters
+// of a word, most notably to handle the Greek final Sigma.
+type lowerCaser struct {
+ undLowerIgnoreSigmaCaser
+
+ context
+
+ first, midWord mapFunc
+}
+
+func (t *lowerCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ t.context = context{dst: dst, src: src, atEOF: atEOF}
+ c := &t.context
+
+ for isInterWord := true; c.next(); {
+ if isInterWord {
+ if c.info.isCased() {
+ if !t.first(c) {
+ break
+ }
+ isInterWord = false
+ } else if !c.copy() {
+ break
+ }
+ } else {
+ if c.info.isNotCasedAndNotCaseIgnorable() {
+ if !c.copy() {
+ break
+ }
+ isInterWord = true
+ } else if !t.midWord(c) {
+ break
+ }
+ }
+ c.checkpoint()
+ }
+ return c.ret()
+}
+
+// titleCaser implements the Transformer interface. Title casing algorithms
+// distinguish between the first letter of a word and subsequent letters of the
+// same word. It uses state to avoid requiring a potentially infinite lookahead.
+type titleCaser struct {
+ context
+
+ // rune mappings used by the actual casing algorithms.
+ title mapFunc
+ lower mapFunc
+ titleSpan spanFunc
+
+ rewrite func(*context)
+}
+
+// Transform implements the standard Unicode title case algorithm as defined in
+// Chapter 3 of The Unicode Standard:
+// toTitlecase(X): Find the word boundaries in X according to Unicode Standard
+// Annex #29, "Unicode Text Segmentation." For each word boundary, find the
+// first cased character F following the word boundary. If F exists, map F to
+// Titlecase_Mapping(F); then map all characters C between F and the following
+// word boundary to Lowercase_Mapping(C).
+func (t *titleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ t.context = context{dst: dst, src: src, atEOF: atEOF, isMidWord: t.isMidWord}
+ c := &t.context
+
+ if !c.next() {
+ return c.ret()
+ }
+
+ for {
+ p := c.info
+ if t.rewrite != nil {
+ t.rewrite(c)
+ }
+
+ wasMid := p.isMid()
+ // Break out of this loop on failure to ensure we do not modify the
+ // state incorrectly.
+ if p.isCased() {
+ if !c.isMidWord {
+ if !t.title(c) {
+ break
+ }
+ c.isMidWord = true
+ } else if !t.lower(c) {
+ break
+ }
+ } else if !c.copy() {
+ break
+ } else if p.isBreak() {
+ c.isMidWord = false
+ }
+
+ // As we save the state of the transformer, it is safe to call
+ // checkpoint after any successful write.
+ if !(c.isMidWord && wasMid) {
+ c.checkpoint()
+ }
+
+ if !c.next() {
+ break
+ }
+ if wasMid && c.info.isMid() {
+ c.isMidWord = false
+ }
+ }
+ return c.ret()
+}
+
+func (t *titleCaser) Span(src []byte, atEOF bool) (n int, err error) {
+ t.context = context{src: src, atEOF: atEOF, isMidWord: t.isMidWord}
+ c := &t.context
+
+ if !c.next() {
+ return c.retSpan()
+ }
+
+ for {
+ p := c.info
+ if t.rewrite != nil {
+ t.rewrite(c)
+ }
+
+ wasMid := p.isMid()
+ // Break out of this loop on failure to ensure we do not modify the
+ // state incorrectly.
+ if p.isCased() {
+ if !c.isMidWord {
+ if !t.titleSpan(c) {
+ break
+ }
+ c.isMidWord = true
+ } else if !isLower(c) {
+ break
+ }
+ } else if p.isBreak() {
+ c.isMidWord = false
+ }
+ // As we save the state of the transformer, it is safe to call
+ // checkpoint after any successful write.
+ if !(c.isMidWord && wasMid) {
+ c.checkpoint()
+ }
+
+ if !c.next() {
+ break
+ }
+ if wasMid && c.info.isMid() {
+ c.isMidWord = false
+ }
+ }
+ return c.retSpan()
+}
+
+// finalSigma adds Greek final Sigma handing to another casing function. It
+// determines whether a lowercased sigma should be σ or ς, by looking ahead for
+// case-ignorables and a cased letters.
+func finalSigma(f mapFunc) mapFunc {
+ return func(c *context) bool {
+ if !c.hasPrefix("Σ") {
+ return f(c)
+ }
+ return finalSigmaBody(c)
+ }
+}
+
+func finalSigmaBody(c *context) bool {
+ // Current rune must be ∑.
+
+ // ::NFD();
+ // # 03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
+ // Σ } [:case-ignorable:]* [:cased:] → σ;
+ // [:cased:] [:case-ignorable:]* { Σ → ς;
+ // ::Any-Lower;
+ // ::NFC();
+
+ p := c.pDst
+ c.writeString("ς")
+
+ // TODO: we should do this here, but right now this will never have an
+ // effect as this is called when the prefix is Sigma, whereas Dutch and
+ // Afrikaans only test for an apostrophe.
+ //
+ // if t.rewrite != nil {
+ // t.rewrite(c)
+ // }
+
+ // We need to do one more iteration after maxIgnorable, as a cased
+ // letter is not an ignorable and may modify the result.
+ wasMid := false
+ for i := 0; i < maxIgnorable+1; i++ {
+ if !c.next() {
+ return false
+ }
+ if !c.info.isCaseIgnorable() {
+ // All Midword runes are also case ignorable, so we are
+ // guaranteed to have a letter or word break here. As we are
+ // unreading the run, there is no need to unset c.isMidWord;
+ // the title caser will handle this.
+ if c.info.isCased() {
+ // p+1 is guaranteed to be in bounds: if writing ς was
+ // successful, p+1 will contain the second byte of ς. If not,
+ // this function will have returned after c.next returned false.
+ c.dst[p+1]++ // ς → σ
+ }
+ c.unreadRune()
+ return true
+ }
+ // A case ignorable may also introduce a word break, so we may need
+ // to continue searching even after detecting a break.
+ isMid := c.info.isMid()
+ if (wasMid && isMid) || c.info.isBreak() {
+ c.isMidWord = false
+ }
+ wasMid = isMid
+ c.copy()
+ }
+ return true
+}
+
+// finalSigmaSpan would be the same as isLower.
+
+// elUpper implements Greek upper casing, which entails removing a predefined
+// set of non-blocked modifiers. Note that these accents should not be removed
+// for title casing!
+// Example: "Οδός" -> "ΟΔΟΣ".
+func elUpper(c *context) bool {
+ // From CLDR:
+ // [:Greek:] [^[:ccc=Not_Reordered:][:ccc=Above:]]*? { [\u0313\u0314\u0301\u0300\u0306\u0342\u0308\u0304] → ;
+ // [:Greek:] [^[:ccc=Not_Reordered:][:ccc=Iota_Subscript:]]*? { \u0345 → ;
+
+ r, _ := utf8.DecodeRune(c.src[c.pSrc:])
+ oldPDst := c.pDst
+ if !upper(c) {
+ return false
+ }
+ if !unicode.Is(unicode.Greek, r) {
+ return true
+ }
+ i := 0
+ // Take the properties of the uppercased rune that is already written to the
+ // destination. This saves us the trouble of having to uppercase the
+ // decomposed rune again.
+ if b := norm.NFD.Properties(c.dst[oldPDst:]).Decomposition(); b != nil {
+ // Restore the destination position and process the decomposed rune.
+ r, sz := utf8.DecodeRune(b)
+ if r <= 0xFF { // See A.6.1
+ return true
+ }
+ c.pDst = oldPDst
+ // Insert the first rune and ignore the modifiers. See A.6.2.
+ c.writeBytes(b[:sz])
+ i = len(b[sz:]) / 2 // Greek modifiers are always of length 2.
+ }
+
+ for ; i < maxIgnorable && c.next(); i++ {
+ switch r, _ := utf8.DecodeRune(c.src[c.pSrc:]); r {
+ // Above and Iota Subscript
+ case 0x0300, // U+0300 COMBINING GRAVE ACCENT
+ 0x0301, // U+0301 COMBINING ACUTE ACCENT
+ 0x0304, // U+0304 COMBINING MACRON
+ 0x0306, // U+0306 COMBINING BREVE
+ 0x0308, // U+0308 COMBINING DIAERESIS
+ 0x0313, // U+0313 COMBINING COMMA ABOVE
+ 0x0314, // U+0314 COMBINING REVERSED COMMA ABOVE
+ 0x0342, // U+0342 COMBINING GREEK PERISPOMENI
+ 0x0345: // U+0345 COMBINING GREEK YPOGEGRAMMENI
+ // No-op. Gobble the modifier.
+
+ default:
+ switch v, _ := trie.lookup(c.src[c.pSrc:]); info(v).cccType() {
+ case cccZero:
+ c.unreadRune()
+ return true
+
+ // We don't need to test for IotaSubscript as the only rune that
+ // qualifies (U+0345) was already excluded in the switch statement
+ // above. See A.4.
+
+ case cccAbove:
+ return c.copy()
+ default:
+ // Some other modifier. We're still allowed to gobble Greek
+ // modifiers after this.
+ c.copy()
+ }
+ }
+ }
+ return i == maxIgnorable
+}
+
+// TODO: implement elUpperSpan (low-priority: complex and infrequent).
+
+func ltLower(c *context) bool {
+ // From CLDR:
+ // # Introduce an explicit dot above when lowercasing capital I's and J's
+ // # whenever there are more accents above.
+ // # (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)
+ // # 0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I
+ // # 004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J
+ // # 012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK
+ // # 00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE
+ // # 00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE
+ // # 0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE
+ // ::NFD();
+ // I } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → i \u0307;
+ // J } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → j \u0307;
+ // I \u0328 (Į) } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → i \u0328 \u0307;
+ // I \u0300 (Ì) → i \u0307 \u0300;
+ // I \u0301 (Í) → i \u0307 \u0301;
+ // I \u0303 (Ĩ) → i \u0307 \u0303;
+ // ::Any-Lower();
+ // ::NFC();
+
+ i := 0
+ if r := c.src[c.pSrc]; r < utf8.RuneSelf {
+ lower(c)
+ if r != 'I' && r != 'J' {
+ return true
+ }
+ } else {
+ p := norm.NFD.Properties(c.src[c.pSrc:])
+ if d := p.Decomposition(); len(d) >= 3 && (d[0] == 'I' || d[0] == 'J') {
+ // UTF-8 optimization: the decomposition will only have an above
+ // modifier if the last rune of the decomposition is in [U+300-U+311].
+ // In all other cases, a decomposition starting with I is always
+ // an I followed by modifiers that are not cased themselves. See A.2.
+ if d[1] == 0xCC && d[2] <= 0x91 { // A.2.4.
+ if !c.writeBytes(d[:1]) {
+ return false
+ }
+ c.dst[c.pDst-1] += 'a' - 'A' // lower
+
+ // Assumption: modifier never changes on lowercase. See A.1.
+ // Assumption: all modifiers added have CCC = Above. See A.2.3.
+ return c.writeString("\u0307") && c.writeBytes(d[1:])
+ }
+ // In all other cases the additional modifiers will have a CCC
+ // that is less than 230 (Above). We will insert the U+0307, if
+ // needed, after these modifiers so that a string in FCD form
+ // will remain so. See A.2.2.
+ lower(c)
+ i = 1
+ } else {
+ return lower(c)
+ }
+ }
+
+ for ; i < maxIgnorable && c.next(); i++ {
+ switch c.info.cccType() {
+ case cccZero:
+ c.unreadRune()
+ return true
+ case cccAbove:
+ return c.writeString("\u0307") && c.copy() // See A.1.
+ default:
+ c.copy() // See A.1.
+ }
+ }
+ return i == maxIgnorable
+}
+
+// ltLowerSpan would be the same as isLower.
+
+func ltUpper(f mapFunc) mapFunc {
+ return func(c *context) bool {
+ // Unicode:
+ // 0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
+ //
+ // From CLDR:
+ // # Remove \u0307 following soft-dotteds (i, j, and the like), with possible
+ // # intervening non-230 marks.
+ // ::NFD();
+ // [:Soft_Dotted:] [^[:ccc=Not_Reordered:][:ccc=Above:]]* { \u0307 → ;
+ // ::Any-Upper();
+ // ::NFC();
+
+ // TODO: See A.5. A soft-dotted rune never has an exception. This would
+ // allow us to overload the exception bit and encode this property in
+ // info. Need to measure performance impact of this.
+ r, _ := utf8.DecodeRune(c.src[c.pSrc:])
+ oldPDst := c.pDst
+ if !f(c) {
+ return false
+ }
+ if !unicode.Is(unicode.Soft_Dotted, r) {
+ return true
+ }
+
+ // We don't need to do an NFD normalization, as a soft-dotted rune never
+ // contains U+0307. See A.3.
+
+ i := 0
+ for ; i < maxIgnorable && c.next(); i++ {
+ switch c.info.cccType() {
+ case cccZero:
+ c.unreadRune()
+ return true
+ case cccAbove:
+ if c.hasPrefix("\u0307") {
+ // We don't do a full NFC, but rather combine runes for
+ // some of the common cases. (Returning NFC or
+ // preserving normal form is neither a requirement nor
+ // a possibility anyway).
+ if !c.next() {
+ return false
+ }
+ if c.dst[oldPDst] == 'I' && c.pDst == oldPDst+1 && c.src[c.pSrc] == 0xcc {
+ s := ""
+ switch c.src[c.pSrc+1] {
+ case 0x80: // U+0300 COMBINING GRAVE ACCENT
+ s = "\u00cc" // U+00CC LATIN CAPITAL LETTER I WITH GRAVE
+ case 0x81: // U+0301 COMBINING ACUTE ACCENT
+ s = "\u00cd" // U+00CD LATIN CAPITAL LETTER I WITH ACUTE
+ case 0x83: // U+0303 COMBINING TILDE
+ s = "\u0128" // U+0128 LATIN CAPITAL LETTER I WITH TILDE
+ case 0x88: // U+0308 COMBINING DIAERESIS
+ s = "\u00cf" // U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS
+ default:
+ }
+ if s != "" {
+ c.pDst = oldPDst
+ return c.writeString(s)
+ }
+ }
+ }
+ return c.copy()
+ default:
+ c.copy()
+ }
+ }
+ return i == maxIgnorable
+ }
+}
+
+// TODO: implement ltUpperSpan (low priority: complex and infrequent).
+
+func aztrUpper(f mapFunc) mapFunc {
+ return func(c *context) bool {
+ // i→İ;
+ if c.src[c.pSrc] == 'i' {
+ return c.writeString("İ")
+ }
+ return f(c)
+ }
+}
+
+func aztrLower(c *context) (done bool) {
+ // From CLDR:
+ // # I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
+ // # 0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+ // İ→i;
+ // # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
+ // # This matches the behavior of the canonically equivalent I-dot_above
+ // # 0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
+ // # When lowercasing, unless an I is before a dot_above, it turns into a dotless i.
+ // # 0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I
+ // I([^[:ccc=Not_Reordered:][:ccc=Above:]]*)\u0307 → i$1 ;
+ // I→ı ;
+ // ::Any-Lower();
+ if c.hasPrefix("\u0130") { // İ
+ return c.writeString("i")
+ }
+ if c.src[c.pSrc] != 'I' {
+ return lower(c)
+ }
+
+ // We ignore the lower-case I for now, but insert it later when we know
+ // which form we need.
+ start := c.pSrc + c.sz
+
+ i := 0
+Loop:
+ // We check for up to n ignorables before \u0307. As \u0307 is an
+ // ignorable as well, n is maxIgnorable-1.
+ for ; i < maxIgnorable && c.next(); i++ {
+ switch c.info.cccType() {
+ case cccAbove:
+ if c.hasPrefix("\u0307") {
+ return c.writeString("i") && c.writeBytes(c.src[start:c.pSrc]) // ignore U+0307
+ }
+ done = true
+ break Loop
+ case cccZero:
+ c.unreadRune()
+ done = true
+ break Loop
+ default:
+ // We'll write this rune after we know which starter to use.
+ }
+ }
+ if i == maxIgnorable {
+ done = true
+ }
+ return c.writeString("ı") && c.writeBytes(c.src[start:c.pSrc+c.sz]) && done
+}
+
+// aztrLowerSpan would be the same as isLower.
+
+func nlTitle(c *context) bool {
+ // From CLDR:
+ // # Special titlecasing for Dutch initial "ij".
+ // ::Any-Title();
+ // # Fix up Ij at the beginning of a "word" (per Any-Title, notUAX #29)
+ // [:^WB=ALetter:] [:WB=Extend:]* [[:WB=MidLetter:][:WB=MidNumLet:]]? { Ij } → IJ ;
+ if c.src[c.pSrc] != 'I' && c.src[c.pSrc] != 'i' {
+ return title(c)
+ }
+
+ if !c.writeString("I") || !c.next() {
+ return false
+ }
+ if c.src[c.pSrc] == 'j' || c.src[c.pSrc] == 'J' {
+ return c.writeString("J")
+ }
+ c.unreadRune()
+ return true
+}
+
+func nlTitleSpan(c *context) bool {
+ // From CLDR:
+ // # Special titlecasing for Dutch initial "ij".
+ // ::Any-Title();
+ // # Fix up Ij at the beginning of a "word" (per Any-Title, notUAX #29)
+ // [:^WB=ALetter:] [:WB=Extend:]* [[:WB=MidLetter:][:WB=MidNumLet:]]? { Ij } → IJ ;
+ if c.src[c.pSrc] != 'I' {
+ return isTitle(c)
+ }
+ if !c.next() || c.src[c.pSrc] == 'j' {
+ return false
+ }
+ if c.src[c.pSrc] != 'J' {
+ c.unreadRune()
+ }
+ return true
+}
+
+// Not part of CLDR, but see https://unicode.org/cldr/trac/ticket/7078.
+func afnlRewrite(c *context) {
+ if c.hasPrefix("'") || c.hasPrefix("’") {
+ c.isMidWord = true
+ }
+}
diff --git a/vendor/golang.org/x/text/cases/tables15.0.0.go b/vendor/golang.org/x/text/cases/tables15.0.0.go
new file mode 100644
index 000000000..6aa111610
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/tables15.0.0.go
@@ -0,0 +1,2527 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+//go:build !go1.27
+
+package cases
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "15.0.0"
+
+var xorData string = "" + // Size: 213 bytes
+ "\x00\x06\x07\x00\x01?\x00\x0f\x03\x00\x0f\x12\x00\x0f\x1f\x00\x0f\x1d" +
+ "\x00\x01\x13\x00\x0f\x16\x00\x0f\x0b\x00\x0f3\x00\x0f7\x00\x01#\x00\x0f?" +
+ "\x00\x0e'\x00\x0f/\x00\x0e>\x00\x0f*\x00\x0c&\x00\x0c*\x00\x0c;\x00\x0c9" +
+ "\x00\x0c%\x00\x01\x08\x00\x03\x0d\x00\x03\x09\x00\x02\x06\x00\x02\x02" +
+ "\x00\x02\x0c\x00\x01\x00\x00\x01\x03\x00\x01\x01\x00\x01 \x00\x01\x0c" +
+ "\x00\x01\x10\x00\x03\x10\x00\x036 \x00\x037 \x00\x0b#\x10\x00\x0b 0\x00" +
+ "\x0b!\x10\x00\x0b!0\x001\x00\x00\x0b(\x04\x00\x03\x04\x1e\x00\x0b)\x08" +
+ "\x00\x03\x0a\x00\x02:\x00\x02>\x00\x02,\x00\x02\x00\x00\x02\x10\x00\x01<" +
+ "\x00\x01&\x00\x01*\x00\x01.\x00\x010\x003 \x00\x01\x18\x00\x01(\x00\x03'" +
+ "\x00\x03)\x00\x03+\x00\x03/\x00\x03\x19\x00\x03\x1b\x00\x03\x1f\x00\x01" +
+ "\x1e\x00\x01\x22"
+
+var exceptions string = "" + // Size: 2450 bytes
+ "\x00\x12\x12μΜΜ\x12\x12ssSSSs\x13\x18i̇i̇\x10\x09II\x13\x1bʼnʼNʼN\x11" +
+ "\x09sSS\x12\x12dždžDž\x12\x12dždžDŽ\x10\x12DŽDž\x12\x12ljljLj\x12\x12ljljLJ\x10\x12LJLj" +
+ "\x12\x12njnjNj\x12\x12njnjNJ\x10\x12NJNj\x13\x1bǰJ̌J̌\x12\x12dzdzDz\x12\x12dzdzDZ\x10" +
+ "\x12DZDz\x13\x18ⱥⱥ\x13\x18ⱦⱦ\x10\x1bⱾⱾ\x10\x1bⱿⱿ\x10\x1bⱯⱯ\x10\x1bⱭⱭ\x10" +
+ "\x1bⱰⱰ\x10\x1bꞫꞫ\x10\x1bꞬꞬ\x10\x1bꞍꞍ\x10\x1bꞪꞪ\x10\x1bꞮꞮ\x10\x1bⱢⱢ\x10" +
+ "\x1bꞭꞭ\x10\x1bⱮⱮ\x10\x1bⱤⱤ\x10\x1bꟅꟅ\x10\x1bꞱꞱ\x10\x1bꞲꞲ\x10\x1bꞰꞰ2\x12ι" +
+ "ΙΙ\x166ΐΪ́Ϊ́\x166ΰΫ́Ϋ́\x12\x12σΣΣ\x12\x12βΒΒ\x12\x12θΘΘ\x12\x12" +
+ "φΦΦ\x12\x12πΠΠ\x12\x12κΚΚ\x12\x12ρΡΡ\x12\x12εΕΕ\x14$եւԵՒԵւ\x10\x1bᲐა" +
+ "\x10\x1bᲑბ\x10\x1bᲒგ\x10\x1bᲓდ\x10\x1bᲔე\x10\x1bᲕვ\x10\x1bᲖზ\x10\x1bᲗთ" +
+ "\x10\x1bᲘი\x10\x1bᲙკ\x10\x1bᲚლ\x10\x1bᲛმ\x10\x1bᲜნ\x10\x1bᲝო\x10\x1bᲞპ" +
+ "\x10\x1bᲟჟ\x10\x1bᲠრ\x10\x1bᲡს\x10\x1bᲢტ\x10\x1bᲣუ\x10\x1bᲤფ\x10\x1bᲥქ" +
+ "\x10\x1bᲦღ\x10\x1bᲧყ\x10\x1bᲨშ\x10\x1bᲩჩ\x10\x1bᲪც\x10\x1bᲫძ\x10\x1bᲬწ" +
+ "\x10\x1bᲭჭ\x10\x1bᲮხ\x10\x1bᲯჯ\x10\x1bᲰჰ\x10\x1bᲱჱ\x10\x1bᲲჲ\x10\x1bᲳჳ" +
+ "\x10\x1bᲴჴ\x10\x1bᲵჵ\x10\x1bᲶჶ\x10\x1bᲷჷ\x10\x1bᲸჸ\x10\x1bᲹჹ\x10\x1bᲺჺ" +
+ "\x10\x1bᲽჽ\x10\x1bᲾჾ\x10\x1bᲿჿ\x12\x12вВВ\x12\x12дДД\x12\x12оОО\x12\x12с" +
+ "СС\x12\x12тТТ\x12\x12тТТ\x12\x12ъЪЪ\x12\x12ѣѢѢ\x13\x1bꙋꙊꙊ\x13\x1bẖH̱H̱" +
+ "\x13\x1bẗT̈T̈\x13\x1bẘW̊W̊\x13\x1bẙY̊Y̊\x13\x1baʾAʾAʾ\x13\x1bṡṠṠ\x12" +
+ "\x10ssß\x14$ὐΥ̓Υ̓\x166ὒΥ̓̀Υ̓̀\x166ὔΥ̓́Υ̓́\x166ὖΥ̓͂Υ̓͂\x15+ἀιἈΙᾈ" +
+ "\x15+ἁιἉΙᾉ\x15+ἂιἊΙᾊ\x15+ἃιἋΙᾋ\x15+ἄιἌΙᾌ\x15+ἅιἍΙᾍ\x15+ἆιἎΙᾎ\x15+ἇιἏΙᾏ" +
+ "\x15\x1dἀιᾀἈΙ\x15\x1dἁιᾁἉΙ\x15\x1dἂιᾂἊΙ\x15\x1dἃιᾃἋΙ\x15\x1dἄιᾄἌΙ\x15" +
+ "\x1dἅιᾅἍΙ\x15\x1dἆιᾆἎΙ\x15\x1dἇιᾇἏΙ\x15+ἠιἨΙᾘ\x15+ἡιἩΙᾙ\x15+ἢιἪΙᾚ\x15+ἣι" +
+ "ἫΙᾛ\x15+ἤιἬΙᾜ\x15+ἥιἭΙᾝ\x15+ἦιἮΙᾞ\x15+ἧιἯΙᾟ\x15\x1dἠιᾐἨΙ\x15\x1dἡιᾑἩΙ" +
+ "\x15\x1dἢιᾒἪΙ\x15\x1dἣιᾓἫΙ\x15\x1dἤιᾔἬΙ\x15\x1dἥιᾕἭΙ\x15\x1dἦιᾖἮΙ\x15" +
+ "\x1dἧιᾗἯΙ\x15+ὠιὨΙᾨ\x15+ὡιὩΙᾩ\x15+ὢιὪΙᾪ\x15+ὣιὫΙᾫ\x15+ὤιὬΙᾬ\x15+ὥιὭΙᾭ" +
+ "\x15+ὦιὮΙᾮ\x15+ὧιὯΙᾯ\x15\x1dὠιᾠὨΙ\x15\x1dὡιᾡὩΙ\x15\x1dὢιᾢὪΙ\x15\x1dὣιᾣὫΙ" +
+ "\x15\x1dὤιᾤὬΙ\x15\x1dὥιᾥὭΙ\x15\x1dὦιᾦὮΙ\x15\x1dὧιᾧὯΙ\x15-ὰιᾺΙᾺͅ\x14#αιΑΙ" +
+ "ᾼ\x14$άιΆΙΆͅ\x14$ᾶΑ͂Α͂\x166ᾶιΑ͂Ιᾼ͂\x14\x1cαιᾳΑΙ\x12\x12ιΙΙ\x15-ὴιῊΙ" +
+ "Ὴͅ\x14#ηιΗΙῌ\x14$ήιΉΙΉͅ\x14$ῆΗ͂Η͂\x166ῆιΗ͂Ιῌ͂\x14\x1cηιῃΗΙ\x166ῒΙ" +
+ "̈̀Ϊ̀\x166ΐΪ́Ϊ́\x14$ῖΙ͂Ι͂\x166ῗΪ͂Ϊ͂\x166ῢΫ̀Ϋ̀\x166ΰΫ́Ϋ" +
+ "́\x14$ῤΡ̓Ρ̓\x14$ῦΥ͂Υ͂\x166ῧΫ͂Ϋ͂\x15-ὼιῺΙῺͅ\x14#ωιΩΙῼ\x14$ώιΏΙΏͅ" +
+ "\x14$ῶΩ͂Ω͂\x166ῶιΩ͂Ιῼ͂\x14\x1cωιῳΩΙ\x12\x10ωω\x11\x08kk\x12\x10åå\x12" +
+ "\x10ɫɫ\x12\x10ɽɽ\x10\x12ȺȺ\x10\x12ȾȾ\x12\x10ɑɑ\x12\x10ɱɱ\x12\x10ɐɐ\x12" +
+ "\x10ɒɒ\x12\x10ȿȿ\x12\x10ɀɀ\x12\x10ɥɥ\x12\x10ɦɦ\x12\x10ɜɜ\x12\x10ɡɡ\x12" +
+ "\x10ɬɬ\x12\x10ɪɪ\x12\x10ʞʞ\x12\x10ʇʇ\x12\x10ʝʝ\x12\x10ʂʂ\x12\x12ffFFFf" +
+ "\x12\x12fiFIFi\x12\x12flFLFl\x13\x1bffiFFIFfi\x13\x1bfflFFLFfl\x12\x12st" +
+ "STSt\x12\x12stSTSt\x14$մնՄՆՄն\x14$մեՄԵՄե\x14$միՄԻՄի\x14$վնՎՆՎն\x14$մխՄԽՄ" +
+ "խ"
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *caseTrie) lookup(s []byte) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return caseValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = caseIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *caseTrie) lookupUnsafe(s []byte) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return caseValues[c0]
+ }
+ i := caseIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *caseTrie) lookupString(s string) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return caseValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = caseIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *caseTrie) lookupStringUnsafe(s string) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return caseValues[c0]
+ }
+ i := caseIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// caseTrie. Total size: 13398 bytes (13.08 KiB). Checksum: 544af6e6b1b70931.
+type caseTrie struct{}
+
+func newCaseTrie(i int) *caseTrie {
+ return &caseTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *caseTrie) lookupValue(n uint32, b byte) uint16 {
+ switch {
+ case n < 22:
+ return uint16(caseValues[n<<6+uint32(b)])
+ default:
+ n -= 22
+ return uint16(sparse.lookup(n, b))
+ }
+}
+
+// caseValues: 24 blocks, 1536 entries, 3072 bytes
+// The third block is the zero block.
+var caseValues = [1536]uint16{
+ // Block 0x0, offset 0x0
+ 0x27: 0x0054,
+ 0x2e: 0x0054,
+ 0x30: 0x0010, 0x31: 0x0010, 0x32: 0x0010, 0x33: 0x0010, 0x34: 0x0010, 0x35: 0x0010,
+ 0x36: 0x0010, 0x37: 0x0010, 0x38: 0x0010, 0x39: 0x0010, 0x3a: 0x0054,
+ // Block 0x1, offset 0x40
+ 0x41: 0x2013, 0x42: 0x2013, 0x43: 0x2013, 0x44: 0x2013, 0x45: 0x2013,
+ 0x46: 0x2013, 0x47: 0x2013, 0x48: 0x2013, 0x49: 0x2013, 0x4a: 0x2013, 0x4b: 0x2013,
+ 0x4c: 0x2013, 0x4d: 0x2013, 0x4e: 0x2013, 0x4f: 0x2013, 0x50: 0x2013, 0x51: 0x2013,
+ 0x52: 0x2013, 0x53: 0x2013, 0x54: 0x2013, 0x55: 0x2013, 0x56: 0x2013, 0x57: 0x2013,
+ 0x58: 0x2013, 0x59: 0x2013, 0x5a: 0x2013,
+ 0x5e: 0x0004, 0x5f: 0x0010, 0x60: 0x0004, 0x61: 0x2012, 0x62: 0x2012, 0x63: 0x2012,
+ 0x64: 0x2012, 0x65: 0x2012, 0x66: 0x2012, 0x67: 0x2012, 0x68: 0x2012, 0x69: 0x2012,
+ 0x6a: 0x2012, 0x6b: 0x2012, 0x6c: 0x2012, 0x6d: 0x2012, 0x6e: 0x2012, 0x6f: 0x2012,
+ 0x70: 0x2012, 0x71: 0x2012, 0x72: 0x2012, 0x73: 0x2012, 0x74: 0x2012, 0x75: 0x2012,
+ 0x76: 0x2012, 0x77: 0x2012, 0x78: 0x2012, 0x79: 0x2012, 0x7a: 0x2012,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x0852, 0xc1: 0x0b53, 0xc2: 0x0113, 0xc3: 0x0112, 0xc4: 0x0113, 0xc5: 0x0112,
+ 0xc6: 0x0b53, 0xc7: 0x0f13, 0xc8: 0x0f12, 0xc9: 0x0e53, 0xca: 0x1153, 0xcb: 0x0713,
+ 0xcc: 0x0712, 0xcd: 0x0012, 0xce: 0x1453, 0xcf: 0x1753, 0xd0: 0x1a53, 0xd1: 0x0313,
+ 0xd2: 0x0312, 0xd3: 0x1d53, 0xd4: 0x2053, 0xd5: 0x2352, 0xd6: 0x2653, 0xd7: 0x2653,
+ 0xd8: 0x0113, 0xd9: 0x0112, 0xda: 0x2952, 0xdb: 0x0012, 0xdc: 0x1d53, 0xdd: 0x2c53,
+ 0xde: 0x2f52, 0xdf: 0x3253, 0xe0: 0x0113, 0xe1: 0x0112, 0xe2: 0x0113, 0xe3: 0x0112,
+ 0xe4: 0x0113, 0xe5: 0x0112, 0xe6: 0x3553, 0xe7: 0x0f13, 0xe8: 0x0f12, 0xe9: 0x3853,
+ 0xea: 0x0012, 0xeb: 0x0012, 0xec: 0x0113, 0xed: 0x0112, 0xee: 0x3553, 0xef: 0x1f13,
+ 0xf0: 0x1f12, 0xf1: 0x3b53, 0xf2: 0x3e53, 0xf3: 0x0713, 0xf4: 0x0712, 0xf5: 0x0313,
+ 0xf6: 0x0312, 0xf7: 0x4153, 0xf8: 0x0113, 0xf9: 0x0112, 0xfa: 0x0012, 0xfb: 0x0010,
+ 0xfc: 0x0113, 0xfd: 0x0112, 0xfe: 0x0012, 0xff: 0x4452,
+ // Block 0x4, offset 0x100
+ 0x100: 0x0010, 0x101: 0x0010, 0x102: 0x0010, 0x103: 0x0010, 0x104: 0x02db, 0x105: 0x0359,
+ 0x106: 0x03da, 0x107: 0x043b, 0x108: 0x04b9, 0x109: 0x053a, 0x10a: 0x059b, 0x10b: 0x0619,
+ 0x10c: 0x069a, 0x10d: 0x0313, 0x10e: 0x0312, 0x10f: 0x1f13, 0x110: 0x1f12, 0x111: 0x0313,
+ 0x112: 0x0312, 0x113: 0x0713, 0x114: 0x0712, 0x115: 0x0313, 0x116: 0x0312, 0x117: 0x0f13,
+ 0x118: 0x0f12, 0x119: 0x0313, 0x11a: 0x0312, 0x11b: 0x0713, 0x11c: 0x0712, 0x11d: 0x1452,
+ 0x11e: 0x0113, 0x11f: 0x0112, 0x120: 0x0113, 0x121: 0x0112, 0x122: 0x0113, 0x123: 0x0112,
+ 0x124: 0x0113, 0x125: 0x0112, 0x126: 0x0113, 0x127: 0x0112, 0x128: 0x0113, 0x129: 0x0112,
+ 0x12a: 0x0113, 0x12b: 0x0112, 0x12c: 0x0113, 0x12d: 0x0112, 0x12e: 0x0113, 0x12f: 0x0112,
+ 0x130: 0x06fa, 0x131: 0x07ab, 0x132: 0x0829, 0x133: 0x08aa, 0x134: 0x0113, 0x135: 0x0112,
+ 0x136: 0x2353, 0x137: 0x4453, 0x138: 0x0113, 0x139: 0x0112, 0x13a: 0x0113, 0x13b: 0x0112,
+ 0x13c: 0x0113, 0x13d: 0x0112, 0x13e: 0x0113, 0x13f: 0x0112,
+ // Block 0x5, offset 0x140
+ 0x140: 0x0a8a, 0x141: 0x0313, 0x142: 0x0312, 0x143: 0x0853, 0x144: 0x4753, 0x145: 0x4a53,
+ 0x146: 0x0113, 0x147: 0x0112, 0x148: 0x0113, 0x149: 0x0112, 0x14a: 0x0113, 0x14b: 0x0112,
+ 0x14c: 0x0113, 0x14d: 0x0112, 0x14e: 0x0113, 0x14f: 0x0112, 0x150: 0x0b0a, 0x151: 0x0b8a,
+ 0x152: 0x0c0a, 0x153: 0x0b52, 0x154: 0x0b52, 0x155: 0x0012, 0x156: 0x0e52, 0x157: 0x1152,
+ 0x158: 0x0012, 0x159: 0x1752, 0x15a: 0x0012, 0x15b: 0x1a52, 0x15c: 0x0c8a, 0x15d: 0x0012,
+ 0x15e: 0x0012, 0x15f: 0x0012, 0x160: 0x1d52, 0x161: 0x0d0a, 0x162: 0x0012, 0x163: 0x2052,
+ 0x164: 0x0012, 0x165: 0x0d8a, 0x166: 0x0e0a, 0x167: 0x0012, 0x168: 0x2652, 0x169: 0x2652,
+ 0x16a: 0x0e8a, 0x16b: 0x0f0a, 0x16c: 0x0f8a, 0x16d: 0x0012, 0x16e: 0x0012, 0x16f: 0x1d52,
+ 0x170: 0x0012, 0x171: 0x100a, 0x172: 0x2c52, 0x173: 0x0012, 0x174: 0x0012, 0x175: 0x3252,
+ 0x176: 0x0012, 0x177: 0x0012, 0x178: 0x0012, 0x179: 0x0012, 0x17a: 0x0012, 0x17b: 0x0012,
+ 0x17c: 0x0012, 0x17d: 0x108a, 0x17e: 0x0012, 0x17f: 0x0012,
+ // Block 0x6, offset 0x180
+ 0x180: 0x3552, 0x181: 0x0012, 0x182: 0x110a, 0x183: 0x3852, 0x184: 0x0012, 0x185: 0x0012,
+ 0x186: 0x0012, 0x187: 0x118a, 0x188: 0x3552, 0x189: 0x4752, 0x18a: 0x3b52, 0x18b: 0x3e52,
+ 0x18c: 0x4a52, 0x18d: 0x0012, 0x18e: 0x0012, 0x18f: 0x0012, 0x190: 0x0012, 0x191: 0x0012,
+ 0x192: 0x4152, 0x193: 0x0012, 0x194: 0x0010, 0x195: 0x0012, 0x196: 0x0012, 0x197: 0x0012,
+ 0x198: 0x0012, 0x199: 0x0012, 0x19a: 0x0012, 0x19b: 0x0012, 0x19c: 0x0012, 0x19d: 0x120a,
+ 0x19e: 0x128a, 0x19f: 0x0012, 0x1a0: 0x0012, 0x1a1: 0x0012, 0x1a2: 0x0012, 0x1a3: 0x0012,
+ 0x1a4: 0x0012, 0x1a5: 0x0012, 0x1a6: 0x0012, 0x1a7: 0x0012, 0x1a8: 0x0012, 0x1a9: 0x0012,
+ 0x1aa: 0x0012, 0x1ab: 0x0012, 0x1ac: 0x0012, 0x1ad: 0x0012, 0x1ae: 0x0012, 0x1af: 0x0012,
+ 0x1b0: 0x0015, 0x1b1: 0x0015, 0x1b2: 0x0015, 0x1b3: 0x0015, 0x1b4: 0x0015, 0x1b5: 0x0015,
+ 0x1b6: 0x0015, 0x1b7: 0x0015, 0x1b8: 0x0015, 0x1b9: 0x0014, 0x1ba: 0x0014, 0x1bb: 0x0014,
+ 0x1bc: 0x0014, 0x1bd: 0x0014, 0x1be: 0x0014, 0x1bf: 0x0014,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x0024, 0x1c1: 0x0024, 0x1c2: 0x0024, 0x1c3: 0x0024, 0x1c4: 0x0024, 0x1c5: 0x130d,
+ 0x1c6: 0x0024, 0x1c7: 0x0034, 0x1c8: 0x0034, 0x1c9: 0x0034, 0x1ca: 0x0024, 0x1cb: 0x0024,
+ 0x1cc: 0x0024, 0x1cd: 0x0034, 0x1ce: 0x0034, 0x1cf: 0x0014, 0x1d0: 0x0024, 0x1d1: 0x0024,
+ 0x1d2: 0x0024, 0x1d3: 0x0034, 0x1d4: 0x0034, 0x1d5: 0x0034, 0x1d6: 0x0034, 0x1d7: 0x0024,
+ 0x1d8: 0x0034, 0x1d9: 0x0034, 0x1da: 0x0034, 0x1db: 0x0024, 0x1dc: 0x0034, 0x1dd: 0x0034,
+ 0x1de: 0x0034, 0x1df: 0x0034, 0x1e0: 0x0034, 0x1e1: 0x0034, 0x1e2: 0x0034, 0x1e3: 0x0024,
+ 0x1e4: 0x0024, 0x1e5: 0x0024, 0x1e6: 0x0024, 0x1e7: 0x0024, 0x1e8: 0x0024, 0x1e9: 0x0024,
+ 0x1ea: 0x0024, 0x1eb: 0x0024, 0x1ec: 0x0024, 0x1ed: 0x0024, 0x1ee: 0x0024, 0x1ef: 0x0024,
+ 0x1f0: 0x0113, 0x1f1: 0x0112, 0x1f2: 0x0113, 0x1f3: 0x0112, 0x1f4: 0x0014, 0x1f5: 0x0004,
+ 0x1f6: 0x0113, 0x1f7: 0x0112, 0x1fa: 0x0015, 0x1fb: 0x4d52,
+ 0x1fc: 0x5052, 0x1fd: 0x5052, 0x1ff: 0x5353,
+ // Block 0x8, offset 0x200
+ 0x204: 0x0004, 0x205: 0x0004,
+ 0x206: 0x2a13, 0x207: 0x0054, 0x208: 0x2513, 0x209: 0x2713, 0x20a: 0x2513,
+ 0x20c: 0x5653, 0x20e: 0x5953, 0x20f: 0x5c53, 0x210: 0x138a, 0x211: 0x2013,
+ 0x212: 0x2013, 0x213: 0x2013, 0x214: 0x2013, 0x215: 0x2013, 0x216: 0x2013, 0x217: 0x2013,
+ 0x218: 0x2013, 0x219: 0x2013, 0x21a: 0x2013, 0x21b: 0x2013, 0x21c: 0x2013, 0x21d: 0x2013,
+ 0x21e: 0x2013, 0x21f: 0x2013, 0x220: 0x5f53, 0x221: 0x5f53, 0x223: 0x5f53,
+ 0x224: 0x5f53, 0x225: 0x5f53, 0x226: 0x5f53, 0x227: 0x5f53, 0x228: 0x5f53, 0x229: 0x5f53,
+ 0x22a: 0x5f53, 0x22b: 0x5f53, 0x22c: 0x2a12, 0x22d: 0x2512, 0x22e: 0x2712, 0x22f: 0x2512,
+ 0x230: 0x14ca, 0x231: 0x2012, 0x232: 0x2012, 0x233: 0x2012, 0x234: 0x2012, 0x235: 0x2012,
+ 0x236: 0x2012, 0x237: 0x2012, 0x238: 0x2012, 0x239: 0x2012, 0x23a: 0x2012, 0x23b: 0x2012,
+ 0x23c: 0x2012, 0x23d: 0x2012, 0x23e: 0x2012, 0x23f: 0x2012,
+ // Block 0x9, offset 0x240
+ 0x240: 0x5f52, 0x241: 0x5f52, 0x242: 0x160a, 0x243: 0x5f52, 0x244: 0x5f52, 0x245: 0x5f52,
+ 0x246: 0x5f52, 0x247: 0x5f52, 0x248: 0x5f52, 0x249: 0x5f52, 0x24a: 0x5f52, 0x24b: 0x5f52,
+ 0x24c: 0x5652, 0x24d: 0x5952, 0x24e: 0x5c52, 0x24f: 0x1813, 0x250: 0x168a, 0x251: 0x170a,
+ 0x252: 0x0013, 0x253: 0x0013, 0x254: 0x0013, 0x255: 0x178a, 0x256: 0x180a, 0x257: 0x1812,
+ 0x258: 0x0113, 0x259: 0x0112, 0x25a: 0x0113, 0x25b: 0x0112, 0x25c: 0x0113, 0x25d: 0x0112,
+ 0x25e: 0x0113, 0x25f: 0x0112, 0x260: 0x0113, 0x261: 0x0112, 0x262: 0x0113, 0x263: 0x0112,
+ 0x264: 0x0113, 0x265: 0x0112, 0x266: 0x0113, 0x267: 0x0112, 0x268: 0x0113, 0x269: 0x0112,
+ 0x26a: 0x0113, 0x26b: 0x0112, 0x26c: 0x0113, 0x26d: 0x0112, 0x26e: 0x0113, 0x26f: 0x0112,
+ 0x270: 0x188a, 0x271: 0x190a, 0x272: 0x0b12, 0x273: 0x5352, 0x274: 0x6253, 0x275: 0x198a,
+ 0x277: 0x0f13, 0x278: 0x0f12, 0x279: 0x0b13, 0x27a: 0x0113, 0x27b: 0x0112,
+ 0x27c: 0x0012, 0x27d: 0x4d53, 0x27e: 0x5053, 0x27f: 0x5053,
+ // Block 0xa, offset 0x280
+ 0x280: 0x6852, 0x281: 0x6852, 0x282: 0x6852, 0x283: 0x6852, 0x284: 0x6852, 0x285: 0x6852,
+ 0x286: 0x6852, 0x287: 0x1a0a, 0x288: 0x0012, 0x28a: 0x0010,
+ 0x291: 0x0034,
+ 0x292: 0x0024, 0x293: 0x0024, 0x294: 0x0024, 0x295: 0x0024, 0x296: 0x0034, 0x297: 0x0024,
+ 0x298: 0x0024, 0x299: 0x0024, 0x29a: 0x0034, 0x29b: 0x0034, 0x29c: 0x0024, 0x29d: 0x0024,
+ 0x29e: 0x0024, 0x29f: 0x0024, 0x2a0: 0x0024, 0x2a1: 0x0024, 0x2a2: 0x0034, 0x2a3: 0x0034,
+ 0x2a4: 0x0034, 0x2a5: 0x0034, 0x2a6: 0x0034, 0x2a7: 0x0034, 0x2a8: 0x0024, 0x2a9: 0x0024,
+ 0x2aa: 0x0034, 0x2ab: 0x0024, 0x2ac: 0x0024, 0x2ad: 0x0034, 0x2ae: 0x0034, 0x2af: 0x0024,
+ 0x2b0: 0x0034, 0x2b1: 0x0034, 0x2b2: 0x0034, 0x2b3: 0x0034, 0x2b4: 0x0034, 0x2b5: 0x0034,
+ 0x2b6: 0x0034, 0x2b7: 0x0034, 0x2b8: 0x0034, 0x2b9: 0x0034, 0x2ba: 0x0034, 0x2bb: 0x0034,
+ 0x2bc: 0x0034, 0x2bd: 0x0034, 0x2bf: 0x0034,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0x0010, 0x2c1: 0x0010, 0x2c2: 0x0010, 0x2c3: 0x0010, 0x2c4: 0x0010, 0x2c5: 0x0010,
+ 0x2c6: 0x0010, 0x2c7: 0x0010, 0x2c8: 0x0010, 0x2c9: 0x0014, 0x2ca: 0x0024, 0x2cb: 0x0024,
+ 0x2cc: 0x0024, 0x2cd: 0x0024, 0x2ce: 0x0024, 0x2cf: 0x0034, 0x2d0: 0x0034, 0x2d1: 0x0034,
+ 0x2d2: 0x0034, 0x2d3: 0x0034, 0x2d4: 0x0024, 0x2d5: 0x0024, 0x2d6: 0x0024, 0x2d7: 0x0024,
+ 0x2d8: 0x0024, 0x2d9: 0x0024, 0x2da: 0x0024, 0x2db: 0x0024, 0x2dc: 0x0024, 0x2dd: 0x0024,
+ 0x2de: 0x0024, 0x2df: 0x0024, 0x2e0: 0x0024, 0x2e1: 0x0024, 0x2e2: 0x0014, 0x2e3: 0x0034,
+ 0x2e4: 0x0024, 0x2e5: 0x0024, 0x2e6: 0x0034, 0x2e7: 0x0024, 0x2e8: 0x0024, 0x2e9: 0x0034,
+ 0x2ea: 0x0024, 0x2eb: 0x0024, 0x2ec: 0x0024, 0x2ed: 0x0034, 0x2ee: 0x0034, 0x2ef: 0x0034,
+ 0x2f0: 0x0034, 0x2f1: 0x0034, 0x2f2: 0x0034, 0x2f3: 0x0024, 0x2f4: 0x0024, 0x2f5: 0x0024,
+ 0x2f6: 0x0034, 0x2f7: 0x0024, 0x2f8: 0x0024, 0x2f9: 0x0034, 0x2fa: 0x0034, 0x2fb: 0x0024,
+ 0x2fc: 0x0024, 0x2fd: 0x0024, 0x2fe: 0x0024, 0x2ff: 0x0024,
+ // Block 0xc, offset 0x300
+ 0x300: 0x7053, 0x301: 0x7053, 0x302: 0x7053, 0x303: 0x7053, 0x304: 0x7053, 0x305: 0x7053,
+ 0x307: 0x7053,
+ 0x30d: 0x7053, 0x310: 0x1aea, 0x311: 0x1b6a,
+ 0x312: 0x1bea, 0x313: 0x1c6a, 0x314: 0x1cea, 0x315: 0x1d6a, 0x316: 0x1dea, 0x317: 0x1e6a,
+ 0x318: 0x1eea, 0x319: 0x1f6a, 0x31a: 0x1fea, 0x31b: 0x206a, 0x31c: 0x20ea, 0x31d: 0x216a,
+ 0x31e: 0x21ea, 0x31f: 0x226a, 0x320: 0x22ea, 0x321: 0x236a, 0x322: 0x23ea, 0x323: 0x246a,
+ 0x324: 0x24ea, 0x325: 0x256a, 0x326: 0x25ea, 0x327: 0x266a, 0x328: 0x26ea, 0x329: 0x276a,
+ 0x32a: 0x27ea, 0x32b: 0x286a, 0x32c: 0x28ea, 0x32d: 0x296a, 0x32e: 0x29ea, 0x32f: 0x2a6a,
+ 0x330: 0x2aea, 0x331: 0x2b6a, 0x332: 0x2bea, 0x333: 0x2c6a, 0x334: 0x2cea, 0x335: 0x2d6a,
+ 0x336: 0x2dea, 0x337: 0x2e6a, 0x338: 0x2eea, 0x339: 0x2f6a, 0x33a: 0x2fea,
+ 0x33c: 0x0015, 0x33d: 0x306a, 0x33e: 0x30ea, 0x33f: 0x316a,
+ // Block 0xd, offset 0x340
+ 0x340: 0x0812, 0x341: 0x0812, 0x342: 0x0812, 0x343: 0x0812, 0x344: 0x0812, 0x345: 0x0812,
+ 0x348: 0x0813, 0x349: 0x0813, 0x34a: 0x0813, 0x34b: 0x0813,
+ 0x34c: 0x0813, 0x34d: 0x0813, 0x350: 0x3b1a, 0x351: 0x0812,
+ 0x352: 0x3bfa, 0x353: 0x0812, 0x354: 0x3d3a, 0x355: 0x0812, 0x356: 0x3e7a, 0x357: 0x0812,
+ 0x359: 0x0813, 0x35b: 0x0813, 0x35d: 0x0813,
+ 0x35f: 0x0813, 0x360: 0x0812, 0x361: 0x0812, 0x362: 0x0812, 0x363: 0x0812,
+ 0x364: 0x0812, 0x365: 0x0812, 0x366: 0x0812, 0x367: 0x0812, 0x368: 0x0813, 0x369: 0x0813,
+ 0x36a: 0x0813, 0x36b: 0x0813, 0x36c: 0x0813, 0x36d: 0x0813, 0x36e: 0x0813, 0x36f: 0x0813,
+ 0x370: 0x9252, 0x371: 0x9252, 0x372: 0x9552, 0x373: 0x9552, 0x374: 0x9852, 0x375: 0x9852,
+ 0x376: 0x9b52, 0x377: 0x9b52, 0x378: 0x9e52, 0x379: 0x9e52, 0x37a: 0xa152, 0x37b: 0xa152,
+ 0x37c: 0x4d52, 0x37d: 0x4d52,
+ // Block 0xe, offset 0x380
+ 0x380: 0x3fba, 0x381: 0x40aa, 0x382: 0x419a, 0x383: 0x428a, 0x384: 0x437a, 0x385: 0x446a,
+ 0x386: 0x455a, 0x387: 0x464a, 0x388: 0x4739, 0x389: 0x4829, 0x38a: 0x4919, 0x38b: 0x4a09,
+ 0x38c: 0x4af9, 0x38d: 0x4be9, 0x38e: 0x4cd9, 0x38f: 0x4dc9, 0x390: 0x4eba, 0x391: 0x4faa,
+ 0x392: 0x509a, 0x393: 0x518a, 0x394: 0x527a, 0x395: 0x536a, 0x396: 0x545a, 0x397: 0x554a,
+ 0x398: 0x5639, 0x399: 0x5729, 0x39a: 0x5819, 0x39b: 0x5909, 0x39c: 0x59f9, 0x39d: 0x5ae9,
+ 0x39e: 0x5bd9, 0x39f: 0x5cc9, 0x3a0: 0x5dba, 0x3a1: 0x5eaa, 0x3a2: 0x5f9a, 0x3a3: 0x608a,
+ 0x3a4: 0x617a, 0x3a5: 0x626a, 0x3a6: 0x635a, 0x3a7: 0x644a, 0x3a8: 0x6539, 0x3a9: 0x6629,
+ 0x3aa: 0x6719, 0x3ab: 0x6809, 0x3ac: 0x68f9, 0x3ad: 0x69e9, 0x3ae: 0x6ad9, 0x3af: 0x6bc9,
+ 0x3b0: 0x0812, 0x3b1: 0x0812, 0x3b2: 0x6cba, 0x3b3: 0x6dca, 0x3b4: 0x6e9a,
+ 0x3b6: 0x6f7a, 0x3b7: 0x705a, 0x3b8: 0x0813, 0x3b9: 0x0813, 0x3ba: 0x9253, 0x3bb: 0x9253,
+ 0x3bc: 0x7199, 0x3bd: 0x0004, 0x3be: 0x726a, 0x3bf: 0x0004,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x0004, 0x3c1: 0x0004, 0x3c2: 0x72ea, 0x3c3: 0x73fa, 0x3c4: 0x74ca,
+ 0x3c6: 0x75aa, 0x3c7: 0x768a, 0x3c8: 0x9553, 0x3c9: 0x9553, 0x3ca: 0x9853, 0x3cb: 0x9853,
+ 0x3cc: 0x77c9, 0x3cd: 0x0004, 0x3ce: 0x0004, 0x3cf: 0x0004, 0x3d0: 0x0812, 0x3d1: 0x0812,
+ 0x3d2: 0x789a, 0x3d3: 0x79da, 0x3d6: 0x7b1a, 0x3d7: 0x7bfa,
+ 0x3d8: 0x0813, 0x3d9: 0x0813, 0x3da: 0x9b53, 0x3db: 0x9b53, 0x3dd: 0x0004,
+ 0x3de: 0x0004, 0x3df: 0x0004, 0x3e0: 0x0812, 0x3e1: 0x0812, 0x3e2: 0x7d3a, 0x3e3: 0x7e7a,
+ 0x3e4: 0x7fba, 0x3e5: 0x0912, 0x3e6: 0x809a, 0x3e7: 0x817a, 0x3e8: 0x0813, 0x3e9: 0x0813,
+ 0x3ea: 0xa153, 0x3eb: 0xa153, 0x3ec: 0x0913, 0x3ed: 0x0004, 0x3ee: 0x0004, 0x3ef: 0x0004,
+ 0x3f2: 0x82ba, 0x3f3: 0x83ca, 0x3f4: 0x849a,
+ 0x3f6: 0x857a, 0x3f7: 0x865a, 0x3f8: 0x9e53, 0x3f9: 0x9e53, 0x3fa: 0x4d53, 0x3fb: 0x4d53,
+ 0x3fc: 0x8799, 0x3fd: 0x0004, 0x3fe: 0x0004,
+ // Block 0x10, offset 0x400
+ 0x402: 0x0013,
+ 0x407: 0x0013, 0x40a: 0x0012, 0x40b: 0x0013,
+ 0x40c: 0x0013, 0x40d: 0x0013, 0x40e: 0x0012, 0x40f: 0x0012, 0x410: 0x0013, 0x411: 0x0013,
+ 0x412: 0x0013, 0x413: 0x0012, 0x415: 0x0013,
+ 0x419: 0x0013, 0x41a: 0x0013, 0x41b: 0x0013, 0x41c: 0x0013, 0x41d: 0x0013,
+ 0x424: 0x0013, 0x426: 0x886b, 0x428: 0x0013,
+ 0x42a: 0x88cb, 0x42b: 0x890b, 0x42c: 0x0013, 0x42d: 0x0013, 0x42f: 0x0012,
+ 0x430: 0x0013, 0x431: 0x0013, 0x432: 0xa453, 0x433: 0x0013, 0x434: 0x0012, 0x435: 0x0010,
+ 0x436: 0x0010, 0x437: 0x0010, 0x438: 0x0010, 0x439: 0x0012,
+ 0x43c: 0x0012, 0x43d: 0x0012, 0x43e: 0x0013, 0x43f: 0x0013,
+ // Block 0x11, offset 0x440
+ 0x440: 0x1a13, 0x441: 0x1a13, 0x442: 0x1e13, 0x443: 0x1e13, 0x444: 0x1a13, 0x445: 0x1a13,
+ 0x446: 0x2613, 0x447: 0x2613, 0x448: 0x2a13, 0x449: 0x2a13, 0x44a: 0x2e13, 0x44b: 0x2e13,
+ 0x44c: 0x2a13, 0x44d: 0x2a13, 0x44e: 0x2613, 0x44f: 0x2613, 0x450: 0xa752, 0x451: 0xa752,
+ 0x452: 0xaa52, 0x453: 0xaa52, 0x454: 0xad52, 0x455: 0xad52, 0x456: 0xaa52, 0x457: 0xaa52,
+ 0x458: 0xa752, 0x459: 0xa752, 0x45a: 0x1a12, 0x45b: 0x1a12, 0x45c: 0x1e12, 0x45d: 0x1e12,
+ 0x45e: 0x1a12, 0x45f: 0x1a12, 0x460: 0x2612, 0x461: 0x2612, 0x462: 0x2a12, 0x463: 0x2a12,
+ 0x464: 0x2e12, 0x465: 0x2e12, 0x466: 0x2a12, 0x467: 0x2a12, 0x468: 0x2612, 0x469: 0x2612,
+ // Block 0x12, offset 0x480
+ 0x480: 0x6552, 0x481: 0x6552, 0x482: 0x6552, 0x483: 0x6552, 0x484: 0x6552, 0x485: 0x6552,
+ 0x486: 0x6552, 0x487: 0x6552, 0x488: 0x6552, 0x489: 0x6552, 0x48a: 0x6552, 0x48b: 0x6552,
+ 0x48c: 0x6552, 0x48d: 0x6552, 0x48e: 0x6552, 0x48f: 0x6552, 0x490: 0xb052, 0x491: 0xb052,
+ 0x492: 0xb052, 0x493: 0xb052, 0x494: 0xb052, 0x495: 0xb052, 0x496: 0xb052, 0x497: 0xb052,
+ 0x498: 0xb052, 0x499: 0xb052, 0x49a: 0xb052, 0x49b: 0xb052, 0x49c: 0xb052, 0x49d: 0xb052,
+ 0x49e: 0xb052, 0x49f: 0xb052, 0x4a0: 0x0113, 0x4a1: 0x0112, 0x4a2: 0x896b, 0x4a3: 0x8b53,
+ 0x4a4: 0x89cb, 0x4a5: 0x8a2a, 0x4a6: 0x8a8a, 0x4a7: 0x0f13, 0x4a8: 0x0f12, 0x4a9: 0x0313,
+ 0x4aa: 0x0312, 0x4ab: 0x0713, 0x4ac: 0x0712, 0x4ad: 0x8aeb, 0x4ae: 0x8b4b, 0x4af: 0x8bab,
+ 0x4b0: 0x8c0b, 0x4b1: 0x0012, 0x4b2: 0x0113, 0x4b3: 0x0112, 0x4b4: 0x0012, 0x4b5: 0x0313,
+ 0x4b6: 0x0312, 0x4b7: 0x0012, 0x4b8: 0x0012, 0x4b9: 0x0012, 0x4ba: 0x0012, 0x4bb: 0x0012,
+ 0x4bc: 0x0015, 0x4bd: 0x0015, 0x4be: 0x8c6b, 0x4bf: 0x8ccb,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0x0113, 0x4c1: 0x0112, 0x4c2: 0x0113, 0x4c3: 0x0112, 0x4c4: 0x0113, 0x4c5: 0x0112,
+ 0x4c6: 0x0113, 0x4c7: 0x0112, 0x4c8: 0x0014, 0x4c9: 0x0014, 0x4ca: 0x0014, 0x4cb: 0x0713,
+ 0x4cc: 0x0712, 0x4cd: 0x8d2b, 0x4ce: 0x0012, 0x4cf: 0x0010, 0x4d0: 0x0113, 0x4d1: 0x0112,
+ 0x4d2: 0x0113, 0x4d3: 0x0112, 0x4d4: 0x6552, 0x4d5: 0x0012, 0x4d6: 0x0113, 0x4d7: 0x0112,
+ 0x4d8: 0x0113, 0x4d9: 0x0112, 0x4da: 0x0113, 0x4db: 0x0112, 0x4dc: 0x0113, 0x4dd: 0x0112,
+ 0x4de: 0x0113, 0x4df: 0x0112, 0x4e0: 0x0113, 0x4e1: 0x0112, 0x4e2: 0x0113, 0x4e3: 0x0112,
+ 0x4e4: 0x0113, 0x4e5: 0x0112, 0x4e6: 0x0113, 0x4e7: 0x0112, 0x4e8: 0x0113, 0x4e9: 0x0112,
+ 0x4ea: 0x8d8b, 0x4eb: 0x8deb, 0x4ec: 0x8e4b, 0x4ed: 0x8eab, 0x4ee: 0x8f0b, 0x4ef: 0x0012,
+ 0x4f0: 0x8f6b, 0x4f1: 0x8fcb, 0x4f2: 0x902b, 0x4f3: 0xb353, 0x4f4: 0x0113, 0x4f5: 0x0112,
+ 0x4f6: 0x0113, 0x4f7: 0x0112, 0x4f8: 0x0113, 0x4f9: 0x0112, 0x4fa: 0x0113, 0x4fb: 0x0112,
+ 0x4fc: 0x0113, 0x4fd: 0x0112, 0x4fe: 0x0113, 0x4ff: 0x0112,
+ // Block 0x14, offset 0x500
+ 0x500: 0x90ea, 0x501: 0x916a, 0x502: 0x91ea, 0x503: 0x926a, 0x504: 0x931a, 0x505: 0x93ca,
+ 0x506: 0x944a,
+ 0x513: 0x94ca, 0x514: 0x95aa, 0x515: 0x968a, 0x516: 0x976a, 0x517: 0x984a,
+ 0x51d: 0x0010,
+ 0x51e: 0x0034, 0x51f: 0x0010, 0x520: 0x0010, 0x521: 0x0010, 0x522: 0x0010, 0x523: 0x0010,
+ 0x524: 0x0010, 0x525: 0x0010, 0x526: 0x0010, 0x527: 0x0010, 0x528: 0x0010,
+ 0x52a: 0x0010, 0x52b: 0x0010, 0x52c: 0x0010, 0x52d: 0x0010, 0x52e: 0x0010, 0x52f: 0x0010,
+ 0x530: 0x0010, 0x531: 0x0010, 0x532: 0x0010, 0x533: 0x0010, 0x534: 0x0010, 0x535: 0x0010,
+ 0x536: 0x0010, 0x538: 0x0010, 0x539: 0x0010, 0x53a: 0x0010, 0x53b: 0x0010,
+ 0x53c: 0x0010, 0x53e: 0x0010,
+ // Block 0x15, offset 0x540
+ 0x540: 0x2713, 0x541: 0x2913, 0x542: 0x2b13, 0x543: 0x2913, 0x544: 0x2f13, 0x545: 0x2913,
+ 0x546: 0x2b13, 0x547: 0x2913, 0x548: 0x2713, 0x549: 0x3913, 0x54a: 0x3b13,
+ 0x54c: 0x3f13, 0x54d: 0x3913, 0x54e: 0x3b13, 0x54f: 0x3913, 0x550: 0x2713, 0x551: 0x2913,
+ 0x552: 0x2b13, 0x554: 0x2f13, 0x555: 0x2913, 0x557: 0xbc52,
+ 0x558: 0xbf52, 0x559: 0xc252, 0x55a: 0xbf52, 0x55b: 0xc552, 0x55c: 0xbf52, 0x55d: 0xc252,
+ 0x55e: 0xbf52, 0x55f: 0xbc52, 0x560: 0xc852, 0x561: 0xcb52, 0x563: 0xce52,
+ 0x564: 0xc852, 0x565: 0xcb52, 0x566: 0xc852, 0x567: 0x2712, 0x568: 0x2912, 0x569: 0x2b12,
+ 0x56a: 0x2912, 0x56b: 0x2f12, 0x56c: 0x2912, 0x56d: 0x2b12, 0x56e: 0x2912, 0x56f: 0x2712,
+ 0x570: 0x3912, 0x571: 0x3b12, 0x573: 0x3f12, 0x574: 0x3912, 0x575: 0x3b12,
+ 0x576: 0x3912, 0x577: 0x2712, 0x578: 0x2912, 0x579: 0x2b12, 0x57b: 0x2f12,
+ 0x57c: 0x2912,
+ // Block 0x16, offset 0x580
+ 0x580: 0x2213, 0x581: 0x2213, 0x582: 0x2613, 0x583: 0x2613, 0x584: 0x2213, 0x585: 0x2213,
+ 0x586: 0x2e13, 0x587: 0x2e13, 0x588: 0x2213, 0x589: 0x2213, 0x58a: 0x2613, 0x58b: 0x2613,
+ 0x58c: 0x2213, 0x58d: 0x2213, 0x58e: 0x3e13, 0x58f: 0x3e13, 0x590: 0x2213, 0x591: 0x2213,
+ 0x592: 0x2613, 0x593: 0x2613, 0x594: 0x2213, 0x595: 0x2213, 0x596: 0x2e13, 0x597: 0x2e13,
+ 0x598: 0x2213, 0x599: 0x2213, 0x59a: 0x2613, 0x59b: 0x2613, 0x59c: 0x2213, 0x59d: 0x2213,
+ 0x59e: 0xd153, 0x59f: 0xd153, 0x5a0: 0xd453, 0x5a1: 0xd453, 0x5a2: 0x2212, 0x5a3: 0x2212,
+ 0x5a4: 0x2612, 0x5a5: 0x2612, 0x5a6: 0x2212, 0x5a7: 0x2212, 0x5a8: 0x2e12, 0x5a9: 0x2e12,
+ 0x5aa: 0x2212, 0x5ab: 0x2212, 0x5ac: 0x2612, 0x5ad: 0x2612, 0x5ae: 0x2212, 0x5af: 0x2212,
+ 0x5b0: 0x3e12, 0x5b1: 0x3e12, 0x5b2: 0x2212, 0x5b3: 0x2212, 0x5b4: 0x2612, 0x5b5: 0x2612,
+ 0x5b6: 0x2212, 0x5b7: 0x2212, 0x5b8: 0x2e12, 0x5b9: 0x2e12, 0x5ba: 0x2212, 0x5bb: 0x2212,
+ 0x5bc: 0x2612, 0x5bd: 0x2612, 0x5be: 0x2212, 0x5bf: 0x2212,
+ // Block 0x17, offset 0x5c0
+ 0x5c2: 0x0010,
+ 0x5c7: 0x0010, 0x5c9: 0x0010, 0x5cb: 0x0010,
+ 0x5cd: 0x0010, 0x5ce: 0x0010, 0x5cf: 0x0010, 0x5d1: 0x0010,
+ 0x5d2: 0x0010, 0x5d4: 0x0010, 0x5d7: 0x0010,
+ 0x5d9: 0x0010, 0x5db: 0x0010, 0x5dd: 0x0010,
+ 0x5df: 0x0010, 0x5e1: 0x0010, 0x5e2: 0x0010,
+ 0x5e4: 0x0010, 0x5e7: 0x0010, 0x5e8: 0x0010, 0x5e9: 0x0010,
+ 0x5ea: 0x0010, 0x5ec: 0x0010, 0x5ed: 0x0010, 0x5ee: 0x0010, 0x5ef: 0x0010,
+ 0x5f0: 0x0010, 0x5f1: 0x0010, 0x5f2: 0x0010, 0x5f4: 0x0010, 0x5f5: 0x0010,
+ 0x5f6: 0x0010, 0x5f7: 0x0010, 0x5f9: 0x0010, 0x5fa: 0x0010, 0x5fb: 0x0010,
+ 0x5fc: 0x0010, 0x5fe: 0x0010,
+}
+
+// caseIndex: 27 blocks, 1728 entries, 3456 bytes
+// Block 0 is the zero block.
+var caseIndex = [1728]uint16{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x16, 0xc3: 0x17, 0xc4: 0x18, 0xc5: 0x19, 0xc6: 0x01, 0xc7: 0x02,
+ 0xc8: 0x1a, 0xc9: 0x03, 0xca: 0x04, 0xcb: 0x1b, 0xcc: 0x1c, 0xcd: 0x05, 0xce: 0x06, 0xcf: 0x07,
+ 0xd0: 0x1d, 0xd1: 0x1e, 0xd2: 0x1f, 0xd3: 0x20, 0xd4: 0x21, 0xd5: 0x22, 0xd6: 0x08, 0xd7: 0x23,
+ 0xd8: 0x24, 0xd9: 0x25, 0xda: 0x26, 0xdb: 0x27, 0xdc: 0x28, 0xdd: 0x29, 0xde: 0x2a, 0xdf: 0x2b,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+ 0xea: 0x06, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x08, 0xef: 0x09,
+ 0xf0: 0x16, 0xf3: 0x18,
+ // Block 0x4, offset 0x100
+ 0x120: 0x2c, 0x121: 0x2d, 0x122: 0x2e, 0x123: 0x09, 0x124: 0x2f, 0x125: 0x30, 0x126: 0x31, 0x127: 0x32,
+ 0x128: 0x33, 0x129: 0x34, 0x12a: 0x35, 0x12b: 0x36, 0x12c: 0x37, 0x12d: 0x38, 0x12e: 0x39, 0x12f: 0x3a,
+ 0x130: 0x3b, 0x131: 0x3c, 0x132: 0x3d, 0x133: 0x3e, 0x134: 0x3f, 0x135: 0x40, 0x136: 0x41, 0x137: 0x42,
+ 0x138: 0x43, 0x139: 0x44, 0x13a: 0x45, 0x13b: 0x46, 0x13c: 0x47, 0x13d: 0x48, 0x13e: 0x49, 0x13f: 0x4a,
+ // Block 0x5, offset 0x140
+ 0x140: 0x4b, 0x141: 0x4c, 0x142: 0x4d, 0x143: 0x0a, 0x144: 0x26, 0x145: 0x26, 0x146: 0x26, 0x147: 0x26,
+ 0x148: 0x26, 0x149: 0x4e, 0x14a: 0x4f, 0x14b: 0x50, 0x14c: 0x51, 0x14d: 0x52, 0x14e: 0x53, 0x14f: 0x54,
+ 0x150: 0x55, 0x151: 0x26, 0x152: 0x26, 0x153: 0x26, 0x154: 0x26, 0x155: 0x26, 0x156: 0x26, 0x157: 0x26,
+ 0x158: 0x26, 0x159: 0x56, 0x15a: 0x57, 0x15b: 0x58, 0x15c: 0x59, 0x15d: 0x5a, 0x15e: 0x5b, 0x15f: 0x5c,
+ 0x160: 0x5d, 0x161: 0x5e, 0x162: 0x5f, 0x163: 0x60, 0x164: 0x61, 0x165: 0x62, 0x167: 0x63,
+ 0x168: 0x64, 0x169: 0x65, 0x16a: 0x66, 0x16b: 0x67, 0x16c: 0x68, 0x16d: 0x69, 0x16e: 0x6a, 0x16f: 0x6b,
+ 0x170: 0x6c, 0x171: 0x6d, 0x172: 0x6e, 0x173: 0x6f, 0x174: 0x70, 0x175: 0x71, 0x176: 0x72, 0x177: 0x73,
+ 0x178: 0x74, 0x179: 0x74, 0x17a: 0x75, 0x17b: 0x74, 0x17c: 0x76, 0x17d: 0x0b, 0x17e: 0x0c, 0x17f: 0x0d,
+ // Block 0x6, offset 0x180
+ 0x180: 0x77, 0x181: 0x78, 0x182: 0x79, 0x183: 0x7a, 0x184: 0x0e, 0x185: 0x7b, 0x186: 0x7c,
+ 0x192: 0x7d, 0x193: 0x0f,
+ 0x1b0: 0x7e, 0x1b1: 0x10, 0x1b2: 0x74, 0x1b3: 0x7f, 0x1b4: 0x80, 0x1b5: 0x81, 0x1b6: 0x82, 0x1b7: 0x83,
+ 0x1b8: 0x84,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x85, 0x1c2: 0x86, 0x1c3: 0x87, 0x1c4: 0x88, 0x1c5: 0x26, 0x1c6: 0x89,
+ // Block 0x8, offset 0x200
+ 0x200: 0x8a, 0x201: 0x26, 0x202: 0x26, 0x203: 0x26, 0x204: 0x26, 0x205: 0x26, 0x206: 0x26, 0x207: 0x26,
+ 0x208: 0x26, 0x209: 0x26, 0x20a: 0x26, 0x20b: 0x26, 0x20c: 0x26, 0x20d: 0x26, 0x20e: 0x26, 0x20f: 0x26,
+ 0x210: 0x26, 0x211: 0x26, 0x212: 0x8b, 0x213: 0x8c, 0x214: 0x26, 0x215: 0x26, 0x216: 0x26, 0x217: 0x26,
+ 0x218: 0x8d, 0x219: 0x8e, 0x21a: 0x8f, 0x21b: 0x90, 0x21c: 0x91, 0x21d: 0x92, 0x21e: 0x11, 0x21f: 0x93,
+ 0x220: 0x94, 0x221: 0x95, 0x222: 0x26, 0x223: 0x96, 0x224: 0x97, 0x225: 0x98, 0x226: 0x99, 0x227: 0x9a,
+ 0x228: 0x9b, 0x229: 0x9c, 0x22a: 0x9d, 0x22b: 0x9e, 0x22c: 0x9f, 0x22d: 0xa0, 0x22e: 0xa1, 0x22f: 0xa2,
+ 0x230: 0x26, 0x231: 0x26, 0x232: 0x26, 0x233: 0x26, 0x234: 0x26, 0x235: 0x26, 0x236: 0x26, 0x237: 0x26,
+ 0x238: 0x26, 0x239: 0x26, 0x23a: 0x26, 0x23b: 0x26, 0x23c: 0x26, 0x23d: 0x26, 0x23e: 0x26, 0x23f: 0x26,
+ // Block 0x9, offset 0x240
+ 0x240: 0x26, 0x241: 0x26, 0x242: 0x26, 0x243: 0x26, 0x244: 0x26, 0x245: 0x26, 0x246: 0x26, 0x247: 0x26,
+ 0x248: 0x26, 0x249: 0x26, 0x24a: 0x26, 0x24b: 0x26, 0x24c: 0x26, 0x24d: 0x26, 0x24e: 0x26, 0x24f: 0x26,
+ 0x250: 0x26, 0x251: 0x26, 0x252: 0x26, 0x253: 0x26, 0x254: 0x26, 0x255: 0x26, 0x256: 0x26, 0x257: 0x26,
+ 0x258: 0x26, 0x259: 0x26, 0x25a: 0x26, 0x25b: 0x26, 0x25c: 0x26, 0x25d: 0x26, 0x25e: 0x26, 0x25f: 0x26,
+ 0x260: 0x26, 0x261: 0x26, 0x262: 0x26, 0x263: 0x26, 0x264: 0x26, 0x265: 0x26, 0x266: 0x26, 0x267: 0x26,
+ 0x268: 0x26, 0x269: 0x26, 0x26a: 0x26, 0x26b: 0x26, 0x26c: 0x26, 0x26d: 0x26, 0x26e: 0x26, 0x26f: 0x26,
+ 0x270: 0x26, 0x271: 0x26, 0x272: 0x26, 0x273: 0x26, 0x274: 0x26, 0x275: 0x26, 0x276: 0x26, 0x277: 0x26,
+ 0x278: 0x26, 0x279: 0x26, 0x27a: 0x26, 0x27b: 0x26, 0x27c: 0x26, 0x27d: 0x26, 0x27e: 0x26, 0x27f: 0x26,
+ // Block 0xa, offset 0x280
+ 0x280: 0x26, 0x281: 0x26, 0x282: 0x26, 0x283: 0x26, 0x284: 0x26, 0x285: 0x26, 0x286: 0x26, 0x287: 0x26,
+ 0x288: 0x26, 0x289: 0x26, 0x28a: 0x26, 0x28b: 0x26, 0x28c: 0x26, 0x28d: 0x26, 0x28e: 0x26, 0x28f: 0x26,
+ 0x290: 0x26, 0x291: 0x26, 0x292: 0x26, 0x293: 0x26, 0x294: 0x26, 0x295: 0x26, 0x296: 0x26, 0x297: 0x26,
+ 0x298: 0x26, 0x299: 0x26, 0x29a: 0x26, 0x29b: 0x26, 0x29c: 0x26, 0x29d: 0x26, 0x29e: 0xa3, 0x29f: 0xa4,
+ // Block 0xb, offset 0x2c0
+ 0x2ec: 0x12, 0x2ed: 0xa5, 0x2ee: 0xa6, 0x2ef: 0xa7,
+ 0x2f0: 0x26, 0x2f1: 0x26, 0x2f2: 0x26, 0x2f3: 0x26, 0x2f4: 0xa8, 0x2f5: 0xa9, 0x2f6: 0xaa, 0x2f7: 0xab,
+ 0x2f8: 0xac, 0x2f9: 0xad, 0x2fa: 0x26, 0x2fb: 0xae, 0x2fc: 0xaf, 0x2fd: 0xb0, 0x2fe: 0xb1, 0x2ff: 0xb2,
+ // Block 0xc, offset 0x300
+ 0x300: 0xb3, 0x301: 0xb4, 0x302: 0x26, 0x303: 0xb5, 0x305: 0xb6, 0x307: 0xb7,
+ 0x30a: 0xb8, 0x30b: 0xb9, 0x30c: 0xba, 0x30d: 0xbb, 0x30e: 0xbc, 0x30f: 0xbd,
+ 0x310: 0xbe, 0x311: 0xbf, 0x312: 0xc0, 0x313: 0xc1, 0x314: 0xc2, 0x315: 0xc3, 0x316: 0x13,
+ 0x318: 0x26, 0x319: 0x26, 0x31a: 0x26, 0x31b: 0x26, 0x31c: 0xc4, 0x31d: 0xc5, 0x31e: 0xc6,
+ 0x320: 0xc7, 0x321: 0xc8, 0x322: 0xc9, 0x323: 0xca, 0x324: 0xcb, 0x326: 0xcc,
+ 0x328: 0xcd, 0x329: 0xce, 0x32a: 0xcf, 0x32b: 0xd0, 0x32c: 0x60, 0x32d: 0xd1, 0x32e: 0xd2,
+ 0x330: 0x26, 0x331: 0xd3, 0x332: 0xd4, 0x333: 0xd5, 0x334: 0xd6,
+ 0x33a: 0xd7, 0x33b: 0xd8, 0x33c: 0xd9, 0x33d: 0xda, 0x33e: 0xdb, 0x33f: 0xdc,
+ // Block 0xd, offset 0x340
+ 0x340: 0xdd, 0x341: 0xde, 0x342: 0xdf, 0x343: 0xe0, 0x344: 0xe1, 0x345: 0xe2, 0x346: 0xe3, 0x347: 0xe4,
+ 0x348: 0xe5, 0x349: 0xe6, 0x34a: 0xe7, 0x34b: 0xe8, 0x34c: 0xe9, 0x34d: 0xea,
+ 0x350: 0xeb, 0x351: 0xec, 0x352: 0xed, 0x353: 0xee, 0x356: 0xef, 0x357: 0xf0,
+ 0x358: 0xf1, 0x359: 0xf2, 0x35a: 0xf3, 0x35b: 0xf4, 0x35c: 0xf5,
+ 0x360: 0xf6, 0x362: 0xf7, 0x363: 0xf8, 0x364: 0xf9, 0x365: 0xfa, 0x366: 0xfb, 0x367: 0xfc,
+ 0x368: 0xfd, 0x369: 0xfe, 0x36a: 0xff, 0x36b: 0x100,
+ 0x370: 0x101, 0x371: 0x102, 0x372: 0x103, 0x374: 0x104, 0x375: 0x105, 0x376: 0x106,
+ 0x37b: 0x107, 0x37c: 0x108, 0x37d: 0x109, 0x37e: 0x10a,
+ // Block 0xe, offset 0x380
+ 0x380: 0x26, 0x381: 0x26, 0x382: 0x26, 0x383: 0x26, 0x384: 0x26, 0x385: 0x26, 0x386: 0x26, 0x387: 0x26,
+ 0x388: 0x26, 0x389: 0x26, 0x38a: 0x26, 0x38b: 0x26, 0x38c: 0x26, 0x38d: 0x26, 0x38e: 0x10b,
+ 0x390: 0x26, 0x391: 0x10c, 0x392: 0x26, 0x393: 0x26, 0x394: 0x26, 0x395: 0x10d,
+ 0x3be: 0xa9, 0x3bf: 0x10e,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x26, 0x3c1: 0x26, 0x3c2: 0x26, 0x3c3: 0x26, 0x3c4: 0x26, 0x3c5: 0x26, 0x3c6: 0x26, 0x3c7: 0x26,
+ 0x3c8: 0x26, 0x3c9: 0x26, 0x3ca: 0x26, 0x3cb: 0x26, 0x3cc: 0x26, 0x3cd: 0x26, 0x3ce: 0x26, 0x3cf: 0x26,
+ 0x3d0: 0x10f, 0x3d1: 0x110,
+ // Block 0x10, offset 0x400
+ 0x410: 0x26, 0x411: 0x26, 0x412: 0x26, 0x413: 0x26, 0x414: 0x26, 0x415: 0x26, 0x416: 0x26, 0x417: 0x26,
+ 0x418: 0x26, 0x419: 0x111,
+ // Block 0x11, offset 0x440
+ 0x460: 0x26, 0x461: 0x26, 0x462: 0x26, 0x463: 0x26, 0x464: 0x26, 0x465: 0x26, 0x466: 0x26, 0x467: 0x26,
+ 0x468: 0x100, 0x469: 0x112, 0x46a: 0x113, 0x46b: 0x114, 0x46c: 0x115, 0x46d: 0x116, 0x46e: 0x117,
+ 0x479: 0x118, 0x47c: 0x26, 0x47d: 0x119, 0x47e: 0x11a, 0x47f: 0x11b,
+ // Block 0x12, offset 0x480
+ 0x4bf: 0x11c,
+ // Block 0x13, offset 0x4c0
+ 0x4f0: 0x26, 0x4f1: 0x11d, 0x4f2: 0x11e,
+ // Block 0x14, offset 0x500
+ 0x53c: 0x11f, 0x53d: 0x120,
+ // Block 0x15, offset 0x540
+ 0x545: 0x121, 0x546: 0x122,
+ 0x549: 0x123,
+ 0x550: 0x124, 0x551: 0x125, 0x552: 0x126, 0x553: 0x127, 0x554: 0x128, 0x555: 0x129, 0x556: 0x12a, 0x557: 0x12b,
+ 0x558: 0x12c, 0x559: 0x12d, 0x55a: 0x12e, 0x55b: 0x12f, 0x55c: 0x130, 0x55d: 0x131, 0x55e: 0x132, 0x55f: 0x133,
+ 0x568: 0x134, 0x569: 0x135, 0x56a: 0x136,
+ 0x57c: 0x137,
+ // Block 0x16, offset 0x580
+ 0x580: 0x138, 0x581: 0x139, 0x582: 0x13a, 0x584: 0x13b, 0x585: 0x13c,
+ 0x58a: 0x13d, 0x58b: 0x13e,
+ 0x593: 0x13f,
+ 0x59f: 0x140,
+ 0x5a0: 0x26, 0x5a1: 0x26, 0x5a2: 0x26, 0x5a3: 0x141, 0x5a4: 0x14, 0x5a5: 0x142,
+ 0x5b8: 0x143, 0x5b9: 0x15, 0x5ba: 0x144,
+ // Block 0x17, offset 0x5c0
+ 0x5c4: 0x145, 0x5c5: 0x146, 0x5c6: 0x147,
+ 0x5cf: 0x148,
+ 0x5ef: 0x149,
+ // Block 0x18, offset 0x600
+ 0x610: 0x0a, 0x611: 0x0b, 0x612: 0x0c, 0x613: 0x0d, 0x614: 0x0e, 0x616: 0x0f,
+ 0x61a: 0x10, 0x61b: 0x11, 0x61c: 0x12, 0x61d: 0x13, 0x61e: 0x14, 0x61f: 0x15,
+ // Block 0x19, offset 0x640
+ 0x640: 0x14a, 0x641: 0x14b, 0x644: 0x14b, 0x645: 0x14b, 0x646: 0x14b, 0x647: 0x14c,
+ // Block 0x1a, offset 0x680
+ 0x6a0: 0x17,
+}
+
+// sparseOffsets: 312 entries, 624 bytes
+var sparseOffsets = []uint16{0x0, 0x9, 0xf, 0x18, 0x24, 0x2e, 0x34, 0x37, 0x3b, 0x3e, 0x42, 0x4c, 0x4e, 0x57, 0x5e, 0x63, 0x71, 0x72, 0x80, 0x8f, 0x99, 0x9c, 0xa3, 0xab, 0xaf, 0xb7, 0xbd, 0xcb, 0xd6, 0xe3, 0xee, 0xfa, 0x104, 0x110, 0x11b, 0x127, 0x133, 0x13b, 0x145, 0x150, 0x15b, 0x167, 0x16d, 0x178, 0x17e, 0x186, 0x189, 0x18e, 0x192, 0x196, 0x19d, 0x1a6, 0x1ae, 0x1af, 0x1b8, 0x1bf, 0x1c7, 0x1cd, 0x1d2, 0x1d6, 0x1d9, 0x1db, 0x1de, 0x1e3, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1f1, 0x1f6, 0x1fa, 0x203, 0x206, 0x209, 0x20f, 0x210, 0x21b, 0x21c, 0x21d, 0x222, 0x22f, 0x238, 0x23e, 0x246, 0x24f, 0x258, 0x261, 0x266, 0x269, 0x274, 0x282, 0x284, 0x28b, 0x28f, 0x29b, 0x29c, 0x2a7, 0x2af, 0x2b7, 0x2bd, 0x2be, 0x2cc, 0x2d1, 0x2d4, 0x2d9, 0x2dd, 0x2e3, 0x2e8, 0x2eb, 0x2f0, 0x2f5, 0x2f6, 0x2fc, 0x2fe, 0x2ff, 0x301, 0x303, 0x306, 0x307, 0x309, 0x30c, 0x312, 0x316, 0x318, 0x31d, 0x324, 0x334, 0x33e, 0x33f, 0x348, 0x34c, 0x351, 0x359, 0x35f, 0x365, 0x36f, 0x374, 0x37d, 0x383, 0x38c, 0x390, 0x398, 0x39a, 0x39c, 0x39f, 0x3a1, 0x3a3, 0x3a4, 0x3a5, 0x3a7, 0x3a9, 0x3af, 0x3b4, 0x3b6, 0x3bd, 0x3c0, 0x3c2, 0x3c8, 0x3cd, 0x3cf, 0x3d0, 0x3d1, 0x3d2, 0x3d4, 0x3d6, 0x3d8, 0x3db, 0x3dd, 0x3e0, 0x3e8, 0x3eb, 0x3ef, 0x3f7, 0x3f9, 0x409, 0x40a, 0x40c, 0x411, 0x417, 0x419, 0x41a, 0x41c, 0x41e, 0x420, 0x42d, 0x42e, 0x42f, 0x433, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43c, 0x43f, 0x440, 0x443, 0x44a, 0x450, 0x452, 0x456, 0x45e, 0x464, 0x468, 0x46f, 0x473, 0x477, 0x480, 0x48a, 0x48c, 0x492, 0x498, 0x4a2, 0x4ac, 0x4ae, 0x4b7, 0x4bd, 0x4c3, 0x4c9, 0x4cc, 0x4d2, 0x4d5, 0x4de, 0x4df, 0x4e6, 0x4ea, 0x4eb, 0x4ee, 0x4f8, 0x4fb, 0x4fd, 0x504, 0x50c, 0x512, 0x519, 0x51a, 0x520, 0x523, 0x52b, 0x532, 0x53c, 0x544, 0x547, 0x54c, 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x557, 0x55a, 0x55b, 0x55e, 0x55f, 0x562, 0x564, 0x568, 0x569, 0x56b, 0x56e, 0x570, 0x573, 0x576, 0x578, 0x57d, 0x57f, 0x580, 0x585, 0x589, 0x58a, 0x58d, 0x591, 0x59c, 0x5a0, 0x5a8, 0x5ad, 0x5b1, 0x5b4, 0x5b8, 0x5bb, 0x5be, 0x5c3, 0x5c7, 0x5cb, 0x5cf, 0x5d3, 0x5d5, 0x5d7, 0x5da, 0x5de, 0x5e4, 0x5e5, 0x5e6, 0x5e9, 0x5eb, 0x5ed, 0x5f0, 0x5f5, 0x5f9, 0x5fb, 0x601, 0x60a, 0x60f, 0x610, 0x613, 0x614, 0x615, 0x616, 0x618, 0x619, 0x61a}
+
+// sparseValues: 1562 entries, 6248 bytes
+var sparseValues = [1562]valueRange{
+ // Block 0x0, offset 0x0
+ {value: 0x0004, lo: 0xa8, hi: 0xa8},
+ {value: 0x0012, lo: 0xaa, hi: 0xaa},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0004, lo: 0xaf, hi: 0xaf},
+ {value: 0x0004, lo: 0xb4, hi: 0xb4},
+ {value: 0x001a, lo: 0xb5, hi: 0xb5},
+ {value: 0x0054, lo: 0xb7, hi: 0xb7},
+ {value: 0x0004, lo: 0xb8, hi: 0xb8},
+ {value: 0x0012, lo: 0xba, hi: 0xba},
+ // Block 0x1, offset 0x9
+ {value: 0x2013, lo: 0x80, hi: 0x96},
+ {value: 0x2013, lo: 0x98, hi: 0x9e},
+ {value: 0x009a, lo: 0x9f, hi: 0x9f},
+ {value: 0x2012, lo: 0xa0, hi: 0xb6},
+ {value: 0x2012, lo: 0xb8, hi: 0xbe},
+ {value: 0x0252, lo: 0xbf, hi: 0xbf},
+ // Block 0x2, offset 0xf
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x011b, lo: 0xb0, hi: 0xb0},
+ {value: 0x019a, lo: 0xb1, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xb7},
+ {value: 0x0012, lo: 0xb8, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x0316, lo: 0xbd, hi: 0xbe},
+ {value: 0x0553, lo: 0xbf, hi: 0xbf},
+ // Block 0x3, offset 0x18
+ {value: 0x0552, lo: 0x80, hi: 0x80},
+ {value: 0x0316, lo: 0x81, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0316, lo: 0x85, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x01da, lo: 0x89, hi: 0x89},
+ {value: 0x0117, lo: 0x8a, hi: 0xb7},
+ {value: 0x0253, lo: 0xb8, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x0316, lo: 0xbd, hi: 0xbe},
+ {value: 0x028a, lo: 0xbf, hi: 0xbf},
+ // Block 0x4, offset 0x24
+ {value: 0x0117, lo: 0x80, hi: 0x9f},
+ {value: 0x2f53, lo: 0xa0, hi: 0xa0},
+ {value: 0x0012, lo: 0xa1, hi: 0xa1},
+ {value: 0x0117, lo: 0xa2, hi: 0xb3},
+ {value: 0x0012, lo: 0xb4, hi: 0xb9},
+ {value: 0x090b, lo: 0xba, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x2953, lo: 0xbd, hi: 0xbd},
+ {value: 0x098b, lo: 0xbe, hi: 0xbe},
+ {value: 0x0a0a, lo: 0xbf, hi: 0xbf},
+ // Block 0x5, offset 0x2e
+ {value: 0x0015, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x97},
+ {value: 0x0004, lo: 0x98, hi: 0x9d},
+ {value: 0x0014, lo: 0x9e, hi: 0x9f},
+ {value: 0x0015, lo: 0xa0, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xbf},
+ // Block 0x6, offset 0x34
+ {value: 0x0024, lo: 0x80, hi: 0x94},
+ {value: 0x0034, lo: 0x95, hi: 0xbc},
+ {value: 0x0024, lo: 0xbd, hi: 0xbf},
+ // Block 0x7, offset 0x37
+ {value: 0x6553, lo: 0x80, hi: 0x8f},
+ {value: 0x2013, lo: 0x90, hi: 0x9f},
+ {value: 0x5f53, lo: 0xa0, hi: 0xaf},
+ {value: 0x2012, lo: 0xb0, hi: 0xbf},
+ // Block 0x8, offset 0x3b
+ {value: 0x5f52, lo: 0x80, hi: 0x8f},
+ {value: 0x6552, lo: 0x90, hi: 0x9f},
+ {value: 0x0117, lo: 0xa0, hi: 0xbf},
+ // Block 0x9, offset 0x3e
+ {value: 0x0117, lo: 0x80, hi: 0x81},
+ {value: 0x0024, lo: 0x83, hi: 0x87},
+ {value: 0x0014, lo: 0x88, hi: 0x89},
+ {value: 0x0117, lo: 0x8a, hi: 0xbf},
+ // Block 0xa, offset 0x42
+ {value: 0x0f13, lo: 0x80, hi: 0x80},
+ {value: 0x0316, lo: 0x81, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0316, lo: 0x85, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x0316, lo: 0x89, hi: 0x8a},
+ {value: 0x0716, lo: 0x8b, hi: 0x8c},
+ {value: 0x0316, lo: 0x8d, hi: 0x8e},
+ {value: 0x0f12, lo: 0x8f, hi: 0x8f},
+ {value: 0x0117, lo: 0x90, hi: 0xbf},
+ // Block 0xb, offset 0x4c
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x6553, lo: 0xb1, hi: 0xbf},
+ // Block 0xc, offset 0x4e
+ {value: 0x3013, lo: 0x80, hi: 0x8f},
+ {value: 0x6853, lo: 0x90, hi: 0x96},
+ {value: 0x0014, lo: 0x99, hi: 0x99},
+ {value: 0x0010, lo: 0x9a, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9e},
+ {value: 0x0054, lo: 0x9f, hi: 0x9f},
+ {value: 0x0012, lo: 0xa0, hi: 0xa0},
+ {value: 0x6552, lo: 0xa1, hi: 0xaf},
+ {value: 0x3012, lo: 0xb0, hi: 0xbf},
+ // Block 0xd, offset 0x57
+ {value: 0x0034, lo: 0x81, hi: 0x82},
+ {value: 0x0024, lo: 0x84, hi: 0x84},
+ {value: 0x0034, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0xaa},
+ {value: 0x0010, lo: 0xaf, hi: 0xb3},
+ {value: 0x0054, lo: 0xb4, hi: 0xb4},
+ // Block 0xe, offset 0x5e
+ {value: 0x0014, lo: 0x80, hi: 0x85},
+ {value: 0x0024, lo: 0x90, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x9a},
+ {value: 0x0014, lo: 0x9c, hi: 0x9c},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xf, offset 0x63
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x8a},
+ {value: 0x0034, lo: 0x8b, hi: 0x92},
+ {value: 0x0024, lo: 0x93, hi: 0x94},
+ {value: 0x0034, lo: 0x95, hi: 0x96},
+ {value: 0x0024, lo: 0x97, hi: 0x9b},
+ {value: 0x0034, lo: 0x9c, hi: 0x9c},
+ {value: 0x0024, lo: 0x9d, hi: 0x9e},
+ {value: 0x0034, lo: 0x9f, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0034, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xbf},
+ // Block 0x10, offset 0x71
+ {value: 0x0010, lo: 0x80, hi: 0xbf},
+ // Block 0x11, offset 0x72
+ {value: 0x0010, lo: 0x80, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x95},
+ {value: 0x0024, lo: 0x96, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x0024, lo: 0x9f, hi: 0xa2},
+ {value: 0x0034, lo: 0xa3, hi: 0xa3},
+ {value: 0x0024, lo: 0xa4, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa6},
+ {value: 0x0024, lo: 0xa7, hi: 0xa8},
+ {value: 0x0034, lo: 0xaa, hi: 0xaa},
+ {value: 0x0024, lo: 0xab, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xbc},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x12, offset 0x80
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0034, lo: 0x91, hi: 0x91},
+ {value: 0x0010, lo: 0x92, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ {value: 0x0034, lo: 0xb1, hi: 0xb1},
+ {value: 0x0024, lo: 0xb2, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0024, lo: 0xb5, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb9},
+ {value: 0x0024, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0024, lo: 0xbd, hi: 0xbd},
+ {value: 0x0034, lo: 0xbe, hi: 0xbe},
+ {value: 0x0024, lo: 0xbf, hi: 0xbf},
+ // Block 0x13, offset 0x8f
+ {value: 0x0024, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0024, lo: 0x83, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0024, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0024, lo: 0x87, hi: 0x87},
+ {value: 0x0034, lo: 0x88, hi: 0x88},
+ {value: 0x0024, lo: 0x89, hi: 0x8a},
+ {value: 0x0010, lo: 0x8d, hi: 0xbf},
+ // Block 0x14, offset 0x99
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0014, lo: 0xa6, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ // Block 0x15, offset 0x9c
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0024, lo: 0xab, hi: 0xb1},
+ {value: 0x0034, lo: 0xb2, hi: 0xb2},
+ {value: 0x0024, lo: 0xb3, hi: 0xb3},
+ {value: 0x0014, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ // Block 0x16, offset 0xa3
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0024, lo: 0x96, hi: 0x99},
+ {value: 0x0014, lo: 0x9a, hi: 0x9a},
+ {value: 0x0024, lo: 0x9b, hi: 0xa3},
+ {value: 0x0014, lo: 0xa4, hi: 0xa4},
+ {value: 0x0024, lo: 0xa5, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa8},
+ {value: 0x0024, lo: 0xa9, hi: 0xad},
+ // Block 0x17, offset 0xab
+ {value: 0x0010, lo: 0x80, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x9b},
+ {value: 0x0010, lo: 0xa0, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x18, offset 0xaf
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0004, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x8e},
+ {value: 0x0014, lo: 0x90, hi: 0x91},
+ {value: 0x0024, lo: 0x98, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x9b},
+ {value: 0x0024, lo: 0x9c, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x19, offset 0xb7
+ {value: 0x0014, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x1a, offset 0xbd
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0024, lo: 0x91, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x92},
+ {value: 0x0024, lo: 0x93, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x97},
+ {value: 0x0010, lo: 0x98, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xbf},
+ // Block 0x1b, offset 0xcb
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb2},
+ {value: 0x0010, lo: 0xb6, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x1c, offset 0xd6
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9c, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xb1},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ {value: 0x0024, lo: 0xbe, hi: 0xbe},
+ // Block 0x1d, offset 0xe3
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8a},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb6},
+ {value: 0x0010, lo: 0xb8, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x1e, offset 0xee
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0014, lo: 0x87, hi: 0x88},
+ {value: 0x0014, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x91, hi: 0x91},
+ {value: 0x0010, lo: 0x99, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9e},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb5},
+ // Block 0x1f, offset 0xfa
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x20, offset 0x104
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x85},
+ {value: 0x0014, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xbf},
+ // Block 0x21, offset 0x110
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x22, offset 0x11b
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9c, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ // Block 0x23, offset 0x127
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8a},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0x95},
+ {value: 0x0010, lo: 0x99, hi: 0x9a},
+ {value: 0x0010, lo: 0x9c, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ {value: 0x0010, lo: 0xa8, hi: 0xaa},
+ {value: 0x0010, lo: 0xae, hi: 0xb9},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x24, offset 0x133
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x86, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ // Block 0x25, offset 0x13b
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x83},
+ {value: 0x0014, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbf},
+ // Block 0x26, offset 0x145
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0014, lo: 0x86, hi: 0x88},
+ {value: 0x0014, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0034, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9a},
+ {value: 0x0010, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ // Block 0x27, offset 0x150
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x28, offset 0x15b
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0014, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x9d, hi: 0x9e},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xb3},
+ // Block 0x29, offset 0x167
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x2a, offset 0x16d
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x86, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x94, hi: 0x97},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xba, hi: 0xbf},
+ // Block 0x2b, offset 0x178
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x96},
+ {value: 0x0010, lo: 0x9a, hi: 0xb1},
+ {value: 0x0010, lo: 0xb3, hi: 0xbb},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ // Block 0x2c, offset 0x17e
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0010, lo: 0x8f, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x94},
+ {value: 0x0014, lo: 0x96, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9f},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ // Block 0x2d, offset 0x186
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb4, hi: 0xb7},
+ {value: 0x0034, lo: 0xb8, hi: 0xba},
+ // Block 0x2e, offset 0x189
+ {value: 0x0004, lo: 0x86, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x87},
+ {value: 0x0034, lo: 0x88, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x2f, offset 0x18e
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb4, hi: 0xb7},
+ {value: 0x0034, lo: 0xb8, hi: 0xba},
+ {value: 0x0014, lo: 0xbb, hi: 0xbc},
+ // Block 0x30, offset 0x192
+ {value: 0x0004, lo: 0x86, hi: 0x86},
+ {value: 0x0034, lo: 0x88, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x31, offset 0x196
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0034, lo: 0x98, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0034, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0034, lo: 0xb9, hi: 0xb9},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x32, offset 0x19d
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0x89, hi: 0xac},
+ {value: 0x0034, lo: 0xb1, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xba, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x33, offset 0x1a6
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0024, lo: 0x82, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0024, lo: 0x86, hi: 0x87},
+ {value: 0x0010, lo: 0x88, hi: 0x8c},
+ {value: 0x0014, lo: 0x8d, hi: 0x97},
+ {value: 0x0014, lo: 0x99, hi: 0xbc},
+ // Block 0x34, offset 0x1ae
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ // Block 0x35, offset 0x1af
+ {value: 0x0010, lo: 0xab, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbc},
+ {value: 0x0014, lo: 0xbd, hi: 0xbe},
+ // Block 0x36, offset 0x1b8
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x96, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x99},
+ {value: 0x0014, lo: 0x9e, hi: 0xa0},
+ {value: 0x0010, lo: 0xa2, hi: 0xa4},
+ {value: 0x0010, lo: 0xa7, hi: 0xad},
+ {value: 0x0014, lo: 0xb1, hi: 0xb4},
+ // Block 0x37, offset 0x1bf
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x6c53, lo: 0xa0, hi: 0xbf},
+ // Block 0x38, offset 0x1c7
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0x9a, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x39, offset 0x1cd
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb5},
+ {value: 0x0010, lo: 0xb8, hi: 0xbe},
+ // Block 0x3a, offset 0x1d2
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x82, hi: 0x85},
+ {value: 0x0010, lo: 0x88, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0xbf},
+ // Block 0x3b, offset 0x1d6
+ {value: 0x0010, lo: 0x80, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0x95},
+ {value: 0x0010, lo: 0x98, hi: 0xbf},
+ // Block 0x3c, offset 0x1d9
+ {value: 0x0010, lo: 0x80, hi: 0x9a},
+ {value: 0x0024, lo: 0x9d, hi: 0x9f},
+ // Block 0x3d, offset 0x1db
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x7453, lo: 0xa0, hi: 0xaf},
+ {value: 0x7853, lo: 0xb0, hi: 0xbf},
+ // Block 0x3e, offset 0x1de
+ {value: 0x7c53, lo: 0x80, hi: 0x8f},
+ {value: 0x8053, lo: 0x90, hi: 0x9f},
+ {value: 0x7c53, lo: 0xa0, hi: 0xaf},
+ {value: 0x0813, lo: 0xb0, hi: 0xb5},
+ {value: 0x0892, lo: 0xb8, hi: 0xbd},
+ // Block 0x3f, offset 0x1e3
+ {value: 0x0010, lo: 0x81, hi: 0xbf},
+ // Block 0x40, offset 0x1e4
+ {value: 0x0010, lo: 0x80, hi: 0xac},
+ {value: 0x0010, lo: 0xaf, hi: 0xbf},
+ // Block 0x41, offset 0x1e6
+ {value: 0x0010, lo: 0x81, hi: 0x9a},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x42, offset 0x1e8
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0010, lo: 0xae, hi: 0xb8},
+ // Block 0x43, offset 0x1ea
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x93},
+ {value: 0x0034, lo: 0x94, hi: 0x94},
+ {value: 0x0030, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x9f, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ {value: 0x0030, lo: 0xb4, hi: 0xb4},
+ // Block 0x44, offset 0x1f1
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x93},
+ {value: 0x0010, lo: 0xa0, hi: 0xac},
+ {value: 0x0010, lo: 0xae, hi: 0xb0},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ // Block 0x45, offset 0x1f6
+ {value: 0x0014, lo: 0xb4, hi: 0xb5},
+ {value: 0x0010, lo: 0xb6, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x46, offset 0x1fa
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0014, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0014, lo: 0x89, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x92},
+ {value: 0x0014, lo: 0x93, hi: 0x93},
+ {value: 0x0004, lo: 0x97, hi: 0x97},
+ {value: 0x0024, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ // Block 0x47, offset 0x203
+ {value: 0x0014, lo: 0x8b, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x48, offset 0x206
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0xb8},
+ // Block 0x49, offset 0x209
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0xa8},
+ {value: 0x0034, lo: 0xa9, hi: 0xa9},
+ {value: 0x0010, lo: 0xaa, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x4a, offset 0x20f
+ {value: 0x0010, lo: 0x80, hi: 0xb5},
+ // Block 0x4b, offset 0x210
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0014, lo: 0xa0, hi: 0xa2},
+ {value: 0x0010, lo: 0xa3, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xab},
+ {value: 0x0010, lo: 0xb0, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb2},
+ {value: 0x0010, lo: 0xb3, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xb9},
+ {value: 0x0024, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbb},
+ // Block 0x4c, offset 0x21b
+ {value: 0x0010, lo: 0x86, hi: 0x8f},
+ // Block 0x4d, offset 0x21c
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x4e, offset 0x21d
+ {value: 0x0010, lo: 0x80, hi: 0x96},
+ {value: 0x0024, lo: 0x97, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0x99, hi: 0x9a},
+ {value: 0x0014, lo: 0x9b, hi: 0x9b},
+ // Block 0x4f, offset 0x222
+ {value: 0x0010, lo: 0x95, hi: 0x95},
+ {value: 0x0014, lo: 0x96, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x9e},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa2},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xac},
+ {value: 0x0010, lo: 0xad, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0024, lo: 0xb5, hi: 0xbc},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x50, offset 0x22f
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0004, lo: 0xa7, hi: 0xa7},
+ {value: 0x0024, lo: 0xb0, hi: 0xb4},
+ {value: 0x0034, lo: 0xb5, hi: 0xba},
+ {value: 0x0024, lo: 0xbb, hi: 0xbc},
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x51, offset 0x238
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0024, lo: 0x81, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x84},
+ {value: 0x0024, lo: 0x85, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0024, lo: 0x8b, hi: 0x8e},
+ // Block 0x52, offset 0x23e
+ {value: 0x0014, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x53, offset 0x246
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0030, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0xab, hi: 0xab},
+ {value: 0x0034, lo: 0xac, hi: 0xac},
+ {value: 0x0024, lo: 0xad, hi: 0xb3},
+ // Block 0x54, offset 0x24f
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa9},
+ {value: 0x0030, lo: 0xaa, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xbf},
+ // Block 0x55, offset 0x258
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0034, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa9},
+ {value: 0x0010, lo: 0xaa, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb1},
+ {value: 0x0030, lo: 0xb2, hi: 0xb3},
+ // Block 0x56, offset 0x261
+ {value: 0x0010, lo: 0x80, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ // Block 0x57, offset 0x266
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8d, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ // Block 0x58, offset 0x269
+ {value: 0x31ea, lo: 0x80, hi: 0x80},
+ {value: 0x326a, lo: 0x81, hi: 0x81},
+ {value: 0x32ea, lo: 0x82, hi: 0x82},
+ {value: 0x336a, lo: 0x83, hi: 0x83},
+ {value: 0x33ea, lo: 0x84, hi: 0x84},
+ {value: 0x346a, lo: 0x85, hi: 0x85},
+ {value: 0x34ea, lo: 0x86, hi: 0x86},
+ {value: 0x356a, lo: 0x87, hi: 0x87},
+ {value: 0x35ea, lo: 0x88, hi: 0x88},
+ {value: 0x8353, lo: 0x90, hi: 0xba},
+ {value: 0x8353, lo: 0xbd, hi: 0xbf},
+ // Block 0x59, offset 0x274
+ {value: 0x0024, lo: 0x90, hi: 0x92},
+ {value: 0x0034, lo: 0x94, hi: 0x99},
+ {value: 0x0024, lo: 0x9a, hi: 0x9b},
+ {value: 0x0034, lo: 0x9c, hi: 0x9f},
+ {value: 0x0024, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0034, lo: 0xa2, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xb3},
+ {value: 0x0024, lo: 0xb4, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb7},
+ {value: 0x0024, lo: 0xb8, hi: 0xb9},
+ {value: 0x0010, lo: 0xba, hi: 0xba},
+ // Block 0x5a, offset 0x282
+ {value: 0x0012, lo: 0x80, hi: 0xab},
+ {value: 0x0015, lo: 0xac, hi: 0xbf},
+ // Block 0x5b, offset 0x284
+ {value: 0x0015, lo: 0x80, hi: 0xaa},
+ {value: 0x0012, lo: 0xab, hi: 0xb7},
+ {value: 0x0015, lo: 0xb8, hi: 0xb8},
+ {value: 0x8752, lo: 0xb9, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xbc},
+ {value: 0x8b52, lo: 0xbd, hi: 0xbd},
+ {value: 0x0012, lo: 0xbe, hi: 0xbf},
+ // Block 0x5c, offset 0x28b
+ {value: 0x0012, lo: 0x80, hi: 0x8d},
+ {value: 0x8f52, lo: 0x8e, hi: 0x8e},
+ {value: 0x0012, lo: 0x8f, hi: 0x9a},
+ {value: 0x0015, lo: 0x9b, hi: 0xbf},
+ // Block 0x5d, offset 0x28f
+ {value: 0x0024, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0024, lo: 0x83, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0024, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x90},
+ {value: 0x0024, lo: 0x91, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xba},
+ {value: 0x0024, lo: 0xbb, hi: 0xbb},
+ {value: 0x0034, lo: 0xbc, hi: 0xbd},
+ {value: 0x0024, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x5e, offset 0x29b
+ {value: 0x0117, lo: 0x80, hi: 0xbf},
+ // Block 0x5f, offset 0x29c
+ {value: 0x0117, lo: 0x80, hi: 0x95},
+ {value: 0x369a, lo: 0x96, hi: 0x96},
+ {value: 0x374a, lo: 0x97, hi: 0x97},
+ {value: 0x37fa, lo: 0x98, hi: 0x98},
+ {value: 0x38aa, lo: 0x99, hi: 0x99},
+ {value: 0x395a, lo: 0x9a, hi: 0x9a},
+ {value: 0x3a0a, lo: 0x9b, hi: 0x9b},
+ {value: 0x0012, lo: 0x9c, hi: 0x9d},
+ {value: 0x3abb, lo: 0x9e, hi: 0x9e},
+ {value: 0x0012, lo: 0x9f, hi: 0x9f},
+ {value: 0x0117, lo: 0xa0, hi: 0xbf},
+ // Block 0x60, offset 0x2a7
+ {value: 0x0812, lo: 0x80, hi: 0x87},
+ {value: 0x0813, lo: 0x88, hi: 0x8f},
+ {value: 0x0812, lo: 0x90, hi: 0x95},
+ {value: 0x0813, lo: 0x98, hi: 0x9d},
+ {value: 0x0812, lo: 0xa0, hi: 0xa7},
+ {value: 0x0813, lo: 0xa8, hi: 0xaf},
+ {value: 0x0812, lo: 0xb0, hi: 0xb7},
+ {value: 0x0813, lo: 0xb8, hi: 0xbf},
+ // Block 0x61, offset 0x2af
+ {value: 0x0004, lo: 0x8b, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8f},
+ {value: 0x0054, lo: 0x98, hi: 0x99},
+ {value: 0x0054, lo: 0xa4, hi: 0xa4},
+ {value: 0x0054, lo: 0xa7, hi: 0xa7},
+ {value: 0x0014, lo: 0xaa, hi: 0xae},
+ {value: 0x0010, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x62, offset 0x2b7
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x94, hi: 0x94},
+ {value: 0x0014, lo: 0xa0, hi: 0xa4},
+ {value: 0x0014, lo: 0xa6, hi: 0xaf},
+ {value: 0x0015, lo: 0xb1, hi: 0xb1},
+ {value: 0x0015, lo: 0xbf, hi: 0xbf},
+ // Block 0x63, offset 0x2bd
+ {value: 0x0015, lo: 0x90, hi: 0x9c},
+ // Block 0x64, offset 0x2be
+ {value: 0x0024, lo: 0x90, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x93},
+ {value: 0x0024, lo: 0x94, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x9a},
+ {value: 0x0024, lo: 0x9b, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0xa0},
+ {value: 0x0024, lo: 0xa1, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa4},
+ {value: 0x0034, lo: 0xa5, hi: 0xa6},
+ {value: 0x0024, lo: 0xa7, hi: 0xa7},
+ {value: 0x0034, lo: 0xa8, hi: 0xa8},
+ {value: 0x0024, lo: 0xa9, hi: 0xa9},
+ {value: 0x0034, lo: 0xaa, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ // Block 0x65, offset 0x2cc
+ {value: 0x0016, lo: 0x85, hi: 0x86},
+ {value: 0x0012, lo: 0x87, hi: 0x89},
+ {value: 0xa452, lo: 0x8e, hi: 0x8e},
+ {value: 0x1013, lo: 0xa0, hi: 0xaf},
+ {value: 0x1012, lo: 0xb0, hi: 0xbf},
+ // Block 0x66, offset 0x2d1
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x88},
+ // Block 0x67, offset 0x2d4
+ {value: 0xa753, lo: 0xb6, hi: 0xb7},
+ {value: 0xaa53, lo: 0xb8, hi: 0xb9},
+ {value: 0xad53, lo: 0xba, hi: 0xbb},
+ {value: 0xaa53, lo: 0xbc, hi: 0xbd},
+ {value: 0xa753, lo: 0xbe, hi: 0xbf},
+ // Block 0x68, offset 0x2d9
+ {value: 0x3013, lo: 0x80, hi: 0x8f},
+ {value: 0x6553, lo: 0x90, hi: 0x9f},
+ {value: 0xb053, lo: 0xa0, hi: 0xaf},
+ {value: 0x3012, lo: 0xb0, hi: 0xbf},
+ // Block 0x69, offset 0x2dd
+ {value: 0x0117, lo: 0x80, hi: 0xa3},
+ {value: 0x0012, lo: 0xa4, hi: 0xa4},
+ {value: 0x0716, lo: 0xab, hi: 0xac},
+ {value: 0x0316, lo: 0xad, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xb3},
+ // Block 0x6a, offset 0x2e3
+ {value: 0x6c52, lo: 0x80, hi: 0x9f},
+ {value: 0x7052, lo: 0xa0, hi: 0xa5},
+ {value: 0x7052, lo: 0xa7, hi: 0xa7},
+ {value: 0x7052, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x6b, offset 0x2e8
+ {value: 0x0010, lo: 0x80, hi: 0xa7},
+ {value: 0x0014, lo: 0xaf, hi: 0xaf},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x6c, offset 0x2eb
+ {value: 0x0010, lo: 0x80, hi: 0x96},
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xae},
+ {value: 0x0010, lo: 0xb0, hi: 0xb6},
+ {value: 0x0010, lo: 0xb8, hi: 0xbe},
+ // Block 0x6d, offset 0x2f0
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9e},
+ {value: 0x0024, lo: 0xa0, hi: 0xbf},
+ // Block 0x6e, offset 0x2f5
+ {value: 0x0014, lo: 0xaf, hi: 0xaf},
+ // Block 0x6f, offset 0x2f6
+ {value: 0x0014, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0xaa, hi: 0xad},
+ {value: 0x0030, lo: 0xae, hi: 0xaf},
+ {value: 0x0004, lo: 0xb1, hi: 0xb5},
+ {value: 0x0014, lo: 0xbb, hi: 0xbb},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ // Block 0x70, offset 0x2fc
+ {value: 0x0034, lo: 0x99, hi: 0x9a},
+ {value: 0x0004, lo: 0x9b, hi: 0x9e},
+ // Block 0x71, offset 0x2fe
+ {value: 0x0004, lo: 0xbc, hi: 0xbe},
+ // Block 0x72, offset 0x2ff
+ {value: 0x0010, lo: 0x85, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xbf},
+ // Block 0x73, offset 0x301
+ {value: 0x0010, lo: 0x80, hi: 0x8e},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x74, offset 0x303
+ {value: 0x0010, lo: 0x80, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x96, hi: 0xbf},
+ // Block 0x75, offset 0x306
+ {value: 0x0010, lo: 0x80, hi: 0x8c},
+ // Block 0x76, offset 0x307
+ {value: 0x0010, lo: 0x90, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ // Block 0x77, offset 0x309
+ {value: 0x0010, lo: 0x80, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0010, lo: 0x90, hi: 0xab},
+ // Block 0x78, offset 0x30c
+ {value: 0x0117, lo: 0x80, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb2},
+ {value: 0x0024, lo: 0xb4, hi: 0xbd},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x79, offset 0x312
+ {value: 0x0117, lo: 0x80, hi: 0x9b},
+ {value: 0x0015, lo: 0x9c, hi: 0x9d},
+ {value: 0x0024, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x7a, offset 0x316
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb1},
+ // Block 0x7b, offset 0x318
+ {value: 0x0004, lo: 0x80, hi: 0x87},
+ {value: 0x0014, lo: 0x88, hi: 0xa1},
+ {value: 0x0117, lo: 0xa2, hi: 0xaf},
+ {value: 0x0012, lo: 0xb0, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xbf},
+ // Block 0x7c, offset 0x31d
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x0015, lo: 0xb0, hi: 0xb0},
+ {value: 0x0012, lo: 0xb1, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x8753, lo: 0xbd, hi: 0xbd},
+ {value: 0x0117, lo: 0xbe, hi: 0xbf},
+ // Block 0x7d, offset 0x324
+ {value: 0x0117, lo: 0x80, hi: 0x83},
+ {value: 0x6553, lo: 0x84, hi: 0x84},
+ {value: 0x908b, lo: 0x85, hi: 0x85},
+ {value: 0x8f53, lo: 0x86, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x0316, lo: 0x89, hi: 0x8a},
+ {value: 0x0117, lo: 0x90, hi: 0x91},
+ {value: 0x0012, lo: 0x93, hi: 0x93},
+ {value: 0x0012, lo: 0x95, hi: 0x95},
+ {value: 0x0117, lo: 0x96, hi: 0x99},
+ {value: 0x0015, lo: 0xb2, hi: 0xb4},
+ {value: 0x0316, lo: 0xb5, hi: 0xb6},
+ {value: 0x0010, lo: 0xb7, hi: 0xb7},
+ {value: 0x0015, lo: 0xb8, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbf},
+ // Block 0x7e, offset 0x334
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8b},
+ {value: 0x0010, lo: 0x8c, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0034, lo: 0xac, hi: 0xac},
+ // Block 0x7f, offset 0x33e
+ {value: 0x0010, lo: 0x80, hi: 0xb3},
+ // Block 0x80, offset 0x33f
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0xa0, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb7},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x81, offset 0x348
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0014, lo: 0xa6, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x82, offset 0x34c
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x91},
+ {value: 0x0010, lo: 0x92, hi: 0x92},
+ {value: 0x0030, lo: 0x93, hi: 0x93},
+ {value: 0x0010, lo: 0xa0, hi: 0xbc},
+ // Block 0x83, offset 0x351
+ {value: 0x0014, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xb9},
+ {value: 0x0010, lo: 0xba, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x84, offset 0x359
+ {value: 0x0030, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0014, lo: 0xa5, hi: 0xa5},
+ {value: 0x0004, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x85, offset 0x35f
+ {value: 0x0010, lo: 0x80, hi: 0xa8},
+ {value: 0x0014, lo: 0xa9, hi: 0xae},
+ {value: 0x0010, lo: 0xaf, hi: 0xb0},
+ {value: 0x0014, lo: 0xb1, hi: 0xb2},
+ {value: 0x0010, lo: 0xb3, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb6},
+ // Block 0x86, offset 0x365
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0010, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0004, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ // Block 0x87, offset 0x36f
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ {value: 0x0024, lo: 0xb2, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0024, lo: 0xb7, hi: 0xb8},
+ {value: 0x0024, lo: 0xbe, hi: 0xbf},
+ // Block 0x88, offset 0x374
+ {value: 0x0024, lo: 0x81, hi: 0x81},
+ {value: 0x0004, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0010, lo: 0xb2, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xb6},
+ // Block 0x89, offset 0x37d
+ {value: 0x0010, lo: 0x81, hi: 0x86},
+ {value: 0x0010, lo: 0x89, hi: 0x8e},
+ {value: 0x0010, lo: 0x91, hi: 0x96},
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xae},
+ {value: 0x0012, lo: 0xb0, hi: 0xbf},
+ // Block 0x8a, offset 0x383
+ {value: 0x0012, lo: 0x80, hi: 0x92},
+ {value: 0xb352, lo: 0x93, hi: 0x93},
+ {value: 0x0012, lo: 0x94, hi: 0x9a},
+ {value: 0x0014, lo: 0x9b, hi: 0x9b},
+ {value: 0x0015, lo: 0x9c, hi: 0x9f},
+ {value: 0x0012, lo: 0xa0, hi: 0xa8},
+ {value: 0x0015, lo: 0xa9, hi: 0xa9},
+ {value: 0x0004, lo: 0xaa, hi: 0xab},
+ {value: 0x74d2, lo: 0xb0, hi: 0xbf},
+ // Block 0x8b, offset 0x38c
+ {value: 0x78d2, lo: 0x80, hi: 0x8f},
+ {value: 0x7cd2, lo: 0x90, hi: 0x9f},
+ {value: 0x80d2, lo: 0xa0, hi: 0xaf},
+ {value: 0x7cd2, lo: 0xb0, hi: 0xbf},
+ // Block 0x8c, offset 0x390
+ {value: 0x0010, lo: 0x80, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xaa},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x8d, offset 0x398
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x8e, offset 0x39a
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x8b, hi: 0xbb},
+ // Block 0x8f, offset 0x39c
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x86, hi: 0xbf},
+ // Block 0x90, offset 0x39f
+ {value: 0x0010, lo: 0x80, hi: 0xb1},
+ {value: 0x0004, lo: 0xb2, hi: 0xbf},
+ // Block 0x91, offset 0x3a1
+ {value: 0x0004, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x93, hi: 0xbf},
+ // Block 0x92, offset 0x3a3
+ {value: 0x0010, lo: 0x80, hi: 0xbd},
+ // Block 0x93, offset 0x3a4
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0x94, offset 0x3a5
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x0010, lo: 0x92, hi: 0xbf},
+ // Block 0x95, offset 0x3a7
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0xb0, hi: 0xbb},
+ // Block 0x96, offset 0x3a9
+ {value: 0x0014, lo: 0x80, hi: 0x8f},
+ {value: 0x0054, lo: 0x93, hi: 0x93},
+ {value: 0x0024, lo: 0xa0, hi: 0xa6},
+ {value: 0x0034, lo: 0xa7, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xaf},
+ {value: 0x0010, lo: 0xb3, hi: 0xb4},
+ // Block 0x97, offset 0x3af
+ {value: 0x0010, lo: 0x8d, hi: 0x8f},
+ {value: 0x0054, lo: 0x92, hi: 0x92},
+ {value: 0x0054, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0xb0, hi: 0xb4},
+ {value: 0x0010, lo: 0xb6, hi: 0xbf},
+ // Block 0x98, offset 0x3b4
+ {value: 0x0010, lo: 0x80, hi: 0xbc},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x99, offset 0x3b6
+ {value: 0x0054, lo: 0x87, hi: 0x87},
+ {value: 0x0054, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0054, lo: 0x9a, hi: 0x9a},
+ {value: 0x5f53, lo: 0xa1, hi: 0xba},
+ {value: 0x0004, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x9a, offset 0x3bd
+ {value: 0x0004, lo: 0x80, hi: 0x80},
+ {value: 0x5f52, lo: 0x81, hi: 0x9a},
+ {value: 0x0004, lo: 0xb0, hi: 0xb0},
+ // Block 0x9b, offset 0x3c0
+ {value: 0x0014, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbe},
+ // Block 0x9c, offset 0x3c2
+ {value: 0x0010, lo: 0x82, hi: 0x87},
+ {value: 0x0010, lo: 0x8a, hi: 0x8f},
+ {value: 0x0010, lo: 0x92, hi: 0x97},
+ {value: 0x0010, lo: 0x9a, hi: 0x9c},
+ {value: 0x0004, lo: 0xa3, hi: 0xa3},
+ {value: 0x0014, lo: 0xb9, hi: 0xbb},
+ // Block 0x9d, offset 0x3c8
+ {value: 0x0010, lo: 0x80, hi: 0x8b},
+ {value: 0x0010, lo: 0x8d, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xba},
+ {value: 0x0010, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x9e, offset 0x3cd
+ {value: 0x0010, lo: 0x80, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x9d},
+ // Block 0x9f, offset 0x3cf
+ {value: 0x0010, lo: 0x80, hi: 0xba},
+ // Block 0xa0, offset 0x3d0
+ {value: 0x0010, lo: 0x80, hi: 0xb4},
+ // Block 0xa1, offset 0x3d1
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ // Block 0xa2, offset 0x3d2
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xa3, offset 0x3d4
+ {value: 0x0010, lo: 0x80, hi: 0x90},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ // Block 0xa4, offset 0x3d6
+ {value: 0x0010, lo: 0x80, hi: 0x9f},
+ {value: 0x0010, lo: 0xad, hi: 0xbf},
+ // Block 0xa5, offset 0x3d8
+ {value: 0x0010, lo: 0x80, hi: 0x8a},
+ {value: 0x0010, lo: 0x90, hi: 0xb5},
+ {value: 0x0024, lo: 0xb6, hi: 0xba},
+ // Block 0xa6, offset 0x3db
+ {value: 0x0010, lo: 0x80, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xa7, offset 0x3dd
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x88, hi: 0x8f},
+ {value: 0x0010, lo: 0x91, hi: 0x95},
+ // Block 0xa8, offset 0x3e0
+ {value: 0x2813, lo: 0x80, hi: 0x87},
+ {value: 0x3813, lo: 0x88, hi: 0x8f},
+ {value: 0x2813, lo: 0x90, hi: 0x97},
+ {value: 0xb653, lo: 0x98, hi: 0x9f},
+ {value: 0xb953, lo: 0xa0, hi: 0xa7},
+ {value: 0x2812, lo: 0xa8, hi: 0xaf},
+ {value: 0x3812, lo: 0xb0, hi: 0xb7},
+ {value: 0x2812, lo: 0xb8, hi: 0xbf},
+ // Block 0xa9, offset 0x3e8
+ {value: 0xb652, lo: 0x80, hi: 0x87},
+ {value: 0xb952, lo: 0x88, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0xaa, offset 0x3eb
+ {value: 0x0010, lo: 0x80, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0xb953, lo: 0xb0, hi: 0xb7},
+ {value: 0xb653, lo: 0xb8, hi: 0xbf},
+ // Block 0xab, offset 0x3ef
+ {value: 0x2813, lo: 0x80, hi: 0x87},
+ {value: 0x3813, lo: 0x88, hi: 0x8f},
+ {value: 0x2813, lo: 0x90, hi: 0x93},
+ {value: 0xb952, lo: 0x98, hi: 0x9f},
+ {value: 0xb652, lo: 0xa0, hi: 0xa7},
+ {value: 0x2812, lo: 0xa8, hi: 0xaf},
+ {value: 0x3812, lo: 0xb0, hi: 0xb7},
+ {value: 0x2812, lo: 0xb8, hi: 0xbb},
+ // Block 0xac, offset 0x3f7
+ {value: 0x0010, lo: 0x80, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xad, offset 0x3f9
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0xbc53, lo: 0xb0, hi: 0xb0},
+ {value: 0xbf53, lo: 0xb1, hi: 0xb1},
+ {value: 0xc253, lo: 0xb2, hi: 0xb2},
+ {value: 0xbf53, lo: 0xb3, hi: 0xb3},
+ {value: 0xc553, lo: 0xb4, hi: 0xb4},
+ {value: 0xbf53, lo: 0xb5, hi: 0xb5},
+ {value: 0xc253, lo: 0xb6, hi: 0xb6},
+ {value: 0xbf53, lo: 0xb7, hi: 0xb7},
+ {value: 0xbc53, lo: 0xb8, hi: 0xb8},
+ {value: 0xc853, lo: 0xb9, hi: 0xb9},
+ {value: 0xcb53, lo: 0xba, hi: 0xba},
+ {value: 0xce53, lo: 0xbc, hi: 0xbc},
+ {value: 0xc853, lo: 0xbd, hi: 0xbd},
+ {value: 0xcb53, lo: 0xbe, hi: 0xbe},
+ {value: 0xc853, lo: 0xbf, hi: 0xbf},
+ // Block 0xae, offset 0x409
+ {value: 0x0010, lo: 0x80, hi: 0xb6},
+ // Block 0xaf, offset 0x40a
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xa7},
+ // Block 0xb0, offset 0x40c
+ {value: 0x0015, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0015, lo: 0x83, hi: 0x85},
+ {value: 0x0015, lo: 0x87, hi: 0xb0},
+ {value: 0x0015, lo: 0xb2, hi: 0xba},
+ // Block 0xb1, offset 0x411
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0010, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0xb5},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xb2, offset 0x417
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb6},
+ // Block 0xb3, offset 0x419
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ // Block 0xb4, offset 0x41a
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ // Block 0xb5, offset 0x41c
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb9},
+ // Block 0xb6, offset 0x41e
+ {value: 0x0010, lo: 0x80, hi: 0xb7},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0xb7, offset 0x420
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x83},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x8e, hi: 0x8e},
+ {value: 0x0024, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x97},
+ {value: 0x0010, lo: 0x99, hi: 0xb5},
+ {value: 0x0024, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xb8, offset 0x42d
+ {value: 0x0010, lo: 0xa0, hi: 0xbc},
+ // Block 0xb9, offset 0x42e
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ // Block 0xba, offset 0x42f
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0x89, hi: 0xa4},
+ {value: 0x0024, lo: 0xa5, hi: 0xa5},
+ {value: 0x0034, lo: 0xa6, hi: 0xa6},
+ // Block 0xbb, offset 0x433
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ // Block 0xbc, offset 0x435
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ // Block 0xbd, offset 0x436
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ // Block 0xbe, offset 0x437
+ {value: 0x5653, lo: 0x80, hi: 0xb2},
+ // Block 0xbf, offset 0x438
+ {value: 0x5652, lo: 0x80, hi: 0xb2},
+ // Block 0xc0, offset 0x439
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0x0024, lo: 0xa4, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xc1, offset 0x43c
+ {value: 0x0010, lo: 0x80, hi: 0xa9},
+ {value: 0x0024, lo: 0xab, hi: 0xac},
+ {value: 0x0010, lo: 0xb0, hi: 0xb1},
+ // Block 0xc2, offset 0x43f
+ {value: 0x0034, lo: 0xbd, hi: 0xbf},
+ // Block 0xc3, offset 0x440
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc4, offset 0x443
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x87},
+ {value: 0x0024, lo: 0x88, hi: 0x8a},
+ {value: 0x0034, lo: 0x8b, hi: 0x8b},
+ {value: 0x0024, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x90},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc5, offset 0x44a
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0024, lo: 0x82, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x83},
+ {value: 0x0024, lo: 0x84, hi: 0x84},
+ {value: 0x0034, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc6, offset 0x450
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0010, lo: 0xa0, hi: 0xb6},
+ // Block 0xc7, offset 0x452
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbf},
+ // Block 0xc8, offset 0x456
+ {value: 0x0014, lo: 0x80, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0034, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xc9, offset 0x45e
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb6},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0014, lo: 0xbd, hi: 0xbd},
+ // Block 0xca, offset 0x464
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0xa8},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xcb, offset 0x468
+ {value: 0x0024, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xab},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb6, hi: 0xbf},
+ // Block 0xcc, offset 0x46f
+ {value: 0x0010, lo: 0x84, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb3},
+ {value: 0x0010, lo: 0xb6, hi: 0xb6},
+ // Block 0xcd, offset 0x473
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xce, offset 0x477
+ {value: 0x0030, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0014, lo: 0x89, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x9a},
+ {value: 0x0010, lo: 0x9c, hi: 0x9c},
+ // Block 0xcf, offset 0x480
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0014, lo: 0xb4, hi: 0xb4},
+ {value: 0x0030, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xb7},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xd0, offset 0x48a
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ // Block 0xd1, offset 0x48c
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa8},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xd2, offset 0x492
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0014, lo: 0x9f, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa2},
+ {value: 0x0014, lo: 0xa3, hi: 0xa8},
+ {value: 0x0034, lo: 0xa9, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xd3, offset 0x498
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0xd4, offset 0x4a2
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0030, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9d, hi: 0xa3},
+ {value: 0x0024, lo: 0xa6, hi: 0xac},
+ {value: 0x0024, lo: 0xb0, hi: 0xb4},
+ // Block 0xd5, offset 0x4ac
+ {value: 0x0010, lo: 0x80, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbf},
+ // Block 0xd6, offset 0x4ae
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8a},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0x9e, hi: 0x9e},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ // Block 0xd7, offset 0x4b7
+ {value: 0x0010, lo: 0x80, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb8},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0xd8, offset 0x4bd
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0x85},
+ {value: 0x0010, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xd9, offset 0x4c3
+ {value: 0x0010, lo: 0x80, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb5},
+ {value: 0x0010, lo: 0xb8, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xda, offset 0x4c9
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x98, hi: 0x9b},
+ {value: 0x0014, lo: 0x9c, hi: 0x9d},
+ // Block 0xdb, offset 0x4cc
+ {value: 0x0010, lo: 0x80, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbc},
+ {value: 0x0014, lo: 0xbd, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xdc, offset 0x4d2
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xdd, offset 0x4d5
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0014, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb5},
+ {value: 0x0030, lo: 0xb6, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ // Block 0xde, offset 0x4de
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ // Block 0xdf, offset 0x4df
+ {value: 0x0014, lo: 0x9d, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xe0, offset 0x4e6
+ {value: 0x0010, lo: 0x80, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ // Block 0xe1, offset 0x4ea
+ {value: 0x5f53, lo: 0xa0, hi: 0xbf},
+ // Block 0xe2, offset 0x4eb
+ {value: 0x5f52, lo: 0x80, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xe3, offset 0x4ee
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x89, hi: 0x89},
+ {value: 0x0010, lo: 0x8c, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0xb5},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0014, lo: 0xbb, hi: 0xbc},
+ {value: 0x0030, lo: 0xbd, hi: 0xbd},
+ {value: 0x0034, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xe4, offset 0x4f8
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xe5, offset 0x4fb
+ {value: 0x0010, lo: 0xa0, hi: 0xa7},
+ {value: 0x0010, lo: 0xaa, hi: 0xbf},
+ // Block 0xe6, offset 0x4fd
+ {value: 0x0010, lo: 0x80, hi: 0x93},
+ {value: 0x0014, lo: 0x94, hi: 0x97},
+ {value: 0x0014, lo: 0x9a, hi: 0x9b},
+ {value: 0x0010, lo: 0x9c, hi: 0x9f},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ // Block 0xe7, offset 0x504
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x8a},
+ {value: 0x0010, lo: 0x8b, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb8},
+ {value: 0x0010, lo: 0xb9, hi: 0xba},
+ {value: 0x0014, lo: 0xbb, hi: 0xbe},
+ // Block 0xe8, offset 0x50c
+ {value: 0x0034, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0014, lo: 0x91, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x98},
+ {value: 0x0014, lo: 0x99, hi: 0x9b},
+ {value: 0x0010, lo: 0x9c, hi: 0xbf},
+ // Block 0xe9, offset 0x512
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0014, lo: 0x8a, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x99},
+ {value: 0x0010, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xea, offset 0x519
+ {value: 0x0010, lo: 0x80, hi: 0xb8},
+ // Block 0xeb, offset 0x51a
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb6},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xec, offset 0x520
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xb2, hi: 0xbf},
+ // Block 0xed, offset 0x523
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x0014, lo: 0x92, hi: 0xa7},
+ {value: 0x0010, lo: 0xa9, hi: 0xa9},
+ {value: 0x0014, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb6},
+ // Block 0xee, offset 0x52b
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0xb0},
+ {value: 0x0014, lo: 0xb1, hi: 0xb6},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0xef, offset 0x532
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x85},
+ {value: 0x0010, lo: 0x86, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xa5},
+ {value: 0x0010, lo: 0xa7, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xbf},
+ // Block 0xf0, offset 0x53c
+ {value: 0x0010, lo: 0x80, hi: 0x8e},
+ {value: 0x0014, lo: 0x90, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x96, hi: 0x96},
+ {value: 0x0034, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ // Block 0xf1, offset 0x544
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb6},
+ // Block 0xf2, offset 0x547
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xba},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0xf3, offset 0x54c
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0030, lo: 0x81, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xf4, offset 0x550
+ {value: 0x0010, lo: 0xb0, hi: 0xb0},
+ // Block 0xf5, offset 0x551
+ {value: 0x0010, lo: 0x80, hi: 0x99},
+ // Block 0xf6, offset 0x552
+ {value: 0x0010, lo: 0x80, hi: 0xae},
+ // Block 0xf7, offset 0x553
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ // Block 0xf8, offset 0x554
+ {value: 0x0010, lo: 0x80, hi: 0xb0},
+ // Block 0xf9, offset 0x555
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xbf},
+ // Block 0xfa, offset 0x557
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x95},
+ // Block 0xfb, offset 0x55a
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ // Block 0xfc, offset 0x55b
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xfd, offset 0x55e
+ {value: 0x0010, lo: 0x80, hi: 0xbe},
+ // Block 0xfe, offset 0x55f
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x90, hi: 0xad},
+ {value: 0x0034, lo: 0xb0, hi: 0xb4},
+ // Block 0xff, offset 0x562
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb6},
+ // Block 0x100, offset 0x564
+ {value: 0x0014, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa3, hi: 0xb7},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x101, offset 0x568
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ // Block 0x102, offset 0x569
+ {value: 0x2013, lo: 0x80, hi: 0x9f},
+ {value: 0x2012, lo: 0xa0, hi: 0xbf},
+ // Block 0x103, offset 0x56b
+ {value: 0x0010, lo: 0x80, hi: 0x8a},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0x104, offset 0x56e
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0014, lo: 0x8f, hi: 0x9f},
+ // Block 0x105, offset 0x570
+ {value: 0x0014, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa3, hi: 0xa4},
+ {value: 0x0030, lo: 0xb0, hi: 0xb1},
+ // Block 0x106, offset 0x573
+ {value: 0x0004, lo: 0xb0, hi: 0xb3},
+ {value: 0x0004, lo: 0xb5, hi: 0xbb},
+ {value: 0x0004, lo: 0xbd, hi: 0xbe},
+ // Block 0x107, offset 0x576
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbc},
+ // Block 0x108, offset 0x578
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x0034, lo: 0x9e, hi: 0x9e},
+ {value: 0x0014, lo: 0xa0, hi: 0xa3},
+ // Block 0x109, offset 0x57d
+ {value: 0x0014, lo: 0x80, hi: 0xad},
+ {value: 0x0014, lo: 0xb0, hi: 0xbf},
+ // Block 0x10a, offset 0x57f
+ {value: 0x0014, lo: 0x80, hi: 0x86},
+ // Block 0x10b, offset 0x580
+ {value: 0x0030, lo: 0xa5, hi: 0xa6},
+ {value: 0x0034, lo: 0xa7, hi: 0xa9},
+ {value: 0x0030, lo: 0xad, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbf},
+ // Block 0x10c, offset 0x585
+ {value: 0x0034, lo: 0x80, hi: 0x82},
+ {value: 0x0024, lo: 0x85, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8b},
+ {value: 0x0024, lo: 0xaa, hi: 0xad},
+ // Block 0x10d, offset 0x589
+ {value: 0x0024, lo: 0x82, hi: 0x84},
+ // Block 0x10e, offset 0x58a
+ {value: 0x0013, lo: 0x80, hi: 0x99},
+ {value: 0x0012, lo: 0x9a, hi: 0xb3},
+ {value: 0x0013, lo: 0xb4, hi: 0xbf},
+ // Block 0x10f, offset 0x58d
+ {value: 0x0013, lo: 0x80, hi: 0x8d},
+ {value: 0x0012, lo: 0x8e, hi: 0x94},
+ {value: 0x0012, lo: 0x96, hi: 0xa7},
+ {value: 0x0013, lo: 0xa8, hi: 0xbf},
+ // Block 0x110, offset 0x591
+ {value: 0x0013, lo: 0x80, hi: 0x81},
+ {value: 0x0012, lo: 0x82, hi: 0x9b},
+ {value: 0x0013, lo: 0x9c, hi: 0x9c},
+ {value: 0x0013, lo: 0x9e, hi: 0x9f},
+ {value: 0x0013, lo: 0xa2, hi: 0xa2},
+ {value: 0x0013, lo: 0xa5, hi: 0xa6},
+ {value: 0x0013, lo: 0xa9, hi: 0xac},
+ {value: 0x0013, lo: 0xae, hi: 0xb5},
+ {value: 0x0012, lo: 0xb6, hi: 0xb9},
+ {value: 0x0012, lo: 0xbb, hi: 0xbb},
+ {value: 0x0012, lo: 0xbd, hi: 0xbf},
+ // Block 0x111, offset 0x59c
+ {value: 0x0012, lo: 0x80, hi: 0x83},
+ {value: 0x0012, lo: 0x85, hi: 0x8f},
+ {value: 0x0013, lo: 0x90, hi: 0xa9},
+ {value: 0x0012, lo: 0xaa, hi: 0xbf},
+ // Block 0x112, offset 0x5a0
+ {value: 0x0012, lo: 0x80, hi: 0x83},
+ {value: 0x0013, lo: 0x84, hi: 0x85},
+ {value: 0x0013, lo: 0x87, hi: 0x8a},
+ {value: 0x0013, lo: 0x8d, hi: 0x94},
+ {value: 0x0013, lo: 0x96, hi: 0x9c},
+ {value: 0x0012, lo: 0x9e, hi: 0xb7},
+ {value: 0x0013, lo: 0xb8, hi: 0xb9},
+ {value: 0x0013, lo: 0xbb, hi: 0xbe},
+ // Block 0x113, offset 0x5a8
+ {value: 0x0013, lo: 0x80, hi: 0x84},
+ {value: 0x0013, lo: 0x86, hi: 0x86},
+ {value: 0x0013, lo: 0x8a, hi: 0x90},
+ {value: 0x0012, lo: 0x92, hi: 0xab},
+ {value: 0x0013, lo: 0xac, hi: 0xbf},
+ // Block 0x114, offset 0x5ad
+ {value: 0x0013, lo: 0x80, hi: 0x85},
+ {value: 0x0012, lo: 0x86, hi: 0x9f},
+ {value: 0x0013, lo: 0xa0, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xbf},
+ // Block 0x115, offset 0x5b1
+ {value: 0x0012, lo: 0x80, hi: 0x93},
+ {value: 0x0013, lo: 0x94, hi: 0xad},
+ {value: 0x0012, lo: 0xae, hi: 0xbf},
+ // Block 0x116, offset 0x5b4
+ {value: 0x0012, lo: 0x80, hi: 0x87},
+ {value: 0x0013, lo: 0x88, hi: 0xa1},
+ {value: 0x0012, lo: 0xa2, hi: 0xbb},
+ {value: 0x0013, lo: 0xbc, hi: 0xbf},
+ // Block 0x117, offset 0x5b8
+ {value: 0x0013, lo: 0x80, hi: 0x95},
+ {value: 0x0012, lo: 0x96, hi: 0xaf},
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x118, offset 0x5bb
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ {value: 0x0012, lo: 0x8a, hi: 0xa5},
+ {value: 0x0013, lo: 0xa8, hi: 0xbf},
+ // Block 0x119, offset 0x5be
+ {value: 0x0013, lo: 0x80, hi: 0x80},
+ {value: 0x0012, lo: 0x82, hi: 0x9a},
+ {value: 0x0012, lo: 0x9c, hi: 0xa1},
+ {value: 0x0013, lo: 0xa2, hi: 0xba},
+ {value: 0x0012, lo: 0xbc, hi: 0xbf},
+ // Block 0x11a, offset 0x5c3
+ {value: 0x0012, lo: 0x80, hi: 0x94},
+ {value: 0x0012, lo: 0x96, hi: 0x9b},
+ {value: 0x0013, lo: 0x9c, hi: 0xb4},
+ {value: 0x0012, lo: 0xb6, hi: 0xbf},
+ // Block 0x11b, offset 0x5c7
+ {value: 0x0012, lo: 0x80, hi: 0x8e},
+ {value: 0x0012, lo: 0x90, hi: 0x95},
+ {value: 0x0013, lo: 0x96, hi: 0xae},
+ {value: 0x0012, lo: 0xb0, hi: 0xbf},
+ // Block 0x11c, offset 0x5cb
+ {value: 0x0012, lo: 0x80, hi: 0x88},
+ {value: 0x0012, lo: 0x8a, hi: 0x8f},
+ {value: 0x0013, lo: 0x90, hi: 0xa8},
+ {value: 0x0012, lo: 0xaa, hi: 0xbf},
+ // Block 0x11d, offset 0x5cf
+ {value: 0x0012, lo: 0x80, hi: 0x82},
+ {value: 0x0012, lo: 0x84, hi: 0x89},
+ {value: 0x0017, lo: 0x8a, hi: 0x8b},
+ {value: 0x0010, lo: 0x8e, hi: 0xbf},
+ // Block 0x11e, offset 0x5d3
+ {value: 0x0014, lo: 0x80, hi: 0xb6},
+ {value: 0x0014, lo: 0xbb, hi: 0xbf},
+ // Block 0x11f, offset 0x5d5
+ {value: 0x0014, lo: 0x80, hi: 0xac},
+ {value: 0x0014, lo: 0xb5, hi: 0xb5},
+ // Block 0x120, offset 0x5d7
+ {value: 0x0014, lo: 0x84, hi: 0x84},
+ {value: 0x0014, lo: 0x9b, hi: 0x9f},
+ {value: 0x0014, lo: 0xa1, hi: 0xaf},
+ // Block 0x121, offset 0x5da
+ {value: 0x0012, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8a, hi: 0x8a},
+ {value: 0x0012, lo: 0x8b, hi: 0x9e},
+ {value: 0x0012, lo: 0xa5, hi: 0xaa},
+ // Block 0x122, offset 0x5de
+ {value: 0x0024, lo: 0x80, hi: 0x86},
+ {value: 0x0024, lo: 0x88, hi: 0x98},
+ {value: 0x0024, lo: 0x9b, hi: 0xa1},
+ {value: 0x0024, lo: 0xa3, hi: 0xa4},
+ {value: 0x0024, lo: 0xa6, hi: 0xaa},
+ {value: 0x0015, lo: 0xb0, hi: 0xbf},
+ // Block 0x123, offset 0x5e4
+ {value: 0x0015, lo: 0x80, hi: 0xad},
+ // Block 0x124, offset 0x5e5
+ {value: 0x0024, lo: 0x8f, hi: 0x8f},
+ // Block 0x125, offset 0x5e6
+ {value: 0x0010, lo: 0x80, hi: 0xac},
+ {value: 0x0024, lo: 0xb0, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xbd},
+ // Block 0x126, offset 0x5e9
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ // Block 0x127, offset 0x5eb
+ {value: 0x0010, lo: 0x90, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xae},
+ // Block 0x128, offset 0x5ed
+ {value: 0x0010, lo: 0x80, hi: 0xab},
+ {value: 0x0024, lo: 0xac, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x129, offset 0x5f0
+ {value: 0x0010, lo: 0x90, hi: 0xaa},
+ {value: 0x0014, lo: 0xab, hi: 0xab},
+ {value: 0x0034, lo: 0xac, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x12a, offset 0x5f5
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xab},
+ {value: 0x0010, lo: 0xad, hi: 0xae},
+ {value: 0x0010, lo: 0xb0, hi: 0xbe},
+ // Block 0x12b, offset 0x5f9
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0034, lo: 0x90, hi: 0x96},
+ // Block 0x12c, offset 0x5fb
+ {value: 0xd152, lo: 0x80, hi: 0x81},
+ {value: 0xd452, lo: 0x82, hi: 0x83},
+ {value: 0x0024, lo: 0x84, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8b},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x12d, offset 0x601
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x9f},
+ {value: 0x0010, lo: 0xa1, hi: 0xa2},
+ {value: 0x0010, lo: 0xa4, hi: 0xa4},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0010, lo: 0xa9, hi: 0xb2},
+ {value: 0x0010, lo: 0xb4, hi: 0xb7},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ // Block 0x12e, offset 0x60a
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0x9b},
+ {value: 0x0010, lo: 0xa1, hi: 0xa3},
+ {value: 0x0010, lo: 0xa5, hi: 0xa9},
+ {value: 0x0010, lo: 0xab, hi: 0xbb},
+ // Block 0x12f, offset 0x60f
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x130, offset 0x610
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ {value: 0x0013, lo: 0x90, hi: 0xa9},
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x131, offset 0x613
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ // Block 0x132, offset 0x614
+ {value: 0x0014, lo: 0xbb, hi: 0xbf},
+ // Block 0x133, offset 0x615
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x134, offset 0x616
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0014, lo: 0xa0, hi: 0xbf},
+ // Block 0x135, offset 0x618
+ {value: 0x0014, lo: 0x80, hi: 0xbf},
+ // Block 0x136, offset 0x619
+ {value: 0x0014, lo: 0x80, hi: 0xaf},
+}
+
+// Total table size 16093 bytes (15KiB); checksum: EE91C452
diff --git a/vendor/golang.org/x/text/cases/tables17.0.0.go b/vendor/golang.org/x/text/cases/tables17.0.0.go
new file mode 100644
index 000000000..cee93cbdc
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/tables17.0.0.go
@@ -0,0 +1,2642 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+//go:build go1.27
+
+package cases
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "17.0.0"
+
+var xorData string = "" + // Size: 237 bytes
+ "\x00\x06\x07\x00\x01?\x00\x0f\x03\x00\x0f\x12\x00\x0f\x1f\x00\x0f\x1d" +
+ "\x00\x01\x13\x00\x0f\x16\x00\x0f\x0b\x00\x0f3\x00\x0f7\x00\x01#\x00\x0f?" +
+ "\x00\x0e'\x00\x0f/\x00\x0e>\x00\x0f*\x00\x0c&\x00\x0c*\x00\x0c;\x00\x0c9" +
+ "\x00\x0c%\x00\x01\x08\x00\x03\x0d\x00\x03\x09\x00\x02\x06\x00\x02\x02" +
+ "\x00\x02\x0c\x00\x01\x00\x00\x01\x03\x00\x01\x01\x00\x01 \x00\x01\x0c" +
+ "\x00\x01\x10\x00\x03\x10\x00\x036 \x00\x037 \x00\x0b#\x10\x00\x0b 0\x00" +
+ "\x0b!\x10\x00\x0b!0\x001\x00\x00\x0b(\x04\x00\x03\x04\x1e\x00\x0b)\x08" +
+ "\x00\x03\x0a\x00\x02:\x00\x02>\x00\x02,\x00\x02\x00\x00\x02\x10\x00\x01<" +
+ "\x00\x01&\x00\x01*\x00\x01.\x00\x010\x003 \x00\x01\x18\x00\x01(\x00\x03'" +
+ "\x00\x03)\x00\x03+\x00\x03/\x00\x03\x19\x00\x03\x1b\x00\x03\x1f\x00\x03 " +
+ "\x00\x01%\x00\x01'\x00\x01+\x00\x01-\x00\x01/\x00\x01;\x00\x01=\x00\x01" +
+ "\x1e\x00\x01\x22"
+
+var exceptions string = "" + // Size: 2478 bytes
+ "\x00\x12\x12μΜΜ\x12\x12ssSSSs\x13\x18i̇i̇\x10\x09II\x13\x1bʼnʼNʼN\x11" +
+ "\x09sSS\x10\x1b\x12\x12dždžDž\x12\x12dždžDŽ\x10\x12DŽDž\x12\x12ljljLj\x12\x12ljljLJ" +
+ "\x10\x12LJLj\x12\x12njnjNj\x12\x12njnjNJ\x10\x12NJNj\x13\x1bǰJ̌J̌\x12\x12dzdzDz\x12" +
+ "\x12dzdzDZ\x10\x12DZDz\x13\x18ⱥⱥ\x13\x18ⱦⱦ\x10\x1bⱾⱾ\x10\x1bⱿⱿ\x10\x1bⱯⱯ\x10" +
+ "\x1bⱭⱭ\x10\x1bⱰⱰ\x10\x1bꞫꞫ\x10\x1bꞬꞬ\x10\x1b\x10\x1bꞍꞍ\x10\x1bꞪꞪ\x10" +
+ "\x1bꞮꞮ\x10\x1bⱢⱢ\x10\x1bꞭꞭ\x10\x1bⱮⱮ\x10\x1bⱤⱤ\x10\x1bꟅꟅ\x10\x1bꞱꞱ\x10" +
+ "\x1bꞲꞲ\x10\x1bꞰꞰ2\x12ιΙΙ\x166ΐΪ́Ϊ́\x166ΰΫ́Ϋ́\x12\x12σΣΣ\x12\x12β" +
+ "ΒΒ\x12\x12θΘΘ\x12\x12φΦΦ\x12\x12πΠΠ\x12\x12κΚΚ\x12\x12ρΡΡ\x12\x12εΕΕ" +
+ "\x14$եւԵՒԵւ\x10\x1bᲐა\x10\x1bᲑბ\x10\x1bᲒგ\x10\x1bᲓდ\x10\x1bᲔე\x10\x1bᲕვ" +
+ "\x10\x1bᲖზ\x10\x1bᲗთ\x10\x1bᲘი\x10\x1bᲙკ\x10\x1bᲚლ\x10\x1bᲛმ\x10\x1bᲜნ" +
+ "\x10\x1bᲝო\x10\x1bᲞპ\x10\x1bᲟჟ\x10\x1bᲠრ\x10\x1bᲡს\x10\x1bᲢტ\x10\x1bᲣუ" +
+ "\x10\x1bᲤფ\x10\x1bᲥქ\x10\x1bᲦღ\x10\x1bᲧყ\x10\x1bᲨშ\x10\x1bᲩჩ\x10\x1bᲪც" +
+ "\x10\x1bᲫძ\x10\x1bᲬწ\x10\x1bᲭჭ\x10\x1bᲮხ\x10\x1bᲯჯ\x10\x1bᲰჰ\x10\x1bᲱჱ" +
+ "\x10\x1bᲲჲ\x10\x1bᲳჳ\x10\x1bᲴჴ\x10\x1bᲵჵ\x10\x1bᲶჶ\x10\x1bᲷჷ\x10\x1bᲸჸ" +
+ "\x10\x1bᲹჹ\x10\x1bᲺჺ\x10\x1bᲽჽ\x10\x1bᲾჾ\x10\x1bᲿჿ\x12\x12вВВ\x12\x12дДД" +
+ "\x12\x12оОО\x12\x12сСС\x12\x12тТТ\x12\x12тТТ\x12\x12ъЪЪ\x12\x12ѣѢѢ\x13" +
+ "\x1bꙋꙊꙊ\x13\x1bẖH̱H̱\x13\x1bẗT̈T̈\x13\x1bẘW̊W̊\x13\x1bẙY̊Y̊\x13\x1ba" +
+ "ʾAʾAʾ\x13\x1bṡṠṠ\x12\x10ssß\x14$ὐΥ̓Υ̓\x166ὒΥ̓̀Υ̓̀\x166ὔΥ̓́Υ̓́\x166" +
+ "ὖΥ̓͂Υ̓͂\x15+ἀιἈΙᾈ\x15+ἁιἉΙᾉ\x15+ἂιἊΙᾊ\x15+ἃιἋΙᾋ\x15+ἄιἌΙᾌ\x15+ἅιἍΙᾍ" +
+ "\x15+ἆιἎΙᾎ\x15+ἇιἏΙᾏ\x15\x1dἀιᾀἈΙ\x15\x1dἁιᾁἉΙ\x15\x1dἂιᾂἊΙ\x15\x1dἃιᾃἋΙ" +
+ "\x15\x1dἄιᾄἌΙ\x15\x1dἅιᾅἍΙ\x15\x1dἆιᾆἎΙ\x15\x1dἇιᾇἏΙ\x15+ἠιἨΙᾘ\x15+ἡιἩΙᾙ" +
+ "\x15+ἢιἪΙᾚ\x15+ἣιἫΙᾛ\x15+ἤιἬΙᾜ\x15+ἥιἭΙᾝ\x15+ἦιἮΙᾞ\x15+ἧιἯΙᾟ\x15\x1dἠιᾐἨ" +
+ "Ι\x15\x1dἡιᾑἩΙ\x15\x1dἢιᾒἪΙ\x15\x1dἣιᾓἫΙ\x15\x1dἤιᾔἬΙ\x15\x1dἥιᾕἭΙ\x15" +
+ "\x1dἦιᾖἮΙ\x15\x1dἧιᾗἯΙ\x15+ὠιὨΙᾨ\x15+ὡιὩΙᾩ\x15+ὢιὪΙᾪ\x15+ὣιὫΙᾫ\x15+ὤιὬΙᾬ" +
+ "\x15+ὥιὭΙᾭ\x15+ὦιὮΙᾮ\x15+ὧιὯΙᾯ\x15\x1dὠιᾠὨΙ\x15\x1dὡιᾡὩΙ\x15\x1dὢιᾢὪΙ" +
+ "\x15\x1dὣιᾣὫΙ\x15\x1dὤιᾤὬΙ\x15\x1dὥιᾥὭΙ\x15\x1dὦιᾦὮΙ\x15\x1dὧιᾧὯΙ\x15-ὰι" +
+ "ᾺΙᾺͅ\x14#αιΑΙᾼ\x14$άιΆΙΆͅ\x14$ᾶΑ͂Α͂\x166ᾶιΑ͂Ιᾼ͂\x14\x1cαιᾳΑΙ\x12" +
+ "\x12ιΙΙ\x15-ὴιῊΙῊͅ\x14#ηιΗΙῌ\x14$ήιΉΙΉͅ\x14$ῆΗ͂Η͂\x166ῆιΗ͂Ιῌ͂\x14\x1c" +
+ "ηιῃΗΙ\x166ῒΪ̀Ϊ̀\x166ΐΪ́Ϊ́\x14$ῖΙ͂Ι͂\x166ῗΪ͂Ϊ͂\x166ῢΫ̀Ϋ" +
+ "̀\x166ΰΫ́Ϋ́\x14$ῤΡ̓Ρ̓\x14$ῦΥ͂Υ͂\x166ῧΫ͂Ϋ͂\x15-ὼιῺΙῺͅ\x14#ωιΩΙ" +
+ "ῼ\x14$ώιΏΙΏͅ\x14$ῶΩ͂Ω͂\x166ῶιΩ͂Ιῼ͂\x14\x1cωιῳΩΙ\x12\x10ωω\x11\x08kk" +
+ "\x12\x10åå\x12\x10ɫɫ\x12\x10ɽɽ\x10\x12ȺȺ\x10\x12ȾȾ\x12\x10ɑɑ\x12\x10ɱɱ" +
+ "\x12\x10ɐɐ\x12\x10ɒɒ\x12\x10ȿȿ\x12\x10ɀɀ\x12\x10ɥɥ\x12\x10ɦɦ\x12\x10ɜɜ" +
+ "\x12\x10ɡɡ\x12\x10ɬɬ\x12\x10ɪɪ\x12\x10ʞʞ\x12\x10ʇʇ\x12\x10ʝʝ\x12\x10ʂʂ" +
+ "\x12\x10ɤɤ\x12\x10ƛƛ\x12\x12ffFFFf\x12\x12fiFIFi\x12\x12flFLFl\x13\x1bff" +
+ "iFFIFfi\x13\x1bfflFFLFfl\x12\x12stSTSt\x12\x12stSTSt\x14$մնՄՆՄն\x14$մեՄԵ" +
+ "Մե\x14$միՄԻՄի\x14$վնՎՆՎն\x14$մխՄԽՄխ"
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *caseTrie) lookup(s []byte) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return caseValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = caseIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *caseTrie) lookupUnsafe(s []byte) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return caseValues[c0]
+ }
+ i := caseIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *caseTrie) lookupString(s string) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return caseValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := caseIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = caseIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = caseIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *caseTrie) lookupStringUnsafe(s string) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return caseValues[c0]
+ }
+ i := caseIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = caseIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// caseTrie. Total size: 14000 bytes (13.67 KiB). Checksum: 76c852e9b991a172.
+type caseTrie struct{}
+
+func newCaseTrie(i int) *caseTrie {
+ return &caseTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *caseTrie) lookupValue(n uint32, b byte) uint16 {
+ switch {
+ case n < 24:
+ return uint16(caseValues[n<<6+uint32(b)])
+ default:
+ n -= 24
+ return uint16(sparse.lookup(n, b))
+ }
+}
+
+// caseValues: 26 blocks, 1664 entries, 3328 bytes
+// The third block is the zero block.
+var caseValues = [1664]uint16{
+ // Block 0x0, offset 0x0
+ 0x27: 0x0054,
+ 0x2e: 0x0054,
+ 0x30: 0x0010, 0x31: 0x0010, 0x32: 0x0010, 0x33: 0x0010, 0x34: 0x0010, 0x35: 0x0010,
+ 0x36: 0x0010, 0x37: 0x0010, 0x38: 0x0010, 0x39: 0x0010, 0x3a: 0x0054,
+ // Block 0x1, offset 0x40
+ 0x41: 0x2013, 0x42: 0x2013, 0x43: 0x2013, 0x44: 0x2013, 0x45: 0x2013,
+ 0x46: 0x2013, 0x47: 0x2013, 0x48: 0x2013, 0x49: 0x2013, 0x4a: 0x2013, 0x4b: 0x2013,
+ 0x4c: 0x2013, 0x4d: 0x2013, 0x4e: 0x2013, 0x4f: 0x2013, 0x50: 0x2013, 0x51: 0x2013,
+ 0x52: 0x2013, 0x53: 0x2013, 0x54: 0x2013, 0x55: 0x2013, 0x56: 0x2013, 0x57: 0x2013,
+ 0x58: 0x2013, 0x59: 0x2013, 0x5a: 0x2013,
+ 0x5e: 0x0004, 0x5f: 0x0010, 0x60: 0x0004, 0x61: 0x2012, 0x62: 0x2012, 0x63: 0x2012,
+ 0x64: 0x2012, 0x65: 0x2012, 0x66: 0x2012, 0x67: 0x2012, 0x68: 0x2012, 0x69: 0x2012,
+ 0x6a: 0x2012, 0x6b: 0x2012, 0x6c: 0x2012, 0x6d: 0x2012, 0x6e: 0x2012, 0x6f: 0x2012,
+ 0x70: 0x2012, 0x71: 0x2012, 0x72: 0x2012, 0x73: 0x2012, 0x74: 0x2012, 0x75: 0x2012,
+ 0x76: 0x2012, 0x77: 0x2012, 0x78: 0x2012, 0x79: 0x2012, 0x7a: 0x2012,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x0852, 0xc1: 0x0b53, 0xc2: 0x0113, 0xc3: 0x0112, 0xc4: 0x0113, 0xc5: 0x0112,
+ 0xc6: 0x0b53, 0xc7: 0x0f13, 0xc8: 0x0f12, 0xc9: 0x0e53, 0xca: 0x1153, 0xcb: 0x0713,
+ 0xcc: 0x0712, 0xcd: 0x0012, 0xce: 0x1453, 0xcf: 0x1753, 0xd0: 0x1a53, 0xd1: 0x0313,
+ 0xd2: 0x0312, 0xd3: 0x1d53, 0xd4: 0x2053, 0xd5: 0x2352, 0xd6: 0x2653, 0xd7: 0x2653,
+ 0xd8: 0x0113, 0xd9: 0x0112, 0xda: 0x2952, 0xdb: 0x02da, 0xdc: 0x1d53, 0xdd: 0x2c53,
+ 0xde: 0x2f52, 0xdf: 0x3253, 0xe0: 0x0113, 0xe1: 0x0112, 0xe2: 0x0113, 0xe3: 0x0112,
+ 0xe4: 0x0113, 0xe5: 0x0112, 0xe6: 0x3553, 0xe7: 0x0f13, 0xe8: 0x0f12, 0xe9: 0x3853,
+ 0xea: 0x0012, 0xeb: 0x0012, 0xec: 0x0113, 0xed: 0x0112, 0xee: 0x3553, 0xef: 0x1f13,
+ 0xf0: 0x1f12, 0xf1: 0x3b53, 0xf2: 0x3e53, 0xf3: 0x0713, 0xf4: 0x0712, 0xf5: 0x0313,
+ 0xf6: 0x0312, 0xf7: 0x4153, 0xf8: 0x0113, 0xf9: 0x0112, 0xfa: 0x0012, 0xfb: 0x0010,
+ 0xfc: 0x0113, 0xfd: 0x0112, 0xfe: 0x0012, 0xff: 0x4452,
+ // Block 0x4, offset 0x100
+ 0x100: 0x0010, 0x101: 0x0010, 0x102: 0x0010, 0x103: 0x0010, 0x104: 0x035b, 0x105: 0x03d9,
+ 0x106: 0x045a, 0x107: 0x04bb, 0x108: 0x0539, 0x109: 0x05ba, 0x10a: 0x061b, 0x10b: 0x0699,
+ 0x10c: 0x071a, 0x10d: 0x0313, 0x10e: 0x0312, 0x10f: 0x1f13, 0x110: 0x1f12, 0x111: 0x0313,
+ 0x112: 0x0312, 0x113: 0x0713, 0x114: 0x0712, 0x115: 0x0313, 0x116: 0x0312, 0x117: 0x0f13,
+ 0x118: 0x0f12, 0x119: 0x0313, 0x11a: 0x0312, 0x11b: 0x0713, 0x11c: 0x0712, 0x11d: 0x1452,
+ 0x11e: 0x0113, 0x11f: 0x0112, 0x120: 0x0113, 0x121: 0x0112, 0x122: 0x0113, 0x123: 0x0112,
+ 0x124: 0x0113, 0x125: 0x0112, 0x126: 0x0113, 0x127: 0x0112, 0x128: 0x0113, 0x129: 0x0112,
+ 0x12a: 0x0113, 0x12b: 0x0112, 0x12c: 0x0113, 0x12d: 0x0112, 0x12e: 0x0113, 0x12f: 0x0112,
+ 0x130: 0x077a, 0x131: 0x082b, 0x132: 0x08a9, 0x133: 0x092a, 0x134: 0x0113, 0x135: 0x0112,
+ 0x136: 0x2353, 0x137: 0x4453, 0x138: 0x0113, 0x139: 0x0112, 0x13a: 0x0113, 0x13b: 0x0112,
+ 0x13c: 0x0113, 0x13d: 0x0112, 0x13e: 0x0113, 0x13f: 0x0112,
+ // Block 0x5, offset 0x140
+ 0x140: 0x0b0a, 0x141: 0x0313, 0x142: 0x0312, 0x143: 0x0853, 0x144: 0x4753, 0x145: 0x4a53,
+ 0x146: 0x0113, 0x147: 0x0112, 0x148: 0x0113, 0x149: 0x0112, 0x14a: 0x0113, 0x14b: 0x0112,
+ 0x14c: 0x0113, 0x14d: 0x0112, 0x14e: 0x0113, 0x14f: 0x0112, 0x150: 0x0b8a, 0x151: 0x0c0a,
+ 0x152: 0x0c8a, 0x153: 0x0b52, 0x154: 0x0b52, 0x155: 0x0012, 0x156: 0x0e52, 0x157: 0x1152,
+ 0x158: 0x0012, 0x159: 0x1752, 0x15a: 0x0012, 0x15b: 0x1a52, 0x15c: 0x0d0a, 0x15d: 0x0012,
+ 0x15e: 0x0012, 0x15f: 0x0012, 0x160: 0x1d52, 0x161: 0x0d8a, 0x162: 0x0012, 0x163: 0x2052,
+ 0x164: 0x0e0a, 0x165: 0x0e8a, 0x166: 0x0f0a, 0x167: 0x0012, 0x168: 0x2652, 0x169: 0x2652,
+ 0x16a: 0x0f8a, 0x16b: 0x100a, 0x16c: 0x108a, 0x16d: 0x0012, 0x16e: 0x0012, 0x16f: 0x1d52,
+ 0x170: 0x0012, 0x171: 0x110a, 0x172: 0x2c52, 0x173: 0x0012, 0x174: 0x0012, 0x175: 0x3252,
+ 0x176: 0x0012, 0x177: 0x0012, 0x178: 0x0012, 0x179: 0x0012, 0x17a: 0x0012, 0x17b: 0x0012,
+ 0x17c: 0x0012, 0x17d: 0x118a, 0x17e: 0x0012, 0x17f: 0x0012,
+ // Block 0x6, offset 0x180
+ 0x180: 0x3552, 0x181: 0x0012, 0x182: 0x120a, 0x183: 0x3852, 0x184: 0x0012, 0x185: 0x0012,
+ 0x186: 0x0012, 0x187: 0x128a, 0x188: 0x3552, 0x189: 0x4752, 0x18a: 0x3b52, 0x18b: 0x3e52,
+ 0x18c: 0x4a52, 0x18d: 0x0012, 0x18e: 0x0012, 0x18f: 0x0012, 0x190: 0x0012, 0x191: 0x0012,
+ 0x192: 0x4152, 0x193: 0x0012, 0x194: 0x0010, 0x195: 0x0010, 0x196: 0x0012, 0x197: 0x0012,
+ 0x198: 0x0012, 0x199: 0x0012, 0x19a: 0x0012, 0x19b: 0x0012, 0x19c: 0x0012, 0x19d: 0x130a,
+ 0x19e: 0x138a, 0x19f: 0x0012, 0x1a0: 0x0012, 0x1a1: 0x0012, 0x1a2: 0x0012, 0x1a3: 0x0012,
+ 0x1a4: 0x0012, 0x1a5: 0x0012, 0x1a6: 0x0012, 0x1a7: 0x0012, 0x1a8: 0x0012, 0x1a9: 0x0012,
+ 0x1aa: 0x0012, 0x1ab: 0x0012, 0x1ac: 0x0012, 0x1ad: 0x0012, 0x1ae: 0x0012, 0x1af: 0x0012,
+ 0x1b0: 0x0015, 0x1b1: 0x0015, 0x1b2: 0x0015, 0x1b3: 0x0015, 0x1b4: 0x0015, 0x1b5: 0x0015,
+ 0x1b6: 0x0015, 0x1b7: 0x0015, 0x1b8: 0x0015, 0x1b9: 0x0014, 0x1ba: 0x0014, 0x1bb: 0x0014,
+ 0x1bc: 0x0014, 0x1bd: 0x0014, 0x1be: 0x0014, 0x1bf: 0x0014,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x0024, 0x1c1: 0x0024, 0x1c2: 0x0024, 0x1c3: 0x0024, 0x1c4: 0x0024, 0x1c5: 0x140d,
+ 0x1c6: 0x0024, 0x1c7: 0x0034, 0x1c8: 0x0034, 0x1c9: 0x0034, 0x1ca: 0x0024, 0x1cb: 0x0024,
+ 0x1cc: 0x0024, 0x1cd: 0x0034, 0x1ce: 0x0034, 0x1cf: 0x0014, 0x1d0: 0x0024, 0x1d1: 0x0024,
+ 0x1d2: 0x0024, 0x1d3: 0x0034, 0x1d4: 0x0034, 0x1d5: 0x0034, 0x1d6: 0x0034, 0x1d7: 0x0024,
+ 0x1d8: 0x0034, 0x1d9: 0x0034, 0x1da: 0x0034, 0x1db: 0x0024, 0x1dc: 0x0034, 0x1dd: 0x0034,
+ 0x1de: 0x0034, 0x1df: 0x0034, 0x1e0: 0x0034, 0x1e1: 0x0034, 0x1e2: 0x0034, 0x1e3: 0x0024,
+ 0x1e4: 0x0024, 0x1e5: 0x0024, 0x1e6: 0x0024, 0x1e7: 0x0024, 0x1e8: 0x0024, 0x1e9: 0x0024,
+ 0x1ea: 0x0024, 0x1eb: 0x0024, 0x1ec: 0x0024, 0x1ed: 0x0024, 0x1ee: 0x0024, 0x1ef: 0x0024,
+ 0x1f0: 0x0113, 0x1f1: 0x0112, 0x1f2: 0x0113, 0x1f3: 0x0112, 0x1f4: 0x0014, 0x1f5: 0x0004,
+ 0x1f6: 0x0113, 0x1f7: 0x0112, 0x1fa: 0x0015, 0x1fb: 0x4d52,
+ 0x1fc: 0x5052, 0x1fd: 0x5052, 0x1ff: 0x5353,
+ // Block 0x8, offset 0x200
+ 0x204: 0x0004, 0x205: 0x0004,
+ 0x206: 0x2a13, 0x207: 0x0054, 0x208: 0x2513, 0x209: 0x2713, 0x20a: 0x2513,
+ 0x20c: 0x5653, 0x20e: 0x5953, 0x20f: 0x5c53, 0x210: 0x148a, 0x211: 0x2013,
+ 0x212: 0x2013, 0x213: 0x2013, 0x214: 0x2013, 0x215: 0x2013, 0x216: 0x2013, 0x217: 0x2013,
+ 0x218: 0x2013, 0x219: 0x2013, 0x21a: 0x2013, 0x21b: 0x2013, 0x21c: 0x2013, 0x21d: 0x2013,
+ 0x21e: 0x2013, 0x21f: 0x2013, 0x220: 0x5f53, 0x221: 0x5f53, 0x223: 0x5f53,
+ 0x224: 0x5f53, 0x225: 0x5f53, 0x226: 0x5f53, 0x227: 0x5f53, 0x228: 0x5f53, 0x229: 0x5f53,
+ 0x22a: 0x5f53, 0x22b: 0x5f53, 0x22c: 0x2a12, 0x22d: 0x2512, 0x22e: 0x2712, 0x22f: 0x2512,
+ 0x230: 0x15ca, 0x231: 0x2012, 0x232: 0x2012, 0x233: 0x2012, 0x234: 0x2012, 0x235: 0x2012,
+ 0x236: 0x2012, 0x237: 0x2012, 0x238: 0x2012, 0x239: 0x2012, 0x23a: 0x2012, 0x23b: 0x2012,
+ 0x23c: 0x2012, 0x23d: 0x2012, 0x23e: 0x2012, 0x23f: 0x2012,
+ // Block 0x9, offset 0x240
+ 0x240: 0x5f52, 0x241: 0x5f52, 0x242: 0x170a, 0x243: 0x5f52, 0x244: 0x5f52, 0x245: 0x5f52,
+ 0x246: 0x5f52, 0x247: 0x5f52, 0x248: 0x5f52, 0x249: 0x5f52, 0x24a: 0x5f52, 0x24b: 0x5f52,
+ 0x24c: 0x5652, 0x24d: 0x5952, 0x24e: 0x5c52, 0x24f: 0x1813, 0x250: 0x178a, 0x251: 0x180a,
+ 0x252: 0x0013, 0x253: 0x0013, 0x254: 0x0013, 0x255: 0x188a, 0x256: 0x190a, 0x257: 0x1812,
+ 0x258: 0x0113, 0x259: 0x0112, 0x25a: 0x0113, 0x25b: 0x0112, 0x25c: 0x0113, 0x25d: 0x0112,
+ 0x25e: 0x0113, 0x25f: 0x0112, 0x260: 0x0113, 0x261: 0x0112, 0x262: 0x0113, 0x263: 0x0112,
+ 0x264: 0x0113, 0x265: 0x0112, 0x266: 0x0113, 0x267: 0x0112, 0x268: 0x0113, 0x269: 0x0112,
+ 0x26a: 0x0113, 0x26b: 0x0112, 0x26c: 0x0113, 0x26d: 0x0112, 0x26e: 0x0113, 0x26f: 0x0112,
+ 0x270: 0x198a, 0x271: 0x1a0a, 0x272: 0x0b12, 0x273: 0x5352, 0x274: 0x6253, 0x275: 0x1a8a,
+ 0x277: 0x0f13, 0x278: 0x0f12, 0x279: 0x0b13, 0x27a: 0x0113, 0x27b: 0x0112,
+ 0x27c: 0x0012, 0x27d: 0x4d53, 0x27e: 0x5053, 0x27f: 0x5053,
+ // Block 0xa, offset 0x280
+ 0x280: 0x6852, 0x281: 0x6852, 0x282: 0x6852, 0x283: 0x6852, 0x284: 0x6852, 0x285: 0x6852,
+ 0x286: 0x6852, 0x287: 0x1b0a, 0x288: 0x0012, 0x28a: 0x0010,
+ 0x291: 0x0034,
+ 0x292: 0x0024, 0x293: 0x0024, 0x294: 0x0024, 0x295: 0x0024, 0x296: 0x0034, 0x297: 0x0024,
+ 0x298: 0x0024, 0x299: 0x0024, 0x29a: 0x0034, 0x29b: 0x0034, 0x29c: 0x0024, 0x29d: 0x0024,
+ 0x29e: 0x0024, 0x29f: 0x0024, 0x2a0: 0x0024, 0x2a1: 0x0024, 0x2a2: 0x0034, 0x2a3: 0x0034,
+ 0x2a4: 0x0034, 0x2a5: 0x0034, 0x2a6: 0x0034, 0x2a7: 0x0034, 0x2a8: 0x0024, 0x2a9: 0x0024,
+ 0x2aa: 0x0034, 0x2ab: 0x0024, 0x2ac: 0x0024, 0x2ad: 0x0034, 0x2ae: 0x0034, 0x2af: 0x0024,
+ 0x2b0: 0x0034, 0x2b1: 0x0034, 0x2b2: 0x0034, 0x2b3: 0x0034, 0x2b4: 0x0034, 0x2b5: 0x0034,
+ 0x2b6: 0x0034, 0x2b7: 0x0034, 0x2b8: 0x0034, 0x2b9: 0x0034, 0x2ba: 0x0034, 0x2bb: 0x0034,
+ 0x2bc: 0x0034, 0x2bd: 0x0034, 0x2bf: 0x0034,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0x0010, 0x2c1: 0x0010, 0x2c2: 0x0010, 0x2c3: 0x0010, 0x2c4: 0x0010, 0x2c5: 0x0010,
+ 0x2c6: 0x0010, 0x2c7: 0x0010, 0x2c8: 0x0010, 0x2c9: 0x0014, 0x2ca: 0x0024, 0x2cb: 0x0024,
+ 0x2cc: 0x0024, 0x2cd: 0x0024, 0x2ce: 0x0024, 0x2cf: 0x0034, 0x2d0: 0x0034, 0x2d1: 0x0034,
+ 0x2d2: 0x0034, 0x2d3: 0x0034, 0x2d4: 0x0024, 0x2d5: 0x0024, 0x2d6: 0x0024, 0x2d7: 0x0024,
+ 0x2d8: 0x0024, 0x2d9: 0x0024, 0x2da: 0x0024, 0x2db: 0x0024, 0x2dc: 0x0024, 0x2dd: 0x0024,
+ 0x2de: 0x0024, 0x2df: 0x0024, 0x2e0: 0x0024, 0x2e1: 0x0024, 0x2e2: 0x0014, 0x2e3: 0x0034,
+ 0x2e4: 0x0024, 0x2e5: 0x0024, 0x2e6: 0x0034, 0x2e7: 0x0024, 0x2e8: 0x0024, 0x2e9: 0x0034,
+ 0x2ea: 0x0024, 0x2eb: 0x0024, 0x2ec: 0x0024, 0x2ed: 0x0034, 0x2ee: 0x0034, 0x2ef: 0x0034,
+ 0x2f0: 0x0034, 0x2f1: 0x0034, 0x2f2: 0x0034, 0x2f3: 0x0024, 0x2f4: 0x0024, 0x2f5: 0x0024,
+ 0x2f6: 0x0034, 0x2f7: 0x0024, 0x2f8: 0x0024, 0x2f9: 0x0034, 0x2fa: 0x0034, 0x2fb: 0x0024,
+ 0x2fc: 0x0024, 0x2fd: 0x0024, 0x2fe: 0x0024, 0x2ff: 0x0024,
+ // Block 0xc, offset 0x300
+ 0x300: 0x7053, 0x301: 0x7053, 0x302: 0x7053, 0x303: 0x7053, 0x304: 0x7053, 0x305: 0x7053,
+ 0x307: 0x7053,
+ 0x30d: 0x7053, 0x310: 0x1bea, 0x311: 0x1c6a,
+ 0x312: 0x1cea, 0x313: 0x1d6a, 0x314: 0x1dea, 0x315: 0x1e6a, 0x316: 0x1eea, 0x317: 0x1f6a,
+ 0x318: 0x1fea, 0x319: 0x206a, 0x31a: 0x20ea, 0x31b: 0x216a, 0x31c: 0x21ea, 0x31d: 0x226a,
+ 0x31e: 0x22ea, 0x31f: 0x236a, 0x320: 0x23ea, 0x321: 0x246a, 0x322: 0x24ea, 0x323: 0x256a,
+ 0x324: 0x25ea, 0x325: 0x266a, 0x326: 0x26ea, 0x327: 0x276a, 0x328: 0x27ea, 0x329: 0x286a,
+ 0x32a: 0x28ea, 0x32b: 0x296a, 0x32c: 0x29ea, 0x32d: 0x2a6a, 0x32e: 0x2aea, 0x32f: 0x2b6a,
+ 0x330: 0x2bea, 0x331: 0x2c6a, 0x332: 0x2cea, 0x333: 0x2d6a, 0x334: 0x2dea, 0x335: 0x2e6a,
+ 0x336: 0x2eea, 0x337: 0x2f6a, 0x338: 0x2fea, 0x339: 0x306a, 0x33a: 0x30ea,
+ 0x33c: 0x0015, 0x33d: 0x316a, 0x33e: 0x31ea, 0x33f: 0x326a,
+ // Block 0xd, offset 0x340
+ 0x340: 0x0812, 0x341: 0x0812, 0x342: 0x0812, 0x343: 0x0812, 0x344: 0x0812, 0x345: 0x0812,
+ 0x348: 0x0813, 0x349: 0x0813, 0x34a: 0x0813, 0x34b: 0x0813,
+ 0x34c: 0x0813, 0x34d: 0x0813, 0x350: 0x3c1a, 0x351: 0x0812,
+ 0x352: 0x3cfa, 0x353: 0x0812, 0x354: 0x3e3a, 0x355: 0x0812, 0x356: 0x3f7a, 0x357: 0x0812,
+ 0x359: 0x0813, 0x35b: 0x0813, 0x35d: 0x0813,
+ 0x35f: 0x0813, 0x360: 0x0812, 0x361: 0x0812, 0x362: 0x0812, 0x363: 0x0812,
+ 0x364: 0x0812, 0x365: 0x0812, 0x366: 0x0812, 0x367: 0x0812, 0x368: 0x0813, 0x369: 0x0813,
+ 0x36a: 0x0813, 0x36b: 0x0813, 0x36c: 0x0813, 0x36d: 0x0813, 0x36e: 0x0813, 0x36f: 0x0813,
+ 0x370: 0x9252, 0x371: 0x9252, 0x372: 0x9552, 0x373: 0x9552, 0x374: 0x9852, 0x375: 0x9852,
+ 0x376: 0x9b52, 0x377: 0x9b52, 0x378: 0x9e52, 0x379: 0x9e52, 0x37a: 0xa152, 0x37b: 0xa152,
+ 0x37c: 0x4d52, 0x37d: 0x4d52,
+ // Block 0xe, offset 0x380
+ 0x380: 0x40ba, 0x381: 0x41aa, 0x382: 0x429a, 0x383: 0x438a, 0x384: 0x447a, 0x385: 0x456a,
+ 0x386: 0x465a, 0x387: 0x474a, 0x388: 0x4839, 0x389: 0x4929, 0x38a: 0x4a19, 0x38b: 0x4b09,
+ 0x38c: 0x4bf9, 0x38d: 0x4ce9, 0x38e: 0x4dd9, 0x38f: 0x4ec9, 0x390: 0x4fba, 0x391: 0x50aa,
+ 0x392: 0x519a, 0x393: 0x528a, 0x394: 0x537a, 0x395: 0x546a, 0x396: 0x555a, 0x397: 0x564a,
+ 0x398: 0x5739, 0x399: 0x5829, 0x39a: 0x5919, 0x39b: 0x5a09, 0x39c: 0x5af9, 0x39d: 0x5be9,
+ 0x39e: 0x5cd9, 0x39f: 0x5dc9, 0x3a0: 0x5eba, 0x3a1: 0x5faa, 0x3a2: 0x609a, 0x3a3: 0x618a,
+ 0x3a4: 0x627a, 0x3a5: 0x636a, 0x3a6: 0x645a, 0x3a7: 0x654a, 0x3a8: 0x6639, 0x3a9: 0x6729,
+ 0x3aa: 0x6819, 0x3ab: 0x6909, 0x3ac: 0x69f9, 0x3ad: 0x6ae9, 0x3ae: 0x6bd9, 0x3af: 0x6cc9,
+ 0x3b0: 0x0812, 0x3b1: 0x0812, 0x3b2: 0x6dba, 0x3b3: 0x6eca, 0x3b4: 0x6f9a,
+ 0x3b6: 0x707a, 0x3b7: 0x715a, 0x3b8: 0x0813, 0x3b9: 0x0813, 0x3ba: 0x9253, 0x3bb: 0x9253,
+ 0x3bc: 0x7299, 0x3bd: 0x0004, 0x3be: 0x736a, 0x3bf: 0x0004,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x0004, 0x3c1: 0x0004, 0x3c2: 0x73ea, 0x3c3: 0x74fa, 0x3c4: 0x75ca,
+ 0x3c6: 0x76aa, 0x3c7: 0x778a, 0x3c8: 0x9553, 0x3c9: 0x9553, 0x3ca: 0x9853, 0x3cb: 0x9853,
+ 0x3cc: 0x78c9, 0x3cd: 0x0004, 0x3ce: 0x0004, 0x3cf: 0x0004, 0x3d0: 0x0812, 0x3d1: 0x0812,
+ 0x3d2: 0x799a, 0x3d3: 0x7ada, 0x3d6: 0x7c1a, 0x3d7: 0x7cfa,
+ 0x3d8: 0x0813, 0x3d9: 0x0813, 0x3da: 0x9b53, 0x3db: 0x9b53, 0x3dd: 0x0004,
+ 0x3de: 0x0004, 0x3df: 0x0004, 0x3e0: 0x0812, 0x3e1: 0x0812, 0x3e2: 0x7e3a, 0x3e3: 0x7f7a,
+ 0x3e4: 0x80ba, 0x3e5: 0x0912, 0x3e6: 0x819a, 0x3e7: 0x827a, 0x3e8: 0x0813, 0x3e9: 0x0813,
+ 0x3ea: 0xa153, 0x3eb: 0xa153, 0x3ec: 0x0913, 0x3ed: 0x0004, 0x3ee: 0x0004, 0x3ef: 0x0004,
+ 0x3f2: 0x83ba, 0x3f3: 0x84ca, 0x3f4: 0x859a,
+ 0x3f6: 0x867a, 0x3f7: 0x875a, 0x3f8: 0x9e53, 0x3f9: 0x9e53, 0x3fa: 0x4d53, 0x3fb: 0x4d53,
+ 0x3fc: 0x8899, 0x3fd: 0x0004, 0x3fe: 0x0004,
+ // Block 0x10, offset 0x400
+ 0x402: 0x0013,
+ 0x407: 0x0013, 0x40a: 0x0012, 0x40b: 0x0013,
+ 0x40c: 0x0013, 0x40d: 0x0013, 0x40e: 0x0012, 0x40f: 0x0012, 0x410: 0x0013, 0x411: 0x0013,
+ 0x412: 0x0013, 0x413: 0x0012, 0x415: 0x0013,
+ 0x419: 0x0013, 0x41a: 0x0013, 0x41b: 0x0013, 0x41c: 0x0013, 0x41d: 0x0013,
+ 0x424: 0x0013, 0x426: 0x896b, 0x428: 0x0013,
+ 0x42a: 0x89cb, 0x42b: 0x8a0b, 0x42c: 0x0013, 0x42d: 0x0013, 0x42f: 0x0012,
+ 0x430: 0x0013, 0x431: 0x0013, 0x432: 0xa453, 0x433: 0x0013, 0x434: 0x0012, 0x435: 0x0010,
+ 0x436: 0x0010, 0x437: 0x0010, 0x438: 0x0010, 0x439: 0x0012,
+ 0x43c: 0x0012, 0x43d: 0x0012, 0x43e: 0x0013, 0x43f: 0x0013,
+ // Block 0x11, offset 0x440
+ 0x440: 0x1a13, 0x441: 0x1a13, 0x442: 0x1e13, 0x443: 0x1e13, 0x444: 0x1a13, 0x445: 0x1a13,
+ 0x446: 0x2613, 0x447: 0x2613, 0x448: 0x2a13, 0x449: 0x2a13, 0x44a: 0x2e13, 0x44b: 0x2e13,
+ 0x44c: 0x2a13, 0x44d: 0x2a13, 0x44e: 0x2613, 0x44f: 0x2613, 0x450: 0xa752, 0x451: 0xa752,
+ 0x452: 0xaa52, 0x453: 0xaa52, 0x454: 0xad52, 0x455: 0xad52, 0x456: 0xaa52, 0x457: 0xaa52,
+ 0x458: 0xa752, 0x459: 0xa752, 0x45a: 0x1a12, 0x45b: 0x1a12, 0x45c: 0x1e12, 0x45d: 0x1e12,
+ 0x45e: 0x1a12, 0x45f: 0x1a12, 0x460: 0x2612, 0x461: 0x2612, 0x462: 0x2a12, 0x463: 0x2a12,
+ 0x464: 0x2e12, 0x465: 0x2e12, 0x466: 0x2a12, 0x467: 0x2a12, 0x468: 0x2612, 0x469: 0x2612,
+ // Block 0x12, offset 0x480
+ 0x480: 0x6552, 0x481: 0x6552, 0x482: 0x6552, 0x483: 0x6552, 0x484: 0x6552, 0x485: 0x6552,
+ 0x486: 0x6552, 0x487: 0x6552, 0x488: 0x6552, 0x489: 0x6552, 0x48a: 0x6552, 0x48b: 0x6552,
+ 0x48c: 0x6552, 0x48d: 0x6552, 0x48e: 0x6552, 0x48f: 0x6552, 0x490: 0xb052, 0x491: 0xb052,
+ 0x492: 0xb052, 0x493: 0xb052, 0x494: 0xb052, 0x495: 0xb052, 0x496: 0xb052, 0x497: 0xb052,
+ 0x498: 0xb052, 0x499: 0xb052, 0x49a: 0xb052, 0x49b: 0xb052, 0x49c: 0xb052, 0x49d: 0xb052,
+ 0x49e: 0xb052, 0x49f: 0xb052, 0x4a0: 0x0113, 0x4a1: 0x0112, 0x4a2: 0x8a6b, 0x4a3: 0x8b53,
+ 0x4a4: 0x8acb, 0x4a5: 0x8b2a, 0x4a6: 0x8b8a, 0x4a7: 0x0f13, 0x4a8: 0x0f12, 0x4a9: 0x0313,
+ 0x4aa: 0x0312, 0x4ab: 0x0713, 0x4ac: 0x0712, 0x4ad: 0x8beb, 0x4ae: 0x8c4b, 0x4af: 0x8cab,
+ 0x4b0: 0x8d0b, 0x4b1: 0x0012, 0x4b2: 0x0113, 0x4b3: 0x0112, 0x4b4: 0x0012, 0x4b5: 0x0313,
+ 0x4b6: 0x0312, 0x4b7: 0x0012, 0x4b8: 0x0012, 0x4b9: 0x0012, 0x4ba: 0x0012, 0x4bb: 0x0012,
+ 0x4bc: 0x0015, 0x4bd: 0x0015, 0x4be: 0x8d6b, 0x4bf: 0x8dcb,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0x0113, 0x4c1: 0x0112, 0x4c2: 0x0113, 0x4c3: 0x0112, 0x4c4: 0x0113, 0x4c5: 0x0112,
+ 0x4c6: 0x0113, 0x4c7: 0x0112, 0x4c8: 0x0014, 0x4c9: 0x0014, 0x4ca: 0x0014, 0x4cb: 0x0713,
+ 0x4cc: 0x0712, 0x4cd: 0x8e2b, 0x4ce: 0x0012, 0x4cf: 0x0010, 0x4d0: 0x0113, 0x4d1: 0x0112,
+ 0x4d2: 0x0113, 0x4d3: 0x0112, 0x4d4: 0x6552, 0x4d5: 0x0012, 0x4d6: 0x0113, 0x4d7: 0x0112,
+ 0x4d8: 0x0113, 0x4d9: 0x0112, 0x4da: 0x0113, 0x4db: 0x0112, 0x4dc: 0x0113, 0x4dd: 0x0112,
+ 0x4de: 0x0113, 0x4df: 0x0112, 0x4e0: 0x0113, 0x4e1: 0x0112, 0x4e2: 0x0113, 0x4e3: 0x0112,
+ 0x4e4: 0x0113, 0x4e5: 0x0112, 0x4e6: 0x0113, 0x4e7: 0x0112, 0x4e8: 0x0113, 0x4e9: 0x0112,
+ 0x4ea: 0x8e8b, 0x4eb: 0x8eeb, 0x4ec: 0x8f4b, 0x4ed: 0x8fab, 0x4ee: 0x900b, 0x4ef: 0x0012,
+ 0x4f0: 0x906b, 0x4f1: 0x90cb, 0x4f2: 0x912b, 0x4f3: 0xb353, 0x4f4: 0x0113, 0x4f5: 0x0112,
+ 0x4f6: 0x0113, 0x4f7: 0x0112, 0x4f8: 0x0113, 0x4f9: 0x0112, 0x4fa: 0x0113, 0x4fb: 0x0112,
+ 0x4fc: 0x0113, 0x4fd: 0x0112, 0x4fe: 0x0113, 0x4ff: 0x0112,
+ // Block 0x14, offset 0x500
+ 0x500: 0x92aa, 0x501: 0x932a, 0x502: 0x93aa, 0x503: 0x942a, 0x504: 0x94da, 0x505: 0x958a,
+ 0x506: 0x960a,
+ 0x513: 0x968a, 0x514: 0x976a, 0x515: 0x984a, 0x516: 0x992a, 0x517: 0x9a0a,
+ 0x51d: 0x0010,
+ 0x51e: 0x0034, 0x51f: 0x0010, 0x520: 0x0010, 0x521: 0x0010, 0x522: 0x0010, 0x523: 0x0010,
+ 0x524: 0x0010, 0x525: 0x0010, 0x526: 0x0010, 0x527: 0x0010, 0x528: 0x0010,
+ 0x52a: 0x0010, 0x52b: 0x0010, 0x52c: 0x0010, 0x52d: 0x0010, 0x52e: 0x0010, 0x52f: 0x0010,
+ 0x530: 0x0010, 0x531: 0x0010, 0x532: 0x0010, 0x533: 0x0010, 0x534: 0x0010, 0x535: 0x0010,
+ 0x536: 0x0010, 0x538: 0x0010, 0x539: 0x0010, 0x53a: 0x0010, 0x53b: 0x0010,
+ 0x53c: 0x0010, 0x53e: 0x0010,
+ // Block 0x15, offset 0x540
+ 0x540: 0x2713, 0x541: 0x2913, 0x542: 0x2b13, 0x543: 0x2913, 0x544: 0x2f13, 0x545: 0x2913,
+ 0x546: 0x2b13, 0x547: 0x2913, 0x548: 0x2713, 0x549: 0x3913, 0x54a: 0x3b13,
+ 0x54c: 0x3f13, 0x54d: 0x3913, 0x54e: 0x3b13, 0x54f: 0x3913, 0x550: 0x2713, 0x551: 0x2913,
+ 0x552: 0x2b13, 0x554: 0x2f13, 0x555: 0x2913, 0x557: 0xbc52,
+ 0x558: 0xbf52, 0x559: 0xc252, 0x55a: 0xbf52, 0x55b: 0xc552, 0x55c: 0xbf52, 0x55d: 0xc252,
+ 0x55e: 0xbf52, 0x55f: 0xbc52, 0x560: 0xc852, 0x561: 0xcb52, 0x563: 0xce52,
+ 0x564: 0xc852, 0x565: 0xcb52, 0x566: 0xc852, 0x567: 0x2712, 0x568: 0x2912, 0x569: 0x2b12,
+ 0x56a: 0x2912, 0x56b: 0x2f12, 0x56c: 0x2912, 0x56d: 0x2b12, 0x56e: 0x2912, 0x56f: 0x2712,
+ 0x570: 0x3912, 0x571: 0x3b12, 0x573: 0x3f12, 0x574: 0x3912, 0x575: 0x3b12,
+ 0x576: 0x3912, 0x577: 0x2712, 0x578: 0x2912, 0x579: 0x2b12, 0x57b: 0x2f12,
+ 0x57c: 0x2912,
+ // Block 0x16, offset 0x580
+ 0x5a0: 0x1b13, 0x5a1: 0x1d13, 0x5a2: 0x1f13, 0x5a3: 0x1d13,
+ 0x5a4: 0x1b13, 0x5a5: 0xd453, 0x5a6: 0xd753, 0x5a7: 0xd453, 0x5a8: 0xda53, 0x5a9: 0xdd53,
+ 0x5aa: 0xe053, 0x5ab: 0xdd53, 0x5ac: 0xda53, 0x5ad: 0xd453, 0x5ae: 0xd753, 0x5af: 0xd453,
+ 0x5b0: 0xe353, 0x5b1: 0xe653, 0x5b2: 0x0553, 0x5b3: 0xe653, 0x5b4: 0xe353, 0x5b5: 0xd453,
+ 0x5b6: 0xd753, 0x5b7: 0xd453, 0x5b8: 0xda53, 0x5bb: 0x1b12,
+ 0x5bc: 0x1d12, 0x5bd: 0x1f12, 0x5be: 0x1d12, 0x5bf: 0x1b12,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0xd452, 0x5c1: 0xd752, 0x5c2: 0xd452, 0x5c3: 0xda52, 0x5c4: 0xdd52, 0x5c5: 0xe052,
+ 0x5c6: 0xdd52, 0x5c7: 0xda52, 0x5c8: 0xd452, 0x5c9: 0xd752, 0x5ca: 0xd452, 0x5cb: 0xe352,
+ 0x5cc: 0xe652, 0x5cd: 0x0552, 0x5ce: 0xe652, 0x5cf: 0xe352, 0x5d0: 0xd452, 0x5d1: 0xd752,
+ 0x5d2: 0xd452, 0x5d3: 0xda52,
+ // Block 0x18, offset 0x600
+ 0x600: 0x2213, 0x601: 0x2213, 0x602: 0x2613, 0x603: 0x2613, 0x604: 0x2213, 0x605: 0x2213,
+ 0x606: 0x2e13, 0x607: 0x2e13, 0x608: 0x2213, 0x609: 0x2213, 0x60a: 0x2613, 0x60b: 0x2613,
+ 0x60c: 0x2213, 0x60d: 0x2213, 0x60e: 0x3e13, 0x60f: 0x3e13, 0x610: 0x2213, 0x611: 0x2213,
+ 0x612: 0x2613, 0x613: 0x2613, 0x614: 0x2213, 0x615: 0x2213, 0x616: 0x2e13, 0x617: 0x2e13,
+ 0x618: 0x2213, 0x619: 0x2213, 0x61a: 0x2613, 0x61b: 0x2613, 0x61c: 0x2213, 0x61d: 0x2213,
+ 0x61e: 0xe953, 0x61f: 0xe953, 0x620: 0xec53, 0x621: 0xec53, 0x622: 0x2212, 0x623: 0x2212,
+ 0x624: 0x2612, 0x625: 0x2612, 0x626: 0x2212, 0x627: 0x2212, 0x628: 0x2e12, 0x629: 0x2e12,
+ 0x62a: 0x2212, 0x62b: 0x2212, 0x62c: 0x2612, 0x62d: 0x2612, 0x62e: 0x2212, 0x62f: 0x2212,
+ 0x630: 0x3e12, 0x631: 0x3e12, 0x632: 0x2212, 0x633: 0x2212, 0x634: 0x2612, 0x635: 0x2612,
+ 0x636: 0x2212, 0x637: 0x2212, 0x638: 0x2e12, 0x639: 0x2e12, 0x63a: 0x2212, 0x63b: 0x2212,
+ 0x63c: 0x2612, 0x63d: 0x2612, 0x63e: 0x2212, 0x63f: 0x2212,
+ // Block 0x19, offset 0x640
+ 0x642: 0x0010,
+ 0x647: 0x0010, 0x649: 0x0010, 0x64b: 0x0010,
+ 0x64d: 0x0010, 0x64e: 0x0010, 0x64f: 0x0010, 0x651: 0x0010,
+ 0x652: 0x0010, 0x654: 0x0010, 0x657: 0x0010,
+ 0x659: 0x0010, 0x65b: 0x0010, 0x65d: 0x0010,
+ 0x65f: 0x0010, 0x661: 0x0010, 0x662: 0x0010,
+ 0x664: 0x0010, 0x667: 0x0010, 0x668: 0x0010, 0x669: 0x0010,
+ 0x66a: 0x0010, 0x66c: 0x0010, 0x66d: 0x0010, 0x66e: 0x0010, 0x66f: 0x0010,
+ 0x670: 0x0010, 0x671: 0x0010, 0x672: 0x0010, 0x674: 0x0010, 0x675: 0x0010,
+ 0x676: 0x0010, 0x677: 0x0010, 0x679: 0x0010, 0x67a: 0x0010, 0x67b: 0x0010,
+ 0x67c: 0x0010, 0x67e: 0x0010,
+}
+
+// caseIndex: 27 blocks, 1728 entries, 3456 bytes
+// Block 0 is the zero block.
+var caseIndex = [1728]uint16{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x18, 0xc3: 0x19, 0xc4: 0x1a, 0xc5: 0x1b, 0xc6: 0x01, 0xc7: 0x02,
+ 0xc8: 0x1c, 0xc9: 0x03, 0xca: 0x04, 0xcb: 0x1d, 0xcc: 0x1e, 0xcd: 0x05, 0xce: 0x06, 0xcf: 0x07,
+ 0xd0: 0x1f, 0xd1: 0x20, 0xd2: 0x21, 0xd3: 0x22, 0xd4: 0x23, 0xd5: 0x24, 0xd6: 0x08, 0xd7: 0x25,
+ 0xd8: 0x26, 0xd9: 0x27, 0xda: 0x28, 0xdb: 0x29, 0xdc: 0x2a, 0xdd: 0x2b, 0xde: 0x2c, 0xdf: 0x2d,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+ 0xea: 0x06, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x08, 0xef: 0x09,
+ 0xf0: 0x16, 0xf3: 0x18,
+ // Block 0x4, offset 0x100
+ 0x120: 0x2e, 0x121: 0x2f, 0x122: 0x30, 0x123: 0x09, 0x124: 0x31, 0x125: 0x32, 0x126: 0x33, 0x127: 0x34,
+ 0x128: 0x35, 0x129: 0x36, 0x12a: 0x37, 0x12b: 0x38, 0x12c: 0x39, 0x12d: 0x3a, 0x12e: 0x3b, 0x12f: 0x3c,
+ 0x130: 0x3d, 0x131: 0x3e, 0x132: 0x3f, 0x133: 0x40, 0x134: 0x41, 0x135: 0x42, 0x136: 0x43, 0x137: 0x44,
+ 0x138: 0x45, 0x139: 0x46, 0x13a: 0x47, 0x13b: 0x48, 0x13c: 0x49, 0x13d: 0x4a, 0x13e: 0x4b, 0x13f: 0x4c,
+ // Block 0x5, offset 0x140
+ 0x140: 0x4d, 0x141: 0x4e, 0x142: 0x4f, 0x143: 0x0a, 0x144: 0x28, 0x145: 0x28, 0x146: 0x28, 0x147: 0x28,
+ 0x148: 0x28, 0x149: 0x50, 0x14a: 0x51, 0x14b: 0x52, 0x14c: 0x53, 0x14d: 0x54, 0x14e: 0x55, 0x14f: 0x56,
+ 0x150: 0x57, 0x151: 0x28, 0x152: 0x28, 0x153: 0x28, 0x154: 0x28, 0x155: 0x28, 0x156: 0x28, 0x157: 0x28,
+ 0x158: 0x28, 0x159: 0x58, 0x15a: 0x59, 0x15b: 0x5a, 0x15c: 0x5b, 0x15d: 0x5c, 0x15e: 0x5d, 0x15f: 0x5e,
+ 0x160: 0x5f, 0x161: 0x60, 0x162: 0x61, 0x163: 0x62, 0x164: 0x63, 0x165: 0x64, 0x167: 0x65,
+ 0x168: 0x66, 0x169: 0x67, 0x16a: 0x68, 0x16b: 0x69, 0x16c: 0x6a, 0x16d: 0x6b, 0x16e: 0x6c, 0x16f: 0x6d,
+ 0x170: 0x6e, 0x171: 0x6f, 0x172: 0x70, 0x173: 0x71, 0x174: 0x72, 0x175: 0x73, 0x176: 0x74, 0x177: 0x75,
+ 0x178: 0x76, 0x179: 0x76, 0x17a: 0x77, 0x17b: 0x76, 0x17c: 0x78, 0x17d: 0x0b, 0x17e: 0x0c, 0x17f: 0x0d,
+ // Block 0x6, offset 0x180
+ 0x180: 0x79, 0x181: 0x7a, 0x182: 0x7b, 0x183: 0x7c, 0x184: 0x0e, 0x185: 0x7d, 0x186: 0x7e,
+ 0x192: 0x7f, 0x193: 0x0f,
+ 0x1b0: 0x80, 0x1b1: 0x10, 0x1b2: 0x76, 0x1b3: 0x81, 0x1b4: 0x82, 0x1b5: 0x83, 0x1b6: 0x84, 0x1b7: 0x85,
+ 0x1b8: 0x86,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x87, 0x1c2: 0x88, 0x1c3: 0x89, 0x1c4: 0x8a, 0x1c5: 0x28, 0x1c6: 0x8b,
+ // Block 0x8, offset 0x200
+ 0x200: 0x8c, 0x201: 0x28, 0x202: 0x28, 0x203: 0x28, 0x204: 0x28, 0x205: 0x28, 0x206: 0x28, 0x207: 0x28,
+ 0x208: 0x28, 0x209: 0x28, 0x20a: 0x28, 0x20b: 0x28, 0x20c: 0x28, 0x20d: 0x28, 0x20e: 0x28, 0x20f: 0x28,
+ 0x210: 0x28, 0x211: 0x28, 0x212: 0x8d, 0x213: 0x8e, 0x214: 0x28, 0x215: 0x28, 0x216: 0x28, 0x217: 0x28,
+ 0x218: 0x8f, 0x219: 0x90, 0x21a: 0x91, 0x21b: 0x92, 0x21c: 0x93, 0x21d: 0x94, 0x21e: 0x11, 0x21f: 0x95,
+ 0x220: 0x96, 0x221: 0x97, 0x222: 0x28, 0x223: 0x98, 0x224: 0x99, 0x225: 0x9a, 0x226: 0x9b, 0x227: 0x9c,
+ 0x228: 0x9d, 0x229: 0x9e, 0x22a: 0x9f, 0x22b: 0xa0, 0x22c: 0xa1, 0x22d: 0xa2, 0x22e: 0xa3, 0x22f: 0xa4,
+ 0x230: 0x28, 0x231: 0x28, 0x232: 0x28, 0x233: 0x28, 0x234: 0x28, 0x235: 0x28, 0x236: 0x28, 0x237: 0x28,
+ 0x238: 0x28, 0x239: 0x28, 0x23a: 0x28, 0x23b: 0x28, 0x23c: 0x28, 0x23d: 0x28, 0x23e: 0x28, 0x23f: 0x28,
+ // Block 0x9, offset 0x240
+ 0x240: 0x28, 0x241: 0x28, 0x242: 0x28, 0x243: 0x28, 0x244: 0x28, 0x245: 0x28, 0x246: 0x28, 0x247: 0x28,
+ 0x248: 0x28, 0x249: 0x28, 0x24a: 0x28, 0x24b: 0x28, 0x24c: 0x28, 0x24d: 0x28, 0x24e: 0x28, 0x24f: 0x28,
+ 0x250: 0x28, 0x251: 0x28, 0x252: 0x28, 0x253: 0x28, 0x254: 0x28, 0x255: 0x28, 0x256: 0x28, 0x257: 0x28,
+ 0x258: 0x28, 0x259: 0x28, 0x25a: 0x28, 0x25b: 0x28, 0x25c: 0x28, 0x25d: 0x28, 0x25e: 0x28, 0x25f: 0x28,
+ 0x260: 0x28, 0x261: 0x28, 0x262: 0x28, 0x263: 0x28, 0x264: 0x28, 0x265: 0x28, 0x266: 0x28, 0x267: 0x28,
+ 0x268: 0x28, 0x269: 0x28, 0x26a: 0x28, 0x26b: 0x28, 0x26c: 0x28, 0x26d: 0x28, 0x26e: 0x28, 0x26f: 0x28,
+ 0x270: 0x28, 0x271: 0x28, 0x272: 0x28, 0x273: 0x28, 0x274: 0x28, 0x275: 0x28, 0x276: 0x28, 0x277: 0x28,
+ 0x278: 0x28, 0x279: 0x28, 0x27a: 0x28, 0x27b: 0x28, 0x27c: 0x28, 0x27d: 0x28, 0x27e: 0x28, 0x27f: 0x28,
+ // Block 0xa, offset 0x280
+ 0x280: 0x28, 0x281: 0x28, 0x282: 0x28, 0x283: 0x28, 0x284: 0x28, 0x285: 0x28, 0x286: 0x28, 0x287: 0x28,
+ 0x288: 0x28, 0x289: 0x28, 0x28a: 0x28, 0x28b: 0x28, 0x28c: 0x28, 0x28d: 0x28, 0x28e: 0x28, 0x28f: 0x28,
+ 0x290: 0x28, 0x291: 0x28, 0x292: 0x28, 0x293: 0x28, 0x294: 0x28, 0x295: 0x28, 0x296: 0x28, 0x297: 0x28,
+ 0x298: 0x28, 0x299: 0x28, 0x29a: 0x28, 0x29b: 0x28, 0x29c: 0x28, 0x29d: 0x28, 0x29e: 0xa5, 0x29f: 0xa6,
+ // Block 0xb, offset 0x2c0
+ 0x2ec: 0x12, 0x2ed: 0xa7, 0x2ee: 0xa8, 0x2ef: 0xa9,
+ 0x2f0: 0x28, 0x2f1: 0x28, 0x2f2: 0x28, 0x2f3: 0x28, 0x2f4: 0xaa, 0x2f5: 0xab, 0x2f6: 0xac, 0x2f7: 0xad,
+ 0x2f8: 0xae, 0x2f9: 0xaf, 0x2fa: 0x28, 0x2fb: 0xb0, 0x2fc: 0xb1, 0x2fd: 0xb2, 0x2fe: 0xb3, 0x2ff: 0xb4,
+ // Block 0xc, offset 0x300
+ 0x300: 0xb5, 0x301: 0xb6, 0x302: 0x28, 0x303: 0xb7, 0x305: 0xb8, 0x307: 0xb9,
+ 0x30a: 0xba, 0x30b: 0xbb, 0x30c: 0xbc, 0x30d: 0xbd, 0x30e: 0xbe, 0x30f: 0xbf,
+ 0x310: 0xc0, 0x311: 0xc1, 0x312: 0xc2, 0x313: 0xc3, 0x314: 0xc4, 0x315: 0xc5, 0x316: 0x13, 0x317: 0x97,
+ 0x318: 0x28, 0x319: 0x28, 0x31a: 0x28, 0x31b: 0x28, 0x31c: 0xc6, 0x31d: 0xc7, 0x31e: 0xc8,
+ 0x320: 0xc9, 0x321: 0xca, 0x322: 0xcb, 0x323: 0xcc, 0x324: 0xcd, 0x325: 0xce, 0x326: 0xcf,
+ 0x328: 0xd0, 0x329: 0xd1, 0x32a: 0xd2, 0x32b: 0xd3, 0x32c: 0x62, 0x32d: 0xd4, 0x32e: 0xd5,
+ 0x330: 0x28, 0x331: 0xd6, 0x332: 0xd7, 0x333: 0xd8, 0x334: 0xd9, 0x335: 0xda, 0x336: 0xdb,
+ 0x33a: 0xdc, 0x33b: 0xdd, 0x33c: 0xde, 0x33d: 0xdf, 0x33e: 0xe0, 0x33f: 0xe1,
+ // Block 0xd, offset 0x340
+ 0x340: 0xe2, 0x341: 0xe3, 0x342: 0xe4, 0x343: 0xe5, 0x344: 0xe6, 0x345: 0xe7, 0x346: 0xe8, 0x347: 0xe9,
+ 0x348: 0xea, 0x349: 0xeb, 0x34a: 0xec, 0x34b: 0xed, 0x34c: 0xee, 0x34d: 0xef, 0x34e: 0xf0, 0x34f: 0xf1,
+ 0x350: 0xf2, 0x351: 0xf3, 0x352: 0xf4, 0x353: 0xf5, 0x356: 0xf6, 0x357: 0xf7,
+ 0x358: 0xf8, 0x359: 0xf9, 0x35a: 0xfa, 0x35b: 0xfb, 0x35c: 0xfc,
+ 0x360: 0xfd, 0x362: 0xfe, 0x363: 0xff, 0x364: 0x100, 0x365: 0x101, 0x366: 0x102, 0x367: 0x103,
+ 0x368: 0x104, 0x369: 0x105, 0x36a: 0x106, 0x36b: 0x107, 0x36d: 0x108, 0x36f: 0x109,
+ 0x370: 0x10a, 0x371: 0x10b, 0x372: 0x10c, 0x374: 0x10d, 0x375: 0x10e, 0x376: 0x10f, 0x377: 0x110,
+ 0x37b: 0x111, 0x37c: 0x112, 0x37d: 0x113, 0x37e: 0x114,
+ // Block 0xe, offset 0x380
+ 0x380: 0x28, 0x381: 0x28, 0x382: 0x28, 0x383: 0x28, 0x384: 0x28, 0x385: 0x28, 0x386: 0x28, 0x387: 0x28,
+ 0x388: 0x28, 0x389: 0x28, 0x38a: 0x28, 0x38b: 0x28, 0x38c: 0x28, 0x38d: 0x28, 0x38e: 0xce,
+ 0x390: 0x28, 0x391: 0x115, 0x392: 0x28, 0x393: 0x28, 0x394: 0x28, 0x395: 0x116,
+ 0x3be: 0xab, 0x3bf: 0x117,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x28, 0x3c1: 0x28, 0x3c2: 0x28, 0x3c3: 0x28, 0x3c4: 0x28, 0x3c5: 0x28, 0x3c6: 0x28, 0x3c7: 0x28,
+ 0x3c8: 0x28, 0x3c9: 0x28, 0x3ca: 0x28, 0x3cb: 0x28, 0x3cc: 0x28, 0x3cd: 0x28, 0x3ce: 0x28, 0x3cf: 0x28,
+ 0x3d0: 0x118, 0x3d1: 0x119, 0x3d2: 0x28, 0x3d3: 0x28, 0x3d4: 0x28, 0x3d5: 0x28, 0x3d6: 0x28, 0x3d7: 0x28,
+ 0x3d8: 0x28, 0x3d9: 0x28, 0x3da: 0x28, 0x3db: 0x28, 0x3dc: 0x28, 0x3dd: 0x28, 0x3de: 0x28, 0x3df: 0x28,
+ 0x3e0: 0x28, 0x3e1: 0x28, 0x3e2: 0x28, 0x3e3: 0x28, 0x3e4: 0x28, 0x3e5: 0x28, 0x3e6: 0x28, 0x3e7: 0x28,
+ 0x3e8: 0x28, 0x3e9: 0x28, 0x3ea: 0x28, 0x3eb: 0x28, 0x3ec: 0x28, 0x3ed: 0x28, 0x3ee: 0x28, 0x3ef: 0x28,
+ 0x3f0: 0x28, 0x3f1: 0x28, 0x3f2: 0x28, 0x3f3: 0x28, 0x3f4: 0x28, 0x3f5: 0x28, 0x3f6: 0x28, 0x3f7: 0x28,
+ 0x3f8: 0x28, 0x3f9: 0x28, 0x3fa: 0x28, 0x3fb: 0x28, 0x3fc: 0x28, 0x3fd: 0x28, 0x3fe: 0x28, 0x3ff: 0x28,
+ // Block 0x10, offset 0x400
+ 0x400: 0x28, 0x401: 0x28, 0x402: 0x28, 0x403: 0x28, 0x404: 0x28, 0x405: 0x28, 0x406: 0x28, 0x407: 0x28,
+ 0x408: 0x28, 0x409: 0x28, 0x40a: 0x28, 0x40b: 0x28, 0x40c: 0x28, 0x40d: 0x28, 0x40e: 0x28, 0x40f: 0xb7,
+ 0x410: 0x28, 0x411: 0x28, 0x412: 0x28, 0x413: 0x28, 0x414: 0x28, 0x415: 0x28, 0x416: 0x28, 0x417: 0x28,
+ 0x418: 0x28, 0x419: 0x11a,
+ // Block 0x11, offset 0x440
+ 0x444: 0x11b,
+ 0x460: 0x28, 0x461: 0x28, 0x462: 0x28, 0x463: 0x28, 0x464: 0x28, 0x465: 0x28, 0x466: 0x28, 0x467: 0x28,
+ 0x468: 0x107, 0x469: 0x11c, 0x46a: 0x11d, 0x46b: 0x11e, 0x46c: 0x11f, 0x46d: 0x120, 0x46e: 0x121,
+ 0x475: 0x122,
+ 0x479: 0x123, 0x47a: 0x14, 0x47b: 0x15, 0x47c: 0x28, 0x47d: 0x124, 0x47e: 0x125, 0x47f: 0x126,
+ // Block 0x12, offset 0x480
+ 0x4bf: 0x127,
+ // Block 0x13, offset 0x4c0
+ 0x4f0: 0x28, 0x4f1: 0x128, 0x4f2: 0x129,
+ // Block 0x14, offset 0x500
+ 0x533: 0x12a,
+ 0x53c: 0x12b, 0x53d: 0x12c,
+ // Block 0x15, offset 0x540
+ 0x545: 0x12d, 0x546: 0x12e,
+ 0x549: 0x12f,
+ 0x550: 0x130, 0x551: 0x131, 0x552: 0x132, 0x553: 0x133, 0x554: 0x134, 0x555: 0x135, 0x556: 0x136, 0x557: 0x137,
+ 0x558: 0x138, 0x559: 0x139, 0x55a: 0x13a, 0x55b: 0x13b, 0x55c: 0x13c, 0x55d: 0x13d, 0x55e: 0x13e, 0x55f: 0x13f,
+ 0x568: 0x140, 0x569: 0x141, 0x56a: 0x142,
+ 0x57c: 0x143,
+ // Block 0x16, offset 0x580
+ 0x580: 0x144, 0x581: 0x145, 0x582: 0x146, 0x584: 0x147, 0x585: 0x148,
+ 0x58a: 0x149, 0x58b: 0x14a,
+ 0x593: 0x14b, 0x597: 0x14c,
+ 0x59b: 0x14d, 0x59f: 0x14e,
+ 0x5a0: 0x28, 0x5a1: 0x28, 0x5a2: 0x28, 0x5a3: 0x14f, 0x5a4: 0x16, 0x5a5: 0x150,
+ 0x5b8: 0x151, 0x5b9: 0x17, 0x5ba: 0x152,
+ // Block 0x17, offset 0x5c0
+ 0x5c4: 0x153, 0x5c5: 0x154, 0x5c6: 0x155,
+ 0x5cf: 0x156,
+ 0x5ef: 0x12a,
+ // Block 0x18, offset 0x600
+ 0x610: 0x0a, 0x611: 0x0b, 0x612: 0x0c, 0x613: 0x0d, 0x614: 0x0e, 0x616: 0x0f,
+ 0x61a: 0x10, 0x61b: 0x11, 0x61c: 0x12, 0x61d: 0x13, 0x61e: 0x14, 0x61f: 0x15,
+ // Block 0x19, offset 0x640
+ 0x640: 0x157, 0x641: 0x158, 0x644: 0x158, 0x645: 0x158, 0x646: 0x158, 0x647: 0x159,
+ // Block 0x1a, offset 0x680
+ 0x6a0: 0x17,
+}
+
+// sparseOffsets: 323 entries, 646 bytes
+var sparseOffsets = []uint16{0x0, 0x9, 0xf, 0x18, 0x24, 0x2e, 0x34, 0x37, 0x3b, 0x3e, 0x42, 0x4c, 0x4e, 0x57, 0x5e, 0x63, 0x71, 0x72, 0x80, 0x8f, 0x99, 0x9c, 0xa3, 0xab, 0xaf, 0xb7, 0xbd, 0xcb, 0xd6, 0xe3, 0xee, 0xfa, 0x104, 0x110, 0x11b, 0x127, 0x133, 0x13b, 0x145, 0x150, 0x15b, 0x167, 0x16d, 0x178, 0x17e, 0x186, 0x189, 0x18e, 0x192, 0x196, 0x19d, 0x1a6, 0x1ae, 0x1af, 0x1b8, 0x1bf, 0x1c7, 0x1cd, 0x1d2, 0x1d6, 0x1d9, 0x1db, 0x1de, 0x1e3, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1f1, 0x1f6, 0x1fa, 0x203, 0x206, 0x209, 0x20f, 0x210, 0x21b, 0x21c, 0x21d, 0x222, 0x22f, 0x238, 0x243, 0x24b, 0x254, 0x25d, 0x266, 0x26b, 0x26e, 0x27a, 0x288, 0x28a, 0x291, 0x295, 0x2a1, 0x2a2, 0x2ad, 0x2b5, 0x2bd, 0x2c3, 0x2c4, 0x2d2, 0x2d7, 0x2da, 0x2df, 0x2e3, 0x2e9, 0x2ee, 0x2f1, 0x2f6, 0x2fb, 0x2fc, 0x302, 0x304, 0x305, 0x307, 0x309, 0x30c, 0x30d, 0x30f, 0x312, 0x318, 0x31c, 0x31e, 0x323, 0x32a, 0x339, 0x343, 0x344, 0x34d, 0x351, 0x356, 0x35e, 0x364, 0x36a, 0x374, 0x379, 0x382, 0x388, 0x391, 0x395, 0x39d, 0x39f, 0x3a1, 0x3a4, 0x3a6, 0x3a8, 0x3a9, 0x3aa, 0x3ac, 0x3ae, 0x3b4, 0x3b9, 0x3bb, 0x3c2, 0x3c5, 0x3c7, 0x3cd, 0x3d2, 0x3d4, 0x3d5, 0x3d6, 0x3d7, 0x3d9, 0x3db, 0x3dd, 0x3e0, 0x3e2, 0x3e5, 0x3ed, 0x3f0, 0x3f4, 0x3fc, 0x3fe, 0x40e, 0x40f, 0x411, 0x416, 0x41c, 0x41e, 0x41f, 0x421, 0x423, 0x424, 0x426, 0x433, 0x434, 0x435, 0x439, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f, 0x442, 0x44a, 0x44b, 0x44e, 0x454, 0x457, 0x45e, 0x464, 0x466, 0x46a, 0x472, 0x478, 0x47c, 0x483, 0x487, 0x48b, 0x494, 0x49e, 0x4a0, 0x4a6, 0x4ac, 0x4b6, 0x4c0, 0x4c6, 0x4d2, 0x4d4, 0x4dd, 0x4e3, 0x4e9, 0x4ef, 0x4f2, 0x4f8, 0x4fb, 0x504, 0x506, 0x50f, 0x513, 0x514, 0x517, 0x521, 0x524, 0x526, 0x52d, 0x535, 0x53b, 0x542, 0x543, 0x549, 0x54b, 0x551, 0x554, 0x55c, 0x563, 0x56d, 0x576, 0x57a, 0x57d, 0x582, 0x587, 0x588, 0x589, 0x58a, 0x58b, 0x58d, 0x591, 0x592, 0x598, 0x59b, 0x59c, 0x59f, 0x5a1, 0x5a5, 0x5a6, 0x5aa, 0x5ac, 0x5af, 0x5b1, 0x5b5, 0x5b8, 0x5ba, 0x5bf, 0x5c0, 0x5c2, 0x5c3, 0x5c8, 0x5cc, 0x5cd, 0x5d0, 0x5d4, 0x5df, 0x5e3, 0x5eb, 0x5f0, 0x5f4, 0x5f7, 0x5fb, 0x5fe, 0x601, 0x606, 0x60a, 0x60e, 0x612, 0x616, 0x618, 0x61a, 0x61d, 0x621, 0x627, 0x628, 0x629, 0x62c, 0x62e, 0x630, 0x633, 0x638, 0x63c, 0x647, 0x64b, 0x64d, 0x653, 0x65c, 0x661, 0x662, 0x665, 0x666, 0x667, 0x669, 0x66a, 0x66b}
+
+// sparseValues: 1643 entries, 6572 bytes
+var sparseValues = [1643]valueRange{
+ // Block 0x0, offset 0x0
+ {value: 0x0004, lo: 0xa8, hi: 0xa8},
+ {value: 0x0012, lo: 0xaa, hi: 0xaa},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0004, lo: 0xaf, hi: 0xaf},
+ {value: 0x0004, lo: 0xb4, hi: 0xb4},
+ {value: 0x001a, lo: 0xb5, hi: 0xb5},
+ {value: 0x0054, lo: 0xb7, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xb8},
+ {value: 0x0012, lo: 0xba, hi: 0xba},
+ // Block 0x1, offset 0x9
+ {value: 0x2013, lo: 0x80, hi: 0x96},
+ {value: 0x2013, lo: 0x98, hi: 0x9e},
+ {value: 0x009a, lo: 0x9f, hi: 0x9f},
+ {value: 0x2012, lo: 0xa0, hi: 0xb6},
+ {value: 0x2012, lo: 0xb8, hi: 0xbe},
+ {value: 0x0252, lo: 0xbf, hi: 0xbf},
+ // Block 0x2, offset 0xf
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x011b, lo: 0xb0, hi: 0xb0},
+ {value: 0x019a, lo: 0xb1, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xb7},
+ {value: 0x0012, lo: 0xb8, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x0316, lo: 0xbd, hi: 0xbe},
+ {value: 0x0553, lo: 0xbf, hi: 0xbf},
+ // Block 0x3, offset 0x18
+ {value: 0x0552, lo: 0x80, hi: 0x80},
+ {value: 0x0316, lo: 0x81, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0316, lo: 0x85, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x01da, lo: 0x89, hi: 0x89},
+ {value: 0x0117, lo: 0x8a, hi: 0xb7},
+ {value: 0x0253, lo: 0xb8, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x0316, lo: 0xbd, hi: 0xbe},
+ {value: 0x028a, lo: 0xbf, hi: 0xbf},
+ // Block 0x4, offset 0x24
+ {value: 0x0117, lo: 0x80, hi: 0x9f},
+ {value: 0x2f53, lo: 0xa0, hi: 0xa0},
+ {value: 0x0012, lo: 0xa1, hi: 0xa1},
+ {value: 0x0117, lo: 0xa2, hi: 0xb3},
+ {value: 0x0012, lo: 0xb4, hi: 0xb9},
+ {value: 0x098b, lo: 0xba, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x2953, lo: 0xbd, hi: 0xbd},
+ {value: 0x0a0b, lo: 0xbe, hi: 0xbe},
+ {value: 0x0a8a, lo: 0xbf, hi: 0xbf},
+ // Block 0x5, offset 0x2e
+ {value: 0x0015, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x97},
+ {value: 0x0004, lo: 0x98, hi: 0x9d},
+ {value: 0x0014, lo: 0x9e, hi: 0x9f},
+ {value: 0x0015, lo: 0xa0, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xbf},
+ // Block 0x6, offset 0x34
+ {value: 0x0024, lo: 0x80, hi: 0x94},
+ {value: 0x0034, lo: 0x95, hi: 0xbc},
+ {value: 0x0024, lo: 0xbd, hi: 0xbf},
+ // Block 0x7, offset 0x37
+ {value: 0x6553, lo: 0x80, hi: 0x8f},
+ {value: 0x2013, lo: 0x90, hi: 0x9f},
+ {value: 0x5f53, lo: 0xa0, hi: 0xaf},
+ {value: 0x2012, lo: 0xb0, hi: 0xbf},
+ // Block 0x8, offset 0x3b
+ {value: 0x5f52, lo: 0x80, hi: 0x8f},
+ {value: 0x6552, lo: 0x90, hi: 0x9f},
+ {value: 0x0117, lo: 0xa0, hi: 0xbf},
+ // Block 0x9, offset 0x3e
+ {value: 0x0117, lo: 0x80, hi: 0x81},
+ {value: 0x0024, lo: 0x83, hi: 0x87},
+ {value: 0x0014, lo: 0x88, hi: 0x89},
+ {value: 0x0117, lo: 0x8a, hi: 0xbf},
+ // Block 0xa, offset 0x42
+ {value: 0x0f13, lo: 0x80, hi: 0x80},
+ {value: 0x0316, lo: 0x81, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0316, lo: 0x85, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x0316, lo: 0x89, hi: 0x8a},
+ {value: 0x0716, lo: 0x8b, hi: 0x8c},
+ {value: 0x0316, lo: 0x8d, hi: 0x8e},
+ {value: 0x0f12, lo: 0x8f, hi: 0x8f},
+ {value: 0x0117, lo: 0x90, hi: 0xbf},
+ // Block 0xb, offset 0x4c
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x6553, lo: 0xb1, hi: 0xbf},
+ // Block 0xc, offset 0x4e
+ {value: 0x3013, lo: 0x80, hi: 0x8f},
+ {value: 0x6853, lo: 0x90, hi: 0x96},
+ {value: 0x0014, lo: 0x99, hi: 0x99},
+ {value: 0x0010, lo: 0x9a, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9e},
+ {value: 0x0054, lo: 0x9f, hi: 0x9f},
+ {value: 0x0012, lo: 0xa0, hi: 0xa0},
+ {value: 0x6552, lo: 0xa1, hi: 0xaf},
+ {value: 0x3012, lo: 0xb0, hi: 0xbf},
+ // Block 0xd, offset 0x57
+ {value: 0x0034, lo: 0x81, hi: 0x82},
+ {value: 0x0024, lo: 0x84, hi: 0x84},
+ {value: 0x0034, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0xaa},
+ {value: 0x0010, lo: 0xaf, hi: 0xb3},
+ {value: 0x0054, lo: 0xb4, hi: 0xb4},
+ // Block 0xe, offset 0x5e
+ {value: 0x0014, lo: 0x80, hi: 0x85},
+ {value: 0x0024, lo: 0x90, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x9a},
+ {value: 0x0014, lo: 0x9c, hi: 0x9c},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xf, offset 0x63
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x8a},
+ {value: 0x0034, lo: 0x8b, hi: 0x92},
+ {value: 0x0024, lo: 0x93, hi: 0x94},
+ {value: 0x0034, lo: 0x95, hi: 0x96},
+ {value: 0x0024, lo: 0x97, hi: 0x9b},
+ {value: 0x0034, lo: 0x9c, hi: 0x9c},
+ {value: 0x0024, lo: 0x9d, hi: 0x9e},
+ {value: 0x0034, lo: 0x9f, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0034, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xbf},
+ // Block 0x10, offset 0x71
+ {value: 0x0010, lo: 0x80, hi: 0xbf},
+ // Block 0x11, offset 0x72
+ {value: 0x0010, lo: 0x80, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x95},
+ {value: 0x0024, lo: 0x96, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x0024, lo: 0x9f, hi: 0xa2},
+ {value: 0x0034, lo: 0xa3, hi: 0xa3},
+ {value: 0x0024, lo: 0xa4, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa6},
+ {value: 0x0024, lo: 0xa7, hi: 0xa8},
+ {value: 0x0034, lo: 0xaa, hi: 0xaa},
+ {value: 0x0024, lo: 0xab, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xbc},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x12, offset 0x80
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0034, lo: 0x91, hi: 0x91},
+ {value: 0x0010, lo: 0x92, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ {value: 0x0034, lo: 0xb1, hi: 0xb1},
+ {value: 0x0024, lo: 0xb2, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0024, lo: 0xb5, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb9},
+ {value: 0x0024, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0024, lo: 0xbd, hi: 0xbd},
+ {value: 0x0034, lo: 0xbe, hi: 0xbe},
+ {value: 0x0024, lo: 0xbf, hi: 0xbf},
+ // Block 0x13, offset 0x8f
+ {value: 0x0024, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0024, lo: 0x83, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0024, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0024, lo: 0x87, hi: 0x87},
+ {value: 0x0034, lo: 0x88, hi: 0x88},
+ {value: 0x0024, lo: 0x89, hi: 0x8a},
+ {value: 0x0010, lo: 0x8d, hi: 0xbf},
+ // Block 0x14, offset 0x99
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0014, lo: 0xa6, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ // Block 0x15, offset 0x9c
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0024, lo: 0xab, hi: 0xb1},
+ {value: 0x0034, lo: 0xb2, hi: 0xb2},
+ {value: 0x0024, lo: 0xb3, hi: 0xb3},
+ {value: 0x0014, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ // Block 0x16, offset 0xa3
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0024, lo: 0x96, hi: 0x99},
+ {value: 0x0014, lo: 0x9a, hi: 0x9a},
+ {value: 0x0024, lo: 0x9b, hi: 0xa3},
+ {value: 0x0014, lo: 0xa4, hi: 0xa4},
+ {value: 0x0024, lo: 0xa5, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa8},
+ {value: 0x0024, lo: 0xa9, hi: 0xad},
+ // Block 0x17, offset 0xab
+ {value: 0x0010, lo: 0x80, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x9b},
+ {value: 0x0010, lo: 0xa0, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x18, offset 0xaf
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0004, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x8f},
+ {value: 0x0014, lo: 0x90, hi: 0x91},
+ {value: 0x0024, lo: 0x97, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x9b},
+ {value: 0x0024, lo: 0x9c, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x19, offset 0xb7
+ {value: 0x0014, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x1a, offset 0xbd
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0024, lo: 0x91, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x92},
+ {value: 0x0024, lo: 0x93, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x97},
+ {value: 0x0010, lo: 0x98, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xbf},
+ // Block 0x1b, offset 0xcb
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb2},
+ {value: 0x0010, lo: 0xb6, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x1c, offset 0xd6
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9c, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xb1},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ {value: 0x0024, lo: 0xbe, hi: 0xbe},
+ // Block 0x1d, offset 0xe3
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8a},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb6},
+ {value: 0x0010, lo: 0xb8, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x1e, offset 0xee
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0014, lo: 0x87, hi: 0x88},
+ {value: 0x0014, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x91, hi: 0x91},
+ {value: 0x0010, lo: 0x99, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9e},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb5},
+ // Block 0x1f, offset 0xfa
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x20, offset 0x104
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x85},
+ {value: 0x0014, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x89, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xbf},
+ // Block 0x21, offset 0x110
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x22, offset 0x11b
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9c, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ // Block 0x23, offset 0x127
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8a},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0x95},
+ {value: 0x0010, lo: 0x99, hi: 0x9a},
+ {value: 0x0010, lo: 0x9c, hi: 0x9c},
+ {value: 0x0010, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ {value: 0x0010, lo: 0xa8, hi: 0xaa},
+ {value: 0x0010, lo: 0xae, hi: 0xb9},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x24, offset 0x133
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x82},
+ {value: 0x0010, lo: 0x86, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ // Block 0x25, offset 0x13b
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x83},
+ {value: 0x0014, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbf},
+ // Block 0x26, offset 0x145
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0014, lo: 0x86, hi: 0x88},
+ {value: 0x0014, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0034, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9a},
+ {value: 0x0010, lo: 0x9c, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ // Block 0x27, offset 0x150
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x28, offset 0x15b
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0014, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x9c, hi: 0x9e},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xb3},
+ // Block 0x29, offset 0x167
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x2a, offset 0x16d
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x86, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x94, hi: 0x97},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa3},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xba, hi: 0xbf},
+ // Block 0x2b, offset 0x178
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x96},
+ {value: 0x0010, lo: 0x9a, hi: 0xb1},
+ {value: 0x0010, lo: 0xb3, hi: 0xbb},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ // Block 0x2c, offset 0x17e
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0010, lo: 0x8f, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x94},
+ {value: 0x0014, lo: 0x96, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9f},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ // Block 0x2d, offset 0x186
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb4, hi: 0xb7},
+ {value: 0x0034, lo: 0xb8, hi: 0xba},
+ // Block 0x2e, offset 0x189
+ {value: 0x0004, lo: 0x86, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x87},
+ {value: 0x0034, lo: 0x88, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x2f, offset 0x18e
+ {value: 0x0014, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb4, hi: 0xb7},
+ {value: 0x0034, lo: 0xb8, hi: 0xba},
+ {value: 0x0014, lo: 0xbb, hi: 0xbc},
+ // Block 0x30, offset 0x192
+ {value: 0x0004, lo: 0x86, hi: 0x86},
+ {value: 0x0034, lo: 0x88, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x31, offset 0x196
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0034, lo: 0x98, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0034, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0034, lo: 0xb9, hi: 0xb9},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x32, offset 0x19d
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0x89, hi: 0xac},
+ {value: 0x0034, lo: 0xb1, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xba, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x33, offset 0x1a6
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0024, lo: 0x82, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0024, lo: 0x86, hi: 0x87},
+ {value: 0x0010, lo: 0x88, hi: 0x8c},
+ {value: 0x0014, lo: 0x8d, hi: 0x97},
+ {value: 0x0014, lo: 0x99, hi: 0xbc},
+ // Block 0x34, offset 0x1ae
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ // Block 0x35, offset 0x1af
+ {value: 0x0010, lo: 0xab, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbc},
+ {value: 0x0014, lo: 0xbd, hi: 0xbe},
+ // Block 0x36, offset 0x1b8
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x96, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x99},
+ {value: 0x0014, lo: 0x9e, hi: 0xa0},
+ {value: 0x0010, lo: 0xa2, hi: 0xa4},
+ {value: 0x0010, lo: 0xa7, hi: 0xad},
+ {value: 0x0014, lo: 0xb1, hi: 0xb4},
+ // Block 0x37, offset 0x1bf
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x6c53, lo: 0xa0, hi: 0xbf},
+ // Block 0x38, offset 0x1c7
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0x9a, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x39, offset 0x1cd
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb5},
+ {value: 0x0010, lo: 0xb8, hi: 0xbe},
+ // Block 0x3a, offset 0x1d2
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x82, hi: 0x85},
+ {value: 0x0010, lo: 0x88, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0xbf},
+ // Block 0x3b, offset 0x1d6
+ {value: 0x0010, lo: 0x80, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0x95},
+ {value: 0x0010, lo: 0x98, hi: 0xbf},
+ // Block 0x3c, offset 0x1d9
+ {value: 0x0010, lo: 0x80, hi: 0x9a},
+ {value: 0x0024, lo: 0x9d, hi: 0x9f},
+ // Block 0x3d, offset 0x1db
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x7453, lo: 0xa0, hi: 0xaf},
+ {value: 0x7853, lo: 0xb0, hi: 0xbf},
+ // Block 0x3e, offset 0x1de
+ {value: 0x7c53, lo: 0x80, hi: 0x8f},
+ {value: 0x8053, lo: 0x90, hi: 0x9f},
+ {value: 0x7c53, lo: 0xa0, hi: 0xaf},
+ {value: 0x0813, lo: 0xb0, hi: 0xb5},
+ {value: 0x0892, lo: 0xb8, hi: 0xbd},
+ // Block 0x3f, offset 0x1e3
+ {value: 0x0010, lo: 0x81, hi: 0xbf},
+ // Block 0x40, offset 0x1e4
+ {value: 0x0010, lo: 0x80, hi: 0xac},
+ {value: 0x0010, lo: 0xaf, hi: 0xbf},
+ // Block 0x41, offset 0x1e6
+ {value: 0x0010, lo: 0x81, hi: 0x9a},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x42, offset 0x1e8
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0010, lo: 0xae, hi: 0xb8},
+ // Block 0x43, offset 0x1ea
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x93},
+ {value: 0x0034, lo: 0x94, hi: 0x94},
+ {value: 0x0030, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x9f, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ {value: 0x0030, lo: 0xb4, hi: 0xb4},
+ // Block 0x44, offset 0x1f1
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x93},
+ {value: 0x0010, lo: 0xa0, hi: 0xac},
+ {value: 0x0010, lo: 0xae, hi: 0xb0},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ // Block 0x45, offset 0x1f6
+ {value: 0x0014, lo: 0xb4, hi: 0xb5},
+ {value: 0x0010, lo: 0xb6, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x46, offset 0x1fa
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0014, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0014, lo: 0x89, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x92},
+ {value: 0x0014, lo: 0x93, hi: 0x93},
+ {value: 0x0004, lo: 0x97, hi: 0x97},
+ {value: 0x0024, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ // Block 0x47, offset 0x203
+ {value: 0x0014, lo: 0x8b, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x48, offset 0x206
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0xb8},
+ // Block 0x49, offset 0x209
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0xa8},
+ {value: 0x0034, lo: 0xa9, hi: 0xa9},
+ {value: 0x0010, lo: 0xaa, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x4a, offset 0x20f
+ {value: 0x0010, lo: 0x80, hi: 0xb5},
+ // Block 0x4b, offset 0x210
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0014, lo: 0xa0, hi: 0xa2},
+ {value: 0x0010, lo: 0xa3, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xab},
+ {value: 0x0010, lo: 0xb0, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb2},
+ {value: 0x0010, lo: 0xb3, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xb9},
+ {value: 0x0024, lo: 0xba, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbb},
+ // Block 0x4c, offset 0x21b
+ {value: 0x0010, lo: 0x86, hi: 0x8f},
+ // Block 0x4d, offset 0x21c
+ {value: 0x0010, lo: 0x90, hi: 0x9a},
+ // Block 0x4e, offset 0x21d
+ {value: 0x0010, lo: 0x80, hi: 0x96},
+ {value: 0x0024, lo: 0x97, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0x99, hi: 0x9a},
+ {value: 0x0014, lo: 0x9b, hi: 0x9b},
+ // Block 0x4f, offset 0x222
+ {value: 0x0010, lo: 0x95, hi: 0x95},
+ {value: 0x0014, lo: 0x96, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x9e},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa2},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xac},
+ {value: 0x0010, lo: 0xad, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0024, lo: 0xb5, hi: 0xbc},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x50, offset 0x22f
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0004, lo: 0xa7, hi: 0xa7},
+ {value: 0x0024, lo: 0xb0, hi: 0xb4},
+ {value: 0x0034, lo: 0xb5, hi: 0xba},
+ {value: 0x0024, lo: 0xbb, hi: 0xbc},
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x51, offset 0x238
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0024, lo: 0x81, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x84},
+ {value: 0x0024, lo: 0x85, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0024, lo: 0x8b, hi: 0x9c},
+ {value: 0x0034, lo: 0x9d, hi: 0x9d},
+ {value: 0x0024, lo: 0xa0, hi: 0xa5},
+ {value: 0x0034, lo: 0xa6, hi: 0xa6},
+ {value: 0x0024, lo: 0xa7, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xab},
+ // Block 0x52, offset 0x243
+ {value: 0x0014, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x53, offset 0x24b
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x83},
+ {value: 0x0030, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0xab, hi: 0xab},
+ {value: 0x0034, lo: 0xac, hi: 0xac},
+ {value: 0x0024, lo: 0xad, hi: 0xb3},
+ // Block 0x54, offset 0x254
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa9},
+ {value: 0x0030, lo: 0xaa, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xbf},
+ // Block 0x55, offset 0x25d
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0034, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa9},
+ {value: 0x0010, lo: 0xaa, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb1},
+ {value: 0x0030, lo: 0xb2, hi: 0xb3},
+ // Block 0x56, offset 0x266
+ {value: 0x0010, lo: 0x80, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ // Block 0x57, offset 0x26b
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8d, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ // Block 0x58, offset 0x26e
+ {value: 0x32ea, lo: 0x80, hi: 0x80},
+ {value: 0x336a, lo: 0x81, hi: 0x81},
+ {value: 0x33ea, lo: 0x82, hi: 0x82},
+ {value: 0x346a, lo: 0x83, hi: 0x83},
+ {value: 0x34ea, lo: 0x84, hi: 0x84},
+ {value: 0x356a, lo: 0x85, hi: 0x85},
+ {value: 0x35ea, lo: 0x86, hi: 0x86},
+ {value: 0x366a, lo: 0x87, hi: 0x87},
+ {value: 0x36ea, lo: 0x88, hi: 0x88},
+ {value: 0x0316, lo: 0x89, hi: 0x8a},
+ {value: 0x8353, lo: 0x90, hi: 0xba},
+ {value: 0x8353, lo: 0xbd, hi: 0xbf},
+ // Block 0x59, offset 0x27a
+ {value: 0x0024, lo: 0x90, hi: 0x92},
+ {value: 0x0034, lo: 0x94, hi: 0x99},
+ {value: 0x0024, lo: 0x9a, hi: 0x9b},
+ {value: 0x0034, lo: 0x9c, hi: 0x9f},
+ {value: 0x0024, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0034, lo: 0xa2, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xb3},
+ {value: 0x0024, lo: 0xb4, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb7},
+ {value: 0x0024, lo: 0xb8, hi: 0xb9},
+ {value: 0x0010, lo: 0xba, hi: 0xba},
+ // Block 0x5a, offset 0x288
+ {value: 0x0012, lo: 0x80, hi: 0xab},
+ {value: 0x0015, lo: 0xac, hi: 0xbf},
+ // Block 0x5b, offset 0x28a
+ {value: 0x0015, lo: 0x80, hi: 0xaa},
+ {value: 0x0012, lo: 0xab, hi: 0xb7},
+ {value: 0x0015, lo: 0xb8, hi: 0xb8},
+ {value: 0x8752, lo: 0xb9, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xbc},
+ {value: 0x8b52, lo: 0xbd, hi: 0xbd},
+ {value: 0x0012, lo: 0xbe, hi: 0xbf},
+ // Block 0x5c, offset 0x291
+ {value: 0x0012, lo: 0x80, hi: 0x8d},
+ {value: 0x8f52, lo: 0x8e, hi: 0x8e},
+ {value: 0x0012, lo: 0x8f, hi: 0x9a},
+ {value: 0x0015, lo: 0x9b, hi: 0xbf},
+ // Block 0x5d, offset 0x295
+ {value: 0x0024, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0024, lo: 0x83, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0024, lo: 0x8b, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x90},
+ {value: 0x0024, lo: 0x91, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xba},
+ {value: 0x0024, lo: 0xbb, hi: 0xbb},
+ {value: 0x0034, lo: 0xbc, hi: 0xbd},
+ {value: 0x0024, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x5e, offset 0x2a1
+ {value: 0x0117, lo: 0x80, hi: 0xbf},
+ // Block 0x5f, offset 0x2a2
+ {value: 0x0117, lo: 0x80, hi: 0x95},
+ {value: 0x379a, lo: 0x96, hi: 0x96},
+ {value: 0x384a, lo: 0x97, hi: 0x97},
+ {value: 0x38fa, lo: 0x98, hi: 0x98},
+ {value: 0x39aa, lo: 0x99, hi: 0x99},
+ {value: 0x3a5a, lo: 0x9a, hi: 0x9a},
+ {value: 0x3b0a, lo: 0x9b, hi: 0x9b},
+ {value: 0x0012, lo: 0x9c, hi: 0x9d},
+ {value: 0x3bbb, lo: 0x9e, hi: 0x9e},
+ {value: 0x0012, lo: 0x9f, hi: 0x9f},
+ {value: 0x0117, lo: 0xa0, hi: 0xbf},
+ // Block 0x60, offset 0x2ad
+ {value: 0x0812, lo: 0x80, hi: 0x87},
+ {value: 0x0813, lo: 0x88, hi: 0x8f},
+ {value: 0x0812, lo: 0x90, hi: 0x95},
+ {value: 0x0813, lo: 0x98, hi: 0x9d},
+ {value: 0x0812, lo: 0xa0, hi: 0xa7},
+ {value: 0x0813, lo: 0xa8, hi: 0xaf},
+ {value: 0x0812, lo: 0xb0, hi: 0xb7},
+ {value: 0x0813, lo: 0xb8, hi: 0xbf},
+ // Block 0x61, offset 0x2b5
+ {value: 0x0004, lo: 0x8b, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8f},
+ {value: 0x0054, lo: 0x98, hi: 0x99},
+ {value: 0x0054, lo: 0xa4, hi: 0xa4},
+ {value: 0x0054, lo: 0xa7, hi: 0xa7},
+ {value: 0x0014, lo: 0xaa, hi: 0xae},
+ {value: 0x0010, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x62, offset 0x2bd
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x94, hi: 0x94},
+ {value: 0x0014, lo: 0xa0, hi: 0xa4},
+ {value: 0x0014, lo: 0xa6, hi: 0xaf},
+ {value: 0x0015, lo: 0xb1, hi: 0xb1},
+ {value: 0x0015, lo: 0xbf, hi: 0xbf},
+ // Block 0x63, offset 0x2c3
+ {value: 0x0015, lo: 0x90, hi: 0x9c},
+ // Block 0x64, offset 0x2c4
+ {value: 0x0024, lo: 0x90, hi: 0x91},
+ {value: 0x0034, lo: 0x92, hi: 0x93},
+ {value: 0x0024, lo: 0x94, hi: 0x97},
+ {value: 0x0034, lo: 0x98, hi: 0x9a},
+ {value: 0x0024, lo: 0x9b, hi: 0x9c},
+ {value: 0x0014, lo: 0x9d, hi: 0xa0},
+ {value: 0x0024, lo: 0xa1, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa4},
+ {value: 0x0034, lo: 0xa5, hi: 0xa6},
+ {value: 0x0024, lo: 0xa7, hi: 0xa7},
+ {value: 0x0034, lo: 0xa8, hi: 0xa8},
+ {value: 0x0024, lo: 0xa9, hi: 0xa9},
+ {value: 0x0034, lo: 0xaa, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ // Block 0x65, offset 0x2d2
+ {value: 0x0016, lo: 0x85, hi: 0x86},
+ {value: 0x0012, lo: 0x87, hi: 0x89},
+ {value: 0xa452, lo: 0x8e, hi: 0x8e},
+ {value: 0x1013, lo: 0xa0, hi: 0xaf},
+ {value: 0x1012, lo: 0xb0, hi: 0xbf},
+ // Block 0x66, offset 0x2d7
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0716, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x88},
+ // Block 0x67, offset 0x2da
+ {value: 0xa753, lo: 0xb6, hi: 0xb7},
+ {value: 0xaa53, lo: 0xb8, hi: 0xb9},
+ {value: 0xad53, lo: 0xba, hi: 0xbb},
+ {value: 0xaa53, lo: 0xbc, hi: 0xbd},
+ {value: 0xa753, lo: 0xbe, hi: 0xbf},
+ // Block 0x68, offset 0x2df
+ {value: 0x3013, lo: 0x80, hi: 0x8f},
+ {value: 0x6553, lo: 0x90, hi: 0x9f},
+ {value: 0xb053, lo: 0xa0, hi: 0xaf},
+ {value: 0x3012, lo: 0xb0, hi: 0xbf},
+ // Block 0x69, offset 0x2e3
+ {value: 0x0117, lo: 0x80, hi: 0xa3},
+ {value: 0x0012, lo: 0xa4, hi: 0xa4},
+ {value: 0x0716, lo: 0xab, hi: 0xac},
+ {value: 0x0316, lo: 0xad, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xb3},
+ // Block 0x6a, offset 0x2e9
+ {value: 0x6c52, lo: 0x80, hi: 0x9f},
+ {value: 0x7052, lo: 0xa0, hi: 0xa5},
+ {value: 0x7052, lo: 0xa7, hi: 0xa7},
+ {value: 0x7052, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x6b, offset 0x2ee
+ {value: 0x0010, lo: 0x80, hi: 0xa7},
+ {value: 0x0014, lo: 0xaf, hi: 0xaf},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0x6c, offset 0x2f1
+ {value: 0x0010, lo: 0x80, hi: 0x96},
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xae},
+ {value: 0x0010, lo: 0xb0, hi: 0xb6},
+ {value: 0x0010, lo: 0xb8, hi: 0xbe},
+ // Block 0x6d, offset 0x2f6
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0x9e},
+ {value: 0x0024, lo: 0xa0, hi: 0xbf},
+ // Block 0x6e, offset 0x2fb
+ {value: 0x0014, lo: 0xaf, hi: 0xaf},
+ // Block 0x6f, offset 0x2fc
+ {value: 0x0014, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0xaa, hi: 0xad},
+ {value: 0x0030, lo: 0xae, hi: 0xaf},
+ {value: 0x0004, lo: 0xb1, hi: 0xb5},
+ {value: 0x0014, lo: 0xbb, hi: 0xbb},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ // Block 0x70, offset 0x302
+ {value: 0x0034, lo: 0x99, hi: 0x9a},
+ {value: 0x0004, lo: 0x9b, hi: 0x9e},
+ // Block 0x71, offset 0x304
+ {value: 0x0004, lo: 0xbc, hi: 0xbe},
+ // Block 0x72, offset 0x305
+ {value: 0x0010, lo: 0x85, hi: 0xaf},
+ {value: 0x0010, lo: 0xb1, hi: 0xbf},
+ // Block 0x73, offset 0x307
+ {value: 0x0010, lo: 0x80, hi: 0x8e},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x74, offset 0x309
+ {value: 0x0010, lo: 0x80, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x96, hi: 0xbf},
+ // Block 0x75, offset 0x30c
+ {value: 0x0010, lo: 0x80, hi: 0x8c},
+ // Block 0x76, offset 0x30d
+ {value: 0x0010, lo: 0x90, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ // Block 0x77, offset 0x30f
+ {value: 0x0010, lo: 0x80, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0010, lo: 0x90, hi: 0xab},
+ // Block 0x78, offset 0x312
+ {value: 0x0117, lo: 0x80, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb2},
+ {value: 0x0024, lo: 0xb4, hi: 0xbd},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x79, offset 0x318
+ {value: 0x0117, lo: 0x80, hi: 0x9b},
+ {value: 0x0015, lo: 0x9c, hi: 0x9d},
+ {value: 0x0024, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x7a, offset 0x31c
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb1},
+ // Block 0x7b, offset 0x31e
+ {value: 0x0004, lo: 0x80, hi: 0x87},
+ {value: 0x0014, lo: 0x88, hi: 0xa1},
+ {value: 0x0117, lo: 0xa2, hi: 0xaf},
+ {value: 0x0012, lo: 0xb0, hi: 0xb1},
+ {value: 0x0117, lo: 0xb2, hi: 0xbf},
+ // Block 0x7c, offset 0x323
+ {value: 0x0117, lo: 0x80, hi: 0xaf},
+ {value: 0x0015, lo: 0xb0, hi: 0xb0},
+ {value: 0x0012, lo: 0xb1, hi: 0xb8},
+ {value: 0x0316, lo: 0xb9, hi: 0xba},
+ {value: 0x0716, lo: 0xbb, hi: 0xbc},
+ {value: 0x8753, lo: 0xbd, hi: 0xbd},
+ {value: 0x0117, lo: 0xbe, hi: 0xbf},
+ // Block 0x7d, offset 0x32a
+ {value: 0x0117, lo: 0x80, hi: 0x83},
+ {value: 0x6553, lo: 0x84, hi: 0x84},
+ {value: 0x918b, lo: 0x85, hi: 0x85},
+ {value: 0x8f53, lo: 0x86, hi: 0x86},
+ {value: 0x0f16, lo: 0x87, hi: 0x88},
+ {value: 0x0316, lo: 0x89, hi: 0x8a},
+ {value: 0x91eb, lo: 0x8b, hi: 0x8b},
+ {value: 0x0117, lo: 0x8c, hi: 0x9b},
+ {value: 0x924b, lo: 0x9c, hi: 0x9c},
+ {value: 0x0015, lo: 0xb1, hi: 0xb4},
+ {value: 0x0316, lo: 0xb5, hi: 0xb6},
+ {value: 0x0010, lo: 0xb7, hi: 0xb7},
+ {value: 0x0015, lo: 0xb8, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbf},
+ // Block 0x7e, offset 0x339
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8b},
+ {value: 0x0010, lo: 0x8c, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0034, lo: 0xac, hi: 0xac},
+ // Block 0x7f, offset 0x343
+ {value: 0x0010, lo: 0x80, hi: 0xb3},
+ // Block 0x80, offset 0x344
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0xa0, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb7},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0010, lo: 0xbd, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x81, offset 0x34d
+ {value: 0x0010, lo: 0x80, hi: 0xa5},
+ {value: 0x0014, lo: 0xa6, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x82, offset 0x351
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x91},
+ {value: 0x0010, lo: 0x92, hi: 0x92},
+ {value: 0x0030, lo: 0x93, hi: 0x93},
+ {value: 0x0010, lo: 0xa0, hi: 0xbc},
+ // Block 0x83, offset 0x356
+ {value: 0x0014, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xb9},
+ {value: 0x0010, lo: 0xba, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0x84, offset 0x35e
+ {value: 0x0030, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0014, lo: 0xa5, hi: 0xa5},
+ {value: 0x0004, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x85, offset 0x364
+ {value: 0x0010, lo: 0x80, hi: 0xa8},
+ {value: 0x0014, lo: 0xa9, hi: 0xae},
+ {value: 0x0010, lo: 0xaf, hi: 0xb0},
+ {value: 0x0014, lo: 0xb1, hi: 0xb2},
+ {value: 0x0010, lo: 0xb3, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb6},
+ // Block 0x86, offset 0x36a
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0x8b},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0010, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0004, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbd},
+ // Block 0x87, offset 0x374
+ {value: 0x0024, lo: 0xb0, hi: 0xb0},
+ {value: 0x0024, lo: 0xb2, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0024, lo: 0xb7, hi: 0xb8},
+ {value: 0x0024, lo: 0xbe, hi: 0xbf},
+ // Block 0x88, offset 0x379
+ {value: 0x0024, lo: 0x81, hi: 0x81},
+ {value: 0x0004, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xab},
+ {value: 0x0014, lo: 0xac, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0010, lo: 0xb2, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xb6},
+ // Block 0x89, offset 0x382
+ {value: 0x0010, lo: 0x81, hi: 0x86},
+ {value: 0x0010, lo: 0x89, hi: 0x8e},
+ {value: 0x0010, lo: 0x91, hi: 0x96},
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xae},
+ {value: 0x0012, lo: 0xb0, hi: 0xbf},
+ // Block 0x8a, offset 0x388
+ {value: 0x0012, lo: 0x80, hi: 0x92},
+ {value: 0xb352, lo: 0x93, hi: 0x93},
+ {value: 0x0012, lo: 0x94, hi: 0x9a},
+ {value: 0x0014, lo: 0x9b, hi: 0x9b},
+ {value: 0x0015, lo: 0x9c, hi: 0x9f},
+ {value: 0x0012, lo: 0xa0, hi: 0xa8},
+ {value: 0x0015, lo: 0xa9, hi: 0xa9},
+ {value: 0x0004, lo: 0xaa, hi: 0xab},
+ {value: 0x74d2, lo: 0xb0, hi: 0xbf},
+ // Block 0x8b, offset 0x391
+ {value: 0x78d2, lo: 0x80, hi: 0x8f},
+ {value: 0x7cd2, lo: 0x90, hi: 0x9f},
+ {value: 0x80d2, lo: 0xa0, hi: 0xaf},
+ {value: 0x7cd2, lo: 0xb0, hi: 0xbf},
+ // Block 0x8c, offset 0x395
+ {value: 0x0010, lo: 0x80, hi: 0xa4},
+ {value: 0x0014, lo: 0xa5, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa7},
+ {value: 0x0014, lo: 0xa8, hi: 0xa8},
+ {value: 0x0010, lo: 0xa9, hi: 0xaa},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0034, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x8d, offset 0x39d
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x8e, offset 0x39f
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x8b, hi: 0xbb},
+ // Block 0x8f, offset 0x3a1
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x86, hi: 0xbf},
+ // Block 0x90, offset 0x3a4
+ {value: 0x0010, lo: 0x80, hi: 0xb1},
+ {value: 0x0004, lo: 0xb2, hi: 0xbf},
+ // Block 0x91, offset 0x3a6
+ {value: 0x0004, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x93, hi: 0xbf},
+ // Block 0x92, offset 0x3a8
+ {value: 0x0010, lo: 0x80, hi: 0xbd},
+ // Block 0x93, offset 0x3a9
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0x94, offset 0x3aa
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x0010, lo: 0x92, hi: 0xbf},
+ // Block 0x95, offset 0x3ac
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0xb0, hi: 0xbb},
+ // Block 0x96, offset 0x3ae
+ {value: 0x0014, lo: 0x80, hi: 0x8f},
+ {value: 0x0054, lo: 0x93, hi: 0x93},
+ {value: 0x0024, lo: 0xa0, hi: 0xa6},
+ {value: 0x0034, lo: 0xa7, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xaf},
+ {value: 0x0010, lo: 0xb3, hi: 0xb4},
+ // Block 0x97, offset 0x3b4
+ {value: 0x0010, lo: 0x8d, hi: 0x8f},
+ {value: 0x0054, lo: 0x92, hi: 0x92},
+ {value: 0x0054, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0xb0, hi: 0xb4},
+ {value: 0x0010, lo: 0xb6, hi: 0xbf},
+ // Block 0x98, offset 0x3b9
+ {value: 0x0010, lo: 0x80, hi: 0xbc},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x99, offset 0x3bb
+ {value: 0x0054, lo: 0x87, hi: 0x87},
+ {value: 0x0054, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0054, lo: 0x9a, hi: 0x9a},
+ {value: 0x5f53, lo: 0xa1, hi: 0xba},
+ {value: 0x0004, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x9a, offset 0x3c2
+ {value: 0x0004, lo: 0x80, hi: 0x80},
+ {value: 0x5f52, lo: 0x81, hi: 0x9a},
+ {value: 0x0004, lo: 0xb0, hi: 0xb0},
+ // Block 0x9b, offset 0x3c5
+ {value: 0x0014, lo: 0x9e, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xbe},
+ // Block 0x9c, offset 0x3c7
+ {value: 0x0010, lo: 0x82, hi: 0x87},
+ {value: 0x0010, lo: 0x8a, hi: 0x8f},
+ {value: 0x0010, lo: 0x92, hi: 0x97},
+ {value: 0x0010, lo: 0x9a, hi: 0x9c},
+ {value: 0x0004, lo: 0xa3, hi: 0xa3},
+ {value: 0x0014, lo: 0xb9, hi: 0xbb},
+ // Block 0x9d, offset 0x3cd
+ {value: 0x0010, lo: 0x80, hi: 0x8b},
+ {value: 0x0010, lo: 0x8d, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xba},
+ {value: 0x0010, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0x9e, offset 0x3d2
+ {value: 0x0010, lo: 0x80, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x9d},
+ // Block 0x9f, offset 0x3d4
+ {value: 0x0010, lo: 0x80, hi: 0xba},
+ // Block 0xa0, offset 0x3d5
+ {value: 0x0010, lo: 0x80, hi: 0xb4},
+ // Block 0xa1, offset 0x3d6
+ {value: 0x0034, lo: 0xbd, hi: 0xbd},
+ // Block 0xa2, offset 0x3d7
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xa3, offset 0x3d9
+ {value: 0x0010, lo: 0x80, hi: 0x90},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ // Block 0xa4, offset 0x3db
+ {value: 0x0010, lo: 0x80, hi: 0x9f},
+ {value: 0x0010, lo: 0xad, hi: 0xbf},
+ // Block 0xa5, offset 0x3dd
+ {value: 0x0010, lo: 0x80, hi: 0x8a},
+ {value: 0x0010, lo: 0x90, hi: 0xb5},
+ {value: 0x0024, lo: 0xb6, hi: 0xba},
+ // Block 0xa6, offset 0x3e0
+ {value: 0x0010, lo: 0x80, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0xa7, offset 0x3e2
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x88, hi: 0x8f},
+ {value: 0x0010, lo: 0x91, hi: 0x95},
+ // Block 0xa8, offset 0x3e5
+ {value: 0x2813, lo: 0x80, hi: 0x87},
+ {value: 0x3813, lo: 0x88, hi: 0x8f},
+ {value: 0x2813, lo: 0x90, hi: 0x97},
+ {value: 0xb653, lo: 0x98, hi: 0x9f},
+ {value: 0xb953, lo: 0xa0, hi: 0xa7},
+ {value: 0x2812, lo: 0xa8, hi: 0xaf},
+ {value: 0x3812, lo: 0xb0, hi: 0xb7},
+ {value: 0x2812, lo: 0xb8, hi: 0xbf},
+ // Block 0xa9, offset 0x3ed
+ {value: 0xb652, lo: 0x80, hi: 0x87},
+ {value: 0xb952, lo: 0x88, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0xaa, offset 0x3f0
+ {value: 0x0010, lo: 0x80, hi: 0x9d},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0xb953, lo: 0xb0, hi: 0xb7},
+ {value: 0xb653, lo: 0xb8, hi: 0xbf},
+ // Block 0xab, offset 0x3f4
+ {value: 0x2813, lo: 0x80, hi: 0x87},
+ {value: 0x3813, lo: 0x88, hi: 0x8f},
+ {value: 0x2813, lo: 0x90, hi: 0x93},
+ {value: 0xb952, lo: 0x98, hi: 0x9f},
+ {value: 0xb652, lo: 0xa0, hi: 0xa7},
+ {value: 0x2812, lo: 0xa8, hi: 0xaf},
+ {value: 0x3812, lo: 0xb0, hi: 0xb7},
+ {value: 0x2812, lo: 0xb8, hi: 0xbb},
+ // Block 0xac, offset 0x3fc
+ {value: 0x0010, lo: 0x80, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xad, offset 0x3fe
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0xbc53, lo: 0xb0, hi: 0xb0},
+ {value: 0xbf53, lo: 0xb1, hi: 0xb1},
+ {value: 0xc253, lo: 0xb2, hi: 0xb2},
+ {value: 0xbf53, lo: 0xb3, hi: 0xb3},
+ {value: 0xc553, lo: 0xb4, hi: 0xb4},
+ {value: 0xbf53, lo: 0xb5, hi: 0xb5},
+ {value: 0xc253, lo: 0xb6, hi: 0xb6},
+ {value: 0xbf53, lo: 0xb7, hi: 0xb7},
+ {value: 0xbc53, lo: 0xb8, hi: 0xb8},
+ {value: 0xc853, lo: 0xb9, hi: 0xb9},
+ {value: 0xcb53, lo: 0xba, hi: 0xba},
+ {value: 0xce53, lo: 0xbc, hi: 0xbc},
+ {value: 0xc853, lo: 0xbd, hi: 0xbd},
+ {value: 0xcb53, lo: 0xbe, hi: 0xbe},
+ {value: 0xc853, lo: 0xbf, hi: 0xbf},
+ // Block 0xae, offset 0x40e
+ {value: 0x0010, lo: 0x80, hi: 0xb6},
+ // Block 0xaf, offset 0x40f
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xa7},
+ // Block 0xb0, offset 0x411
+ {value: 0x0015, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x82},
+ {value: 0x0015, lo: 0x83, hi: 0x85},
+ {value: 0x0015, lo: 0x87, hi: 0xb0},
+ {value: 0x0015, lo: 0xb2, hi: 0xba},
+ // Block 0xb1, offset 0x416
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0010, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0xb5},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0010, lo: 0xbc, hi: 0xbc},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xb2, offset 0x41c
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb6},
+ // Block 0xb3, offset 0x41e
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ // Block 0xb4, offset 0x41f
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ {value: 0x0010, lo: 0xb4, hi: 0xb5},
+ // Block 0xb5, offset 0x421
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb9},
+ // Block 0xb6, offset 0x423
+ {value: 0x0010, lo: 0x80, hi: 0x99},
+ // Block 0xb7, offset 0x424
+ {value: 0x0010, lo: 0x80, hi: 0xb7},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0xb8, offset 0x426
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x83},
+ {value: 0x0014, lo: 0x85, hi: 0x86},
+ {value: 0x0014, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x8d},
+ {value: 0x0014, lo: 0x8e, hi: 0x8e},
+ {value: 0x0024, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x97},
+ {value: 0x0010, lo: 0x99, hi: 0xb5},
+ {value: 0x0024, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xb9, offset 0x433
+ {value: 0x0010, lo: 0xa0, hi: 0xbc},
+ // Block 0xba, offset 0x434
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ // Block 0xbb, offset 0x435
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0010, lo: 0x89, hi: 0xa4},
+ {value: 0x0024, lo: 0xa5, hi: 0xa5},
+ {value: 0x0034, lo: 0xa6, hi: 0xa6},
+ // Block 0xbc, offset 0x439
+ {value: 0x0010, lo: 0x80, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ // Block 0xbd, offset 0x43b
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ // Block 0xbe, offset 0x43c
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ // Block 0xbf, offset 0x43d
+ {value: 0x5653, lo: 0x80, hi: 0xb2},
+ // Block 0xc0, offset 0x43e
+ {value: 0x5652, lo: 0x80, hi: 0xb2},
+ // Block 0xc1, offset 0x43f
+ {value: 0x0010, lo: 0x80, hi: 0xa3},
+ {value: 0x0024, lo: 0xa4, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xc2, offset 0x442
+ {value: 0x0010, lo: 0x80, hi: 0x8d},
+ {value: 0x0014, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x8f, hi: 0x8f},
+ {value: 0x2013, lo: 0x90, hi: 0x9f},
+ {value: 0xd153, lo: 0xa0, hi: 0xa5},
+ {value: 0x0024, lo: 0xa9, hi: 0xad},
+ {value: 0x0014, lo: 0xaf, hi: 0xaf},
+ {value: 0x2012, lo: 0xb0, hi: 0xbf},
+ // Block 0xc3, offset 0x44a
+ {value: 0xd152, lo: 0x80, hi: 0x85},
+ // Block 0xc4, offset 0x44b
+ {value: 0x0010, lo: 0x80, hi: 0xa9},
+ {value: 0x0024, lo: 0xab, hi: 0xac},
+ {value: 0x0010, lo: 0xb0, hi: 0xb1},
+ // Block 0xc5, offset 0x44e
+ {value: 0x0010, lo: 0x82, hi: 0x84},
+ {value: 0x0014, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0x86, hi: 0x87},
+ {value: 0x0034, lo: 0xba, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbc},
+ {value: 0x0034, lo: 0xbd, hi: 0xbf},
+ // Block 0xc6, offset 0x454
+ {value: 0x0010, lo: 0x80, hi: 0x9c},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc7, offset 0x457
+ {value: 0x0010, lo: 0x80, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x87},
+ {value: 0x0024, lo: 0x88, hi: 0x8a},
+ {value: 0x0034, lo: 0x8b, hi: 0x8b},
+ {value: 0x0024, lo: 0x8c, hi: 0x8c},
+ {value: 0x0034, lo: 0x8d, hi: 0x90},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc8, offset 0x45e
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0024, lo: 0x82, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x83},
+ {value: 0x0024, lo: 0x84, hi: 0x84},
+ {value: 0x0034, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xc9, offset 0x464
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0010, lo: 0xa0, hi: 0xb6},
+ // Block 0xca, offset 0x466
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbf},
+ // Block 0xcb, offset 0x46a
+ {value: 0x0014, lo: 0x80, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0xa6, hi: 0xaf},
+ {value: 0x0034, lo: 0xb0, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xcc, offset 0x472
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb6},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ {value: 0x0014, lo: 0xbd, hi: 0xbd},
+ // Block 0xcd, offset 0x478
+ {value: 0x0014, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0xa8},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xce, offset 0x47c
+ {value: 0x0024, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xab},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb6, hi: 0xbf},
+ // Block 0xcf, offset 0x483
+ {value: 0x0010, lo: 0x84, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0xb2},
+ {value: 0x0034, lo: 0xb3, hi: 0xb3},
+ {value: 0x0010, lo: 0xb6, hi: 0xb6},
+ // Block 0xd0, offset 0x487
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xd1, offset 0x48b
+ {value: 0x0030, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0014, lo: 0x89, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8c},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0x9a},
+ {value: 0x0010, lo: 0x9c, hi: 0x9c},
+ // Block 0xd2, offset 0x494
+ {value: 0x0010, lo: 0x80, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb1},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0014, lo: 0xb4, hi: 0xb4},
+ {value: 0x0030, lo: 0xb5, hi: 0xb5},
+ {value: 0x0034, lo: 0xb6, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xb7},
+ {value: 0x0014, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xd3, offset 0x49e
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ // Block 0xd4, offset 0x4a0
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0x8d},
+ {value: 0x0010, lo: 0x8f, hi: 0x9d},
+ {value: 0x0010, lo: 0x9f, hi: 0xa8},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xd5, offset 0x4a6
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0014, lo: 0x9f, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa2},
+ {value: 0x0014, lo: 0xa3, hi: 0xa8},
+ {value: 0x0034, lo: 0xa9, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xd6, offset 0x4ac
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x8c},
+ {value: 0x0010, lo: 0x8f, hi: 0x90},
+ {value: 0x0010, lo: 0x93, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb5, hi: 0xb9},
+ {value: 0x0034, lo: 0xbb, hi: 0xbc},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0xd7, offset 0x4b6
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x84},
+ {value: 0x0010, lo: 0x87, hi: 0x88},
+ {value: 0x0010, lo: 0x8b, hi: 0x8c},
+ {value: 0x0030, lo: 0x8d, hi: 0x8d},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x9d, hi: 0xa3},
+ {value: 0x0024, lo: 0xa6, hi: 0xac},
+ {value: 0x0024, lo: 0xb0, hi: 0xb4},
+ // Block 0xd8, offset 0x4c0
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0x8b},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ {value: 0x0010, lo: 0x90, hi: 0xb5},
+ {value: 0x0010, lo: 0xb7, hi: 0xba},
+ {value: 0x0014, lo: 0xbb, hi: 0xbf},
+ // Block 0xd9, offset 0x4c6
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x85, hi: 0x85},
+ {value: 0x0010, lo: 0x87, hi: 0x8a},
+ {value: 0x0010, lo: 0x8c, hi: 0x8d},
+ {value: 0x0034, lo: 0x8e, hi: 0x8e},
+ {value: 0x0030, lo: 0x8f, hi: 0x8f},
+ {value: 0x0034, lo: 0x90, hi: 0x90},
+ {value: 0x0010, lo: 0x91, hi: 0x91},
+ {value: 0x0014, lo: 0x92, hi: 0x92},
+ {value: 0x0010, lo: 0x93, hi: 0x93},
+ {value: 0x0014, lo: 0xa1, hi: 0xa2},
+ // Block 0xda, offset 0x4d2
+ {value: 0x0010, lo: 0x80, hi: 0xb7},
+ {value: 0x0014, lo: 0xb8, hi: 0xbf},
+ // Block 0xdb, offset 0x4d4
+ {value: 0x0010, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x84},
+ {value: 0x0010, lo: 0x85, hi: 0x85},
+ {value: 0x0034, lo: 0x86, hi: 0x86},
+ {value: 0x0010, lo: 0x87, hi: 0x8a},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0024, lo: 0x9e, hi: 0x9e},
+ {value: 0x0010, lo: 0x9f, hi: 0xa1},
+ // Block 0xdc, offset 0x4dd
+ {value: 0x0010, lo: 0x80, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb8},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0xdd, offset 0x4e3
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x83},
+ {value: 0x0010, lo: 0x84, hi: 0x85},
+ {value: 0x0010, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xde, offset 0x4e9
+ {value: 0x0010, lo: 0x80, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb5},
+ {value: 0x0010, lo: 0xb8, hi: 0xbb},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xdf, offset 0x4ef
+ {value: 0x0034, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x98, hi: 0x9b},
+ {value: 0x0014, lo: 0x9c, hi: 0x9d},
+ // Block 0xe0, offset 0x4f2
+ {value: 0x0010, lo: 0x80, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xba},
+ {value: 0x0010, lo: 0xbb, hi: 0xbc},
+ {value: 0x0014, lo: 0xbd, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xe1, offset 0x4f8
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x84, hi: 0x84},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xe2, offset 0x4fb
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0014, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xac, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xad},
+ {value: 0x0010, lo: 0xae, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb5},
+ {value: 0x0030, lo: 0xb6, hi: 0xb6},
+ {value: 0x0034, lo: 0xb7, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ // Block 0xe3, offset 0x504
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x90, hi: 0xa3},
+ // Block 0xe4, offset 0x506
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0x9e, hi: 0x9e},
+ {value: 0x0014, lo: 0x9f, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa5},
+ {value: 0x0010, lo: 0xa6, hi: 0xa6},
+ {value: 0x0014, lo: 0xa7, hi: 0xaa},
+ {value: 0x0034, lo: 0xab, hi: 0xab},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xe5, offset 0x50f
+ {value: 0x0010, lo: 0x80, hi: 0xae},
+ {value: 0x0014, lo: 0xaf, hi: 0xb7},
+ {value: 0x0010, lo: 0xb8, hi: 0xb8},
+ {value: 0x0034, lo: 0xb9, hi: 0xba},
+ // Block 0xe6, offset 0x513
+ {value: 0x5f53, lo: 0xa0, hi: 0xbf},
+ // Block 0xe7, offset 0x514
+ {value: 0x5f52, lo: 0x80, hi: 0x9f},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xe8, offset 0x517
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x89, hi: 0x89},
+ {value: 0x0010, lo: 0x8c, hi: 0x93},
+ {value: 0x0010, lo: 0x95, hi: 0x96},
+ {value: 0x0010, lo: 0x98, hi: 0xb5},
+ {value: 0x0010, lo: 0xb7, hi: 0xb8},
+ {value: 0x0014, lo: 0xbb, hi: 0xbc},
+ {value: 0x0030, lo: 0xbd, hi: 0xbd},
+ {value: 0x0034, lo: 0xbe, hi: 0xbe},
+ {value: 0x0010, lo: 0xbf, hi: 0xbf},
+ // Block 0xe9, offset 0x521
+ {value: 0x0010, lo: 0x80, hi: 0x82},
+ {value: 0x0034, lo: 0x83, hi: 0x83},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0xea, offset 0x524
+ {value: 0x0010, lo: 0xa0, hi: 0xa7},
+ {value: 0x0010, lo: 0xaa, hi: 0xbf},
+ // Block 0xeb, offset 0x526
+ {value: 0x0010, lo: 0x80, hi: 0x93},
+ {value: 0x0014, lo: 0x94, hi: 0x97},
+ {value: 0x0014, lo: 0x9a, hi: 0x9b},
+ {value: 0x0010, lo: 0x9c, hi: 0x9f},
+ {value: 0x0034, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0010, lo: 0xa3, hi: 0xa4},
+ // Block 0xec, offset 0x52d
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0014, lo: 0x81, hi: 0x8a},
+ {value: 0x0010, lo: 0x8b, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb3},
+ {value: 0x0034, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb8},
+ {value: 0x0010, lo: 0xb9, hi: 0xba},
+ {value: 0x0014, lo: 0xbb, hi: 0xbe},
+ // Block 0xed, offset 0x535
+ {value: 0x0034, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x90},
+ {value: 0x0014, lo: 0x91, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x98},
+ {value: 0x0014, lo: 0x99, hi: 0x9b},
+ {value: 0x0010, lo: 0x9c, hi: 0xbf},
+ // Block 0xee, offset 0x53b
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0014, lo: 0x8a, hi: 0x96},
+ {value: 0x0010, lo: 0x97, hi: 0x97},
+ {value: 0x0014, lo: 0x98, hi: 0x98},
+ {value: 0x0034, lo: 0x99, hi: 0x99},
+ {value: 0x0010, lo: 0x9d, hi: 0x9d},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xef, offset 0x542
+ {value: 0x0010, lo: 0x80, hi: 0xb8},
+ // Block 0xf0, offset 0x543
+ {value: 0x0014, lo: 0xa0, hi: 0xa0},
+ {value: 0x0010, lo: 0xa1, hi: 0xa1},
+ {value: 0x0014, lo: 0xa2, hi: 0xa4},
+ {value: 0x0010, lo: 0xa5, hi: 0xa5},
+ {value: 0x0014, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ // Block 0xf1, offset 0x549
+ {value: 0x0010, lo: 0x80, hi: 0xa0},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0xf2, offset 0x54b
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x8a, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xb6},
+ {value: 0x0014, lo: 0xb8, hi: 0xbd},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0034, lo: 0xbf, hi: 0xbf},
+ // Block 0xf3, offset 0x551
+ {value: 0x0010, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xb2, hi: 0xbf},
+ // Block 0xf4, offset 0x554
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ {value: 0x0014, lo: 0x92, hi: 0xa7},
+ {value: 0x0010, lo: 0xa9, hi: 0xa9},
+ {value: 0x0014, lo: 0xaa, hi: 0xb0},
+ {value: 0x0010, lo: 0xb1, hi: 0xb1},
+ {value: 0x0014, lo: 0xb2, hi: 0xb3},
+ {value: 0x0010, lo: 0xb4, hi: 0xb4},
+ {value: 0x0014, lo: 0xb5, hi: 0xb6},
+ // Block 0xf5, offset 0x55c
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ {value: 0x0010, lo: 0x88, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0xb0},
+ {value: 0x0014, lo: 0xb1, hi: 0xb6},
+ {value: 0x0014, lo: 0xba, hi: 0xba},
+ {value: 0x0014, lo: 0xbc, hi: 0xbd},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0xf6, offset 0x563
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0014, lo: 0x83, hi: 0x83},
+ {value: 0x0034, lo: 0x84, hi: 0x85},
+ {value: 0x0010, lo: 0x86, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x87},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa0, hi: 0xa5},
+ {value: 0x0010, lo: 0xa7, hi: 0xa8},
+ {value: 0x0010, lo: 0xaa, hi: 0xbf},
+ // Block 0xf7, offset 0x56d
+ {value: 0x0010, lo: 0x80, hi: 0x8e},
+ {value: 0x0014, lo: 0x90, hi: 0x91},
+ {value: 0x0010, lo: 0x93, hi: 0x94},
+ {value: 0x0014, lo: 0x95, hi: 0x95},
+ {value: 0x0010, lo: 0x96, hi: 0x96},
+ {value: 0x0034, lo: 0x97, hi: 0x97},
+ {value: 0x0010, lo: 0x98, hi: 0x98},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0xf8, offset 0x576
+ {value: 0x0010, lo: 0x80, hi: 0x98},
+ {value: 0x0014, lo: 0x99, hi: 0x99},
+ {value: 0x0010, lo: 0x9a, hi: 0x9b},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ // Block 0xf9, offset 0x57a
+ {value: 0x0010, lo: 0xa0, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xb4},
+ {value: 0x0010, lo: 0xb5, hi: 0xb6},
+ // Block 0xfa, offset 0x57d
+ {value: 0x0014, lo: 0x80, hi: 0x81},
+ {value: 0x0010, lo: 0x82, hi: 0x90},
+ {value: 0x0010, lo: 0x92, hi: 0xb5},
+ {value: 0x0014, lo: 0xb6, hi: 0xba},
+ {value: 0x0010, lo: 0xbe, hi: 0xbf},
+ // Block 0xfb, offset 0x582
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0030, lo: 0x81, hi: 0x81},
+ {value: 0x0034, lo: 0x82, hi: 0x82},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0014, lo: 0x9a, hi: 0x9a},
+ // Block 0xfc, offset 0x587
+ {value: 0x0010, lo: 0xb0, hi: 0xb0},
+ // Block 0xfd, offset 0x588
+ {value: 0x0010, lo: 0x80, hi: 0xae},
+ // Block 0xfe, offset 0x589
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ // Block 0xff, offset 0x58a
+ {value: 0x0010, lo: 0x80, hi: 0xb0},
+ // Block 0x100, offset 0x58b
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0014, lo: 0xb0, hi: 0xbf},
+ // Block 0x101, offset 0x58d
+ {value: 0x0014, lo: 0x80, hi: 0x80},
+ {value: 0x0010, lo: 0x81, hi: 0x86},
+ {value: 0x0014, lo: 0x87, hi: 0x95},
+ {value: 0x0010, lo: 0xa0, hi: 0xbf},
+ // Block 0x102, offset 0x591
+ {value: 0x0010, lo: 0x80, hi: 0x86},
+ // Block 0x103, offset 0x592
+ {value: 0x0010, lo: 0x80, hi: 0x9d},
+ {value: 0x0014, lo: 0x9e, hi: 0xa9},
+ {value: 0x0010, lo: 0xaa, hi: 0xac},
+ {value: 0x0014, lo: 0xad, hi: 0xae},
+ {value: 0x0034, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x104, offset 0x598
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0010, lo: 0xa0, hi: 0xa9},
+ {value: 0x0010, lo: 0xb0, hi: 0xbf},
+ // Block 0x105, offset 0x59b
+ {value: 0x0010, lo: 0x80, hi: 0xbe},
+ // Block 0x106, offset 0x59c
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x90, hi: 0xad},
+ {value: 0x0034, lo: 0xb0, hi: 0xb4},
+ // Block 0x107, offset 0x59f
+ {value: 0x0010, lo: 0x80, hi: 0xaf},
+ {value: 0x0024, lo: 0xb0, hi: 0xb6},
+ // Block 0x108, offset 0x5a1
+ {value: 0x0014, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0010, lo: 0xa3, hi: 0xb7},
+ {value: 0x0010, lo: 0xbd, hi: 0xbf},
+ // Block 0x109, offset 0x5a5
+ {value: 0x0010, lo: 0x80, hi: 0x8f},
+ // Block 0x10a, offset 0x5a6
+ {value: 0x0014, lo: 0x80, hi: 0x82},
+ {value: 0x0010, lo: 0x83, hi: 0xaa},
+ {value: 0x0014, lo: 0xab, hi: 0xac},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x10b, offset 0x5aa
+ {value: 0x2013, lo: 0x80, hi: 0x9f},
+ {value: 0x2012, lo: 0xa0, hi: 0xbf},
+ // Block 0x10c, offset 0x5ac
+ {value: 0x0010, lo: 0x80, hi: 0x8a},
+ {value: 0x0014, lo: 0x8f, hi: 0x8f},
+ {value: 0x0010, lo: 0x90, hi: 0xbf},
+ // Block 0x10d, offset 0x5af
+ {value: 0x0010, lo: 0x80, hi: 0x87},
+ {value: 0x0014, lo: 0x8f, hi: 0x9f},
+ // Block 0x10e, offset 0x5b1
+ {value: 0x0014, lo: 0xa0, hi: 0xa1},
+ {value: 0x0014, lo: 0xa3, hi: 0xa4},
+ {value: 0x0030, lo: 0xb0, hi: 0xb1},
+ {value: 0x0004, lo: 0xb2, hi: 0xb3},
+ // Block 0x10f, offset 0x5b5
+ {value: 0x0004, lo: 0xb0, hi: 0xb3},
+ {value: 0x0004, lo: 0xb5, hi: 0xbb},
+ {value: 0x0004, lo: 0xbd, hi: 0xbe},
+ // Block 0x110, offset 0x5b8
+ {value: 0x0010, lo: 0x80, hi: 0xaa},
+ {value: 0x0010, lo: 0xb0, hi: 0xbc},
+ // Block 0x111, offset 0x5ba
+ {value: 0x0010, lo: 0x80, hi: 0x88},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ {value: 0x0014, lo: 0x9d, hi: 0x9d},
+ {value: 0x0034, lo: 0x9e, hi: 0x9e},
+ {value: 0x0014, lo: 0xa0, hi: 0xa3},
+ // Block 0x112, offset 0x5bf
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x113, offset 0x5c0
+ {value: 0x0014, lo: 0x80, hi: 0xad},
+ {value: 0x0014, lo: 0xb0, hi: 0xbf},
+ // Block 0x114, offset 0x5c2
+ {value: 0x0014, lo: 0x80, hi: 0x86},
+ // Block 0x115, offset 0x5c3
+ {value: 0x0030, lo: 0xa5, hi: 0xa6},
+ {value: 0x0034, lo: 0xa7, hi: 0xa9},
+ {value: 0x0030, lo: 0xad, hi: 0xb2},
+ {value: 0x0014, lo: 0xb3, hi: 0xba},
+ {value: 0x0034, lo: 0xbb, hi: 0xbf},
+ // Block 0x116, offset 0x5c8
+ {value: 0x0034, lo: 0x80, hi: 0x82},
+ {value: 0x0024, lo: 0x85, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8b},
+ {value: 0x0024, lo: 0xaa, hi: 0xad},
+ // Block 0x117, offset 0x5cc
+ {value: 0x0024, lo: 0x82, hi: 0x84},
+ // Block 0x118, offset 0x5cd
+ {value: 0x0013, lo: 0x80, hi: 0x99},
+ {value: 0x0012, lo: 0x9a, hi: 0xb3},
+ {value: 0x0013, lo: 0xb4, hi: 0xbf},
+ // Block 0x119, offset 0x5d0
+ {value: 0x0013, lo: 0x80, hi: 0x8d},
+ {value: 0x0012, lo: 0x8e, hi: 0x94},
+ {value: 0x0012, lo: 0x96, hi: 0xa7},
+ {value: 0x0013, lo: 0xa8, hi: 0xbf},
+ // Block 0x11a, offset 0x5d4
+ {value: 0x0013, lo: 0x80, hi: 0x81},
+ {value: 0x0012, lo: 0x82, hi: 0x9b},
+ {value: 0x0013, lo: 0x9c, hi: 0x9c},
+ {value: 0x0013, lo: 0x9e, hi: 0x9f},
+ {value: 0x0013, lo: 0xa2, hi: 0xa2},
+ {value: 0x0013, lo: 0xa5, hi: 0xa6},
+ {value: 0x0013, lo: 0xa9, hi: 0xac},
+ {value: 0x0013, lo: 0xae, hi: 0xb5},
+ {value: 0x0012, lo: 0xb6, hi: 0xb9},
+ {value: 0x0012, lo: 0xbb, hi: 0xbb},
+ {value: 0x0012, lo: 0xbd, hi: 0xbf},
+ // Block 0x11b, offset 0x5df
+ {value: 0x0012, lo: 0x80, hi: 0x83},
+ {value: 0x0012, lo: 0x85, hi: 0x8f},
+ {value: 0x0013, lo: 0x90, hi: 0xa9},
+ {value: 0x0012, lo: 0xaa, hi: 0xbf},
+ // Block 0x11c, offset 0x5e3
+ {value: 0x0012, lo: 0x80, hi: 0x83},
+ {value: 0x0013, lo: 0x84, hi: 0x85},
+ {value: 0x0013, lo: 0x87, hi: 0x8a},
+ {value: 0x0013, lo: 0x8d, hi: 0x94},
+ {value: 0x0013, lo: 0x96, hi: 0x9c},
+ {value: 0x0012, lo: 0x9e, hi: 0xb7},
+ {value: 0x0013, lo: 0xb8, hi: 0xb9},
+ {value: 0x0013, lo: 0xbb, hi: 0xbe},
+ // Block 0x11d, offset 0x5eb
+ {value: 0x0013, lo: 0x80, hi: 0x84},
+ {value: 0x0013, lo: 0x86, hi: 0x86},
+ {value: 0x0013, lo: 0x8a, hi: 0x90},
+ {value: 0x0012, lo: 0x92, hi: 0xab},
+ {value: 0x0013, lo: 0xac, hi: 0xbf},
+ // Block 0x11e, offset 0x5f0
+ {value: 0x0013, lo: 0x80, hi: 0x85},
+ {value: 0x0012, lo: 0x86, hi: 0x9f},
+ {value: 0x0013, lo: 0xa0, hi: 0xb9},
+ {value: 0x0012, lo: 0xba, hi: 0xbf},
+ // Block 0x11f, offset 0x5f4
+ {value: 0x0012, lo: 0x80, hi: 0x93},
+ {value: 0x0013, lo: 0x94, hi: 0xad},
+ {value: 0x0012, lo: 0xae, hi: 0xbf},
+ // Block 0x120, offset 0x5f7
+ {value: 0x0012, lo: 0x80, hi: 0x87},
+ {value: 0x0013, lo: 0x88, hi: 0xa1},
+ {value: 0x0012, lo: 0xa2, hi: 0xbb},
+ {value: 0x0013, lo: 0xbc, hi: 0xbf},
+ // Block 0x121, offset 0x5fb
+ {value: 0x0013, lo: 0x80, hi: 0x95},
+ {value: 0x0012, lo: 0x96, hi: 0xaf},
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x122, offset 0x5fe
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ {value: 0x0012, lo: 0x8a, hi: 0xa5},
+ {value: 0x0013, lo: 0xa8, hi: 0xbf},
+ // Block 0x123, offset 0x601
+ {value: 0x0013, lo: 0x80, hi: 0x80},
+ {value: 0x0012, lo: 0x82, hi: 0x9a},
+ {value: 0x0012, lo: 0x9c, hi: 0xa1},
+ {value: 0x0013, lo: 0xa2, hi: 0xba},
+ {value: 0x0012, lo: 0xbc, hi: 0xbf},
+ // Block 0x124, offset 0x606
+ {value: 0x0012, lo: 0x80, hi: 0x94},
+ {value: 0x0012, lo: 0x96, hi: 0x9b},
+ {value: 0x0013, lo: 0x9c, hi: 0xb4},
+ {value: 0x0012, lo: 0xb6, hi: 0xbf},
+ // Block 0x125, offset 0x60a
+ {value: 0x0012, lo: 0x80, hi: 0x8e},
+ {value: 0x0012, lo: 0x90, hi: 0x95},
+ {value: 0x0013, lo: 0x96, hi: 0xae},
+ {value: 0x0012, lo: 0xb0, hi: 0xbf},
+ // Block 0x126, offset 0x60e
+ {value: 0x0012, lo: 0x80, hi: 0x88},
+ {value: 0x0012, lo: 0x8a, hi: 0x8f},
+ {value: 0x0013, lo: 0x90, hi: 0xa8},
+ {value: 0x0012, lo: 0xaa, hi: 0xbf},
+ // Block 0x127, offset 0x612
+ {value: 0x0012, lo: 0x80, hi: 0x82},
+ {value: 0x0012, lo: 0x84, hi: 0x89},
+ {value: 0x0017, lo: 0x8a, hi: 0x8b},
+ {value: 0x0010, lo: 0x8e, hi: 0xbf},
+ // Block 0x128, offset 0x616
+ {value: 0x0014, lo: 0x80, hi: 0xb6},
+ {value: 0x0014, lo: 0xbb, hi: 0xbf},
+ // Block 0x129, offset 0x618
+ {value: 0x0014, lo: 0x80, hi: 0xac},
+ {value: 0x0014, lo: 0xb5, hi: 0xb5},
+ // Block 0x12a, offset 0x61a
+ {value: 0x0014, lo: 0x84, hi: 0x84},
+ {value: 0x0014, lo: 0x9b, hi: 0x9f},
+ {value: 0x0014, lo: 0xa1, hi: 0xaf},
+ // Block 0x12b, offset 0x61d
+ {value: 0x0012, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8a, hi: 0x8a},
+ {value: 0x0012, lo: 0x8b, hi: 0x9e},
+ {value: 0x0012, lo: 0xa5, hi: 0xaa},
+ // Block 0x12c, offset 0x621
+ {value: 0x0024, lo: 0x80, hi: 0x86},
+ {value: 0x0024, lo: 0x88, hi: 0x98},
+ {value: 0x0024, lo: 0x9b, hi: 0xa1},
+ {value: 0x0024, lo: 0xa3, hi: 0xa4},
+ {value: 0x0024, lo: 0xa6, hi: 0xaa},
+ {value: 0x0015, lo: 0xb0, hi: 0xbf},
+ // Block 0x12d, offset 0x627
+ {value: 0x0015, lo: 0x80, hi: 0xad},
+ // Block 0x12e, offset 0x628
+ {value: 0x0024, lo: 0x8f, hi: 0x8f},
+ // Block 0x12f, offset 0x629
+ {value: 0x0010, lo: 0x80, hi: 0xac},
+ {value: 0x0024, lo: 0xb0, hi: 0xb6},
+ {value: 0x0014, lo: 0xb7, hi: 0xbd},
+ // Block 0x130, offset 0x62c
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8e, hi: 0x8e},
+ // Block 0x131, offset 0x62e
+ {value: 0x0010, lo: 0x90, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xae},
+ // Block 0x132, offset 0x630
+ {value: 0x0010, lo: 0x80, hi: 0xab},
+ {value: 0x0024, lo: 0xac, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x133, offset 0x633
+ {value: 0x0010, lo: 0x90, hi: 0xaa},
+ {value: 0x0014, lo: 0xab, hi: 0xab},
+ {value: 0x0034, lo: 0xac, hi: 0xae},
+ {value: 0x0024, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb9},
+ // Block 0x134, offset 0x638
+ {value: 0x0010, lo: 0x90, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xae},
+ {value: 0x0034, lo: 0xaf, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xba},
+ // Block 0x135, offset 0x63c
+ {value: 0x0010, lo: 0x80, hi: 0x9e},
+ {value: 0x0010, lo: 0xa0, hi: 0xa2},
+ {value: 0x0024, lo: 0xa3, hi: 0xa3},
+ {value: 0x0010, lo: 0xa4, hi: 0xa5},
+ {value: 0x0024, lo: 0xa6, hi: 0xa6},
+ {value: 0x0010, lo: 0xa7, hi: 0xad},
+ {value: 0x0024, lo: 0xae, hi: 0xaf},
+ {value: 0x0010, lo: 0xb0, hi: 0xb4},
+ {value: 0x0024, lo: 0xb5, hi: 0xb5},
+ {value: 0x0010, lo: 0xbe, hi: 0xbe},
+ {value: 0x0014, lo: 0xbf, hi: 0xbf},
+ // Block 0x136, offset 0x647
+ {value: 0x0010, lo: 0xa0, hi: 0xa6},
+ {value: 0x0010, lo: 0xa8, hi: 0xab},
+ {value: 0x0010, lo: 0xad, hi: 0xae},
+ {value: 0x0010, lo: 0xb0, hi: 0xbe},
+ // Block 0x137, offset 0x64b
+ {value: 0x0010, lo: 0x80, hi: 0x84},
+ {value: 0x0034, lo: 0x90, hi: 0x96},
+ // Block 0x138, offset 0x64d
+ {value: 0xe952, lo: 0x80, hi: 0x81},
+ {value: 0xec52, lo: 0x82, hi: 0x83},
+ {value: 0x0024, lo: 0x84, hi: 0x89},
+ {value: 0x0034, lo: 0x8a, hi: 0x8a},
+ {value: 0x0014, lo: 0x8b, hi: 0x8b},
+ {value: 0x0010, lo: 0x90, hi: 0x99},
+ // Block 0x139, offset 0x653
+ {value: 0x0010, lo: 0x80, hi: 0x83},
+ {value: 0x0010, lo: 0x85, hi: 0x9f},
+ {value: 0x0010, lo: 0xa1, hi: 0xa2},
+ {value: 0x0010, lo: 0xa4, hi: 0xa4},
+ {value: 0x0010, lo: 0xa7, hi: 0xa7},
+ {value: 0x0010, lo: 0xa9, hi: 0xb2},
+ {value: 0x0010, lo: 0xb4, hi: 0xb7},
+ {value: 0x0010, lo: 0xb9, hi: 0xb9},
+ {value: 0x0010, lo: 0xbb, hi: 0xbb},
+ // Block 0x13a, offset 0x65c
+ {value: 0x0010, lo: 0x80, hi: 0x89},
+ {value: 0x0010, lo: 0x8b, hi: 0x9b},
+ {value: 0x0010, lo: 0xa1, hi: 0xa3},
+ {value: 0x0010, lo: 0xa5, hi: 0xa9},
+ {value: 0x0010, lo: 0xab, hi: 0xbb},
+ // Block 0x13b, offset 0x661
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x13c, offset 0x662
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ {value: 0x0013, lo: 0x90, hi: 0xa9},
+ {value: 0x0013, lo: 0xb0, hi: 0xbf},
+ // Block 0x13d, offset 0x665
+ {value: 0x0013, lo: 0x80, hi: 0x89},
+ // Block 0x13e, offset 0x666
+ {value: 0x0014, lo: 0xbb, hi: 0xbf},
+ // Block 0x13f, offset 0x667
+ {value: 0x0014, lo: 0x81, hi: 0x81},
+ {value: 0x0014, lo: 0xa0, hi: 0xbf},
+ // Block 0x140, offset 0x669
+ {value: 0x0014, lo: 0x80, hi: 0xbf},
+ // Block 0x141, offset 0x66a
+ {value: 0x0014, lo: 0x80, hi: 0xaf},
+}
+
+// Total table size 16747 bytes (16KiB); checksum: D520269F
diff --git a/vendor/golang.org/x/text/cases/trieval.go b/vendor/golang.org/x/text/cases/trieval.go
new file mode 100644
index 000000000..4e4d13fe5
--- /dev/null
+++ b/vendor/golang.org/x/text/cases/trieval.go
@@ -0,0 +1,217 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package cases
+
+// This file contains definitions for interpreting the trie value of the case
+// trie generated by "go run gen*.go". It is shared by both the generator
+// program and the resultant package. Sharing is achieved by the generator
+// copying gen_trieval.go to trieval.go and changing what's above this comment.
+
+// info holds case information for a single rune. It is the value returned
+// by a trie lookup. Most mapping information can be stored in a single 16-bit
+// value. If not, for example when a rune is mapped to multiple runes, the value
+// stores some basic case data and an index into an array with additional data.
+//
+// The per-rune values have the following format:
+//
+// if (exception) {
+// 15..4 unsigned exception index
+// } else {
+// 15..8 XOR pattern or index to XOR pattern for case mapping
+// Only 13..8 are used for XOR patterns.
+// 7 inverseFold (fold to upper, not to lower)
+// 6 index: interpret the XOR pattern as an index
+// or isMid if case mode is cIgnorableUncased.
+// 5..4 CCC: zero (normal or break), above or other
+// }
+// 3 exception: interpret this value as an exception index
+// (TODO: is this bit necessary? Probably implied from case mode.)
+// 2..0 case mode
+//
+// For the non-exceptional cases, a rune must be either uncased, lowercase or
+// uppercase. If the rune is cased, the XOR pattern maps either a lowercase
+// rune to uppercase or an uppercase rune to lowercase (applied to the 10
+// least-significant bits of the rune).
+//
+// See the definitions below for a more detailed description of the various
+// bits.
+type info uint16
+
+const (
+ casedMask = 0x0003
+ fullCasedMask = 0x0007
+ ignorableMask = 0x0006
+ ignorableValue = 0x0004
+
+ inverseFoldBit = 1 << 7
+ isMidBit = 1 << 6
+
+ exceptionBit = 1 << 3
+ exceptionShift = 4
+ numExceptionBits = 12
+
+ xorIndexBit = 1 << 6
+ xorShift = 8
+
+ // There is no mapping if all xor bits and the exception bit are zero.
+ hasMappingMask = 0xff80 | exceptionBit
+)
+
+// The case mode bits encodes the case type of a rune. This includes uncased,
+// title, upper and lower case and case ignorable. (For a definition of these
+// terms see Chapter 3 of The Unicode Standard Core Specification.) In some rare
+// cases, a rune can be both cased and case-ignorable. This is encoded by
+// cIgnorableCased. A rune of this type is always lower case. Some runes are
+// cased while not having a mapping.
+//
+// A common pattern for scripts in the Unicode standard is for upper and lower
+// case runes to alternate for increasing rune values (e.g. the accented Latin
+// ranges starting from U+0100 and U+1E00 among others and some Cyrillic
+// characters). We use this property by defining a cXORCase mode, where the case
+// mode (always upper or lower case) is derived from the rune value. As the XOR
+// pattern for case mappings is often identical for successive runes, using
+// cXORCase can result in large series of identical trie values. This, in turn,
+// allows us to better compress the trie blocks.
+const (
+ cUncased info = iota // 000
+ cTitle // 001
+ cLower // 010
+ cUpper // 011
+ cIgnorableUncased // 100
+ cIgnorableCased // 101 // lower case if mappings exist
+ cXORCase // 11x // case is cLower | ((rune&1) ^ x)
+
+ maxCaseMode = cUpper
+)
+
+func (c info) isCased() bool {
+ return c&casedMask != 0
+}
+
+func (c info) isCaseIgnorable() bool {
+ return c&ignorableMask == ignorableValue
+}
+
+func (c info) isNotCasedAndNotCaseIgnorable() bool {
+ return c&fullCasedMask == 0
+}
+
+func (c info) isCaseIgnorableAndNotCased() bool {
+ return c&fullCasedMask == cIgnorableUncased
+}
+
+func (c info) isMid() bool {
+ return c&(fullCasedMask|isMidBit) == isMidBit|cIgnorableUncased
+}
+
+// The case mapping implementation will need to know about various Canonical
+// Combining Class (CCC) values. We encode two of these in the trie value:
+// cccZero (0) and cccAbove (230). If the value is cccOther, it means that
+// CCC(r) > 0, but not 230. A value of cccBreak means that CCC(r) == 0 and that
+// the rune also has the break category Break (see below).
+const (
+ cccBreak info = iota << 4
+ cccZero
+ cccAbove
+ cccOther
+
+ cccMask = cccBreak | cccZero | cccAbove | cccOther
+)
+
+const (
+ starter = 0
+ above = 230
+ iotaSubscript = 240
+)
+
+// The exceptions slice holds data that does not fit in a normal info entry.
+// The entry is pointed to by the exception index in an entry. It has the
+// following format:
+//
+// Header:
+//
+// byte 0:
+// 7..6 unused
+// 5..4 CCC type (same bits as entry)
+// 3 unused
+// 2..0 length of fold
+//
+// byte 1:
+// 7..6 unused
+// 5..3 length of 1st mapping of case type
+// 2..0 length of 2nd mapping of case type
+//
+// case 1st 2nd
+// lower -> upper, title
+// upper -> lower, title
+// title -> lower, upper
+//
+// Lengths with the value 0x7 indicate no value and implies no change.
+// A length of 0 indicates a mapping to zero-length string.
+//
+// Body bytes:
+//
+// case folding bytes
+// lowercase mapping bytes
+// uppercase mapping bytes
+// titlecase mapping bytes
+// closure mapping bytes (for NFKC_Casefold). (TODO)
+//
+// Fallbacks:
+//
+// missing fold -> lower
+// missing title -> upper
+// all missing -> original rune
+//
+// exceptions starts with a dummy byte to enforce that there is no zero index
+// value.
+const (
+ lengthMask = 0x07
+ lengthBits = 3
+ noChange = 0
+)
+
+// References to generated trie.
+
+var trie = newCaseTrie(0)
+
+var sparse = sparseBlocks{
+ values: sparseValues[:],
+ offsets: sparseOffsets[:],
+}
+
+// Sparse block lookup code.
+
+// valueRange is an entry in a sparse block.
+type valueRange struct {
+ value uint16
+ lo, hi byte
+}
+
+type sparseBlocks struct {
+ values []valueRange
+ offsets []uint16
+}
+
+// lookup returns the value from values block n for byte b using binary search.
+func (s *sparseBlocks) lookup(n uint32, b byte) uint16 {
+ lo := s.offsets[n]
+ hi := s.offsets[n+1]
+ for lo < hi {
+ m := lo + (hi-lo)/2
+ r := s.values[m]
+ if r.lo <= b && b <= r.hi {
+ return r.value
+ }
+ if b < r.lo {
+ hi = m
+ } else {
+ lo = m + 1
+ }
+ }
+ return 0
+}
+
+// lastRuneForTesting is the last rune used for testing. Everything after this
+// is boring.
+const lastRuneForTesting = rune(0x1FFFF)
diff --git a/vendor/golang.org/x/text/internal/internal.go b/vendor/golang.org/x/text/internal/internal.go
new file mode 100644
index 000000000..3cddbbdda
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/internal.go
@@ -0,0 +1,49 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package internal contains non-exported functionality that are used by
+// packages in the text repository.
+package internal // import "golang.org/x/text/internal"
+
+import (
+ "sort"
+
+ "golang.org/x/text/language"
+)
+
+// SortTags sorts tags in place.
+func SortTags(tags []language.Tag) {
+ sort.Sort(sorter(tags))
+}
+
+type sorter []language.Tag
+
+func (s sorter) Len() int {
+ return len(s)
+}
+
+func (s sorter) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+
+func (s sorter) Less(i, j int) bool {
+ return s[i].String() < s[j].String()
+}
+
+// UniqueTags sorts and filters duplicate tags in place and returns a slice with
+// only unique tags.
+func UniqueTags(tags []language.Tag) []language.Tag {
+ if len(tags) <= 1 {
+ return tags
+ }
+ SortTags(tags)
+ k := 0
+ for i := 1; i < len(tags); i++ {
+ if tags[k].String() < tags[i].String() {
+ k++
+ tags[k] = tags[i]
+ }
+ }
+ return tags[:k+1]
+}
diff --git a/vendor/golang.org/x/text/internal/language/common.go b/vendor/golang.org/x/text/internal/language/common.go
new file mode 100644
index 000000000..cdfdb7497
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/common.go
@@ -0,0 +1,16 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package language
+
+// This file contains code common to the maketables.go and the package code.
+
+// AliasType is the type of an alias in AliasMap.
+type AliasType int8
+
+const (
+ Deprecated AliasType = iota
+ Macro
+ Legacy
+
+ AliasTypeUnknown AliasType = -1
+)
diff --git a/vendor/golang.org/x/text/internal/language/compact.go b/vendor/golang.org/x/text/internal/language/compact.go
new file mode 100644
index 000000000..46a001507
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact.go
@@ -0,0 +1,29 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+// CompactCoreInfo is a compact integer with the three core tags encoded.
+type CompactCoreInfo uint32
+
+// GetCompactCore generates a uint32 value that is guaranteed to be unique for
+// different language, region, and script values.
+func GetCompactCore(t Tag) (cci CompactCoreInfo, ok bool) {
+ if t.LangID > langNoIndexOffset {
+ return 0, false
+ }
+ cci |= CompactCoreInfo(t.LangID) << (8 + 12)
+ cci |= CompactCoreInfo(t.ScriptID) << 12
+ cci |= CompactCoreInfo(t.RegionID)
+ return cci, true
+}
+
+// Tag generates a tag from c.
+func (c CompactCoreInfo) Tag() Tag {
+ return Tag{
+ LangID: Language(c >> 20),
+ RegionID: Region(c & 0x3ff),
+ ScriptID: Script(c>>12) & 0xff,
+ }
+}
diff --git a/vendor/golang.org/x/text/internal/language/compact/compact.go b/vendor/golang.org/x/text/internal/language/compact/compact.go
new file mode 100644
index 000000000..1b36935ef
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact/compact.go
@@ -0,0 +1,61 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package compact defines a compact representation of language tags.
+//
+// Common language tags (at least all for which locale information is defined
+// in CLDR) are assigned a unique index. Each Tag is associated with such an
+// ID for selecting language-related resources (such as translations) as well
+// as one for selecting regional defaults (currency, number formatting, etc.)
+//
+// It may want to export this functionality at some point, but at this point
+// this is only available for use within x/text.
+package compact // import "golang.org/x/text/internal/language/compact"
+
+import (
+ "sort"
+ "strings"
+
+ "golang.org/x/text/internal/language"
+)
+
+// ID is an integer identifying a single tag.
+type ID uint16
+
+func getCoreIndex(t language.Tag) (id ID, ok bool) {
+ cci, ok := language.GetCompactCore(t)
+ if !ok {
+ return 0, false
+ }
+ i := sort.Search(len(coreTags), func(i int) bool {
+ return cci <= coreTags[i]
+ })
+ if i == len(coreTags) || coreTags[i] != cci {
+ return 0, false
+ }
+ return ID(i), true
+}
+
+// Parent returns the ID of the parent or the root ID if id is already the root.
+func (id ID) Parent() ID {
+ return parents[id]
+}
+
+// Tag converts id to an internal language Tag.
+func (id ID) Tag() language.Tag {
+ if int(id) >= len(coreTags) {
+ return specialTags[int(id)-len(coreTags)]
+ }
+ return coreTags[id].Tag()
+}
+
+var specialTags []language.Tag
+
+func init() {
+ tags := strings.Split(specialTagsStr, " ")
+ specialTags = make([]language.Tag, len(tags))
+ for i, t := range tags {
+ specialTags[i] = language.MustParse(t)
+ }
+}
diff --git a/vendor/golang.org/x/text/internal/language/compact/language.go b/vendor/golang.org/x/text/internal/language/compact/language.go
new file mode 100644
index 000000000..8c1b6666f
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact/language.go
@@ -0,0 +1,260 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go gen_index.go -output tables.go
+//go:generate go run gen_parents.go
+
+package compact
+
+// TODO: Remove above NOTE after:
+// - verifying that tables are dropped correctly (most notably matcher tables).
+
+import (
+ "strings"
+
+ "golang.org/x/text/internal/language"
+)
+
+// Tag represents a BCP 47 language tag. It is used to specify an instance of a
+// specific language or locale. All language tag values are guaranteed to be
+// well-formed.
+type Tag struct {
+ // NOTE: exported tags will become part of the public API.
+ language ID
+ locale ID
+ full fullTag // always a language.Tag for now.
+}
+
+const _und = 0
+
+type fullTag interface {
+ IsRoot() bool
+ Parent() language.Tag
+}
+
+// Make a compact Tag from a fully specified internal language Tag.
+func Make(t language.Tag) (tag Tag) {
+ if region := t.TypeForKey("rg"); len(region) == 6 && region[2:] == "zzzz" {
+ if r, err := language.ParseRegion(region[:2]); err == nil {
+ tFull := t
+ t, _ = t.SetTypeForKey("rg", "")
+ // TODO: should we not consider "va" for the language tag?
+ var exact1, exact2 bool
+ tag.language, exact1 = FromTag(t)
+ t.RegionID = r
+ tag.locale, exact2 = FromTag(t)
+ if !exact1 || !exact2 {
+ tag.full = tFull
+ }
+ return tag
+ }
+ }
+ lang, ok := FromTag(t)
+ tag.language = lang
+ tag.locale = lang
+ if !ok {
+ tag.full = t
+ }
+ return tag
+}
+
+// Tag returns an internal language Tag version of this tag.
+func (t Tag) Tag() language.Tag {
+ if t.full != nil {
+ return t.full.(language.Tag)
+ }
+ tag := t.language.Tag()
+ if t.language != t.locale {
+ loc := t.locale.Tag()
+ tag, _ = tag.SetTypeForKey("rg", strings.ToLower(loc.RegionID.String())+"zzzz")
+ }
+ return tag
+}
+
+// IsCompact reports whether this tag is fully defined in terms of ID.
+func (t *Tag) IsCompact() bool {
+ return t.full == nil
+}
+
+// MayHaveVariants reports whether a tag may have variants. If it returns false
+// it is guaranteed the tag does not have variants.
+func (t Tag) MayHaveVariants() bool {
+ return t.full != nil || int(t.language) >= len(coreTags)
+}
+
+// MayHaveExtensions reports whether a tag may have extensions. If it returns
+// false it is guaranteed the tag does not have them.
+func (t Tag) MayHaveExtensions() bool {
+ return t.full != nil ||
+ int(t.language) >= len(coreTags) ||
+ t.language != t.locale
+}
+
+// IsRoot returns true if t is equal to language "und".
+func (t Tag) IsRoot() bool {
+ if t.full != nil {
+ return t.full.IsRoot()
+ }
+ return t.language == _und
+}
+
+// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
+// specific language are substituted with fields from the parent language.
+// The parent for a language may change for newer versions of CLDR.
+func (t Tag) Parent() Tag {
+ if t.full != nil {
+ return Make(t.full.Parent())
+ }
+ if t.language != t.locale {
+ // Simulate stripping -u-rg-xxxxxx
+ return Tag{language: t.language, locale: t.language}
+ }
+ // TODO: use parent lookup table once cycle from internal package is
+ // removed. Probably by internalizing the table and declaring this fast
+ // enough.
+ // lang := compactID(internal.Parent(uint16(t.language)))
+ lang, _ := FromTag(t.language.Tag().Parent())
+ return Tag{language: lang, locale: lang}
+}
+
+// nextToken returns token t and the rest of the string.
+func nextToken(s string) (t, tail string) {
+ p := strings.Index(s[1:], "-")
+ if p == -1 {
+ return s[1:], ""
+ }
+ p++
+ return s[1:p], s[p:]
+}
+
+// LanguageID returns an index, where 0 <= index < NumCompactTags, for tags
+// for which data exists in the text repository.The index will change over time
+// and should not be stored in persistent storage. If t does not match a compact
+// index, exact will be false and the compact index will be returned for the
+// first match after repeatedly taking the Parent of t.
+func LanguageID(t Tag) (id ID, exact bool) {
+ return t.language, t.full == nil
+}
+
+// RegionalID returns the ID for the regional variant of this tag. This index is
+// used to indicate region-specific overrides, such as default currency, default
+// calendar and week data, default time cycle, and default measurement system
+// and unit preferences.
+//
+// For instance, the tag en-GB-u-rg-uszzzz specifies British English with US
+// settings for currency, number formatting, etc. The CompactIndex for this tag
+// will be that for en-GB, while the RegionalID will be the one corresponding to
+// en-US.
+func RegionalID(t Tag) (id ID, exact bool) {
+ return t.locale, t.full == nil
+}
+
+// LanguageTag returns t stripped of regional variant indicators.
+//
+// At the moment this means it is stripped of a regional and variant subtag "rg"
+// and "va" in the "u" extension.
+func (t Tag) LanguageTag() Tag {
+ if t.full == nil {
+ return Tag{language: t.language, locale: t.language}
+ }
+ tt := t.Tag()
+ tt.SetTypeForKey("rg", "")
+ tt.SetTypeForKey("va", "")
+ return Make(tt)
+}
+
+// RegionalTag returns the regional variant of the tag.
+//
+// At the moment this means that the region is set from the regional subtag
+// "rg" in the "u" extension.
+func (t Tag) RegionalTag() Tag {
+ rt := Tag{language: t.locale, locale: t.locale}
+ if t.full == nil {
+ return rt
+ }
+ b := language.Builder{}
+ tag := t.Tag()
+ // tag, _ = tag.SetTypeForKey("rg", "")
+ b.SetTag(t.locale.Tag())
+ if v := tag.Variants(); v != "" {
+ for _, v := range strings.Split(v, "-") {
+ b.AddVariant(v)
+ }
+ }
+ for _, e := range tag.Extensions() {
+ b.AddExt(e)
+ }
+ return t
+}
+
+// FromTag reports closest matching ID for an internal language Tag.
+func FromTag(t language.Tag) (id ID, exact bool) {
+ // TODO: perhaps give more frequent tags a lower index.
+ // TODO: we could make the indexes stable. This will excluded some
+ // possibilities for optimization, so don't do this quite yet.
+ exact = true
+
+ b, s, r := t.Raw()
+ if t.HasString() {
+ if t.IsPrivateUse() {
+ // We have no entries for user-defined tags.
+ return 0, false
+ }
+ hasExtra := false
+ if t.HasVariants() {
+ if t.HasExtensions() {
+ build := language.Builder{}
+ build.SetTag(language.Tag{LangID: b, ScriptID: s, RegionID: r})
+ build.AddVariant(t.Variants())
+ exact = false
+ t = build.Make()
+ }
+ hasExtra = true
+ } else if _, ok := t.Extension('u'); ok {
+ // TODO: va may mean something else. Consider not considering it.
+ // Strip all but the 'va' entry.
+ old := t
+ variant := t.TypeForKey("va")
+ t = language.Tag{LangID: b, ScriptID: s, RegionID: r}
+ if variant != "" {
+ t, _ = t.SetTypeForKey("va", variant)
+ hasExtra = true
+ }
+ exact = old == t
+ } else {
+ exact = false
+ }
+ if hasExtra {
+ // We have some variants.
+ for i, s := range specialTags {
+ if s == t {
+ return ID(i + len(coreTags)), exact
+ }
+ }
+ exact = false
+ }
+ }
+ if x, ok := getCoreIndex(t); ok {
+ return x, exact
+ }
+ exact = false
+ if r != 0 && s == 0 {
+ // Deal with cases where an extra script is inserted for the region.
+ t, _ := t.Maximize()
+ if x, ok := getCoreIndex(t); ok {
+ return x, exact
+ }
+ }
+ for t = t.Parent(); t != root; t = t.Parent() {
+ // No variants specified: just compare core components.
+ // The key has the form lllssrrr, where l, s, and r are nibbles for
+ // respectively the langID, scriptID, and regionID.
+ if x, ok := getCoreIndex(t); ok {
+ return x, exact
+ }
+ }
+ return 0, exact
+}
+
+var root = language.Tag{}
diff --git a/vendor/golang.org/x/text/internal/language/compact/parents.go b/vendor/golang.org/x/text/internal/language/compact/parents.go
new file mode 100644
index 000000000..8d810723c
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact/parents.go
@@ -0,0 +1,120 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package compact
+
+// parents maps a compact index of a tag to the compact index of the parent of
+// this tag.
+var parents = []ID{ // 775 elements
+ // Entry 0 - 3F
+ 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0004, 0x0000, 0x0006,
+ 0x0000, 0x0008, 0x0000, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0000,
+ 0x0000, 0x0028, 0x0000, 0x002a, 0x0000, 0x002c, 0x0000, 0x0000,
+ 0x002f, 0x002e, 0x002e, 0x0000, 0x0033, 0x0000, 0x0035, 0x0000,
+ 0x0037, 0x0000, 0x0039, 0x0000, 0x003b, 0x0000, 0x0000, 0x003e,
+ // Entry 40 - 7F
+ 0x0000, 0x0040, 0x0040, 0x0000, 0x0043, 0x0043, 0x0000, 0x0046,
+ 0x0000, 0x0048, 0x0000, 0x0000, 0x004b, 0x004a, 0x004a, 0x0000,
+ 0x004f, 0x004f, 0x004f, 0x004f, 0x0000, 0x0054, 0x0054, 0x0000,
+ 0x0057, 0x0000, 0x0059, 0x0000, 0x005b, 0x0000, 0x005d, 0x005d,
+ 0x0000, 0x0060, 0x0000, 0x0062, 0x0000, 0x0064, 0x0000, 0x0066,
+ 0x0066, 0x0000, 0x0069, 0x0000, 0x006b, 0x006b, 0x006b, 0x006b,
+ 0x006b, 0x006b, 0x006b, 0x0000, 0x0073, 0x0000, 0x0075, 0x0000,
+ 0x0077, 0x0000, 0x0000, 0x007a, 0x0000, 0x007c, 0x0000, 0x007e,
+ // Entry 80 - BF
+ 0x0000, 0x0080, 0x0080, 0x0000, 0x0083, 0x0083, 0x0000, 0x0086,
+ 0x0087, 0x0087, 0x0087, 0x0086, 0x0088, 0x0087, 0x0087, 0x0087,
+ 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088,
+ 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087, 0x0088, 0x0087,
+ 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0086,
+ // Entry C0 - FF
+ 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087,
+ 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087,
+ 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0086, 0x0087,
+ 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0000,
+ 0x00ef, 0x0000, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2,
+ 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f1, 0x00f1,
+ // Entry 100 - 13F
+ 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1,
+ 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x0000, 0x010e,
+ 0x0000, 0x0110, 0x0000, 0x0112, 0x0000, 0x0114, 0x0114, 0x0000,
+ 0x0117, 0x0117, 0x0117, 0x0117, 0x0000, 0x011c, 0x0000, 0x011e,
+ 0x0000, 0x0120, 0x0120, 0x0000, 0x0123, 0x0123, 0x0123, 0x0123,
+ 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123,
+ 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123,
+ 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123,
+ // Entry 140 - 17F
+ 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123,
+ 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123,
+ 0x0123, 0x0123, 0x0000, 0x0152, 0x0000, 0x0154, 0x0000, 0x0156,
+ 0x0000, 0x0158, 0x0000, 0x015a, 0x0000, 0x015c, 0x015c, 0x015c,
+ 0x0000, 0x0160, 0x0000, 0x0000, 0x0163, 0x0000, 0x0165, 0x0000,
+ 0x0167, 0x0167, 0x0167, 0x0000, 0x016b, 0x0000, 0x016d, 0x0000,
+ 0x016f, 0x0000, 0x0171, 0x0171, 0x0000, 0x0174, 0x0000, 0x0176,
+ 0x0000, 0x0178, 0x0000, 0x017a, 0x0000, 0x017c, 0x0000, 0x017e,
+ // Entry 180 - 1BF
+ 0x0000, 0x0000, 0x0000, 0x0182, 0x0000, 0x0184, 0x0184, 0x0184,
+ 0x0184, 0x0000, 0x0000, 0x0000, 0x018b, 0x0000, 0x0000, 0x018e,
+ 0x0000, 0x0000, 0x0191, 0x0000, 0x0000, 0x0000, 0x0195, 0x0000,
+ 0x0197, 0x0000, 0x0000, 0x019a, 0x0000, 0x0000, 0x019d, 0x0000,
+ 0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000,
+ 0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x0000, 0x01ad, 0x0000,
+ 0x01af, 0x0000, 0x01b1, 0x01b1, 0x0000, 0x01b4, 0x0000, 0x01b6,
+ 0x0000, 0x01b8, 0x0000, 0x01ba, 0x0000, 0x01bc, 0x0000, 0x0000,
+ // Entry 1C0 - 1FF
+ 0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x0000,
+ 0x01c7, 0x0000, 0x01c9, 0x0000, 0x01cb, 0x01cb, 0x01cb, 0x01cb,
+ 0x0000, 0x01d0, 0x0000, 0x01d2, 0x01d2, 0x0000, 0x01d5, 0x0000,
+ 0x01d7, 0x0000, 0x01d9, 0x0000, 0x01db, 0x0000, 0x01dd, 0x0000,
+ 0x01df, 0x01df, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6,
+ 0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x0000, 0x01ee,
+ 0x0000, 0x01f0, 0x0000, 0x0000, 0x01f3, 0x0000, 0x01f5, 0x01f5,
+ 0x01f5, 0x0000, 0x01f9, 0x0000, 0x01fb, 0x0000, 0x01fd, 0x0000,
+ // Entry 200 - 23F
+ 0x01ff, 0x0000, 0x0000, 0x0202, 0x0000, 0x0204, 0x0204, 0x0000,
+ 0x0207, 0x0000, 0x0209, 0x0209, 0x0000, 0x020c, 0x020c, 0x0000,
+ 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x0000,
+ 0x0217, 0x0000, 0x0219, 0x0000, 0x021b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0221, 0x0000, 0x0000, 0x0224, 0x0000, 0x0226,
+ 0x0226, 0x0000, 0x0229, 0x0000, 0x022b, 0x022b, 0x0000, 0x0000,
+ 0x022f, 0x022e, 0x022e, 0x0000, 0x0000, 0x0234, 0x0000, 0x0236,
+ 0x0000, 0x0238, 0x0000, 0x0244, 0x023a, 0x0244, 0x0244, 0x0244,
+ // Entry 240 - 27F
+ 0x0244, 0x0244, 0x0244, 0x0244, 0x023a, 0x0244, 0x0244, 0x0000,
+ 0x0247, 0x0247, 0x0247, 0x0000, 0x024b, 0x0000, 0x024d, 0x0000,
+ 0x024f, 0x024f, 0x0000, 0x0252, 0x0000, 0x0254, 0x0254, 0x0254,
+ 0x0254, 0x0254, 0x0254, 0x0000, 0x025b, 0x0000, 0x025d, 0x0000,
+ 0x025f, 0x0000, 0x0261, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000,
+ 0x0000, 0x0268, 0x0268, 0x0268, 0x0000, 0x026c, 0x0000, 0x026e,
+ 0x0000, 0x0270, 0x0000, 0x0000, 0x0000, 0x0274, 0x0273, 0x0273,
+ 0x0000, 0x0278, 0x0000, 0x027a, 0x0000, 0x027c, 0x0000, 0x0000,
+ // Entry 280 - 2BF
+ 0x0000, 0x0000, 0x0281, 0x0000, 0x0000, 0x0284, 0x0000, 0x0286,
+ 0x0286, 0x0286, 0x0286, 0x0000, 0x028b, 0x028b, 0x028b, 0x0000,
+ 0x028f, 0x028f, 0x028f, 0x028f, 0x028f, 0x0000, 0x0295, 0x0295,
+ 0x0295, 0x0295, 0x0000, 0x0000, 0x0000, 0x0000, 0x029d, 0x029d,
+ 0x029d, 0x0000, 0x02a1, 0x02a1, 0x02a1, 0x02a1, 0x0000, 0x0000,
+ 0x02a7, 0x02a7, 0x02a7, 0x02a7, 0x0000, 0x02ac, 0x0000, 0x02ae,
+ 0x02ae, 0x0000, 0x02b1, 0x0000, 0x02b3, 0x0000, 0x02b5, 0x02b5,
+ 0x0000, 0x0000, 0x02b9, 0x0000, 0x0000, 0x0000, 0x02bd, 0x0000,
+ // Entry 2C0 - 2FF
+ 0x02bf, 0x02bf, 0x0000, 0x0000, 0x02c3, 0x0000, 0x02c5, 0x0000,
+ 0x02c7, 0x0000, 0x02c9, 0x0000, 0x02cb, 0x0000, 0x02cd, 0x02cd,
+ 0x0000, 0x0000, 0x02d1, 0x0000, 0x02d3, 0x02d0, 0x02d0, 0x0000,
+ 0x0000, 0x02d8, 0x02d7, 0x02d7, 0x0000, 0x0000, 0x02dd, 0x0000,
+ 0x02df, 0x0000, 0x02e1, 0x0000, 0x0000, 0x02e4, 0x0000, 0x02e6,
+ 0x0000, 0x0000, 0x02e9, 0x0000, 0x02eb, 0x0000, 0x02ed, 0x0000,
+ 0x02ef, 0x02ef, 0x0000, 0x0000, 0x02f3, 0x02f2, 0x02f2, 0x0000,
+ 0x02f7, 0x0000, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x0000,
+ // Entry 300 - 33F
+ 0x02ff, 0x0300, 0x02ff, 0x0000, 0x0303, 0x0051, 0x00e6,
+} // Size: 1574 bytes
+
+// Total table size 1574 bytes (1KiB); checksum: 895AAF0B
diff --git a/vendor/golang.org/x/text/internal/language/compact/tables.go b/vendor/golang.org/x/text/internal/language/compact/tables.go
new file mode 100644
index 000000000..a09ed198a
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact/tables.go
@@ -0,0 +1,1015 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package compact
+
+import "golang.org/x/text/internal/language"
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "32"
+
+// NumCompactTags is the number of common tags. The maximum tag is
+// NumCompactTags-1.
+const NumCompactTags = 775
+const (
+ undIndex ID = 0
+ afIndex ID = 1
+ afNAIndex ID = 2
+ afZAIndex ID = 3
+ agqIndex ID = 4
+ agqCMIndex ID = 5
+ akIndex ID = 6
+ akGHIndex ID = 7
+ amIndex ID = 8
+ amETIndex ID = 9
+ arIndex ID = 10
+ ar001Index ID = 11
+ arAEIndex ID = 12
+ arBHIndex ID = 13
+ arDJIndex ID = 14
+ arDZIndex ID = 15
+ arEGIndex ID = 16
+ arEHIndex ID = 17
+ arERIndex ID = 18
+ arILIndex ID = 19
+ arIQIndex ID = 20
+ arJOIndex ID = 21
+ arKMIndex ID = 22
+ arKWIndex ID = 23
+ arLBIndex ID = 24
+ arLYIndex ID = 25
+ arMAIndex ID = 26
+ arMRIndex ID = 27
+ arOMIndex ID = 28
+ arPSIndex ID = 29
+ arQAIndex ID = 30
+ arSAIndex ID = 31
+ arSDIndex ID = 32
+ arSOIndex ID = 33
+ arSSIndex ID = 34
+ arSYIndex ID = 35
+ arTDIndex ID = 36
+ arTNIndex ID = 37
+ arYEIndex ID = 38
+ arsIndex ID = 39
+ asIndex ID = 40
+ asINIndex ID = 41
+ asaIndex ID = 42
+ asaTZIndex ID = 43
+ astIndex ID = 44
+ astESIndex ID = 45
+ azIndex ID = 46
+ azCyrlIndex ID = 47
+ azCyrlAZIndex ID = 48
+ azLatnIndex ID = 49
+ azLatnAZIndex ID = 50
+ basIndex ID = 51
+ basCMIndex ID = 52
+ beIndex ID = 53
+ beBYIndex ID = 54
+ bemIndex ID = 55
+ bemZMIndex ID = 56
+ bezIndex ID = 57
+ bezTZIndex ID = 58
+ bgIndex ID = 59
+ bgBGIndex ID = 60
+ bhIndex ID = 61
+ bmIndex ID = 62
+ bmMLIndex ID = 63
+ bnIndex ID = 64
+ bnBDIndex ID = 65
+ bnINIndex ID = 66
+ boIndex ID = 67
+ boCNIndex ID = 68
+ boINIndex ID = 69
+ brIndex ID = 70
+ brFRIndex ID = 71
+ brxIndex ID = 72
+ brxINIndex ID = 73
+ bsIndex ID = 74
+ bsCyrlIndex ID = 75
+ bsCyrlBAIndex ID = 76
+ bsLatnIndex ID = 77
+ bsLatnBAIndex ID = 78
+ caIndex ID = 79
+ caADIndex ID = 80
+ caESIndex ID = 81
+ caFRIndex ID = 82
+ caITIndex ID = 83
+ ccpIndex ID = 84
+ ccpBDIndex ID = 85
+ ccpINIndex ID = 86
+ ceIndex ID = 87
+ ceRUIndex ID = 88
+ cggIndex ID = 89
+ cggUGIndex ID = 90
+ chrIndex ID = 91
+ chrUSIndex ID = 92
+ ckbIndex ID = 93
+ ckbIQIndex ID = 94
+ ckbIRIndex ID = 95
+ csIndex ID = 96
+ csCZIndex ID = 97
+ cuIndex ID = 98
+ cuRUIndex ID = 99
+ cyIndex ID = 100
+ cyGBIndex ID = 101
+ daIndex ID = 102
+ daDKIndex ID = 103
+ daGLIndex ID = 104
+ davIndex ID = 105
+ davKEIndex ID = 106
+ deIndex ID = 107
+ deATIndex ID = 108
+ deBEIndex ID = 109
+ deCHIndex ID = 110
+ deDEIndex ID = 111
+ deITIndex ID = 112
+ deLIIndex ID = 113
+ deLUIndex ID = 114
+ djeIndex ID = 115
+ djeNEIndex ID = 116
+ dsbIndex ID = 117
+ dsbDEIndex ID = 118
+ duaIndex ID = 119
+ duaCMIndex ID = 120
+ dvIndex ID = 121
+ dyoIndex ID = 122
+ dyoSNIndex ID = 123
+ dzIndex ID = 124
+ dzBTIndex ID = 125
+ ebuIndex ID = 126
+ ebuKEIndex ID = 127
+ eeIndex ID = 128
+ eeGHIndex ID = 129
+ eeTGIndex ID = 130
+ elIndex ID = 131
+ elCYIndex ID = 132
+ elGRIndex ID = 133
+ enIndex ID = 134
+ en001Index ID = 135
+ en150Index ID = 136
+ enAGIndex ID = 137
+ enAIIndex ID = 138
+ enASIndex ID = 139
+ enATIndex ID = 140
+ enAUIndex ID = 141
+ enBBIndex ID = 142
+ enBEIndex ID = 143
+ enBIIndex ID = 144
+ enBMIndex ID = 145
+ enBSIndex ID = 146
+ enBWIndex ID = 147
+ enBZIndex ID = 148
+ enCAIndex ID = 149
+ enCCIndex ID = 150
+ enCHIndex ID = 151
+ enCKIndex ID = 152
+ enCMIndex ID = 153
+ enCXIndex ID = 154
+ enCYIndex ID = 155
+ enDEIndex ID = 156
+ enDGIndex ID = 157
+ enDKIndex ID = 158
+ enDMIndex ID = 159
+ enERIndex ID = 160
+ enFIIndex ID = 161
+ enFJIndex ID = 162
+ enFKIndex ID = 163
+ enFMIndex ID = 164
+ enGBIndex ID = 165
+ enGDIndex ID = 166
+ enGGIndex ID = 167
+ enGHIndex ID = 168
+ enGIIndex ID = 169
+ enGMIndex ID = 170
+ enGUIndex ID = 171
+ enGYIndex ID = 172
+ enHKIndex ID = 173
+ enIEIndex ID = 174
+ enILIndex ID = 175
+ enIMIndex ID = 176
+ enINIndex ID = 177
+ enIOIndex ID = 178
+ enJEIndex ID = 179
+ enJMIndex ID = 180
+ enKEIndex ID = 181
+ enKIIndex ID = 182
+ enKNIndex ID = 183
+ enKYIndex ID = 184
+ enLCIndex ID = 185
+ enLRIndex ID = 186
+ enLSIndex ID = 187
+ enMGIndex ID = 188
+ enMHIndex ID = 189
+ enMOIndex ID = 190
+ enMPIndex ID = 191
+ enMSIndex ID = 192
+ enMTIndex ID = 193
+ enMUIndex ID = 194
+ enMWIndex ID = 195
+ enMYIndex ID = 196
+ enNAIndex ID = 197
+ enNFIndex ID = 198
+ enNGIndex ID = 199
+ enNLIndex ID = 200
+ enNRIndex ID = 201
+ enNUIndex ID = 202
+ enNZIndex ID = 203
+ enPGIndex ID = 204
+ enPHIndex ID = 205
+ enPKIndex ID = 206
+ enPNIndex ID = 207
+ enPRIndex ID = 208
+ enPWIndex ID = 209
+ enRWIndex ID = 210
+ enSBIndex ID = 211
+ enSCIndex ID = 212
+ enSDIndex ID = 213
+ enSEIndex ID = 214
+ enSGIndex ID = 215
+ enSHIndex ID = 216
+ enSIIndex ID = 217
+ enSLIndex ID = 218
+ enSSIndex ID = 219
+ enSXIndex ID = 220
+ enSZIndex ID = 221
+ enTCIndex ID = 222
+ enTKIndex ID = 223
+ enTOIndex ID = 224
+ enTTIndex ID = 225
+ enTVIndex ID = 226
+ enTZIndex ID = 227
+ enUGIndex ID = 228
+ enUMIndex ID = 229
+ enUSIndex ID = 230
+ enVCIndex ID = 231
+ enVGIndex ID = 232
+ enVIIndex ID = 233
+ enVUIndex ID = 234
+ enWSIndex ID = 235
+ enZAIndex ID = 236
+ enZMIndex ID = 237
+ enZWIndex ID = 238
+ eoIndex ID = 239
+ eo001Index ID = 240
+ esIndex ID = 241
+ es419Index ID = 242
+ esARIndex ID = 243
+ esBOIndex ID = 244
+ esBRIndex ID = 245
+ esBZIndex ID = 246
+ esCLIndex ID = 247
+ esCOIndex ID = 248
+ esCRIndex ID = 249
+ esCUIndex ID = 250
+ esDOIndex ID = 251
+ esEAIndex ID = 252
+ esECIndex ID = 253
+ esESIndex ID = 254
+ esGQIndex ID = 255
+ esGTIndex ID = 256
+ esHNIndex ID = 257
+ esICIndex ID = 258
+ esMXIndex ID = 259
+ esNIIndex ID = 260
+ esPAIndex ID = 261
+ esPEIndex ID = 262
+ esPHIndex ID = 263
+ esPRIndex ID = 264
+ esPYIndex ID = 265
+ esSVIndex ID = 266
+ esUSIndex ID = 267
+ esUYIndex ID = 268
+ esVEIndex ID = 269
+ etIndex ID = 270
+ etEEIndex ID = 271
+ euIndex ID = 272
+ euESIndex ID = 273
+ ewoIndex ID = 274
+ ewoCMIndex ID = 275
+ faIndex ID = 276
+ faAFIndex ID = 277
+ faIRIndex ID = 278
+ ffIndex ID = 279
+ ffCMIndex ID = 280
+ ffGNIndex ID = 281
+ ffMRIndex ID = 282
+ ffSNIndex ID = 283
+ fiIndex ID = 284
+ fiFIIndex ID = 285
+ filIndex ID = 286
+ filPHIndex ID = 287
+ foIndex ID = 288
+ foDKIndex ID = 289
+ foFOIndex ID = 290
+ frIndex ID = 291
+ frBEIndex ID = 292
+ frBFIndex ID = 293
+ frBIIndex ID = 294
+ frBJIndex ID = 295
+ frBLIndex ID = 296
+ frCAIndex ID = 297
+ frCDIndex ID = 298
+ frCFIndex ID = 299
+ frCGIndex ID = 300
+ frCHIndex ID = 301
+ frCIIndex ID = 302
+ frCMIndex ID = 303
+ frDJIndex ID = 304
+ frDZIndex ID = 305
+ frFRIndex ID = 306
+ frGAIndex ID = 307
+ frGFIndex ID = 308
+ frGNIndex ID = 309
+ frGPIndex ID = 310
+ frGQIndex ID = 311
+ frHTIndex ID = 312
+ frKMIndex ID = 313
+ frLUIndex ID = 314
+ frMAIndex ID = 315
+ frMCIndex ID = 316
+ frMFIndex ID = 317
+ frMGIndex ID = 318
+ frMLIndex ID = 319
+ frMQIndex ID = 320
+ frMRIndex ID = 321
+ frMUIndex ID = 322
+ frNCIndex ID = 323
+ frNEIndex ID = 324
+ frPFIndex ID = 325
+ frPMIndex ID = 326
+ frREIndex ID = 327
+ frRWIndex ID = 328
+ frSCIndex ID = 329
+ frSNIndex ID = 330
+ frSYIndex ID = 331
+ frTDIndex ID = 332
+ frTGIndex ID = 333
+ frTNIndex ID = 334
+ frVUIndex ID = 335
+ frWFIndex ID = 336
+ frYTIndex ID = 337
+ furIndex ID = 338
+ furITIndex ID = 339
+ fyIndex ID = 340
+ fyNLIndex ID = 341
+ gaIndex ID = 342
+ gaIEIndex ID = 343
+ gdIndex ID = 344
+ gdGBIndex ID = 345
+ glIndex ID = 346
+ glESIndex ID = 347
+ gswIndex ID = 348
+ gswCHIndex ID = 349
+ gswFRIndex ID = 350
+ gswLIIndex ID = 351
+ guIndex ID = 352
+ guINIndex ID = 353
+ guwIndex ID = 354
+ guzIndex ID = 355
+ guzKEIndex ID = 356
+ gvIndex ID = 357
+ gvIMIndex ID = 358
+ haIndex ID = 359
+ haGHIndex ID = 360
+ haNEIndex ID = 361
+ haNGIndex ID = 362
+ hawIndex ID = 363
+ hawUSIndex ID = 364
+ heIndex ID = 365
+ heILIndex ID = 366
+ hiIndex ID = 367
+ hiINIndex ID = 368
+ hrIndex ID = 369
+ hrBAIndex ID = 370
+ hrHRIndex ID = 371
+ hsbIndex ID = 372
+ hsbDEIndex ID = 373
+ huIndex ID = 374
+ huHUIndex ID = 375
+ hyIndex ID = 376
+ hyAMIndex ID = 377
+ idIndex ID = 378
+ idIDIndex ID = 379
+ igIndex ID = 380
+ igNGIndex ID = 381
+ iiIndex ID = 382
+ iiCNIndex ID = 383
+ inIndex ID = 384
+ ioIndex ID = 385
+ isIndex ID = 386
+ isISIndex ID = 387
+ itIndex ID = 388
+ itCHIndex ID = 389
+ itITIndex ID = 390
+ itSMIndex ID = 391
+ itVAIndex ID = 392
+ iuIndex ID = 393
+ iwIndex ID = 394
+ jaIndex ID = 395
+ jaJPIndex ID = 396
+ jboIndex ID = 397
+ jgoIndex ID = 398
+ jgoCMIndex ID = 399
+ jiIndex ID = 400
+ jmcIndex ID = 401
+ jmcTZIndex ID = 402
+ jvIndex ID = 403
+ jwIndex ID = 404
+ kaIndex ID = 405
+ kaGEIndex ID = 406
+ kabIndex ID = 407
+ kabDZIndex ID = 408
+ kajIndex ID = 409
+ kamIndex ID = 410
+ kamKEIndex ID = 411
+ kcgIndex ID = 412
+ kdeIndex ID = 413
+ kdeTZIndex ID = 414
+ keaIndex ID = 415
+ keaCVIndex ID = 416
+ khqIndex ID = 417
+ khqMLIndex ID = 418
+ kiIndex ID = 419
+ kiKEIndex ID = 420
+ kkIndex ID = 421
+ kkKZIndex ID = 422
+ kkjIndex ID = 423
+ kkjCMIndex ID = 424
+ klIndex ID = 425
+ klGLIndex ID = 426
+ klnIndex ID = 427
+ klnKEIndex ID = 428
+ kmIndex ID = 429
+ kmKHIndex ID = 430
+ knIndex ID = 431
+ knINIndex ID = 432
+ koIndex ID = 433
+ koKPIndex ID = 434
+ koKRIndex ID = 435
+ kokIndex ID = 436
+ kokINIndex ID = 437
+ ksIndex ID = 438
+ ksINIndex ID = 439
+ ksbIndex ID = 440
+ ksbTZIndex ID = 441
+ ksfIndex ID = 442
+ ksfCMIndex ID = 443
+ kshIndex ID = 444
+ kshDEIndex ID = 445
+ kuIndex ID = 446
+ kwIndex ID = 447
+ kwGBIndex ID = 448
+ kyIndex ID = 449
+ kyKGIndex ID = 450
+ lagIndex ID = 451
+ lagTZIndex ID = 452
+ lbIndex ID = 453
+ lbLUIndex ID = 454
+ lgIndex ID = 455
+ lgUGIndex ID = 456
+ lktIndex ID = 457
+ lktUSIndex ID = 458
+ lnIndex ID = 459
+ lnAOIndex ID = 460
+ lnCDIndex ID = 461
+ lnCFIndex ID = 462
+ lnCGIndex ID = 463
+ loIndex ID = 464
+ loLAIndex ID = 465
+ lrcIndex ID = 466
+ lrcIQIndex ID = 467
+ lrcIRIndex ID = 468
+ ltIndex ID = 469
+ ltLTIndex ID = 470
+ luIndex ID = 471
+ luCDIndex ID = 472
+ luoIndex ID = 473
+ luoKEIndex ID = 474
+ luyIndex ID = 475
+ luyKEIndex ID = 476
+ lvIndex ID = 477
+ lvLVIndex ID = 478
+ masIndex ID = 479
+ masKEIndex ID = 480
+ masTZIndex ID = 481
+ merIndex ID = 482
+ merKEIndex ID = 483
+ mfeIndex ID = 484
+ mfeMUIndex ID = 485
+ mgIndex ID = 486
+ mgMGIndex ID = 487
+ mghIndex ID = 488
+ mghMZIndex ID = 489
+ mgoIndex ID = 490
+ mgoCMIndex ID = 491
+ mkIndex ID = 492
+ mkMKIndex ID = 493
+ mlIndex ID = 494
+ mlINIndex ID = 495
+ mnIndex ID = 496
+ mnMNIndex ID = 497
+ moIndex ID = 498
+ mrIndex ID = 499
+ mrINIndex ID = 500
+ msIndex ID = 501
+ msBNIndex ID = 502
+ msMYIndex ID = 503
+ msSGIndex ID = 504
+ mtIndex ID = 505
+ mtMTIndex ID = 506
+ muaIndex ID = 507
+ muaCMIndex ID = 508
+ myIndex ID = 509
+ myMMIndex ID = 510
+ mznIndex ID = 511
+ mznIRIndex ID = 512
+ nahIndex ID = 513
+ naqIndex ID = 514
+ naqNAIndex ID = 515
+ nbIndex ID = 516
+ nbNOIndex ID = 517
+ nbSJIndex ID = 518
+ ndIndex ID = 519
+ ndZWIndex ID = 520
+ ndsIndex ID = 521
+ ndsDEIndex ID = 522
+ ndsNLIndex ID = 523
+ neIndex ID = 524
+ neINIndex ID = 525
+ neNPIndex ID = 526
+ nlIndex ID = 527
+ nlAWIndex ID = 528
+ nlBEIndex ID = 529
+ nlBQIndex ID = 530
+ nlCWIndex ID = 531
+ nlNLIndex ID = 532
+ nlSRIndex ID = 533
+ nlSXIndex ID = 534
+ nmgIndex ID = 535
+ nmgCMIndex ID = 536
+ nnIndex ID = 537
+ nnNOIndex ID = 538
+ nnhIndex ID = 539
+ nnhCMIndex ID = 540
+ noIndex ID = 541
+ nqoIndex ID = 542
+ nrIndex ID = 543
+ nsoIndex ID = 544
+ nusIndex ID = 545
+ nusSSIndex ID = 546
+ nyIndex ID = 547
+ nynIndex ID = 548
+ nynUGIndex ID = 549
+ omIndex ID = 550
+ omETIndex ID = 551
+ omKEIndex ID = 552
+ orIndex ID = 553
+ orINIndex ID = 554
+ osIndex ID = 555
+ osGEIndex ID = 556
+ osRUIndex ID = 557
+ paIndex ID = 558
+ paArabIndex ID = 559
+ paArabPKIndex ID = 560
+ paGuruIndex ID = 561
+ paGuruINIndex ID = 562
+ papIndex ID = 563
+ plIndex ID = 564
+ plPLIndex ID = 565
+ prgIndex ID = 566
+ prg001Index ID = 567
+ psIndex ID = 568
+ psAFIndex ID = 569
+ ptIndex ID = 570
+ ptAOIndex ID = 571
+ ptBRIndex ID = 572
+ ptCHIndex ID = 573
+ ptCVIndex ID = 574
+ ptGQIndex ID = 575
+ ptGWIndex ID = 576
+ ptLUIndex ID = 577
+ ptMOIndex ID = 578
+ ptMZIndex ID = 579
+ ptPTIndex ID = 580
+ ptSTIndex ID = 581
+ ptTLIndex ID = 582
+ quIndex ID = 583
+ quBOIndex ID = 584
+ quECIndex ID = 585
+ quPEIndex ID = 586
+ rmIndex ID = 587
+ rmCHIndex ID = 588
+ rnIndex ID = 589
+ rnBIIndex ID = 590
+ roIndex ID = 591
+ roMDIndex ID = 592
+ roROIndex ID = 593
+ rofIndex ID = 594
+ rofTZIndex ID = 595
+ ruIndex ID = 596
+ ruBYIndex ID = 597
+ ruKGIndex ID = 598
+ ruKZIndex ID = 599
+ ruMDIndex ID = 600
+ ruRUIndex ID = 601
+ ruUAIndex ID = 602
+ rwIndex ID = 603
+ rwRWIndex ID = 604
+ rwkIndex ID = 605
+ rwkTZIndex ID = 606
+ sahIndex ID = 607
+ sahRUIndex ID = 608
+ saqIndex ID = 609
+ saqKEIndex ID = 610
+ sbpIndex ID = 611
+ sbpTZIndex ID = 612
+ sdIndex ID = 613
+ sdPKIndex ID = 614
+ sdhIndex ID = 615
+ seIndex ID = 616
+ seFIIndex ID = 617
+ seNOIndex ID = 618
+ seSEIndex ID = 619
+ sehIndex ID = 620
+ sehMZIndex ID = 621
+ sesIndex ID = 622
+ sesMLIndex ID = 623
+ sgIndex ID = 624
+ sgCFIndex ID = 625
+ shIndex ID = 626
+ shiIndex ID = 627
+ shiLatnIndex ID = 628
+ shiLatnMAIndex ID = 629
+ shiTfngIndex ID = 630
+ shiTfngMAIndex ID = 631
+ siIndex ID = 632
+ siLKIndex ID = 633
+ skIndex ID = 634
+ skSKIndex ID = 635
+ slIndex ID = 636
+ slSIIndex ID = 637
+ smaIndex ID = 638
+ smiIndex ID = 639
+ smjIndex ID = 640
+ smnIndex ID = 641
+ smnFIIndex ID = 642
+ smsIndex ID = 643
+ snIndex ID = 644
+ snZWIndex ID = 645
+ soIndex ID = 646
+ soDJIndex ID = 647
+ soETIndex ID = 648
+ soKEIndex ID = 649
+ soSOIndex ID = 650
+ sqIndex ID = 651
+ sqALIndex ID = 652
+ sqMKIndex ID = 653
+ sqXKIndex ID = 654
+ srIndex ID = 655
+ srCyrlIndex ID = 656
+ srCyrlBAIndex ID = 657
+ srCyrlMEIndex ID = 658
+ srCyrlRSIndex ID = 659
+ srCyrlXKIndex ID = 660
+ srLatnIndex ID = 661
+ srLatnBAIndex ID = 662
+ srLatnMEIndex ID = 663
+ srLatnRSIndex ID = 664
+ srLatnXKIndex ID = 665
+ ssIndex ID = 666
+ ssyIndex ID = 667
+ stIndex ID = 668
+ svIndex ID = 669
+ svAXIndex ID = 670
+ svFIIndex ID = 671
+ svSEIndex ID = 672
+ swIndex ID = 673
+ swCDIndex ID = 674
+ swKEIndex ID = 675
+ swTZIndex ID = 676
+ swUGIndex ID = 677
+ syrIndex ID = 678
+ taIndex ID = 679
+ taINIndex ID = 680
+ taLKIndex ID = 681
+ taMYIndex ID = 682
+ taSGIndex ID = 683
+ teIndex ID = 684
+ teINIndex ID = 685
+ teoIndex ID = 686
+ teoKEIndex ID = 687
+ teoUGIndex ID = 688
+ tgIndex ID = 689
+ tgTJIndex ID = 690
+ thIndex ID = 691
+ thTHIndex ID = 692
+ tiIndex ID = 693
+ tiERIndex ID = 694
+ tiETIndex ID = 695
+ tigIndex ID = 696
+ tkIndex ID = 697
+ tkTMIndex ID = 698
+ tlIndex ID = 699
+ tnIndex ID = 700
+ toIndex ID = 701
+ toTOIndex ID = 702
+ trIndex ID = 703
+ trCYIndex ID = 704
+ trTRIndex ID = 705
+ tsIndex ID = 706
+ ttIndex ID = 707
+ ttRUIndex ID = 708
+ twqIndex ID = 709
+ twqNEIndex ID = 710
+ tzmIndex ID = 711
+ tzmMAIndex ID = 712
+ ugIndex ID = 713
+ ugCNIndex ID = 714
+ ukIndex ID = 715
+ ukUAIndex ID = 716
+ urIndex ID = 717
+ urINIndex ID = 718
+ urPKIndex ID = 719
+ uzIndex ID = 720
+ uzArabIndex ID = 721
+ uzArabAFIndex ID = 722
+ uzCyrlIndex ID = 723
+ uzCyrlUZIndex ID = 724
+ uzLatnIndex ID = 725
+ uzLatnUZIndex ID = 726
+ vaiIndex ID = 727
+ vaiLatnIndex ID = 728
+ vaiLatnLRIndex ID = 729
+ vaiVaiiIndex ID = 730
+ vaiVaiiLRIndex ID = 731
+ veIndex ID = 732
+ viIndex ID = 733
+ viVNIndex ID = 734
+ voIndex ID = 735
+ vo001Index ID = 736
+ vunIndex ID = 737
+ vunTZIndex ID = 738
+ waIndex ID = 739
+ waeIndex ID = 740
+ waeCHIndex ID = 741
+ woIndex ID = 742
+ woSNIndex ID = 743
+ xhIndex ID = 744
+ xogIndex ID = 745
+ xogUGIndex ID = 746
+ yavIndex ID = 747
+ yavCMIndex ID = 748
+ yiIndex ID = 749
+ yi001Index ID = 750
+ yoIndex ID = 751
+ yoBJIndex ID = 752
+ yoNGIndex ID = 753
+ yueIndex ID = 754
+ yueHansIndex ID = 755
+ yueHansCNIndex ID = 756
+ yueHantIndex ID = 757
+ yueHantHKIndex ID = 758
+ zghIndex ID = 759
+ zghMAIndex ID = 760
+ zhIndex ID = 761
+ zhHansIndex ID = 762
+ zhHansCNIndex ID = 763
+ zhHansHKIndex ID = 764
+ zhHansMOIndex ID = 765
+ zhHansSGIndex ID = 766
+ zhHantIndex ID = 767
+ zhHantHKIndex ID = 768
+ zhHantMOIndex ID = 769
+ zhHantTWIndex ID = 770
+ zuIndex ID = 771
+ zuZAIndex ID = 772
+ caESvalenciaIndex ID = 773
+ enUSuvaposixIndex ID = 774
+)
+
+var coreTags = []language.CompactCoreInfo{ // 773 elements
+ // Entry 0 - 1F
+ 0x00000000, 0x01600000, 0x016000d3, 0x01600162,
+ 0x01c00000, 0x01c00052, 0x02100000, 0x02100081,
+ 0x02700000, 0x02700070, 0x03a00000, 0x03a00001,
+ 0x03a00023, 0x03a00039, 0x03a00063, 0x03a00068,
+ 0x03a0006c, 0x03a0006d, 0x03a0006e, 0x03a00098,
+ 0x03a0009c, 0x03a000a2, 0x03a000a9, 0x03a000ad,
+ 0x03a000b1, 0x03a000ba, 0x03a000bb, 0x03a000ca,
+ 0x03a000e2, 0x03a000ee, 0x03a000f4, 0x03a00109,
+ // Entry 20 - 3F
+ 0x03a0010c, 0x03a00116, 0x03a00118, 0x03a0011d,
+ 0x03a00121, 0x03a00129, 0x03a0015f, 0x04000000,
+ 0x04300000, 0x0430009a, 0x04400000, 0x04400130,
+ 0x04800000, 0x0480006f, 0x05800000, 0x05820000,
+ 0x05820032, 0x0585b000, 0x0585b032, 0x05e00000,
+ 0x05e00052, 0x07100000, 0x07100047, 0x07500000,
+ 0x07500163, 0x07900000, 0x07900130, 0x07e00000,
+ 0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c4,
+ // Entry 40 - 5F
+ 0x0a500000, 0x0a500035, 0x0a50009a, 0x0a900000,
+ 0x0a900053, 0x0a90009a, 0x0b200000, 0x0b200079,
+ 0x0b500000, 0x0b50009a, 0x0b700000, 0x0b720000,
+ 0x0b720033, 0x0b75b000, 0x0b75b033, 0x0d700000,
+ 0x0d700022, 0x0d70006f, 0x0d700079, 0x0d70009f,
+ 0x0db00000, 0x0db00035, 0x0db0009a, 0x0dc00000,
+ 0x0dc00107, 0x0df00000, 0x0df00132, 0x0e500000,
+ 0x0e500136, 0x0e900000, 0x0e90009c, 0x0e90009d,
+ // Entry 60 - 7F
+ 0x0fa00000, 0x0fa0005f, 0x0fe00000, 0x0fe00107,
+ 0x10000000, 0x1000007c, 0x10100000, 0x10100064,
+ 0x10100083, 0x10800000, 0x108000a5, 0x10d00000,
+ 0x10d0002e, 0x10d00036, 0x10d0004e, 0x10d00061,
+ 0x10d0009f, 0x10d000b3, 0x10d000b8, 0x11700000,
+ 0x117000d5, 0x11f00000, 0x11f00061, 0x12400000,
+ 0x12400052, 0x12800000, 0x12b00000, 0x12b00115,
+ 0x12d00000, 0x12d00043, 0x12f00000, 0x12f000a5,
+ // Entry 80 - 9F
+ 0x13000000, 0x13000081, 0x13000123, 0x13600000,
+ 0x1360005e, 0x13600088, 0x13900000, 0x13900001,
+ 0x1390001a, 0x13900025, 0x13900026, 0x1390002d,
+ 0x1390002e, 0x1390002f, 0x13900034, 0x13900036,
+ 0x1390003a, 0x1390003d, 0x13900042, 0x13900046,
+ 0x13900048, 0x13900049, 0x1390004a, 0x1390004e,
+ 0x13900050, 0x13900052, 0x1390005d, 0x1390005e,
+ 0x13900061, 0x13900062, 0x13900064, 0x13900065,
+ // Entry A0 - BF
+ 0x1390006e, 0x13900073, 0x13900074, 0x13900075,
+ 0x13900076, 0x1390007c, 0x1390007d, 0x13900080,
+ 0x13900081, 0x13900082, 0x13900084, 0x1390008b,
+ 0x1390008d, 0x1390008e, 0x13900097, 0x13900098,
+ 0x13900099, 0x1390009a, 0x1390009b, 0x139000a0,
+ 0x139000a1, 0x139000a5, 0x139000a8, 0x139000aa,
+ 0x139000ae, 0x139000b2, 0x139000b5, 0x139000b6,
+ 0x139000c0, 0x139000c1, 0x139000c7, 0x139000c8,
+ // Entry C0 - DF
+ 0x139000cb, 0x139000cc, 0x139000cd, 0x139000cf,
+ 0x139000d1, 0x139000d3, 0x139000d6, 0x139000d7,
+ 0x139000da, 0x139000de, 0x139000e0, 0x139000e1,
+ 0x139000e7, 0x139000e8, 0x139000e9, 0x139000ec,
+ 0x139000ed, 0x139000f1, 0x13900108, 0x1390010a,
+ 0x1390010b, 0x1390010c, 0x1390010d, 0x1390010e,
+ 0x1390010f, 0x13900110, 0x13900113, 0x13900118,
+ 0x1390011c, 0x1390011e, 0x13900120, 0x13900126,
+ // Entry E0 - FF
+ 0x1390012a, 0x1390012d, 0x1390012e, 0x13900130,
+ 0x13900132, 0x13900134, 0x13900136, 0x1390013a,
+ 0x1390013d, 0x1390013e, 0x13900140, 0x13900143,
+ 0x13900162, 0x13900163, 0x13900165, 0x13c00000,
+ 0x13c00001, 0x13e00000, 0x13e0001f, 0x13e0002c,
+ 0x13e0003f, 0x13e00041, 0x13e00048, 0x13e00051,
+ 0x13e00054, 0x13e00057, 0x13e0005a, 0x13e00066,
+ 0x13e00069, 0x13e0006a, 0x13e0006f, 0x13e00087,
+ // Entry 100 - 11F
+ 0x13e0008a, 0x13e00090, 0x13e00095, 0x13e000d0,
+ 0x13e000d9, 0x13e000e3, 0x13e000e5, 0x13e000e8,
+ 0x13e000ed, 0x13e000f2, 0x13e0011b, 0x13e00136,
+ 0x13e00137, 0x13e0013c, 0x14000000, 0x1400006b,
+ 0x14500000, 0x1450006f, 0x14600000, 0x14600052,
+ 0x14800000, 0x14800024, 0x1480009d, 0x14e00000,
+ 0x14e00052, 0x14e00085, 0x14e000ca, 0x14e00115,
+ 0x15100000, 0x15100073, 0x15300000, 0x153000e8,
+ // Entry 120 - 13F
+ 0x15800000, 0x15800064, 0x15800077, 0x15e00000,
+ 0x15e00036, 0x15e00037, 0x15e0003a, 0x15e0003b,
+ 0x15e0003c, 0x15e00049, 0x15e0004b, 0x15e0004c,
+ 0x15e0004d, 0x15e0004e, 0x15e0004f, 0x15e00052,
+ 0x15e00063, 0x15e00068, 0x15e00079, 0x15e0007b,
+ 0x15e0007f, 0x15e00085, 0x15e00086, 0x15e00087,
+ 0x15e00092, 0x15e000a9, 0x15e000b8, 0x15e000bb,
+ 0x15e000bc, 0x15e000bf, 0x15e000c0, 0x15e000c4,
+ // Entry 140 - 15F
+ 0x15e000c9, 0x15e000ca, 0x15e000cd, 0x15e000d4,
+ 0x15e000d5, 0x15e000e6, 0x15e000eb, 0x15e00103,
+ 0x15e00108, 0x15e0010b, 0x15e00115, 0x15e0011d,
+ 0x15e00121, 0x15e00123, 0x15e00129, 0x15e00140,
+ 0x15e00141, 0x15e00160, 0x16900000, 0x1690009f,
+ 0x16d00000, 0x16d000da, 0x16e00000, 0x16e00097,
+ 0x17e00000, 0x17e0007c, 0x19000000, 0x1900006f,
+ 0x1a300000, 0x1a30004e, 0x1a300079, 0x1a3000b3,
+ // Entry 160 - 17F
+ 0x1a400000, 0x1a40009a, 0x1a900000, 0x1ab00000,
+ 0x1ab000a5, 0x1ac00000, 0x1ac00099, 0x1b400000,
+ 0x1b400081, 0x1b4000d5, 0x1b4000d7, 0x1b800000,
+ 0x1b800136, 0x1bc00000, 0x1bc00098, 0x1be00000,
+ 0x1be0009a, 0x1d100000, 0x1d100033, 0x1d100091,
+ 0x1d200000, 0x1d200061, 0x1d500000, 0x1d500093,
+ 0x1d700000, 0x1d700028, 0x1e100000, 0x1e100096,
+ 0x1e700000, 0x1e7000d7, 0x1ea00000, 0x1ea00053,
+ // Entry 180 - 19F
+ 0x1f300000, 0x1f500000, 0x1f800000, 0x1f80009e,
+ 0x1f900000, 0x1f90004e, 0x1f90009f, 0x1f900114,
+ 0x1f900139, 0x1fa00000, 0x1fb00000, 0x20000000,
+ 0x200000a3, 0x20300000, 0x20700000, 0x20700052,
+ 0x20800000, 0x20a00000, 0x20a00130, 0x20e00000,
+ 0x20f00000, 0x21000000, 0x2100007e, 0x21200000,
+ 0x21200068, 0x21600000, 0x21700000, 0x217000a5,
+ 0x21f00000, 0x22300000, 0x22300130, 0x22700000,
+ // Entry 1A0 - 1BF
+ 0x2270005b, 0x23400000, 0x234000c4, 0x23900000,
+ 0x239000a5, 0x24200000, 0x242000af, 0x24400000,
+ 0x24400052, 0x24500000, 0x24500083, 0x24600000,
+ 0x246000a5, 0x24a00000, 0x24a000a7, 0x25100000,
+ 0x2510009a, 0x25400000, 0x254000ab, 0x254000ac,
+ 0x25600000, 0x2560009a, 0x26a00000, 0x26a0009a,
+ 0x26b00000, 0x26b00130, 0x26d00000, 0x26d00052,
+ 0x26e00000, 0x26e00061, 0x27400000, 0x28100000,
+ // Entry 1C0 - 1DF
+ 0x2810007c, 0x28a00000, 0x28a000a6, 0x29100000,
+ 0x29100130, 0x29500000, 0x295000b8, 0x2a300000,
+ 0x2a300132, 0x2af00000, 0x2af00136, 0x2b500000,
+ 0x2b50002a, 0x2b50004b, 0x2b50004c, 0x2b50004d,
+ 0x2b800000, 0x2b8000b0, 0x2bf00000, 0x2bf0009c,
+ 0x2bf0009d, 0x2c000000, 0x2c0000b7, 0x2c200000,
+ 0x2c20004b, 0x2c400000, 0x2c4000a5, 0x2c500000,
+ 0x2c5000a5, 0x2c700000, 0x2c7000b9, 0x2d100000,
+ // Entry 1E0 - 1FF
+ 0x2d1000a5, 0x2d100130, 0x2e900000, 0x2e9000a5,
+ 0x2ed00000, 0x2ed000cd, 0x2f100000, 0x2f1000c0,
+ 0x2f200000, 0x2f2000d2, 0x2f400000, 0x2f400052,
+ 0x2ff00000, 0x2ff000c3, 0x30400000, 0x3040009a,
+ 0x30b00000, 0x30b000c6, 0x31000000, 0x31b00000,
+ 0x31b0009a, 0x31f00000, 0x31f0003e, 0x31f000d1,
+ 0x31f0010e, 0x32000000, 0x320000cc, 0x32500000,
+ 0x32500052, 0x33100000, 0x331000c5, 0x33a00000,
+ // Entry 200 - 21F
+ 0x33a0009d, 0x34100000, 0x34500000, 0x345000d3,
+ 0x34700000, 0x347000db, 0x34700111, 0x34e00000,
+ 0x34e00165, 0x35000000, 0x35000061, 0x350000da,
+ 0x35100000, 0x3510009a, 0x351000dc, 0x36700000,
+ 0x36700030, 0x36700036, 0x36700040, 0x3670005c,
+ 0x367000da, 0x36700117, 0x3670011c, 0x36800000,
+ 0x36800052, 0x36a00000, 0x36a000db, 0x36c00000,
+ 0x36c00052, 0x36f00000, 0x37500000, 0x37600000,
+ // Entry 220 - 23F
+ 0x37a00000, 0x38000000, 0x38000118, 0x38700000,
+ 0x38900000, 0x38900132, 0x39000000, 0x39000070,
+ 0x390000a5, 0x39500000, 0x3950009a, 0x39800000,
+ 0x3980007e, 0x39800107, 0x39d00000, 0x39d05000,
+ 0x39d050e9, 0x39d36000, 0x39d3609a, 0x3a100000,
+ 0x3b300000, 0x3b3000ea, 0x3bd00000, 0x3bd00001,
+ 0x3be00000, 0x3be00024, 0x3c000000, 0x3c00002a,
+ 0x3c000041, 0x3c00004e, 0x3c00005b, 0x3c000087,
+ // Entry 240 - 25F
+ 0x3c00008c, 0x3c0000b8, 0x3c0000c7, 0x3c0000d2,
+ 0x3c0000ef, 0x3c000119, 0x3c000127, 0x3c400000,
+ 0x3c40003f, 0x3c40006a, 0x3c4000e5, 0x3d400000,
+ 0x3d40004e, 0x3d900000, 0x3d90003a, 0x3dc00000,
+ 0x3dc000bd, 0x3dc00105, 0x3de00000, 0x3de00130,
+ 0x3e200000, 0x3e200047, 0x3e2000a6, 0x3e2000af,
+ 0x3e2000bd, 0x3e200107, 0x3e200131, 0x3e500000,
+ 0x3e500108, 0x3e600000, 0x3e600130, 0x3eb00000,
+ // Entry 260 - 27F
+ 0x3eb00107, 0x3ec00000, 0x3ec000a5, 0x3f300000,
+ 0x3f300130, 0x3fa00000, 0x3fa000e9, 0x3fc00000,
+ 0x3fd00000, 0x3fd00073, 0x3fd000db, 0x3fd0010d,
+ 0x3ff00000, 0x3ff000d2, 0x40100000, 0x401000c4,
+ 0x40200000, 0x4020004c, 0x40700000, 0x40800000,
+ 0x4085b000, 0x4085b0bb, 0x408eb000, 0x408eb0bb,
+ 0x40c00000, 0x40c000b4, 0x41200000, 0x41200112,
+ 0x41600000, 0x41600110, 0x41c00000, 0x41d00000,
+ // Entry 280 - 29F
+ 0x41e00000, 0x41f00000, 0x41f00073, 0x42200000,
+ 0x42300000, 0x42300165, 0x42900000, 0x42900063,
+ 0x42900070, 0x429000a5, 0x42900116, 0x43100000,
+ 0x43100027, 0x431000c3, 0x4310014e, 0x43200000,
+ 0x43220000, 0x43220033, 0x432200be, 0x43220106,
+ 0x4322014e, 0x4325b000, 0x4325b033, 0x4325b0be,
+ 0x4325b106, 0x4325b14e, 0x43700000, 0x43a00000,
+ 0x43b00000, 0x44400000, 0x44400031, 0x44400073,
+ // Entry 2A0 - 2BF
+ 0x4440010d, 0x44500000, 0x4450004b, 0x445000a5,
+ 0x44500130, 0x44500132, 0x44e00000, 0x45000000,
+ 0x4500009a, 0x450000b4, 0x450000d1, 0x4500010e,
+ 0x46100000, 0x4610009a, 0x46400000, 0x464000a5,
+ 0x46400132, 0x46700000, 0x46700125, 0x46b00000,
+ 0x46b00124, 0x46f00000, 0x46f0006e, 0x46f00070,
+ 0x47100000, 0x47600000, 0x47600128, 0x47a00000,
+ 0x48000000, 0x48200000, 0x4820012a, 0x48a00000,
+ // Entry 2C0 - 2DF
+ 0x48a0005e, 0x48a0012c, 0x48e00000, 0x49400000,
+ 0x49400107, 0x4a400000, 0x4a4000d5, 0x4a900000,
+ 0x4a9000bb, 0x4ac00000, 0x4ac00053, 0x4ae00000,
+ 0x4ae00131, 0x4b400000, 0x4b40009a, 0x4b4000e9,
+ 0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000,
+ 0x4bc20138, 0x4bc5b000, 0x4bc5b138, 0x4be00000,
+ 0x4be5b000, 0x4be5b0b5, 0x4bef4000, 0x4bef40b5,
+ 0x4c000000, 0x4c300000, 0x4c30013f, 0x4c900000,
+ // Entry 2E0 - 2FF
+ 0x4c900001, 0x4cc00000, 0x4cc00130, 0x4ce00000,
+ 0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500115,
+ 0x4f200000, 0x4fb00000, 0x4fb00132, 0x50900000,
+ 0x50900052, 0x51200000, 0x51200001, 0x51800000,
+ 0x5180003b, 0x518000d7, 0x51f00000, 0x51f3b000,
+ 0x51f3b053, 0x51f3c000, 0x51f3c08e, 0x52800000,
+ 0x528000bb, 0x52900000, 0x5293b000, 0x5293b053,
+ 0x5293b08e, 0x5293b0c7, 0x5293b10e, 0x5293c000,
+ // Entry 300 - 31F
+ 0x5293c08e, 0x5293c0c7, 0x5293c12f, 0x52f00000,
+ 0x52f00162,
+} // Size: 3116 bytes
+
+const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix"
+
+// Total table size 3147 bytes (3KiB); checksum: 5A8FFFA5
diff --git a/vendor/golang.org/x/text/internal/language/compact/tags.go b/vendor/golang.org/x/text/internal/language/compact/tags.go
new file mode 100644
index 000000000..ca135d295
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compact/tags.go
@@ -0,0 +1,91 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package compact
+
+var (
+ und = Tag{}
+
+ Und Tag = Tag{}
+
+ Afrikaans Tag = Tag{language: afIndex, locale: afIndex}
+ Amharic Tag = Tag{language: amIndex, locale: amIndex}
+ Arabic Tag = Tag{language: arIndex, locale: arIndex}
+ ModernStandardArabic Tag = Tag{language: ar001Index, locale: ar001Index}
+ Azerbaijani Tag = Tag{language: azIndex, locale: azIndex}
+ Bulgarian Tag = Tag{language: bgIndex, locale: bgIndex}
+ Bengali Tag = Tag{language: bnIndex, locale: bnIndex}
+ Catalan Tag = Tag{language: caIndex, locale: caIndex}
+ Czech Tag = Tag{language: csIndex, locale: csIndex}
+ Danish Tag = Tag{language: daIndex, locale: daIndex}
+ German Tag = Tag{language: deIndex, locale: deIndex}
+ Greek Tag = Tag{language: elIndex, locale: elIndex}
+ English Tag = Tag{language: enIndex, locale: enIndex}
+ AmericanEnglish Tag = Tag{language: enUSIndex, locale: enUSIndex}
+ BritishEnglish Tag = Tag{language: enGBIndex, locale: enGBIndex}
+ Spanish Tag = Tag{language: esIndex, locale: esIndex}
+ EuropeanSpanish Tag = Tag{language: esESIndex, locale: esESIndex}
+ LatinAmericanSpanish Tag = Tag{language: es419Index, locale: es419Index}
+ Estonian Tag = Tag{language: etIndex, locale: etIndex}
+ Persian Tag = Tag{language: faIndex, locale: faIndex}
+ Finnish Tag = Tag{language: fiIndex, locale: fiIndex}
+ Filipino Tag = Tag{language: filIndex, locale: filIndex}
+ French Tag = Tag{language: frIndex, locale: frIndex}
+ CanadianFrench Tag = Tag{language: frCAIndex, locale: frCAIndex}
+ Gujarati Tag = Tag{language: guIndex, locale: guIndex}
+ Hebrew Tag = Tag{language: heIndex, locale: heIndex}
+ Hindi Tag = Tag{language: hiIndex, locale: hiIndex}
+ Croatian Tag = Tag{language: hrIndex, locale: hrIndex}
+ Hungarian Tag = Tag{language: huIndex, locale: huIndex}
+ Armenian Tag = Tag{language: hyIndex, locale: hyIndex}
+ Indonesian Tag = Tag{language: idIndex, locale: idIndex}
+ Icelandic Tag = Tag{language: isIndex, locale: isIndex}
+ Italian Tag = Tag{language: itIndex, locale: itIndex}
+ Japanese Tag = Tag{language: jaIndex, locale: jaIndex}
+ Georgian Tag = Tag{language: kaIndex, locale: kaIndex}
+ Kazakh Tag = Tag{language: kkIndex, locale: kkIndex}
+ Khmer Tag = Tag{language: kmIndex, locale: kmIndex}
+ Kannada Tag = Tag{language: knIndex, locale: knIndex}
+ Korean Tag = Tag{language: koIndex, locale: koIndex}
+ Kirghiz Tag = Tag{language: kyIndex, locale: kyIndex}
+ Lao Tag = Tag{language: loIndex, locale: loIndex}
+ Lithuanian Tag = Tag{language: ltIndex, locale: ltIndex}
+ Latvian Tag = Tag{language: lvIndex, locale: lvIndex}
+ Macedonian Tag = Tag{language: mkIndex, locale: mkIndex}
+ Malayalam Tag = Tag{language: mlIndex, locale: mlIndex}
+ Mongolian Tag = Tag{language: mnIndex, locale: mnIndex}
+ Marathi Tag = Tag{language: mrIndex, locale: mrIndex}
+ Malay Tag = Tag{language: msIndex, locale: msIndex}
+ Burmese Tag = Tag{language: myIndex, locale: myIndex}
+ Nepali Tag = Tag{language: neIndex, locale: neIndex}
+ Dutch Tag = Tag{language: nlIndex, locale: nlIndex}
+ Norwegian Tag = Tag{language: noIndex, locale: noIndex}
+ Punjabi Tag = Tag{language: paIndex, locale: paIndex}
+ Polish Tag = Tag{language: plIndex, locale: plIndex}
+ Portuguese Tag = Tag{language: ptIndex, locale: ptIndex}
+ BrazilianPortuguese Tag = Tag{language: ptBRIndex, locale: ptBRIndex}
+ EuropeanPortuguese Tag = Tag{language: ptPTIndex, locale: ptPTIndex}
+ Romanian Tag = Tag{language: roIndex, locale: roIndex}
+ Russian Tag = Tag{language: ruIndex, locale: ruIndex}
+ Sinhala Tag = Tag{language: siIndex, locale: siIndex}
+ Slovak Tag = Tag{language: skIndex, locale: skIndex}
+ Slovenian Tag = Tag{language: slIndex, locale: slIndex}
+ Albanian Tag = Tag{language: sqIndex, locale: sqIndex}
+ Serbian Tag = Tag{language: srIndex, locale: srIndex}
+ SerbianLatin Tag = Tag{language: srLatnIndex, locale: srLatnIndex}
+ Swedish Tag = Tag{language: svIndex, locale: svIndex}
+ Swahili Tag = Tag{language: swIndex, locale: swIndex}
+ Tamil Tag = Tag{language: taIndex, locale: taIndex}
+ Telugu Tag = Tag{language: teIndex, locale: teIndex}
+ Thai Tag = Tag{language: thIndex, locale: thIndex}
+ Turkish Tag = Tag{language: trIndex, locale: trIndex}
+ Ukrainian Tag = Tag{language: ukIndex, locale: ukIndex}
+ Urdu Tag = Tag{language: urIndex, locale: urIndex}
+ Uzbek Tag = Tag{language: uzIndex, locale: uzIndex}
+ Vietnamese Tag = Tag{language: viIndex, locale: viIndex}
+ Chinese Tag = Tag{language: zhIndex, locale: zhIndex}
+ SimplifiedChinese Tag = Tag{language: zhHansIndex, locale: zhHansIndex}
+ TraditionalChinese Tag = Tag{language: zhHantIndex, locale: zhHantIndex}
+ Zulu Tag = Tag{language: zuIndex, locale: zuIndex}
+)
diff --git a/vendor/golang.org/x/text/internal/language/compose.go b/vendor/golang.org/x/text/internal/language/compose.go
new file mode 100644
index 000000000..4ae78e0fa
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/compose.go
@@ -0,0 +1,167 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "sort"
+ "strings"
+)
+
+// A Builder allows constructing a Tag from individual components.
+// Its main user is Compose in the top-level language package.
+type Builder struct {
+ Tag Tag
+
+ private string // the x extension
+ variants []string
+ extensions []string
+}
+
+// Make returns a new Tag from the current settings.
+func (b *Builder) Make() Tag {
+ t := b.Tag
+
+ if len(b.extensions) > 0 || len(b.variants) > 0 {
+ sort.Sort(sortVariants(b.variants))
+ sort.Strings(b.extensions)
+
+ if b.private != "" {
+ b.extensions = append(b.extensions, b.private)
+ }
+ n := maxCoreSize + tokenLen(b.variants...) + tokenLen(b.extensions...)
+ buf := make([]byte, n)
+ p := t.genCoreBytes(buf)
+ t.pVariant = byte(p)
+ p += appendTokens(buf[p:], b.variants...)
+ t.pExt = uint16(p)
+ p += appendTokens(buf[p:], b.extensions...)
+ t.str = string(buf[:p])
+ // We may not always need to remake the string, but when or when not
+ // to do so is rather tricky.
+ scan := makeScanner(buf[:p])
+ t, _ = parse(&scan, "")
+ return t
+
+ } else if b.private != "" {
+ t.str = b.private
+ t.RemakeString()
+ }
+ return t
+}
+
+// SetTag copies all the settings from a given Tag. Any previously set values
+// are discarded.
+func (b *Builder) SetTag(t Tag) {
+ b.Tag.LangID = t.LangID
+ b.Tag.RegionID = t.RegionID
+ b.Tag.ScriptID = t.ScriptID
+ // TODO: optimize
+ b.variants = b.variants[:0]
+ if variants := t.Variants(); variants != "" {
+ for _, vr := range strings.Split(variants[1:], "-") {
+ b.variants = append(b.variants, vr)
+ }
+ }
+ b.extensions, b.private = b.extensions[:0], ""
+ for _, e := range t.Extensions() {
+ b.AddExt(e)
+ }
+}
+
+// AddExt adds extension e to the tag. e must be a valid extension as returned
+// by Tag.Extension. If the extension already exists, it will be discarded,
+// except for a -u extension, where non-existing key-type pairs will added.
+func (b *Builder) AddExt(e string) {
+ if e[0] == 'x' {
+ if b.private == "" {
+ b.private = e
+ }
+ return
+ }
+ for i, s := range b.extensions {
+ if s[0] == e[0] {
+ if e[0] == 'u' {
+ b.extensions[i] += e[1:]
+ }
+ return
+ }
+ }
+ b.extensions = append(b.extensions, e)
+}
+
+// SetExt sets the extension e to the tag. e must be a valid extension as
+// returned by Tag.Extension. If the extension already exists, it will be
+// overwritten, except for a -u extension, where the individual key-type pairs
+// will be set.
+func (b *Builder) SetExt(e string) {
+ if e[0] == 'x' {
+ b.private = e
+ return
+ }
+ for i, s := range b.extensions {
+ if s[0] == e[0] {
+ if e[0] == 'u' {
+ b.extensions[i] = e + s[1:]
+ } else {
+ b.extensions[i] = e
+ }
+ return
+ }
+ }
+ b.extensions = append(b.extensions, e)
+}
+
+// AddVariant adds any number of variants.
+func (b *Builder) AddVariant(v ...string) {
+ for _, v := range v {
+ if v != "" {
+ b.variants = append(b.variants, v)
+ }
+ }
+}
+
+// ClearVariants removes any variants previously added, including those
+// copied from a Tag in SetTag.
+func (b *Builder) ClearVariants() {
+ b.variants = b.variants[:0]
+}
+
+// ClearExtensions removes any extensions previously added, including those
+// copied from a Tag in SetTag.
+func (b *Builder) ClearExtensions() {
+ b.private = ""
+ b.extensions = b.extensions[:0]
+}
+
+func tokenLen(token ...string) (n int) {
+ for _, t := range token {
+ n += len(t) + 1
+ }
+ return
+}
+
+func appendTokens(b []byte, token ...string) int {
+ p := 0
+ for _, t := range token {
+ b[p] = '-'
+ copy(b[p+1:], t)
+ p += 1 + len(t)
+ }
+ return p
+}
+
+type sortVariants []string
+
+func (s sortVariants) Len() int {
+ return len(s)
+}
+
+func (s sortVariants) Swap(i, j int) {
+ s[j], s[i] = s[i], s[j]
+}
+
+func (s sortVariants) Less(i, j int) bool {
+ return variantIndex[s[i]] < variantIndex[s[j]]
+}
diff --git a/vendor/golang.org/x/text/internal/language/coverage.go b/vendor/golang.org/x/text/internal/language/coverage.go
new file mode 100644
index 000000000..9b20b88fe
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/coverage.go
@@ -0,0 +1,28 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+// BaseLanguages returns the list of all supported base languages. It generates
+// the list by traversing the internal structures.
+func BaseLanguages() []Language {
+ base := make([]Language, 0, NumLanguages)
+ for i := 0; i < langNoIndexOffset; i++ {
+ // We included "und" already for the value 0.
+ if i != nonCanonicalUnd {
+ base = append(base, Language(i))
+ }
+ }
+ i := langNoIndexOffset
+ for _, v := range langNoIndex {
+ for k := 0; k < 8; k++ {
+ if v&1 == 1 {
+ base = append(base, Language(i))
+ }
+ v >>= 1
+ i++
+ }
+ }
+ return base
+}
diff --git a/vendor/golang.org/x/text/internal/language/language.go b/vendor/golang.org/x/text/internal/language/language.go
new file mode 100644
index 000000000..09d41c736
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/language.go
@@ -0,0 +1,627 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go gen_common.go -output tables.go
+
+package language // import "golang.org/x/text/internal/language"
+
+// TODO: Remove above NOTE after:
+// - verifying that tables are dropped correctly (most notably matcher tables).
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+const (
+ // maxCoreSize is the maximum size of a BCP 47 tag without variants and
+ // extensions. Equals max lang (3) + script (4) + max reg (3) + 2 dashes.
+ maxCoreSize = 12
+
+ // max99thPercentileSize is a somewhat arbitrary buffer size that presumably
+ // is large enough to hold at least 99% of the BCP 47 tags.
+ max99thPercentileSize = 32
+
+ // maxSimpleUExtensionSize is the maximum size of a -u extension with one
+ // key-type pair. Equals len("-u-") + key (2) + dash + max value (8).
+ maxSimpleUExtensionSize = 14
+)
+
+// Tag represents a BCP 47 language tag. It is used to specify an instance of a
+// specific language or locale. All language tag values are guaranteed to be
+// well-formed. The zero value of Tag is Und.
+type Tag struct {
+ // TODO: the following fields have the form TagTypeID. This name is chosen
+ // to allow refactoring the public package without conflicting with its
+ // Base, Script, and Region methods. Once the transition is fully completed
+ // the ID can be stripped from the name.
+
+ LangID Language
+ RegionID Region
+ // TODO: we will soon run out of positions for ScriptID. Idea: instead of
+ // storing lang, region, and ScriptID codes, store only the compact index and
+ // have a lookup table from this code to its expansion. This greatly speeds
+ // up table lookup, speed up common variant cases.
+ // This will also immediately free up 3 extra bytes. Also, the pVariant
+ // field can now be moved to the lookup table, as the compact index uniquely
+ // determines the offset of a possible variant.
+ ScriptID Script
+ pVariant byte // offset in str, includes preceding '-'
+ pExt uint16 // offset of first extension, includes preceding '-'
+
+ // str is the string representation of the Tag. It will only be used if the
+ // tag has variants or extensions.
+ str string
+}
+
+// Make is a convenience wrapper for Parse that omits the error.
+// In case of an error, a sensible default is returned.
+func Make(s string) Tag {
+ t, _ := Parse(s)
+ return t
+}
+
+// Raw returns the raw base language, script and region, without making an
+// attempt to infer their values.
+// TODO: consider removing
+func (t Tag) Raw() (b Language, s Script, r Region) {
+ return t.LangID, t.ScriptID, t.RegionID
+}
+
+// equalTags compares language, script and region subtags only.
+func (t Tag) equalTags(a Tag) bool {
+ return t.LangID == a.LangID && t.ScriptID == a.ScriptID && t.RegionID == a.RegionID
+}
+
+// IsRoot returns true if t is equal to language "und".
+func (t Tag) IsRoot() bool {
+ if int(t.pVariant) < len(t.str) {
+ return false
+ }
+ return t.equalTags(Und)
+}
+
+// IsPrivateUse reports whether the Tag consists solely of an IsPrivateUse use
+// tag.
+func (t Tag) IsPrivateUse() bool {
+ return t.str != "" && t.pVariant == 0
+}
+
+// RemakeString is used to update t.str in case lang, script or region changed.
+// It is assumed that pExt and pVariant still point to the start of the
+// respective parts.
+func (t *Tag) RemakeString() {
+ if t.str == "" {
+ return
+ }
+ extra := t.str[t.pVariant:]
+ if t.pVariant > 0 {
+ extra = extra[1:]
+ }
+ if t.equalTags(Und) && strings.HasPrefix(extra, "x-") {
+ t.str = extra
+ t.pVariant = 0
+ t.pExt = 0
+ return
+ }
+ var buf [max99thPercentileSize]byte // avoid extra memory allocation in most cases.
+ b := buf[:t.genCoreBytes(buf[:])]
+ if extra != "" {
+ diff := len(b) - int(t.pVariant)
+ b = append(b, '-')
+ b = append(b, extra...)
+ t.pVariant = uint8(int(t.pVariant) + diff)
+ t.pExt = uint16(int(t.pExt) + diff)
+ } else {
+ t.pVariant = uint8(len(b))
+ t.pExt = uint16(len(b))
+ }
+ t.str = string(b)
+}
+
+// genCoreBytes writes a string for the base languages, script and region tags
+// to the given buffer and returns the number of bytes written. It will never
+// write more than maxCoreSize bytes.
+func (t *Tag) genCoreBytes(buf []byte) int {
+ n := t.LangID.StringToBuf(buf[:])
+ if t.ScriptID != 0 {
+ n += copy(buf[n:], "-")
+ n += copy(buf[n:], t.ScriptID.String())
+ }
+ if t.RegionID != 0 {
+ n += copy(buf[n:], "-")
+ n += copy(buf[n:], t.RegionID.String())
+ }
+ return n
+}
+
+// String returns the canonical string representation of the language tag.
+func (t Tag) String() string {
+ if t.str != "" {
+ return t.str
+ }
+ if t.ScriptID == 0 && t.RegionID == 0 {
+ return t.LangID.String()
+ }
+ buf := [maxCoreSize]byte{}
+ return string(buf[:t.genCoreBytes(buf[:])])
+}
+
+// MarshalText implements encoding.TextMarshaler.
+func (t Tag) MarshalText() (text []byte, err error) {
+ if t.str != "" {
+ text = append(text, t.str...)
+ } else if t.ScriptID == 0 && t.RegionID == 0 {
+ text = append(text, t.LangID.String()...)
+ } else {
+ buf := [maxCoreSize]byte{}
+ text = buf[:t.genCoreBytes(buf[:])]
+ }
+ return text, nil
+}
+
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (t *Tag) UnmarshalText(text []byte) error {
+ tag, err := Parse(string(text))
+ *t = tag
+ return err
+}
+
+// Variants returns the part of the tag holding all variants or the empty string
+// if there are no variants defined.
+func (t Tag) Variants() string {
+ if t.pVariant == 0 {
+ return ""
+ }
+ return t.str[t.pVariant:t.pExt]
+}
+
+// VariantOrPrivateUseTags returns variants or private use tags.
+func (t Tag) VariantOrPrivateUseTags() string {
+ if t.pExt > 0 {
+ return t.str[t.pVariant:t.pExt]
+ }
+ return t.str[t.pVariant:]
+}
+
+// HasString reports whether this tag defines more than just the raw
+// components.
+func (t Tag) HasString() bool {
+ return t.str != ""
+}
+
+// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
+// specific language are substituted with fields from the parent language.
+// The parent for a language may change for newer versions of CLDR.
+func (t Tag) Parent() Tag {
+ if t.str != "" {
+ // Strip the variants and extensions.
+ b, s, r := t.Raw()
+ t = Tag{LangID: b, ScriptID: s, RegionID: r}
+ if t.RegionID == 0 && t.ScriptID != 0 && t.LangID != 0 {
+ base, _ := addTags(Tag{LangID: t.LangID})
+ if base.ScriptID == t.ScriptID {
+ return Tag{LangID: t.LangID}
+ }
+ }
+ return t
+ }
+ if t.LangID != 0 {
+ if t.RegionID != 0 {
+ maxScript := t.ScriptID
+ if maxScript == 0 {
+ max, _ := addTags(t)
+ maxScript = max.ScriptID
+ }
+
+ for i := range parents {
+ if Language(parents[i].lang) == t.LangID && Script(parents[i].maxScript) == maxScript {
+ for _, r := range parents[i].fromRegion {
+ if Region(r) == t.RegionID {
+ return Tag{
+ LangID: t.LangID,
+ ScriptID: Script(parents[i].script),
+ RegionID: Region(parents[i].toRegion),
+ }
+ }
+ }
+ }
+ }
+
+ // Strip the script if it is the default one.
+ base, _ := addTags(Tag{LangID: t.LangID})
+ if base.ScriptID != maxScript {
+ return Tag{LangID: t.LangID, ScriptID: maxScript}
+ }
+ return Tag{LangID: t.LangID}
+ } else if t.ScriptID != 0 {
+ // The parent for an base-script pair with a non-default script is
+ // "und" instead of the base language.
+ base, _ := addTags(Tag{LangID: t.LangID})
+ if base.ScriptID != t.ScriptID {
+ return Und
+ }
+ return Tag{LangID: t.LangID}
+ }
+ }
+ return Und
+}
+
+// ParseExtension parses s as an extension and returns it on success.
+func ParseExtension(s string) (ext string, err error) {
+ defer func() {
+ if recover() != nil {
+ ext = ""
+ err = ErrSyntax
+ }
+ }()
+
+ scan := makeScannerString(s)
+ var end int
+ if n := len(scan.token); n != 1 {
+ return "", ErrSyntax
+ }
+ scan.toLower(0, len(scan.b))
+ end = parseExtension(&scan)
+ if end != len(s) {
+ return "", ErrSyntax
+ }
+ return string(scan.b), nil
+}
+
+// HasVariants reports whether t has variants.
+func (t Tag) HasVariants() bool {
+ return uint16(t.pVariant) < t.pExt
+}
+
+// HasExtensions reports whether t has extensions.
+func (t Tag) HasExtensions() bool {
+ return int(t.pExt) < len(t.str)
+}
+
+// Extension returns the extension of type x for tag t. It will return
+// false for ok if t does not have the requested extension. The returned
+// extension will be invalid in this case.
+func (t Tag) Extension(x byte) (ext string, ok bool) {
+ for i := int(t.pExt); i < len(t.str)-1; {
+ var ext string
+ i, ext = getExtension(t.str, i)
+ if ext[0] == x {
+ return ext, true
+ }
+ }
+ return "", false
+}
+
+// Extensions returns all extensions of t.
+func (t Tag) Extensions() []string {
+ e := []string{}
+ for i := int(t.pExt); i < len(t.str)-1; {
+ var ext string
+ i, ext = getExtension(t.str, i)
+ e = append(e, ext)
+ }
+ return e
+}
+
+// TypeForKey returns the type associated with the given key, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// TypeForKey will traverse the inheritance chain to get the correct value.
+//
+// If there are multiple types associated with a key, only the first will be
+// returned. If there is no type associated with a key, it returns the empty
+// string.
+func (t Tag) TypeForKey(key string) string {
+ if _, start, end, _ := t.findTypeForKey(key); end != start {
+ s := t.str[start:end]
+ if p := strings.IndexByte(s, '-'); p >= 0 {
+ s = s[:p]
+ }
+ return s
+ }
+ return ""
+}
+
+var (
+ errPrivateUse = errors.New("cannot set a key on a private use tag")
+ errInvalidArguments = errors.New("invalid key or type")
+)
+
+// SetTypeForKey returns a new Tag with the key set to type, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// An empty value removes an existing pair with the same key.
+func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
+ if t.IsPrivateUse() {
+ return t, errPrivateUse
+ }
+ if len(key) != 2 {
+ return t, errInvalidArguments
+ }
+
+ // Remove the setting if value is "".
+ if value == "" {
+ start, sep, end, _ := t.findTypeForKey(key)
+ if start != sep {
+ // Remove a possible empty extension.
+ switch {
+ case t.str[start-2] != '-': // has previous elements.
+ case end == len(t.str), // end of string
+ end+2 < len(t.str) && t.str[end+2] == '-': // end of extension
+ start -= 2
+ }
+ if start == int(t.pVariant) && end == len(t.str) {
+ t.str = ""
+ t.pVariant, t.pExt = 0, 0
+ } else {
+ t.str = fmt.Sprintf("%s%s", t.str[:start], t.str[end:])
+ }
+ }
+ return t, nil
+ }
+
+ if len(value) < 3 || len(value) > 8 {
+ return t, errInvalidArguments
+ }
+
+ var (
+ buf [maxCoreSize + maxSimpleUExtensionSize]byte
+ uStart int // start of the -u extension.
+ )
+
+ // Generate the tag string if needed.
+ if t.str == "" {
+ uStart = t.genCoreBytes(buf[:])
+ buf[uStart] = '-'
+ uStart++
+ }
+
+ // Create new key-type pair and parse it to verify.
+ b := buf[uStart:]
+ copy(b, "u-")
+ copy(b[2:], key)
+ b[4] = '-'
+ b = b[:5+copy(b[5:], value)]
+ scan := makeScanner(b)
+ if parseExtensions(&scan); scan.err != nil {
+ return t, scan.err
+ }
+
+ // Assemble the replacement string.
+ if t.str == "" {
+ t.pVariant, t.pExt = byte(uStart-1), uint16(uStart-1)
+ t.str = string(buf[:uStart+len(b)])
+ } else {
+ s := t.str
+ start, sep, end, hasExt := t.findTypeForKey(key)
+ if start == sep {
+ if hasExt {
+ b = b[2:]
+ }
+ t.str = fmt.Sprintf("%s-%s%s", s[:sep], b, s[end:])
+ } else {
+ t.str = fmt.Sprintf("%s-%s%s", s[:start+3], value, s[end:])
+ }
+ }
+ return t, nil
+}
+
+// findTypeForKey returns the start and end position for the type corresponding
+// to key or the point at which to insert the key-value pair if the type
+// wasn't found. The hasExt return value reports whether an -u extension was present.
+// Note: the extensions are typically very small and are likely to contain
+// only one key-type pair.
+func (t Tag) findTypeForKey(key string) (start, sep, end int, hasExt bool) {
+ p := int(t.pExt)
+ if len(key) != 2 || p == len(t.str) || p == 0 {
+ return p, p, p, false
+ }
+ s := t.str
+
+ // Find the correct extension.
+ for p++; s[p] != 'u'; p++ {
+ if s[p] > 'u' {
+ p--
+ return p, p, p, false
+ }
+ if p = nextExtension(s, p); p == len(s) {
+ return len(s), len(s), len(s), false
+ }
+ }
+ // Proceed to the hyphen following the extension name.
+ p++
+
+ // curKey is the key currently being processed.
+ curKey := ""
+
+ // Iterate over keys until we get the end of a section.
+ for {
+ end = p
+ for p++; p < len(s) && s[p] != '-'; p++ {
+ }
+ n := p - end - 1
+ if n <= 2 && curKey == key {
+ if sep < end {
+ sep++
+ }
+ return start, sep, end, true
+ }
+ switch n {
+ case 0, // invalid string
+ 1: // next extension
+ return end, end, end, true
+ case 2:
+ // next key
+ curKey = s[end+1 : p]
+ if curKey > key {
+ return end, end, end, true
+ }
+ start = end
+ sep = p
+ }
+ }
+}
+
+// ParseBase parses a 2- or 3-letter ISO 639 code.
+// It returns a ValueError if s is a well-formed but unknown language identifier
+// or another error if another error occurred.
+func ParseBase(s string) (l Language, err error) {
+ defer func() {
+ if recover() != nil {
+ l = 0
+ err = ErrSyntax
+ }
+ }()
+
+ if n := len(s); n < 2 || 3 < n {
+ return 0, ErrSyntax
+ }
+ var buf [3]byte
+ return getLangID(buf[:copy(buf[:], s)])
+}
+
+// ParseScript parses a 4-letter ISO 15924 code.
+// It returns a ValueError if s is a well-formed but unknown script identifier
+// or another error if another error occurred.
+func ParseScript(s string) (scr Script, err error) {
+ defer func() {
+ if recover() != nil {
+ scr = 0
+ err = ErrSyntax
+ }
+ }()
+
+ if len(s) != 4 {
+ return 0, ErrSyntax
+ }
+ var buf [4]byte
+ return getScriptID(script, buf[:copy(buf[:], s)])
+}
+
+// EncodeM49 returns the Region for the given UN M.49 code.
+// It returns an error if r is not a valid code.
+func EncodeM49(r int) (Region, error) {
+ return getRegionM49(r)
+}
+
+// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code.
+// It returns a ValueError if s is a well-formed but unknown region identifier
+// or another error if another error occurred.
+func ParseRegion(s string) (r Region, err error) {
+ defer func() {
+ if recover() != nil {
+ r = 0
+ err = ErrSyntax
+ }
+ }()
+
+ if n := len(s); n < 2 || 3 < n {
+ return 0, ErrSyntax
+ }
+ var buf [3]byte
+ return getRegionID(buf[:copy(buf[:], s)])
+}
+
+// IsCountry returns whether this region is a country or autonomous area. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsCountry() bool {
+ if r == 0 || r.IsGroup() || r.IsPrivateUse() && r != _XK {
+ return false
+ }
+ return true
+}
+
+// IsGroup returns whether this region defines a collection of regions. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsGroup() bool {
+ if r == 0 {
+ return false
+ }
+ return int(regionInclusion[r]) < len(regionContainment)
+}
+
+// Contains returns whether Region c is contained by Region r. It returns true
+// if c == r.
+func (r Region) Contains(c Region) bool {
+ if r == c {
+ return true
+ }
+ g := regionInclusion[r]
+ if g >= nRegionGroups {
+ return false
+ }
+ m := regionContainment[g]
+
+ d := regionInclusion[c]
+ b := regionInclusionBits[d]
+
+ // A contained country may belong to multiple disjoint groups. Matching any
+ // of these indicates containment. If the contained region is a group, it
+ // must strictly be a subset.
+ if d >= nRegionGroups {
+ return b&m != 0
+ }
+ return b&^m == 0
+}
+
+var errNoTLD = errors.New("language: region is not a valid ccTLD")
+
+// TLD returns the country code top-level domain (ccTLD). UK is returned for GB.
+// In all other cases it returns either the region itself or an error.
+//
+// This method may return an error for a region for which there exists a
+// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The
+// region will already be canonicalized it was obtained from a Tag that was
+// obtained using any of the default methods.
+func (r Region) TLD() (Region, error) {
+ // See http://en.wikipedia.org/wiki/Country_code_top-level_domain for the
+ // difference between ISO 3166-1 and IANA ccTLD.
+ if r == _GB {
+ r = _UK
+ }
+ if (r.typ() & ccTLD) == 0 {
+ return 0, errNoTLD
+ }
+ return r, nil
+}
+
+// Canonicalize returns the region or a possible replacement if the region is
+// deprecated. It will not return a replacement for deprecated regions that
+// are split into multiple regions.
+func (r Region) Canonicalize() Region {
+ if cr := normRegion(r); cr != 0 {
+ return cr
+ }
+ return r
+}
+
+// Variant represents a registered variant of a language as defined by BCP 47.
+type Variant struct {
+ ID uint8
+ str string
+}
+
+// ParseVariant parses and returns a Variant. An error is returned if s is not
+// a valid variant.
+func ParseVariant(s string) (v Variant, err error) {
+ defer func() {
+ if recover() != nil {
+ v = Variant{}
+ err = ErrSyntax
+ }
+ }()
+
+ s = strings.ToLower(s)
+ if id, ok := variantIndex[s]; ok {
+ return Variant{id, s}, nil
+ }
+ return Variant{}, NewValueError([]byte(s))
+}
+
+// String returns the string representation of the variant.
+func (v Variant) String() string {
+ return v.str
+}
diff --git a/vendor/golang.org/x/text/internal/language/lookup.go b/vendor/golang.org/x/text/internal/language/lookup.go
new file mode 100644
index 000000000..231b4fbde
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/lookup.go
@@ -0,0 +1,412 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strconv"
+
+ "golang.org/x/text/internal/tag"
+)
+
+// findIndex tries to find the given tag in idx and returns a standardized error
+// if it could not be found.
+func findIndex(idx tag.Index, key []byte, form string) (index int, err error) {
+ if !tag.FixCase(form, key) {
+ return 0, ErrSyntax
+ }
+ i := idx.Index(key)
+ if i == -1 {
+ return 0, NewValueError(key)
+ }
+ return i, nil
+}
+
+func searchUint(imap []uint16, key uint16) int {
+ return sort.Search(len(imap), func(i int) bool {
+ return imap[i] >= key
+ })
+}
+
+type Language uint16
+
+// getLangID returns the langID of s if s is a canonical subtag
+// or langUnknown if s is not a canonical subtag.
+func getLangID(s []byte) (Language, error) {
+ if len(s) == 2 {
+ return getLangISO2(s)
+ }
+ return getLangISO3(s)
+}
+
+// TODO language normalization as well as the AliasMaps could be moved to the
+// higher level package, but it is a bit tricky to separate the generation.
+
+func (id Language) Canonicalize() (Language, AliasType) {
+ return normLang(id)
+}
+
+// normLang returns the mapped langID of id according to mapping m.
+func normLang(id Language) (Language, AliasType) {
+ k := sort.Search(len(AliasMap), func(i int) bool {
+ return AliasMap[i].From >= uint16(id)
+ })
+ if k < len(AliasMap) && AliasMap[k].From == uint16(id) {
+ return Language(AliasMap[k].To), AliasTypes[k]
+ }
+ return id, AliasTypeUnknown
+}
+
+// getLangISO2 returns the langID for the given 2-letter ISO language code
+// or unknownLang if this does not exist.
+func getLangISO2(s []byte) (Language, error) {
+ if !tag.FixCase("zz", s) {
+ return 0, ErrSyntax
+ }
+ if i := lang.Index(s); i != -1 && lang.Elem(i)[3] != 0 {
+ return Language(i), nil
+ }
+ return 0, NewValueError(s)
+}
+
+const base = 'z' - 'a' + 1
+
+func strToInt(s []byte) uint {
+ v := uint(0)
+ for i := 0; i < len(s); i++ {
+ v *= base
+ v += uint(s[i] - 'a')
+ }
+ return v
+}
+
+// converts the given integer to the original ASCII string passed to strToInt.
+// len(s) must match the number of characters obtained.
+func intToStr(v uint, s []byte) {
+ for i := len(s) - 1; i >= 0; i-- {
+ s[i] = byte(v%base) + 'a'
+ v /= base
+ }
+}
+
+// getLangISO3 returns the langID for the given 3-letter ISO language code
+// or unknownLang if this does not exist.
+func getLangISO3(s []byte) (Language, error) {
+ if tag.FixCase("und", s) {
+ // first try to match canonical 3-letter entries
+ for i := lang.Index(s[:2]); i != -1; i = lang.Next(s[:2], i) {
+ if e := lang.Elem(i); e[3] == 0 && e[2] == s[2] {
+ // We treat "und" as special and always translate it to "unspecified".
+ // Note that ZZ and Zzzz are private use and are not treated as
+ // unspecified by default.
+ id := Language(i)
+ if id == nonCanonicalUnd {
+ return 0, nil
+ }
+ return id, nil
+ }
+ }
+ if i := altLangISO3.Index(s); i != -1 {
+ return Language(altLangIndex[altLangISO3.Elem(i)[3]]), nil
+ }
+ n := strToInt(s)
+ if langNoIndex[n/8]&(1<<(n%8)) != 0 {
+ return Language(n) + langNoIndexOffset, nil
+ }
+ // Check for non-canonical uses of ISO3.
+ for i := lang.Index(s[:1]); i != -1; i = lang.Next(s[:1], i) {
+ if e := lang.Elem(i); e[2] == s[1] && e[3] == s[2] {
+ return Language(i), nil
+ }
+ }
+ return 0, NewValueError(s)
+ }
+ return 0, ErrSyntax
+}
+
+// StringToBuf writes the string to b and returns the number of bytes
+// written. cap(b) must be >= 3.
+func (id Language) StringToBuf(b []byte) int {
+ if id >= langNoIndexOffset {
+ intToStr(uint(id)-langNoIndexOffset, b[:3])
+ return 3
+ } else if id == 0 {
+ return copy(b, "und")
+ }
+ l := lang[id<<2:]
+ if l[3] == 0 {
+ return copy(b, l[:3])
+ }
+ return copy(b, l[:2])
+}
+
+// String returns the BCP 47 representation of the langID.
+// Use b as variable name, instead of id, to ensure the variable
+// used is consistent with that of Base in which this type is embedded.
+func (b Language) String() string {
+ if b == 0 {
+ return "und"
+ } else if b >= langNoIndexOffset {
+ b -= langNoIndexOffset
+ buf := [3]byte{}
+ intToStr(uint(b), buf[:])
+ return string(buf[:])
+ }
+ l := lang.Elem(int(b))
+ if l[3] == 0 {
+ return l[:3]
+ }
+ return l[:2]
+}
+
+// ISO3 returns the ISO 639-3 language code.
+func (b Language) ISO3() string {
+ if b == 0 || b >= langNoIndexOffset {
+ return b.String()
+ }
+ l := lang.Elem(int(b))
+ if l[3] == 0 {
+ return l[:3]
+ } else if l[2] == 0 {
+ return altLangISO3.Elem(int(l[3]))[:3]
+ }
+ // This allocation will only happen for 3-letter ISO codes
+ // that are non-canonical BCP 47 language identifiers.
+ return l[0:1] + l[2:4]
+}
+
+// IsPrivateUse reports whether this language code is reserved for private use.
+func (b Language) IsPrivateUse() bool {
+ return langPrivateStart <= b && b <= langPrivateEnd
+}
+
+// SuppressScript returns the script marked as SuppressScript in the IANA
+// language tag repository, or 0 if there is no such script.
+func (b Language) SuppressScript() Script {
+ if b < langNoIndexOffset {
+ return Script(suppressScript[b])
+ }
+ return 0
+}
+
+type Region uint16
+
+// getRegionID returns the region id for s if s is a valid 2-letter region code
+// or unknownRegion.
+func getRegionID(s []byte) (Region, error) {
+ if len(s) == 3 {
+ if isAlpha(s[0]) {
+ return getRegionISO3(s)
+ }
+ if i, err := strconv.ParseUint(string(s), 10, 10); err == nil {
+ return getRegionM49(int(i))
+ }
+ }
+ return getRegionISO2(s)
+}
+
+// getRegionISO2 returns the regionID for the given 2-letter ISO country code
+// or unknownRegion if this does not exist.
+func getRegionISO2(s []byte) (Region, error) {
+ i, err := findIndex(regionISO, s, "ZZ")
+ if err != nil {
+ return 0, err
+ }
+ return Region(i) + isoRegionOffset, nil
+}
+
+// getRegionISO3 returns the regionID for the given 3-letter ISO country code
+// or unknownRegion if this does not exist.
+func getRegionISO3(s []byte) (Region, error) {
+ if tag.FixCase("ZZZ", s) {
+ for i := regionISO.Index(s[:1]); i != -1; i = regionISO.Next(s[:1], i) {
+ if e := regionISO.Elem(i); e[2] == s[1] && e[3] == s[2] {
+ return Region(i) + isoRegionOffset, nil
+ }
+ }
+ for i := 0; i < len(altRegionISO3); i += 3 {
+ if tag.Compare(altRegionISO3[i:i+3], s) == 0 {
+ return Region(altRegionIDs[i/3]), nil
+ }
+ }
+ return 0, NewValueError(s)
+ }
+ return 0, ErrSyntax
+}
+
+func getRegionM49(n int) (Region, error) {
+ if 0 < n && n <= 999 {
+ const (
+ searchBits = 7
+ regionBits = 9
+ regionMask = 1<> searchBits
+ buf := fromM49[m49Index[idx]:m49Index[idx+1]]
+ val := uint16(n) << regionBits // we rely on bits shifting out
+ i := sort.Search(len(buf), func(i int) bool {
+ return buf[i] >= val
+ })
+ if r := fromM49[int(m49Index[idx])+i]; r&^regionMask == val {
+ return Region(r & regionMask), nil
+ }
+ }
+ var e ValueError
+ fmt.Fprint(bytes.NewBuffer([]byte(e.v[:])), n)
+ return 0, e
+}
+
+// normRegion returns a region if r is deprecated or 0 otherwise.
+// TODO: consider supporting BYS (-> BLR), CSK (-> 200 or CZ), PHI (-> PHL) and AFI (-> DJ).
+// TODO: consider mapping split up regions to new most populous one (like CLDR).
+func normRegion(r Region) Region {
+ m := regionOldMap
+ k := sort.Search(len(m), func(i int) bool {
+ return m[i].From >= uint16(r)
+ })
+ if k < len(m) && m[k].From == uint16(r) {
+ return Region(m[k].To)
+ }
+ return 0
+}
+
+const (
+ iso3166UserAssigned = 1 << iota
+ ccTLD
+ bcp47Region
+)
+
+func (r Region) typ() byte {
+ return regionTypes[r]
+}
+
+// String returns the BCP 47 representation for the region.
+// It returns "ZZ" for an unspecified region.
+func (r Region) String() string {
+ if r < isoRegionOffset {
+ if r == 0 {
+ return "ZZ"
+ }
+ return fmt.Sprintf("%03d", r.M49())
+ }
+ r -= isoRegionOffset
+ return regionISO.Elem(int(r))[:2]
+}
+
+// ISO3 returns the 3-letter ISO code of r.
+// Note that not all regions have a 3-letter ISO code.
+// In such cases this method returns "ZZZ".
+func (r Region) ISO3() string {
+ if r < isoRegionOffset {
+ return "ZZZ"
+ }
+ r -= isoRegionOffset
+ reg := regionISO.Elem(int(r))
+ switch reg[2] {
+ case 0:
+ return altRegionISO3[reg[3]:][:3]
+ case ' ':
+ return "ZZZ"
+ }
+ return reg[0:1] + reg[2:4]
+}
+
+// M49 returns the UN M.49 encoding of r, or 0 if this encoding
+// is not defined for r.
+func (r Region) M49() int {
+ return int(m49[r])
+}
+
+// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This
+// may include private-use tags that are assigned by CLDR and used in this
+// implementation. So IsPrivateUse and IsCountry can be simultaneously true.
+func (r Region) IsPrivateUse() bool {
+ return r.typ()&iso3166UserAssigned != 0
+}
+
+type Script uint16
+
+// getScriptID returns the script id for string s. It assumes that s
+// is of the format [A-Z][a-z]{3}.
+func getScriptID(idx tag.Index, s []byte) (Script, error) {
+ i, err := findIndex(idx, s, "Zzzz")
+ return Script(i), err
+}
+
+// String returns the script code in title case.
+// It returns "Zzzz" for an unspecified script.
+func (s Script) String() string {
+ if s == 0 {
+ return "Zzzz"
+ }
+ return script.Elem(int(s))
+}
+
+// IsPrivateUse reports whether this script code is reserved for private use.
+func (s Script) IsPrivateUse() bool {
+ return _Qaaa <= s && s <= _Qabx
+}
+
+const (
+ maxAltTaglen = len("en-US-POSIX")
+ maxLen = maxAltTaglen
+)
+
+var (
+ // grandfatheredMap holds a mapping from legacy and grandfathered tags to
+ // their base language or index to more elaborate tag.
+ grandfatheredMap = map[[maxLen]byte]int16{
+ [maxLen]byte{'a', 'r', 't', '-', 'l', 'o', 'j', 'b', 'a', 'n'}: _jbo, // art-lojban
+ [maxLen]byte{'i', '-', 'a', 'm', 'i'}: _ami, // i-ami
+ [maxLen]byte{'i', '-', 'b', 'n', 'n'}: _bnn, // i-bnn
+ [maxLen]byte{'i', '-', 'h', 'a', 'k'}: _hak, // i-hak
+ [maxLen]byte{'i', '-', 'k', 'l', 'i', 'n', 'g', 'o', 'n'}: _tlh, // i-klingon
+ [maxLen]byte{'i', '-', 'l', 'u', 'x'}: _lb, // i-lux
+ [maxLen]byte{'i', '-', 'n', 'a', 'v', 'a', 'j', 'o'}: _nv, // i-navajo
+ [maxLen]byte{'i', '-', 'p', 'w', 'n'}: _pwn, // i-pwn
+ [maxLen]byte{'i', '-', 't', 'a', 'o'}: _tao, // i-tao
+ [maxLen]byte{'i', '-', 't', 'a', 'y'}: _tay, // i-tay
+ [maxLen]byte{'i', '-', 't', 's', 'u'}: _tsu, // i-tsu
+ [maxLen]byte{'n', 'o', '-', 'b', 'o', 'k'}: _nb, // no-bok
+ [maxLen]byte{'n', 'o', '-', 'n', 'y', 'n'}: _nn, // no-nyn
+ [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'f', 'r'}: _sfb, // sgn-BE-FR
+ [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'n', 'l'}: _vgt, // sgn-BE-NL
+ [maxLen]byte{'s', 'g', 'n', '-', 'c', 'h', '-', 'd', 'e'}: _sgg, // sgn-CH-DE
+ [maxLen]byte{'z', 'h', '-', 'g', 'u', 'o', 'y', 'u'}: _cmn, // zh-guoyu
+ [maxLen]byte{'z', 'h', '-', 'h', 'a', 'k', 'k', 'a'}: _hak, // zh-hakka
+ [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n', '-', 'n', 'a', 'n'}: _nan, // zh-min-nan
+ [maxLen]byte{'z', 'h', '-', 'x', 'i', 'a', 'n', 'g'}: _hsn, // zh-xiang
+
+ // Grandfathered tags with no modern replacement will be converted as
+ // follows:
+ [maxLen]byte{'c', 'e', 'l', '-', 'g', 'a', 'u', 'l', 'i', 's', 'h'}: -1, // cel-gaulish
+ [maxLen]byte{'e', 'n', '-', 'g', 'b', '-', 'o', 'e', 'd'}: -2, // en-GB-oed
+ [maxLen]byte{'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}: -3, // i-default
+ [maxLen]byte{'i', '-', 'e', 'n', 'o', 'c', 'h', 'i', 'a', 'n'}: -4, // i-enochian
+ [maxLen]byte{'i', '-', 'm', 'i', 'n', 'g', 'o'}: -5, // i-mingo
+ [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n'}: -6, // zh-min
+
+ // CLDR-specific tag.
+ [maxLen]byte{'r', 'o', 'o', 't'}: 0, // root
+ [maxLen]byte{'e', 'n', '-', 'u', 's', '-', 'p', 'o', 's', 'i', 'x'}: -7, // en_US_POSIX"
+ }
+
+ altTagIndex = [...]uint8{0, 17, 31, 45, 61, 74, 86, 102}
+
+ altTags = "xtg-x-cel-gaulishen-GB-oxendicten-x-i-defaultund-x-i-enochiansee-x-i-mingonan-x-zh-minen-US-u-va-posix"
+)
+
+func grandfathered(s [maxAltTaglen]byte) (t Tag, ok bool) {
+ if v, ok := grandfatheredMap[s]; ok {
+ if v < 0 {
+ return Make(altTags[altTagIndex[-v-1]:altTagIndex[-v]]), true
+ }
+ t.LangID = Language(v)
+ return t, true
+ }
+ return t, false
+}
diff --git a/vendor/golang.org/x/text/internal/language/match.go b/vendor/golang.org/x/text/internal/language/match.go
new file mode 100644
index 000000000..75a2dbca7
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/match.go
@@ -0,0 +1,226 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import "errors"
+
+type scriptRegionFlags uint8
+
+const (
+ isList = 1 << iota
+ scriptInFrom
+ regionInFrom
+)
+
+func (t *Tag) setUndefinedLang(id Language) {
+ if t.LangID == 0 {
+ t.LangID = id
+ }
+}
+
+func (t *Tag) setUndefinedScript(id Script) {
+ if t.ScriptID == 0 {
+ t.ScriptID = id
+ }
+}
+
+func (t *Tag) setUndefinedRegion(id Region) {
+ if t.RegionID == 0 || t.RegionID.Contains(id) {
+ t.RegionID = id
+ }
+}
+
+// ErrMissingLikelyTagsData indicates no information was available
+// to compute likely values of missing tags.
+var ErrMissingLikelyTagsData = errors.New("missing likely tags data")
+
+// addLikelySubtags sets subtags to their most likely value, given the locale.
+// In most cases this means setting fields for unknown values, but in some
+// cases it may alter a value. It returns an ErrMissingLikelyTagsData error
+// if the given locale cannot be expanded.
+func (t Tag) addLikelySubtags() (Tag, error) {
+ id, err := addTags(t)
+ if err != nil {
+ return t, err
+ } else if id.equalTags(t) {
+ return t, nil
+ }
+ id.RemakeString()
+ return id, nil
+}
+
+// specializeRegion attempts to specialize a group region.
+func specializeRegion(t *Tag) bool {
+ if i := regionInclusion[t.RegionID]; i < nRegionGroups {
+ x := likelyRegionGroup[i]
+ if Language(x.lang) == t.LangID && Script(x.script) == t.ScriptID {
+ t.RegionID = Region(x.region)
+ }
+ return true
+ }
+ return false
+}
+
+// Maximize returns a new tag with missing tags filled in.
+func (t Tag) Maximize() (Tag, error) {
+ return addTags(t)
+}
+
+func addTags(t Tag) (Tag, error) {
+ // We leave private use identifiers alone.
+ if t.IsPrivateUse() {
+ return t, nil
+ }
+ if t.ScriptID != 0 && t.RegionID != 0 {
+ if t.LangID != 0 {
+ // already fully specified
+ specializeRegion(&t)
+ return t, nil
+ }
+ // Search matches for und-script-region. Note that for these cases
+ // region will never be a group so there is no need to check for this.
+ list := likelyRegion[t.RegionID : t.RegionID+1]
+ if x := list[0]; x.flags&isList != 0 {
+ list = likelyRegionList[x.lang : x.lang+uint16(x.script)]
+ }
+ for _, x := range list {
+ // Deviating from the spec. See match_test.go for details.
+ if Script(x.script) == t.ScriptID {
+ t.setUndefinedLang(Language(x.lang))
+ return t, nil
+ }
+ }
+ }
+ if t.LangID != 0 {
+ // Search matches for lang-script and lang-region, where lang != und.
+ if t.LangID < langNoIndexOffset {
+ x := likelyLang[t.LangID]
+ if x.flags&isList != 0 {
+ list := likelyLangList[x.region : x.region+uint16(x.script)]
+ if t.ScriptID != 0 {
+ for _, x := range list {
+ if Script(x.script) == t.ScriptID && x.flags&scriptInFrom != 0 {
+ t.setUndefinedRegion(Region(x.region))
+ return t, nil
+ }
+ }
+ } else if t.RegionID != 0 {
+ count := 0
+ goodScript := true
+ tt := t
+ for _, x := range list {
+ // We visit all entries for which the script was not
+ // defined, including the ones where the region was not
+ // defined. This allows for proper disambiguation within
+ // regions.
+ if x.flags&scriptInFrom == 0 && t.RegionID.Contains(Region(x.region)) {
+ tt.RegionID = Region(x.region)
+ tt.setUndefinedScript(Script(x.script))
+ goodScript = goodScript && tt.ScriptID == Script(x.script)
+ count++
+ }
+ }
+ if count == 1 {
+ return tt, nil
+ }
+ // Even if we fail to find a unique Region, we might have
+ // an unambiguous script.
+ if goodScript {
+ t.ScriptID = tt.ScriptID
+ }
+ }
+ }
+ }
+ } else {
+ // Search matches for und-script.
+ if t.ScriptID != 0 {
+ x := likelyScript[t.ScriptID]
+ if x.region != 0 {
+ t.setUndefinedRegion(Region(x.region))
+ t.setUndefinedLang(Language(x.lang))
+ return t, nil
+ }
+ }
+ // Search matches for und-region. If und-script-region exists, it would
+ // have been found earlier.
+ if t.RegionID != 0 {
+ if i := regionInclusion[t.RegionID]; i < nRegionGroups {
+ x := likelyRegionGroup[i]
+ if x.region != 0 {
+ t.setUndefinedLang(Language(x.lang))
+ t.setUndefinedScript(Script(x.script))
+ t.RegionID = Region(x.region)
+ }
+ } else {
+ x := likelyRegion[t.RegionID]
+ if x.flags&isList != 0 {
+ x = likelyRegionList[x.lang]
+ }
+ if x.script != 0 && x.flags != scriptInFrom {
+ t.setUndefinedLang(Language(x.lang))
+ t.setUndefinedScript(Script(x.script))
+ return t, nil
+ }
+ }
+ }
+ }
+
+ // Search matches for lang.
+ if t.LangID < langNoIndexOffset {
+ x := likelyLang[t.LangID]
+ if x.flags&isList != 0 {
+ x = likelyLangList[x.region]
+ }
+ if x.region != 0 {
+ t.setUndefinedScript(Script(x.script))
+ t.setUndefinedRegion(Region(x.region))
+ }
+ specializeRegion(&t)
+ if t.LangID == 0 {
+ t.LangID = _en // default language
+ }
+ return t, nil
+ }
+ return t, ErrMissingLikelyTagsData
+}
+
+func (t *Tag) setTagsFrom(id Tag) {
+ t.LangID = id.LangID
+ t.ScriptID = id.ScriptID
+ t.RegionID = id.RegionID
+}
+
+// minimize removes the region or script subtags from t such that
+// t.addLikelySubtags() == t.minimize().addLikelySubtags().
+func (t Tag) minimize() (Tag, error) {
+ t, err := minimizeTags(t)
+ if err != nil {
+ return t, err
+ }
+ t.RemakeString()
+ return t, nil
+}
+
+// minimizeTags mimics the behavior of the ICU 51 C implementation.
+func minimizeTags(t Tag) (Tag, error) {
+ if t.equalTags(Und) {
+ return t, nil
+ }
+ max, err := addTags(t)
+ if err != nil {
+ return t, err
+ }
+ for _, id := range [...]Tag{
+ {LangID: t.LangID},
+ {LangID: t.LangID, RegionID: t.RegionID},
+ {LangID: t.LangID, ScriptID: t.ScriptID},
+ } {
+ if x, err := addTags(id); err == nil && max.equalTags(x) {
+ t.setTagsFrom(id)
+ break
+ }
+ }
+ return t, nil
+}
diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go
new file mode 100644
index 000000000..aad1e0acf
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/parse.go
@@ -0,0 +1,608 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "sort"
+
+ "golang.org/x/text/internal/tag"
+)
+
+// isAlpha returns true if the byte is not a digit.
+// b must be an ASCII letter or digit.
+func isAlpha(b byte) bool {
+ return b > '9'
+}
+
+// isAlphaNum returns true if the string contains only ASCII letters or digits.
+func isAlphaNum(s []byte) bool {
+ for _, c := range s {
+ if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9') {
+ return false
+ }
+ }
+ return true
+}
+
+// ErrSyntax is returned by any of the parsing functions when the
+// input is not well-formed, according to BCP 47.
+// TODO: return the position at which the syntax error occurred?
+var ErrSyntax = errors.New("language: tag is not well-formed")
+
+// ErrDuplicateKey is returned when a tag contains the same key twice with
+// different values in the -u section.
+var ErrDuplicateKey = errors.New("language: different values for same key in -u extension")
+
+// ValueError is returned by any of the parsing functions when the
+// input is well-formed but the respective subtag is not recognized
+// as a valid value.
+type ValueError struct {
+ v [8]byte
+}
+
+// NewValueError creates a new ValueError.
+func NewValueError(tag []byte) ValueError {
+ var e ValueError
+ copy(e.v[:], tag)
+ return e
+}
+
+func (e ValueError) tag() []byte {
+ n := bytes.IndexByte(e.v[:], 0)
+ if n == -1 {
+ n = 8
+ }
+ return e.v[:n]
+}
+
+// Error implements the error interface.
+func (e ValueError) Error() string {
+ return fmt.Sprintf("language: subtag %q is well-formed but unknown", e.tag())
+}
+
+// Subtag returns the subtag for which the error occurred.
+func (e ValueError) Subtag() string {
+ return string(e.tag())
+}
+
+// scanner is used to scan BCP 47 tokens, which are separated by _ or -.
+type scanner struct {
+ b []byte
+ bytes [max99thPercentileSize]byte
+ token []byte
+ start int // start position of the current token
+ end int // end position of the current token
+ next int // next point for scan
+ err error
+ done bool
+}
+
+func makeScannerString(s string) scanner {
+ scan := scanner{}
+ if len(s) <= len(scan.bytes) {
+ scan.b = scan.bytes[:copy(scan.bytes[:], s)]
+ } else {
+ scan.b = []byte(s)
+ }
+ scan.init()
+ return scan
+}
+
+// makeScanner returns a scanner using b as the input buffer.
+// b is not copied and may be modified by the scanner routines.
+func makeScanner(b []byte) scanner {
+ scan := scanner{b: b}
+ scan.init()
+ return scan
+}
+
+func (s *scanner) init() {
+ for i, c := range s.b {
+ if c == '_' {
+ s.b[i] = '-'
+ }
+ }
+ s.scan()
+}
+
+// restToLower converts the string between start and end to lower case.
+func (s *scanner) toLower(start, end int) {
+ for i := start; i < end; i++ {
+ c := s.b[i]
+ if 'A' <= c && c <= 'Z' {
+ s.b[i] += 'a' - 'A'
+ }
+ }
+}
+
+func (s *scanner) setError(e error) {
+ if s.err == nil || (e == ErrSyntax && s.err != ErrSyntax) {
+ s.err = e
+ }
+}
+
+// resizeRange shrinks or grows the array at position oldStart such that
+// a new string of size newSize can fit between oldStart and oldEnd.
+// Sets the scan point to after the resized range.
+func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) {
+ s.start = oldStart
+ if end := oldStart + newSize; end != oldEnd {
+ diff := end - oldEnd
+ var b []byte
+ if n := len(s.b) + diff; n > cap(s.b) {
+ b = make([]byte, n)
+ copy(b, s.b[:oldStart])
+ } else {
+ b = s.b[:n]
+ }
+ copy(b[end:], s.b[oldEnd:])
+ s.b = b
+ s.next = end + (s.next - s.end)
+ s.end = end
+ }
+}
+
+// replace replaces the current token with repl.
+func (s *scanner) replace(repl string) {
+ s.resizeRange(s.start, s.end, len(repl))
+ copy(s.b[s.start:], repl)
+}
+
+// gobble removes the current token from the input.
+// Caller must call scan after calling gobble.
+func (s *scanner) gobble(e error) {
+ s.setError(e)
+ if s.start == 0 {
+ s.b = s.b[:+copy(s.b, s.b[s.next:])]
+ s.end = 0
+ } else {
+ s.b = s.b[:s.start-1+copy(s.b[s.start-1:], s.b[s.end:])]
+ s.end = s.start - 1
+ }
+ s.next = s.start
+}
+
+// deleteRange removes the given range from s.b before the current token.
+func (s *scanner) deleteRange(start, end int) {
+ s.b = s.b[:start+copy(s.b[start:], s.b[end:])]
+ diff := end - start
+ s.next -= diff
+ s.start -= diff
+ s.end -= diff
+}
+
+// scan parses the next token of a BCP 47 string. Tokens that are larger
+// than 8 characters or include non-alphanumeric characters result in an error
+// and are gobbled and removed from the output.
+// It returns the end position of the last token consumed.
+func (s *scanner) scan() (end int) {
+ end = s.end
+ s.token = nil
+ for s.start = s.next; s.next < len(s.b); {
+ i := bytes.IndexByte(s.b[s.next:], '-')
+ if i == -1 {
+ s.end = len(s.b)
+ s.next = len(s.b)
+ i = s.end - s.start
+ } else {
+ s.end = s.next + i
+ s.next = s.end + 1
+ }
+ token := s.b[s.start:s.end]
+ if i < 1 || i > 8 || !isAlphaNum(token) {
+ s.gobble(ErrSyntax)
+ continue
+ }
+ s.token = token
+ return end
+ }
+ if n := len(s.b); n > 0 && s.b[n-1] == '-' {
+ s.setError(ErrSyntax)
+ s.b = s.b[:len(s.b)-1]
+ }
+ s.done = true
+ return end
+}
+
+// acceptMinSize parses multiple tokens of the given size or greater.
+// It returns the end position of the last token consumed.
+func (s *scanner) acceptMinSize(min int) (end int) {
+ end = s.end
+ s.scan()
+ for ; len(s.token) >= min; s.scan() {
+ end = s.end
+ }
+ return end
+}
+
+// Parse parses the given BCP 47 string and returns a valid Tag. If parsing
+// failed it returns an error and any part of the tag that could be parsed.
+// If parsing succeeded but an unknown value was found, it returns
+// ValueError. The Tag returned in this case is just stripped of the unknown
+// value. All other values are preserved. It accepts tags in the BCP 47 format
+// and extensions to this standard defined in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+func Parse(s string) (t Tag, err error) {
+ // TODO: consider supporting old-style locale key-value pairs.
+ if s == "" {
+ return Und, ErrSyntax
+ }
+ defer func() {
+ if recover() != nil {
+ t = Und
+ err = ErrSyntax
+ return
+ }
+ }()
+ if len(s) <= maxAltTaglen {
+ b := [maxAltTaglen]byte{}
+ for i, c := range s {
+ // Generating invalid UTF-8 is okay as it won't match.
+ if 'A' <= c && c <= 'Z' {
+ c += 'a' - 'A'
+ } else if c == '_' {
+ c = '-'
+ }
+ b[i] = byte(c)
+ }
+ if t, ok := grandfathered(b); ok {
+ return t, nil
+ }
+ }
+ scan := makeScannerString(s)
+ return parse(&scan, s)
+}
+
+func parse(scan *scanner, s string) (t Tag, err error) {
+ t = Und
+ var end int
+ if n := len(scan.token); n <= 1 {
+ scan.toLower(0, len(scan.b))
+ if n == 0 || scan.token[0] != 'x' {
+ return t, ErrSyntax
+ }
+ end = parseExtensions(scan)
+ } else if n >= 4 {
+ return Und, ErrSyntax
+ } else { // the usual case
+ t, end = parseTag(scan, true)
+ if n := len(scan.token); n == 1 {
+ t.pExt = uint16(end)
+ end = parseExtensions(scan)
+ } else if end < len(scan.b) {
+ scan.setError(ErrSyntax)
+ scan.b = scan.b[:end]
+ }
+ }
+ if int(t.pVariant) < len(scan.b) {
+ if end < len(s) {
+ s = s[:end]
+ }
+ if len(s) > 0 && tag.Compare(s, scan.b) == 0 {
+ t.str = s
+ } else {
+ t.str = string(scan.b)
+ }
+ } else {
+ t.pVariant, t.pExt = 0, 0
+ }
+ return t, scan.err
+}
+
+// parseTag parses language, script, region and variants.
+// It returns a Tag and the end position in the input that was parsed.
+// If doNorm is true, then - will be normalized to .
+func parseTag(scan *scanner, doNorm bool) (t Tag, end int) {
+ var e error
+ // TODO: set an error if an unknown lang, script or region is encountered.
+ t.LangID, e = getLangID(scan.token)
+ scan.setError(e)
+ scan.replace(t.LangID.String())
+ langStart := scan.start
+ end = scan.scan()
+ for len(scan.token) == 3 && isAlpha(scan.token[0]) {
+ // From http://tools.ietf.org/html/bcp47, - tags are equivalent
+ // to a tag of the form .
+ if doNorm {
+ lang, e := getLangID(scan.token)
+ if lang != 0 {
+ t.LangID = lang
+ langStr := lang.String()
+ copy(scan.b[langStart:], langStr)
+ scan.b[langStart+len(langStr)] = '-'
+ scan.start = langStart + len(langStr) + 1
+ }
+ scan.gobble(e)
+ }
+ end = scan.scan()
+ }
+ if len(scan.token) == 4 && isAlpha(scan.token[0]) {
+ t.ScriptID, e = getScriptID(script, scan.token)
+ if t.ScriptID == 0 {
+ scan.gobble(e)
+ }
+ end = scan.scan()
+ }
+ if n := len(scan.token); n >= 2 && n <= 3 {
+ t.RegionID, e = getRegionID(scan.token)
+ if t.RegionID == 0 {
+ scan.gobble(e)
+ } else {
+ scan.replace(t.RegionID.String())
+ }
+ end = scan.scan()
+ }
+ scan.toLower(scan.start, len(scan.b))
+ t.pVariant = byte(end)
+ end = parseVariants(scan, end, t)
+ t.pExt = uint16(end)
+ return t, end
+}
+
+var separator = []byte{'-'}
+
+// parseVariants scans tokens as long as each token is a valid variant string.
+// Duplicate variants are removed.
+func parseVariants(scan *scanner, end int, t Tag) int {
+ start := scan.start
+ varIDBuf := [4]uint8{}
+ variantBuf := [4][]byte{}
+ varID := varIDBuf[:0]
+ variant := variantBuf[:0]
+ last := -1
+ needSort := false
+ for ; len(scan.token) >= 4; scan.scan() {
+ // TODO: measure the impact of needing this conversion and redesign
+ // the data structure if there is an issue.
+ v, ok := variantIndex[string(scan.token)]
+ if !ok {
+ // unknown variant
+ // TODO: allow user-defined variants?
+ scan.gobble(NewValueError(scan.token))
+ continue
+ }
+ varID = append(varID, v)
+ variant = append(variant, scan.token)
+ if !needSort {
+ if last < int(v) {
+ last = int(v)
+ } else {
+ needSort = true
+ // There is no legal combinations of more than 7 variants
+ // (and this is by no means a useful sequence).
+ const maxVariants = 8
+ if len(varID) > maxVariants {
+ break
+ }
+ }
+ }
+ end = scan.end
+ }
+ if needSort {
+ sort.Sort(variantsSort{varID, variant})
+ k, l := 0, -1
+ for i, v := range varID {
+ w := int(v)
+ if l == w {
+ // Remove duplicates.
+ continue
+ }
+ varID[k] = varID[i]
+ variant[k] = variant[i]
+ k++
+ l = w
+ }
+ if str := bytes.Join(variant[:k], separator); len(str) == 0 {
+ end = start - 1
+ } else {
+ scan.resizeRange(start, end, len(str))
+ copy(scan.b[scan.start:], str)
+ end = scan.end
+ }
+ }
+ return end
+}
+
+type variantsSort struct {
+ i []uint8
+ v [][]byte
+}
+
+func (s variantsSort) Len() int {
+ return len(s.i)
+}
+
+func (s variantsSort) Swap(i, j int) {
+ s.i[i], s.i[j] = s.i[j], s.i[i]
+ s.v[i], s.v[j] = s.v[j], s.v[i]
+}
+
+func (s variantsSort) Less(i, j int) bool {
+ return s.i[i] < s.i[j]
+}
+
+type bytesSort struct {
+ b [][]byte
+ n int // first n bytes to compare
+}
+
+func (b bytesSort) Len() int {
+ return len(b.b)
+}
+
+func (b bytesSort) Swap(i, j int) {
+ b.b[i], b.b[j] = b.b[j], b.b[i]
+}
+
+func (b bytesSort) Less(i, j int) bool {
+ for k := 0; k < b.n; k++ {
+ if b.b[i][k] == b.b[j][k] {
+ continue
+ }
+ return b.b[i][k] < b.b[j][k]
+ }
+ return false
+}
+
+// parseExtensions parses and normalizes the extensions in the buffer.
+// It returns the last position of scan.b that is part of any extension.
+// It also trims scan.b to remove excess parts accordingly.
+func parseExtensions(scan *scanner) int {
+ start := scan.start
+ exts := [][]byte{}
+ private := []byte{}
+ end := scan.end
+ for len(scan.token) == 1 {
+ extStart := scan.start
+ ext := scan.token[0]
+ end = parseExtension(scan)
+ extension := scan.b[extStart:end]
+ if len(extension) < 3 || (ext != 'x' && len(extension) < 4) {
+ scan.setError(ErrSyntax)
+ end = extStart
+ continue
+ } else if start == extStart && (ext == 'x' || scan.start == len(scan.b)) {
+ scan.b = scan.b[:end]
+ return end
+ } else if ext == 'x' {
+ private = extension
+ break
+ }
+ exts = append(exts, extension)
+ }
+ sort.Sort(bytesSort{exts, 1})
+ if len(private) > 0 {
+ exts = append(exts, private)
+ }
+ scan.b = scan.b[:start]
+ if len(exts) > 0 {
+ scan.b = append(scan.b, bytes.Join(exts, separator)...)
+ } else if start > 0 {
+ // Strip trailing '-'.
+ scan.b = scan.b[:start-1]
+ }
+ return end
+}
+
+// parseExtension parses a single extension and returns the position of
+// the extension end.
+func parseExtension(scan *scanner) int {
+ start, end := scan.start, scan.end
+ switch scan.token[0] {
+ case 'u': // https://www.ietf.org/rfc/rfc6067.txt
+ attrStart := end
+ scan.scan()
+ for last := []byte{}; len(scan.token) > 2; scan.scan() {
+ if bytes.Compare(scan.token, last) != -1 {
+ // Attributes are unsorted. Start over from scratch.
+ p := attrStart + 1
+ scan.next = p
+ attrs := [][]byte{}
+ for scan.scan(); len(scan.token) > 2; scan.scan() {
+ attrs = append(attrs, scan.token)
+ end = scan.end
+ }
+ sort.Sort(bytesSort{attrs, 3})
+ copy(scan.b[p:], bytes.Join(attrs, separator))
+ break
+ }
+ last = scan.token
+ end = scan.end
+ }
+ // Scan key-type sequences. A key is of length 2 and may be followed
+ // by 0 or more "type" subtags from 3 to the maximum of 8 letters.
+ var last, key []byte
+ for attrEnd := end; len(scan.token) == 2; last = key {
+ key = scan.token
+ end = scan.end
+ for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() {
+ end = scan.end
+ }
+ // TODO: check key value validity
+ if bytes.Compare(key, last) != 1 || scan.err != nil {
+ // We have an invalid key or the keys are not sorted.
+ // Start scanning keys from scratch and reorder.
+ p := attrEnd + 1
+ scan.next = p
+ keys := [][]byte{}
+ for scan.scan(); len(scan.token) == 2; {
+ keyStart := scan.start
+ end = scan.end
+ for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() {
+ end = scan.end
+ }
+ keys = append(keys, scan.b[keyStart:end])
+ }
+ sort.Stable(bytesSort{keys, 2})
+ if n := len(keys); n > 0 {
+ k := 0
+ for i := 1; i < n; i++ {
+ if !bytes.Equal(keys[k][:2], keys[i][:2]) {
+ k++
+ keys[k] = keys[i]
+ } else if !bytes.Equal(keys[k], keys[i]) {
+ scan.setError(ErrDuplicateKey)
+ }
+ }
+ keys = keys[:k+1]
+ }
+ reordered := bytes.Join(keys, separator)
+ if e := p + len(reordered); e < end {
+ scan.deleteRange(e, end)
+ end = e
+ }
+ copy(scan.b[p:], reordered)
+ break
+ }
+ }
+ case 't': // https://www.ietf.org/rfc/rfc6497.txt
+ scan.scan()
+ if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) {
+ _, end = parseTag(scan, false)
+ scan.toLower(start, end)
+ }
+ for len(scan.token) == 2 && !isAlpha(scan.token[1]) {
+ end = scan.acceptMinSize(3)
+ }
+ case 'x':
+ end = scan.acceptMinSize(1)
+ default:
+ end = scan.acceptMinSize(2)
+ }
+ return end
+}
+
+// getExtension returns the name, body and end position of the extension.
+func getExtension(s string, p int) (end int, ext string) {
+ if s[p] == '-' {
+ p++
+ }
+ if s[p] == 'x' {
+ return len(s), s[p:]
+ }
+ end = nextExtension(s, p)
+ return end, s[p:end]
+}
+
+// nextExtension finds the next extension within the string, searching
+// for the -- pattern from position p.
+// In the fast majority of cases, language tags will have at most
+// one extension and extensions tend to be small.
+func nextExtension(s string, p int) int {
+ for n := len(s) - 3; p < n; {
+ if s[p] == '-' {
+ if s[p+2] == '-' {
+ return p
+ }
+ p += 3
+ } else {
+ p++
+ }
+ }
+ return len(s)
+}
diff --git a/vendor/golang.org/x/text/internal/language/tables.go b/vendor/golang.org/x/text/internal/language/tables.go
new file mode 100644
index 000000000..14167e74e
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/tables.go
@@ -0,0 +1,3494 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package language
+
+import "golang.org/x/text/internal/tag"
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "32"
+
+const NumLanguages = 8798
+
+const NumScripts = 261
+
+const NumRegions = 358
+
+type FromTo struct {
+ From uint16
+ To uint16
+}
+
+const nonCanonicalUnd = 1201
+const (
+ _af = 22
+ _am = 39
+ _ar = 58
+ _az = 88
+ _bg = 126
+ _bn = 165
+ _ca = 215
+ _cs = 250
+ _da = 257
+ _de = 269
+ _el = 310
+ _en = 313
+ _es = 318
+ _et = 320
+ _fa = 328
+ _fi = 337
+ _fil = 339
+ _fr = 350
+ _gu = 420
+ _he = 444
+ _hi = 446
+ _hr = 465
+ _hu = 469
+ _hy = 471
+ _id = 481
+ _is = 504
+ _it = 505
+ _ja = 512
+ _ka = 528
+ _kk = 578
+ _km = 586
+ _kn = 593
+ _ko = 596
+ _ky = 650
+ _lo = 696
+ _lt = 704
+ _lv = 711
+ _mk = 767
+ _ml = 772
+ _mn = 779
+ _mo = 784
+ _mr = 795
+ _ms = 799
+ _mul = 806
+ _my = 817
+ _nb = 839
+ _ne = 849
+ _nl = 871
+ _no = 879
+ _pa = 925
+ _pl = 947
+ _pt = 960
+ _ro = 988
+ _ru = 994
+ _sh = 1031
+ _si = 1036
+ _sk = 1042
+ _sl = 1046
+ _sq = 1073
+ _sr = 1074
+ _sv = 1092
+ _sw = 1093
+ _ta = 1104
+ _te = 1121
+ _th = 1131
+ _tl = 1146
+ _tn = 1152
+ _tr = 1162
+ _uk = 1198
+ _ur = 1204
+ _uz = 1212
+ _vi = 1219
+ _zh = 1321
+ _zu = 1327
+ _jbo = 515
+ _ami = 1650
+ _bnn = 2357
+ _hak = 438
+ _tlh = 14467
+ _lb = 661
+ _nv = 899
+ _pwn = 12055
+ _tao = 14188
+ _tay = 14198
+ _tsu = 14662
+ _nn = 874
+ _sfb = 13629
+ _vgt = 15701
+ _sgg = 13660
+ _cmn = 3007
+ _nan = 835
+ _hsn = 467
+)
+
+const langPrivateStart = 0x2f72
+
+const langPrivateEnd = 0x3179
+
+// lang holds an alphabetically sorted list of ISO-639 language identifiers.
+// All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag.
+// For 2-byte language identifiers, the two successive bytes have the following meaning:
+// - if the first letter of the 2- and 3-letter ISO codes are the same:
+// the second and third letter of the 3-letter ISO code.
+// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3.
+//
+// For 3-byte language identifiers the 4th byte is 0.
+const lang tag.Index = "" + // Size: 5324 bytes
+ "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" +
+ "cd\x00ace\x00ach\x00ada\x00ade\x00adj\x00ady\x00adz\x00aeveaeb\x00aey" +
+ "\x00affragc\x00agd\x00agg\x00agm\x00ago\x00agq\x00aha\x00ahl\x00aho\x00a" +
+ "jg\x00akkaakk\x00ala\x00ali\x00aln\x00alt\x00ammhamm\x00amn\x00amo\x00am" +
+ "p\x00anrganc\x00ank\x00ann\x00any\x00aoj\x00aom\x00aoz\x00apc\x00apd\x00" +
+ "ape\x00apr\x00aps\x00apz\x00arraarc\x00arh\x00arn\x00aro\x00arq\x00ars" +
+ "\x00ary\x00arz\x00assmasa\x00ase\x00asg\x00aso\x00ast\x00ata\x00atg\x00a" +
+ "tj\x00auy\x00avvaavl\x00avn\x00avt\x00avu\x00awa\x00awb\x00awo\x00awx" +
+ "\x00ayymayb\x00azzebaakbal\x00ban\x00bap\x00bar\x00bas\x00bav\x00bax\x00" +
+ "bba\x00bbb\x00bbc\x00bbd\x00bbj\x00bbp\x00bbr\x00bcf\x00bch\x00bci\x00bc" +
+ "m\x00bcn\x00bco\x00bcq\x00bcu\x00bdd\x00beelbef\x00beh\x00bej\x00bem\x00" +
+ "bet\x00bew\x00bex\x00bez\x00bfd\x00bfq\x00bft\x00bfy\x00bgulbgc\x00bgn" +
+ "\x00bgx\x00bhihbhb\x00bhg\x00bhi\x00bhk\x00bhl\x00bho\x00bhy\x00biisbib" +
+ "\x00big\x00bik\x00bim\x00bin\x00bio\x00biq\x00bjh\x00bji\x00bjj\x00bjn" +
+ "\x00bjo\x00bjr\x00bjt\x00bjz\x00bkc\x00bkm\x00bkq\x00bku\x00bkv\x00blt" +
+ "\x00bmambmh\x00bmk\x00bmq\x00bmu\x00bnenbng\x00bnm\x00bnp\x00boodboj\x00" +
+ "bom\x00bon\x00bpy\x00bqc\x00bqi\x00bqp\x00bqv\x00brrebra\x00brh\x00brx" +
+ "\x00brz\x00bsosbsj\x00bsq\x00bss\x00bst\x00bto\x00btt\x00btv\x00bua\x00b" +
+ "uc\x00bud\x00bug\x00buk\x00bum\x00buo\x00bus\x00buu\x00bvb\x00bwd\x00bwr" +
+ "\x00bxh\x00bye\x00byn\x00byr\x00bys\x00byv\x00byx\x00bza\x00bze\x00bzf" +
+ "\x00bzh\x00bzw\x00caatcan\x00cbj\x00cch\x00ccp\x00ceheceb\x00cfa\x00cgg" +
+ "\x00chhachk\x00chm\x00cho\x00chp\x00chr\x00cja\x00cjm\x00cjv\x00ckb\x00c" +
+ "kl\x00cko\x00cky\x00cla\x00cme\x00cmg\x00cooscop\x00cps\x00crrecrh\x00cr" +
+ "j\x00crk\x00crl\x00crm\x00crs\x00csescsb\x00csw\x00ctd\x00cuhucvhvcyymda" +
+ "andad\x00daf\x00dag\x00dah\x00dak\x00dar\x00dav\x00dbd\x00dbq\x00dcc\x00" +
+ "ddn\x00deeuded\x00den\x00dga\x00dgh\x00dgi\x00dgl\x00dgr\x00dgz\x00dia" +
+ "\x00dje\x00dnj\x00dob\x00doi\x00dop\x00dow\x00dri\x00drs\x00dsb\x00dtm" +
+ "\x00dtp\x00dts\x00dty\x00dua\x00duc\x00dud\x00dug\x00dvivdva\x00dww\x00d" +
+ "yo\x00dyu\x00dzzodzg\x00ebu\x00eeweefi\x00egl\x00egy\x00eka\x00eky\x00el" +
+ "llema\x00emi\x00enngenn\x00enq\x00eopoeri\x00es\x00\x05esu\x00etstetr" +
+ "\x00ett\x00etu\x00etx\x00euusewo\x00ext\x00faasfaa\x00fab\x00fag\x00fai" +
+ "\x00fan\x00ffulffi\x00ffm\x00fiinfia\x00fil\x00fit\x00fjijflr\x00fmp\x00" +
+ "foaofod\x00fon\x00for\x00fpe\x00fqs\x00frrafrc\x00frp\x00frr\x00frs\x00f" +
+ "ub\x00fud\x00fue\x00fuf\x00fuh\x00fuq\x00fur\x00fuv\x00fuy\x00fvr\x00fyr" +
+ "ygalegaa\x00gaf\x00gag\x00gah\x00gaj\x00gam\x00gan\x00gaw\x00gay\x00gba" +
+ "\x00gbf\x00gbm\x00gby\x00gbz\x00gcr\x00gdlagde\x00gdn\x00gdr\x00geb\x00g" +
+ "ej\x00gel\x00gez\x00gfk\x00ggn\x00ghs\x00gil\x00gim\x00gjk\x00gjn\x00gju" +
+ "\x00gkn\x00gkp\x00gllgglk\x00gmm\x00gmv\x00gnrngnd\x00gng\x00god\x00gof" +
+ "\x00goi\x00gom\x00gon\x00gor\x00gos\x00got\x00grb\x00grc\x00grt\x00grw" +
+ "\x00gsw\x00guujgub\x00guc\x00gud\x00gur\x00guw\x00gux\x00guz\x00gvlvgvf" +
+ "\x00gvr\x00gvs\x00gwc\x00gwi\x00gwt\x00gyi\x00haauhag\x00hak\x00ham\x00h" +
+ "aw\x00haz\x00hbb\x00hdy\x00heebhhy\x00hiinhia\x00hif\x00hig\x00hih\x00hi" +
+ "l\x00hla\x00hlu\x00hmd\x00hmt\x00hnd\x00hne\x00hnj\x00hnn\x00hno\x00homo" +
+ "hoc\x00hoj\x00hot\x00hrrvhsb\x00hsn\x00htathuunhui\x00hyyehzerianaian" +
+ "\x00iar\x00iba\x00ibb\x00iby\x00ica\x00ich\x00idndidd\x00idi\x00idu\x00i" +
+ "eleife\x00igboigb\x00ige\x00iiiiijj\x00ikpkikk\x00ikt\x00ikw\x00ikx\x00i" +
+ "lo\x00imo\x00inndinh\x00iodoiou\x00iri\x00isslittaiukuiw\x00\x03iwm\x00i" +
+ "ws\x00izh\x00izi\x00japnjab\x00jam\x00jbo\x00jbu\x00jen\x00jgk\x00jgo" +
+ "\x00ji\x00\x06jib\x00jmc\x00jml\x00jra\x00jut\x00jvavjwavkaatkaa\x00kab" +
+ "\x00kac\x00kad\x00kai\x00kaj\x00kam\x00kao\x00kbd\x00kbm\x00kbp\x00kbq" +
+ "\x00kbx\x00kby\x00kcg\x00kck\x00kcl\x00kct\x00kde\x00kdh\x00kdl\x00kdt" +
+ "\x00kea\x00ken\x00kez\x00kfo\x00kfr\x00kfy\x00kgonkge\x00kgf\x00kgp\x00k" +
+ "ha\x00khb\x00khn\x00khq\x00khs\x00kht\x00khw\x00khz\x00kiikkij\x00kiu" +
+ "\x00kiw\x00kjuakjd\x00kjg\x00kjs\x00kjy\x00kkazkkc\x00kkj\x00klalkln\x00" +
+ "klq\x00klt\x00klx\x00kmhmkmb\x00kmh\x00kmo\x00kms\x00kmu\x00kmw\x00knank" +
+ "nf\x00knp\x00koorkoi\x00kok\x00kol\x00kos\x00koz\x00kpe\x00kpf\x00kpo" +
+ "\x00kpr\x00kpx\x00kqb\x00kqf\x00kqs\x00kqy\x00kraukrc\x00kri\x00krj\x00k" +
+ "rl\x00krs\x00kru\x00ksasksb\x00ksd\x00ksf\x00ksh\x00ksj\x00ksr\x00ktb" +
+ "\x00ktm\x00kto\x00kuurkub\x00kud\x00kue\x00kuj\x00kum\x00kun\x00kup\x00k" +
+ "us\x00kvomkvg\x00kvr\x00kvx\x00kw\x00\x01kwj\x00kwo\x00kxa\x00kxc\x00kxm" +
+ "\x00kxp\x00kxw\x00kxz\x00kyirkye\x00kyx\x00kzr\x00laatlab\x00lad\x00lag" +
+ "\x00lah\x00laj\x00las\x00lbtzlbe\x00lbu\x00lbw\x00lcm\x00lcp\x00ldb\x00l" +
+ "ed\x00lee\x00lem\x00lep\x00leq\x00leu\x00lez\x00lguglgg\x00liimlia\x00li" +
+ "d\x00lif\x00lig\x00lih\x00lij\x00lis\x00ljp\x00lki\x00lkt\x00lle\x00lln" +
+ "\x00lmn\x00lmo\x00lmp\x00lninlns\x00lnu\x00loaoloj\x00lok\x00lol\x00lor" +
+ "\x00los\x00loz\x00lrc\x00ltitltg\x00luublua\x00luo\x00luy\x00luz\x00lvav" +
+ "lwl\x00lzh\x00lzz\x00mad\x00maf\x00mag\x00mai\x00mak\x00man\x00mas\x00ma" +
+ "w\x00maz\x00mbh\x00mbo\x00mbq\x00mbu\x00mbw\x00mci\x00mcp\x00mcq\x00mcr" +
+ "\x00mcu\x00mda\x00mde\x00mdf\x00mdh\x00mdj\x00mdr\x00mdx\x00med\x00mee" +
+ "\x00mek\x00men\x00mer\x00met\x00meu\x00mfa\x00mfe\x00mfn\x00mfo\x00mfq" +
+ "\x00mglgmgh\x00mgl\x00mgo\x00mgp\x00mgy\x00mhahmhi\x00mhl\x00mirimif\x00" +
+ "min\x00mis\x00miw\x00mkkdmki\x00mkl\x00mkp\x00mkw\x00mlalmle\x00mlp\x00m" +
+ "ls\x00mmo\x00mmu\x00mmx\x00mnonmna\x00mnf\x00mni\x00mnw\x00moolmoa\x00mo" +
+ "e\x00moh\x00mos\x00mox\x00mpp\x00mps\x00mpt\x00mpx\x00mql\x00mrarmrd\x00" +
+ "mrj\x00mro\x00mssamtltmtc\x00mtf\x00mti\x00mtr\x00mua\x00mul\x00mur\x00m" +
+ "us\x00mva\x00mvn\x00mvy\x00mwk\x00mwr\x00mwv\x00mxc\x00mxm\x00myyamyk" +
+ "\x00mym\x00myv\x00myw\x00myx\x00myz\x00mzk\x00mzm\x00mzn\x00mzp\x00mzw" +
+ "\x00mzz\x00naaunac\x00naf\x00nah\x00nak\x00nan\x00nap\x00naq\x00nas\x00n" +
+ "bobnca\x00nce\x00ncf\x00nch\x00nco\x00ncu\x00nddendc\x00nds\x00neepneb" +
+ "\x00new\x00nex\x00nfr\x00ngdonga\x00ngb\x00ngl\x00nhb\x00nhe\x00nhw\x00n" +
+ "if\x00nii\x00nij\x00nin\x00niu\x00niy\x00niz\x00njo\x00nkg\x00nko\x00nll" +
+ "dnmg\x00nmz\x00nnnonnf\x00nnh\x00nnk\x00nnm\x00noornod\x00noe\x00non\x00" +
+ "nop\x00nou\x00nqo\x00nrblnrb\x00nsk\x00nsn\x00nso\x00nss\x00ntm\x00ntr" +
+ "\x00nui\x00nup\x00nus\x00nuv\x00nux\x00nvavnwb\x00nxq\x00nxr\x00nyyanym" +
+ "\x00nyn\x00nzi\x00occiogc\x00ojjiokr\x00okv\x00omrmong\x00onn\x00ons\x00" +
+ "opm\x00orrioro\x00oru\x00osssosa\x00ota\x00otk\x00ozm\x00paanpag\x00pal" +
+ "\x00pam\x00pap\x00pau\x00pbi\x00pcd\x00pcm\x00pdc\x00pdt\x00ped\x00peo" +
+ "\x00pex\x00pfl\x00phl\x00phn\x00pilipil\x00pip\x00pka\x00pko\x00plolpla" +
+ "\x00pms\x00png\x00pnn\x00pnt\x00pon\x00ppo\x00pra\x00prd\x00prg\x00psusp" +
+ "ss\x00ptorptp\x00puu\x00pwa\x00quuequc\x00qug\x00rai\x00raj\x00rao\x00rc" +
+ "f\x00rej\x00rel\x00res\x00rgn\x00rhg\x00ria\x00rif\x00rjs\x00rkt\x00rmoh" +
+ "rmf\x00rmo\x00rmt\x00rmu\x00rnunrna\x00rng\x00roonrob\x00rof\x00roo\x00r" +
+ "ro\x00rtm\x00ruusrue\x00rug\x00rw\x00\x04rwk\x00rwo\x00ryu\x00saansaf" +
+ "\x00sah\x00saq\x00sas\x00sat\x00sav\x00saz\x00sba\x00sbe\x00sbp\x00scrds" +
+ "ck\x00scl\x00scn\x00sco\x00scs\x00sdndsdc\x00sdh\x00semesef\x00seh\x00se" +
+ "i\x00ses\x00sgagsga\x00sgs\x00sgw\x00sgz\x00sh\x00\x02shi\x00shk\x00shn" +
+ "\x00shu\x00siinsid\x00sig\x00sil\x00sim\x00sjr\x00sklkskc\x00skr\x00sks" +
+ "\x00sllvsld\x00sli\x00sll\x00sly\x00smmosma\x00smi\x00smj\x00smn\x00smp" +
+ "\x00smq\x00sms\x00snnasnc\x00snk\x00snp\x00snx\x00sny\x00soomsok\x00soq" +
+ "\x00sou\x00soy\x00spd\x00spl\x00sps\x00sqqisrrpsrb\x00srn\x00srr\x00srx" +
+ "\x00ssswssd\x00ssg\x00ssy\x00stotstk\x00stq\x00suunsua\x00sue\x00suk\x00" +
+ "sur\x00sus\x00svweswwaswb\x00swc\x00swg\x00swp\x00swv\x00sxn\x00sxw\x00s" +
+ "yl\x00syr\x00szl\x00taamtaj\x00tal\x00tan\x00taq\x00tbc\x00tbd\x00tbf" +
+ "\x00tbg\x00tbo\x00tbw\x00tbz\x00tci\x00tcy\x00tdd\x00tdg\x00tdh\x00teelt" +
+ "ed\x00tem\x00teo\x00tet\x00tfi\x00tggktgc\x00tgo\x00tgu\x00thhathl\x00th" +
+ "q\x00thr\x00tiirtif\x00tig\x00tik\x00tim\x00tio\x00tiv\x00tkuktkl\x00tkr" +
+ "\x00tkt\x00tlgltlf\x00tlx\x00tly\x00tmh\x00tmy\x00tnsntnh\x00toontof\x00" +
+ "tog\x00toq\x00tpi\x00tpm\x00tpz\x00tqo\x00trurtru\x00trv\x00trw\x00tssot" +
+ "sd\x00tsf\x00tsg\x00tsj\x00tsw\x00ttatttd\x00tte\x00ttj\x00ttr\x00tts" +
+ "\x00ttt\x00tuh\x00tul\x00tum\x00tuq\x00tvd\x00tvl\x00tvu\x00twwitwh\x00t" +
+ "wq\x00txg\x00tyahtya\x00tyv\x00tzm\x00ubu\x00udm\x00ugiguga\x00ukkruli" +
+ "\x00umb\x00und\x00unr\x00unx\x00urrduri\x00urt\x00urw\x00usa\x00utr\x00u" +
+ "vh\x00uvl\x00uzzbvag\x00vai\x00van\x00veenvec\x00vep\x00viievic\x00viv" +
+ "\x00vls\x00vmf\x00vmw\x00voolvot\x00vro\x00vun\x00vut\x00walnwae\x00waj" +
+ "\x00wal\x00wan\x00war\x00wbp\x00wbq\x00wbr\x00wci\x00wer\x00wgi\x00whg" +
+ "\x00wib\x00wiu\x00wiv\x00wja\x00wji\x00wls\x00wmo\x00wnc\x00wni\x00wnu" +
+ "\x00woolwob\x00wos\x00wrs\x00wsk\x00wtm\x00wuu\x00wuv\x00wwa\x00xav\x00x" +
+ "bi\x00xcr\x00xes\x00xhhoxla\x00xlc\x00xld\x00xmf\x00xmn\x00xmr\x00xna" +
+ "\x00xnr\x00xog\x00xon\x00xpr\x00xrb\x00xsa\x00xsi\x00xsm\x00xsr\x00xwe" +
+ "\x00yam\x00yao\x00yap\x00yas\x00yat\x00yav\x00yay\x00yaz\x00yba\x00ybb" +
+ "\x00yby\x00yer\x00ygr\x00ygw\x00yiidyko\x00yle\x00ylg\x00yll\x00yml\x00y" +
+ "ooryon\x00yrb\x00yre\x00yrl\x00yss\x00yua\x00yue\x00yuj\x00yut\x00yuw" +
+ "\x00zahazag\x00zbl\x00zdj\x00zea\x00zgh\x00zhhozhx\x00zia\x00zlm\x00zmi" +
+ "\x00zne\x00zuulzxx\x00zza\x00\xff\xff\xff\xff"
+
+const langNoIndexOffset = 1330
+
+// langNoIndex is a bit vector of all 3-letter language codes that are not used as an index
+// in lookup tables. The language ids for these language codes are derived directly
+// from the letters and are not consecutive.
+// Size: 2197 bytes, 2197 elements
+var langNoIndex = [2197]uint8{
+ // Entry 0 - 3F
+ 0xff, 0xf8, 0xed, 0xfe, 0xeb, 0xd3, 0x3b, 0xd2,
+ 0xfb, 0xbf, 0x7a, 0xfa, 0x37, 0x1d, 0x3c, 0x57,
+ 0x6e, 0x97, 0x73, 0x38, 0xfb, 0xea, 0xbf, 0x70,
+ 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x72,
+ 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77,
+ 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2,
+ 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xbc, 0x0a, 0x6a,
+ 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff,
+ // Entry 40 - 7F
+ 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0,
+ 0x5d, 0xe3, 0x97, 0x14, 0x07, 0x20, 0xdd, 0xed,
+ 0x9f, 0x3f, 0xc9, 0x21, 0xf8, 0x3f, 0x94, 0x35,
+ 0x7c, 0x5f, 0xff, 0x5f, 0x8e, 0x6e, 0xdf, 0xff,
+ 0xff, 0xff, 0x55, 0x7c, 0xd3, 0xfd, 0xbf, 0xb5,
+ 0x7b, 0xdf, 0x7f, 0xf7, 0xca, 0xfe, 0xdb, 0xa3,
+ 0xa8, 0xff, 0x1f, 0x67, 0x7d, 0xeb, 0xef, 0xce,
+ 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf,
+ // Entry 80 - BF
+ 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x7f, 0xff, 0xff,
+ 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7,
+ 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba,
+ 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff,
+ 0xfd, 0xdf, 0xfb, 0xfe, 0x9d, 0xb4, 0xd3, 0xff,
+ 0xef, 0xff, 0xdf, 0xf7, 0x7f, 0xb7, 0xfd, 0xd5,
+ 0xa5, 0x77, 0x40, 0xff, 0x9c, 0xc1, 0x41, 0x2c,
+ 0x08, 0x21, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80,
+ // Entry C0 - FF
+ 0xfb, 0x4a, 0xf2, 0x9f, 0xb4, 0x42, 0x41, 0x96,
+ 0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56,
+ 0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7f, 0xf3, 0xef,
+ 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10,
+ 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x7b, 0x35,
+ 0x3e, 0xc7, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00,
+ 0xb0, 0x05, 0x80, 0x00, 0x20, 0x00, 0x00, 0x03,
+ 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d,
+ // Entry 100 - 13F
+ 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64,
+ 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00,
+ 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3,
+ 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x41, 0x0c,
+ 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f,
+ 0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56,
+ 0x90, 0x6d, 0x01, 0x2e, 0x96, 0x69, 0x20, 0xfb,
+ // Entry 140 - 17F
+ 0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x16,
+ 0x03, 0x00, 0x00, 0xb0, 0x14, 0x23, 0x50, 0x06,
+ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09,
+ 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x05,
+ 0x08, 0x00, 0x00, 0x05, 0x00, 0x80, 0x28, 0x04,
+ 0x00, 0x00, 0x40, 0xd5, 0x2d, 0x00, 0x64, 0x35,
+ 0x24, 0x52, 0xf4, 0xd5, 0xbf, 0x62, 0xc9, 0x03,
+ // Entry 180 - 1BF
+ 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98,
+ 0x21, 0x18, 0x81, 0x08, 0x00, 0x01, 0x40, 0x82,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x40, 0x00, 0x44, 0x00, 0x00, 0x80, 0xea,
+ 0xa9, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ // Entry 1C0 - 1FF
+ 0x00, 0x03, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x20, 0x04, 0xa6, 0x00, 0x04, 0x00, 0x00,
+ 0x81, 0x50, 0x00, 0x00, 0x00, 0x11, 0x84, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x55,
+ 0x02, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x40,
+ 0x30, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0xcd, 0xbf, 0x7a, 0xbf,
+ // Entry 200 - 23F
+ 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27,
+ 0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5,
+ 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe1, 0xdf,
+ 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x81, 0xe3,
+ 0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d,
+ 0x79, 0xed, 0x1c, 0x7f, 0x04, 0x08, 0x00, 0x01,
+ 0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f,
+ 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54,
+ // Entry 240 - 27F
+ 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00,
+ 0x20, 0x7b, 0x78, 0x02, 0x07, 0x84, 0x00, 0xf0,
+ 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00,
+ 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04,
+ 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00,
+ 0x91, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff,
+ 0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66,
+ // Entry 280 - 2BF
+ 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05,
+ 0xb5, 0xb6, 0x80, 0x08, 0x04, 0x00, 0x04, 0x51,
+ 0xe2, 0xef, 0xfd, 0x3f, 0x05, 0x09, 0x08, 0x05,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60,
+ 0xe7, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80,
+ 0x03, 0x00, 0x00, 0x00, 0x8c, 0x50, 0x40, 0x04,
+ 0x84, 0x47, 0x84, 0x40, 0x20, 0x10, 0x00, 0x20,
+ // Entry 2C0 - 2FF
+ 0x02, 0x50, 0x80, 0x11, 0x00, 0x99, 0x6c, 0xe2,
+ 0x50, 0x27, 0x1d, 0x11, 0x29, 0x0e, 0x59, 0xe9,
+ 0x33, 0x08, 0x00, 0x20, 0x04, 0x40, 0x10, 0x00,
+ 0x00, 0x00, 0x50, 0x44, 0x92, 0x49, 0xd6, 0x5d,
+ 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00,
+ 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01,
+ 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x40, 0x08,
+ 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x8d, 0x12, 0x00,
+ // Entry 300 - 33F
+ 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0,
+ 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80,
+ 0x00, 0x01, 0xd0, 0x16, 0x40, 0x00, 0x10, 0xb0,
+ 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00,
+ 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80,
+ 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0xd8, 0x6f, 0x15, 0x02, 0x08, 0x00,
+ // Entry 340 - 37F
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xe3,
+ 0xdd, 0xbf, 0xf9, 0xf9, 0x3b, 0x7f, 0x7f, 0xdb,
+ 0xfd, 0xfc, 0xfe, 0xdf, 0xff, 0xfd, 0xff, 0xf6,
+ 0xfb, 0xfc, 0xf7, 0x1f, 0xff, 0xb3, 0x6c, 0xff,
+ 0xd9, 0xad, 0xdf, 0xfe, 0xef, 0xba, 0xdf, 0xff,
+ 0xff, 0xff, 0xb7, 0xdd, 0x7d, 0xbf, 0xab, 0x7f,
+ 0xfd, 0xfd, 0xdf, 0x2f, 0x9c, 0xdf, 0xf3, 0x6f,
+ // Entry 380 - 3BF
+ 0xdf, 0xdd, 0xff, 0xfb, 0xee, 0xd2, 0xab, 0x5f,
+ 0xd5, 0xdf, 0x7f, 0xff, 0xeb, 0xff, 0xe4, 0x4d,
+ 0xf9, 0xff, 0xfe, 0xf7, 0xfd, 0xdf, 0xfb, 0xbf,
+ 0xee, 0xdb, 0x6f, 0xef, 0xff, 0x7f, 0xff, 0xff,
+ 0xf7, 0x5f, 0xd3, 0x3b, 0xfd, 0xd9, 0xdf, 0xeb,
+ 0xbc, 0x08, 0x05, 0x24, 0xff, 0x07, 0x70, 0xfe,
+ 0xe6, 0x5e, 0x00, 0x08, 0x00, 0x83, 0x7d, 0x1f,
+ 0x06, 0xe6, 0x72, 0x60, 0xd1, 0x3c, 0x7f, 0x44,
+ // Entry 3C0 - 3FF
+ 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57,
+ 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7,
+ 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x20,
+ 0x40, 0x54, 0x9f, 0x8a, 0xdf, 0xf9, 0x6e, 0x11,
+ 0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x03,
+ 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x40, 0x00, 0x10,
+ 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2,
+ 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe,
+ // Entry 400 - 43F
+ 0x53, 0x6f, 0xdf, 0xe7, 0xdb, 0x65, 0xbb, 0x7f,
+ 0xfa, 0xff, 0x77, 0xf3, 0xef, 0xbf, 0xfd, 0xf7,
+ 0xdf, 0xdf, 0x9b, 0x7f, 0xff, 0xff, 0x7f, 0x6f,
+ 0xf7, 0xfb, 0xeb, 0xdf, 0xbc, 0xff, 0xbf, 0x6b,
+ 0x7b, 0xfb, 0xff, 0xce, 0x76, 0xbd, 0xf7, 0xf7,
+ 0xdf, 0xdc, 0xf7, 0xf7, 0xff, 0xdf, 0xf3, 0xfe,
+ 0xef, 0xff, 0xff, 0xff, 0xb6, 0x7f, 0x7f, 0xde,
+ 0xf7, 0xb9, 0xeb, 0x77, 0xff, 0xfb, 0xbf, 0xdf,
+ // Entry 440 - 47F
+ 0xfd, 0xfe, 0xfb, 0xff, 0xfe, 0xeb, 0x1f, 0x7d,
+ 0x2f, 0xfd, 0xb6, 0xb5, 0xa5, 0xfc, 0xff, 0xfd,
+ 0x7f, 0x4e, 0xbf, 0x8f, 0xae, 0xff, 0xee, 0xdf,
+ 0x7f, 0xf7, 0x73, 0x02, 0x02, 0x04, 0xfc, 0xf7,
+ 0xff, 0xb7, 0xd7, 0xef, 0xfe, 0xcd, 0xf5, 0xce,
+ 0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xfd,
+ 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff,
+ 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4,
+ // Entry 480 - 4BF
+ 0x93, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb,
+ 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20,
+ 0x14, 0x00, 0x55, 0x51, 0xc2, 0x65, 0xf5, 0x41,
+ 0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x85, 0xc5, 0x05,
+ 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x05,
+ 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00,
+ 0x06, 0x11, 0x20, 0x00, 0x18, 0x01, 0x92, 0xf1,
+ // Entry 4C0 - 4FF
+ 0xfd, 0x47, 0x69, 0x06, 0x95, 0x06, 0x57, 0xed,
+ 0xfb, 0x4d, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40,
+ 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83,
+ 0xb8, 0x4f, 0x10, 0x8e, 0x89, 0x46, 0xde, 0xf7,
+ 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00,
+ 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d,
+ 0xbe, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41,
+ // Entry 500 - 53F
+ 0x30, 0xff, 0x79, 0x72, 0x04, 0x00, 0x00, 0x49,
+ 0x2d, 0x14, 0x27, 0x5f, 0xed, 0xf1, 0x3f, 0xe7,
+ 0x3f, 0x00, 0x00, 0x02, 0xc6, 0xa0, 0x1e, 0xf8,
+ 0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe7, 0xf7,
+ 0xfd, 0xfc, 0xd5, 0xed, 0x47, 0xf4, 0x7e, 0x10,
+ 0x01, 0x01, 0x84, 0x6d, 0xff, 0xf7, 0xdd, 0xf9,
+ 0x5b, 0x05, 0x86, 0xed, 0xf5, 0x77, 0xbd, 0x3c,
+ 0x00, 0x00, 0x00, 0x42, 0x71, 0x42, 0x00, 0x40,
+ // Entry 540 - 57F
+ 0x00, 0x00, 0x01, 0x43, 0x19, 0x24, 0x08, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ // Entry 580 - 5BF
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xab, 0xbd, 0xe7, 0x57, 0xee, 0x13, 0x5d,
+ 0x09, 0xc1, 0x40, 0x21, 0xfa, 0x17, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xce, 0xfb, 0xbf,
+ 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x30, 0x15, 0xa3, 0x10, 0x00, 0x00, 0x00,
+ 0x11, 0x04, 0x16, 0x00, 0x00, 0x02, 0x20, 0x81,
+ 0xa3, 0x01, 0x50, 0x00, 0x00, 0x83, 0x11, 0x40,
+ // Entry 5C0 - 5FF
+ 0x00, 0x00, 0x00, 0xf0, 0xdd, 0x7b, 0xbe, 0x02,
+ 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02,
+ 0x3d, 0x40, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d,
+ 0x31, 0x00, 0x00, 0x00, 0x01, 0x18, 0x02, 0x20,
+ 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00,
+ 0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f,
+ 0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe,
+ // Entry 600 - 63F
+ 0x7b, 0x4b, 0x40, 0x10, 0xe1, 0xfd, 0xaf, 0xd9,
+ 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1,
+ 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7,
+ 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd,
+ 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x9f,
+ 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe,
+ 0xbe, 0x5f, 0x46, 0x5b, 0xe9, 0x5f, 0x50, 0x18,
+ 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f,
+ // Entry 640 - 67F
+ 0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c,
+ 0xff, 0xe4, 0xef, 0x6f, 0xff, 0xfc, 0xdd, 0xde,
+ 0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x3f, 0x00, 0x98,
+ 0x02, 0xfb, 0xa3, 0xef, 0xf3, 0xd6, 0xf2, 0xff,
+ 0xb9, 0xda, 0x7d, 0xd0, 0x3e, 0x15, 0x7b, 0xb4,
+ 0xf5, 0x3e, 0xff, 0xff, 0xf1, 0xf7, 0xff, 0xe7,
+ 0x5f, 0xff, 0xff, 0x9e, 0xdf, 0xf6, 0xd7, 0xb9,
+ 0xef, 0x27, 0x80, 0xbb, 0xc5, 0xff, 0xff, 0xe3,
+ // Entry 680 - 6BF
+ 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37,
+ 0xce, 0x7f, 0x44, 0x1d, 0x73, 0x7f, 0xf8, 0xda,
+ 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x79, 0xa0,
+ 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08,
+ 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00,
+ 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x09, 0x06,
+ 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00,
+ 0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f,
+ // Entry 6C0 - 6FF
+ 0x54, 0x4d, 0xf1, 0x16, 0x44, 0xd5, 0x42, 0x08,
+ 0x40, 0x02, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41,
+ 0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x80, 0x10, 0x10, 0xab,
+ 0x6d, 0x93, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x25, 0x00, 0x00,
+ // Entry 700 - 73F
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x80, 0x86, 0xc2, 0x00, 0x00, 0x01, 0x00, 0x01,
+ 0xff, 0x18, 0x02, 0x00, 0x02, 0xf0, 0xfd, 0x79,
+ 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 740 - 77F
+ 0x00, 0x00, 0x00, 0xef, 0xd5, 0xfd, 0xcf, 0x7e,
+ 0xb0, 0x11, 0x00, 0x00, 0x00, 0x92, 0x01, 0x46,
+ 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04,
+ 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a,
+ 0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75,
+ 0x97, 0x7c, 0xdf, 0x31, 0xcc, 0x68, 0xd1, 0x03,
+ 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60,
+ // Entry 780 - 7BF
+ 0x83, 0x68, 0x01, 0x10, 0x8b, 0x38, 0x8a, 0x01,
+ 0x00, 0x00, 0x20, 0x00, 0x24, 0x44, 0x00, 0x00,
+ 0x10, 0x03, 0x31, 0x02, 0x01, 0x00, 0x00, 0xf0,
+ 0xf5, 0xff, 0xd5, 0x97, 0xbc, 0x70, 0xd6, 0x78,
+ 0x78, 0x15, 0x50, 0x05, 0xa4, 0x84, 0xa9, 0x41,
+ 0x00, 0x00, 0x00, 0x6b, 0x39, 0x52, 0x74, 0x40,
+ 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02,
+ 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed,
+ // Entry 7C0 - 7FF
+ 0xdd, 0xbf, 0xf2, 0x5d, 0xc7, 0x0c, 0xd5, 0x42,
+ 0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56,
+ 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff,
+ 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d,
+ 0x4e, 0x4a, 0x08, 0x50, 0x28, 0x30, 0xe0, 0x80,
+ 0x10, 0x20, 0x24, 0x00, 0xff, 0x2f, 0xd3, 0x60,
+ 0xfe, 0x01, 0x02, 0x88, 0x2a, 0x40, 0x16, 0x01,
+ 0x01, 0x15, 0x2b, 0x3c, 0x01, 0x00, 0x00, 0x10,
+ // Entry 800 - 83F
+ 0x90, 0x49, 0x41, 0x02, 0x02, 0x01, 0xe1, 0xbf,
+ 0xbf, 0x03, 0x00, 0x00, 0x10, 0xdc, 0xa3, 0xd1,
+ 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3,
+ 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80,
+ 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84,
+ 0x2f, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93,
+ 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10,
+ 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00,
+ // Entry 840 - 87F
+ 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x16, 0x89,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28,
+ 0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00,
+ 0x00, 0xcb, 0xe4, 0x3a, 0x46, 0x88, 0x54, 0xf1,
+ 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50,
+ 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40,
+ 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1,
+ // Entry 880 - 8BF
+ 0x76, 0x16, 0x08, 0x03, 0x10, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24,
+ 0x0a, 0x00, 0x80, 0x00, 0x00,
+}
+
+// altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives
+// to 2-letter language codes that cannot be derived using the method described above.
+// Each 3-letter code is followed by its 1-byte langID.
+const altLangISO3 tag.Index = "---\x00cor\x00hbs\x01heb\x02kin\x03spa\x04yid\x05\xff\xff\xff\xff"
+
+// altLangIndex is used to convert indexes in altLangISO3 to langIDs.
+// Size: 12 bytes, 6 elements
+var altLangIndex = [6]uint16{
+ 0x0281, 0x0407, 0x01fb, 0x03e5, 0x013e, 0x0208,
+}
+
+// AliasMap maps langIDs to their suggested replacements.
+// Size: 772 bytes, 193 elements
+var AliasMap = [193]FromTo{
+ 0: {From: 0x82, To: 0x88},
+ 1: {From: 0x187, To: 0x1ae},
+ 2: {From: 0x1f3, To: 0x1e1},
+ 3: {From: 0x1fb, To: 0x1bc},
+ 4: {From: 0x208, To: 0x512},
+ 5: {From: 0x20f, To: 0x20e},
+ 6: {From: 0x310, To: 0x3dc},
+ 7: {From: 0x347, To: 0x36f},
+ 8: {From: 0x407, To: 0x432},
+ 9: {From: 0x47a, To: 0x153},
+ 10: {From: 0x490, To: 0x451},
+ 11: {From: 0x4a2, To: 0x21},
+ 12: {From: 0x53e, To: 0x544},
+ 13: {From: 0x58f, To: 0x12d},
+ 14: {From: 0x62b, To: 0x34},
+ 15: {From: 0x62f, To: 0x14},
+ 16: {From: 0x630, To: 0x1eb1},
+ 17: {From: 0x651, To: 0x431},
+ 18: {From: 0x662, To: 0x431},
+ 19: {From: 0x6ed, To: 0x3a},
+ 20: {From: 0x6f8, To: 0x1d7},
+ 21: {From: 0x709, To: 0x3625},
+ 22: {From: 0x73e, To: 0x21a1},
+ 23: {From: 0x7b3, To: 0x56},
+ 24: {From: 0x7b9, To: 0x299b},
+ 25: {From: 0x7c5, To: 0x58},
+ 26: {From: 0x7e6, To: 0x145},
+ 27: {From: 0x80c, To: 0x5a},
+ 28: {From: 0x815, To: 0x8d},
+ 29: {From: 0x87e, To: 0x810},
+ 30: {From: 0x8a8, To: 0x8b7},
+ 31: {From: 0x8c3, To: 0xee3},
+ 32: {From: 0x8fa, To: 0x1dc},
+ 33: {From: 0x9ef, To: 0x331},
+ 34: {From: 0xa36, To: 0x2c5},
+ 35: {From: 0xa3d, To: 0xbf},
+ 36: {From: 0xabe, To: 0x3322},
+ 37: {From: 0xb38, To: 0x529},
+ 38: {From: 0xb75, To: 0x265a},
+ 39: {From: 0xb7e, To: 0xbc3},
+ 40: {From: 0xb9b, To: 0x44e},
+ 41: {From: 0xbbc, To: 0x4229},
+ 42: {From: 0xbbf, To: 0x529},
+ 43: {From: 0xbfe, To: 0x2da7},
+ 44: {From: 0xc2e, To: 0x3181},
+ 45: {From: 0xcb9, To: 0xf3},
+ 46: {From: 0xd08, To: 0xfa},
+ 47: {From: 0xdc8, To: 0x11a},
+ 48: {From: 0xdd7, To: 0x32d},
+ 49: {From: 0xdf8, To: 0xdfb},
+ 50: {From: 0xdfe, To: 0x531},
+ 51: {From: 0xe01, To: 0xdf3},
+ 52: {From: 0xedf, To: 0x205a},
+ 53: {From: 0xee9, To: 0x222e},
+ 54: {From: 0xeee, To: 0x2e9a},
+ 55: {From: 0xf39, To: 0x367},
+ 56: {From: 0x10d0, To: 0x140},
+ 57: {From: 0x1104, To: 0x2d0},
+ 58: {From: 0x11a0, To: 0x1ec},
+ 59: {From: 0x1279, To: 0x21},
+ 60: {From: 0x1424, To: 0x15e},
+ 61: {From: 0x1470, To: 0x14e},
+ 62: {From: 0x151f, To: 0xd9b},
+ 63: {From: 0x1523, To: 0x390},
+ 64: {From: 0x1532, To: 0x19f},
+ 65: {From: 0x1580, To: 0x210},
+ 66: {From: 0x1583, To: 0x10d},
+ 67: {From: 0x15a3, To: 0x3caf},
+ 68: {From: 0x1630, To: 0x222e},
+ 69: {From: 0x166a, To: 0x19b},
+ 70: {From: 0x16c8, To: 0x136},
+ 71: {From: 0x1700, To: 0x29f8},
+ 72: {From: 0x1718, To: 0x194},
+ 73: {From: 0x1727, To: 0xf3f},
+ 74: {From: 0x177a, To: 0x178},
+ 75: {From: 0x1809, To: 0x17b6},
+ 76: {From: 0x1816, To: 0x18f3},
+ 77: {From: 0x188a, To: 0x436},
+ 78: {From: 0x1979, To: 0x1d01},
+ 79: {From: 0x1a74, To: 0x2bb0},
+ 80: {From: 0x1a8a, To: 0x1f8},
+ 81: {From: 0x1b5a, To: 0x1fa},
+ 82: {From: 0x1b86, To: 0x1515},
+ 83: {From: 0x1d64, To: 0x2c9b},
+ 84: {From: 0x2038, To: 0x37b1},
+ 85: {From: 0x203d, To: 0x20dd},
+ 86: {From: 0x2042, To: 0x2e00},
+ 87: {From: 0x205a, To: 0x30b},
+ 88: {From: 0x20e3, To: 0x274},
+ 89: {From: 0x20ee, To: 0x263},
+ 90: {From: 0x20f2, To: 0x22d},
+ 91: {From: 0x20f9, To: 0x256},
+ 92: {From: 0x210f, To: 0x21eb},
+ 93: {From: 0x2135, To: 0x27d},
+ 94: {From: 0x2160, To: 0x913},
+ 95: {From: 0x2199, To: 0x121},
+ 96: {From: 0x21ce, To: 0x1561},
+ 97: {From: 0x21e6, To: 0x504},
+ 98: {From: 0x21f4, To: 0x49f},
+ 99: {From: 0x21fb, To: 0x269},
+ 100: {From: 0x222d, To: 0x121},
+ 101: {From: 0x2237, To: 0x121},
+ 102: {From: 0x2248, To: 0x217d},
+ 103: {From: 0x2262, To: 0x92a},
+ 104: {From: 0x2316, To: 0x3226},
+ 105: {From: 0x236a, To: 0x2835},
+ 106: {From: 0x2382, To: 0x3365},
+ 107: {From: 0x2472, To: 0x2c7},
+ 108: {From: 0x24e4, To: 0x2ff},
+ 109: {From: 0x24f0, To: 0x2fa},
+ 110: {From: 0x24fa, To: 0x31f},
+ 111: {From: 0x2550, To: 0xb5b},
+ 112: {From: 0x25a9, To: 0xe2},
+ 113: {From: 0x263e, To: 0x2d0},
+ 114: {From: 0x26c9, To: 0x26b4},
+ 115: {From: 0x26f9, To: 0x3c8},
+ 116: {From: 0x2727, To: 0x3caf},
+ 117: {From: 0x2755, To: 0x6a4},
+ 118: {From: 0x2765, To: 0x26b4},
+ 119: {From: 0x2789, To: 0x4358},
+ 120: {From: 0x27c9, To: 0x2001},
+ 121: {From: 0x28ea, To: 0x27b1},
+ 122: {From: 0x28ef, To: 0x2837},
+ 123: {From: 0x28fe, To: 0xaa5},
+ 124: {From: 0x2914, To: 0x351},
+ 125: {From: 0x2986, To: 0x2da7},
+ 126: {From: 0x29f0, To: 0x96b},
+ 127: {From: 0x2b1a, To: 0x38d},
+ 128: {From: 0x2bfc, To: 0x395},
+ 129: {From: 0x2c3f, To: 0x3caf},
+ 130: {From: 0x2ce1, To: 0x2201},
+ 131: {From: 0x2cfc, To: 0x3be},
+ 132: {From: 0x2d13, To: 0x597},
+ 133: {From: 0x2d47, To: 0x148},
+ 134: {From: 0x2d48, To: 0x148},
+ 135: {From: 0x2dff, To: 0x2f1},
+ 136: {From: 0x2e08, To: 0x19cc},
+ 137: {From: 0x2e10, To: 0xc45},
+ 138: {From: 0x2e1a, To: 0x2d95},
+ 139: {From: 0x2e21, To: 0x292},
+ 140: {From: 0x2e54, To: 0x7d},
+ 141: {From: 0x2e65, To: 0x2282},
+ 142: {From: 0x2e97, To: 0x1a4},
+ 143: {From: 0x2ea0, To: 0x2e9b},
+ 144: {From: 0x2eef, To: 0x2ed7},
+ 145: {From: 0x3193, To: 0x3c4},
+ 146: {From: 0x3366, To: 0x338e},
+ 147: {From: 0x342a, To: 0x3dc},
+ 148: {From: 0x34ee, To: 0x18d0},
+ 149: {From: 0x35c8, To: 0x2c9b},
+ 150: {From: 0x35e6, To: 0x412},
+ 151: {From: 0x35f5, To: 0x24b},
+ 152: {From: 0x360d, To: 0x1dc},
+ 153: {From: 0x3658, To: 0x246},
+ 154: {From: 0x3676, To: 0x3f4},
+ 155: {From: 0x36fd, To: 0x445},
+ 156: {From: 0x3747, To: 0x3b42},
+ 157: {From: 0x37c0, To: 0x121},
+ 158: {From: 0x3816, To: 0x38f2},
+ 159: {From: 0x382a, To: 0x2b48},
+ 160: {From: 0x382b, To: 0x2c9b},
+ 161: {From: 0x382f, To: 0xa9},
+ 162: {From: 0x3832, To: 0x3228},
+ 163: {From: 0x386c, To: 0x39a6},
+ 164: {From: 0x3892, To: 0x3fc0},
+ 165: {From: 0x38a0, To: 0x45f},
+ 166: {From: 0x38a5, To: 0x39d7},
+ 167: {From: 0x38b4, To: 0x1fa4},
+ 168: {From: 0x38b5, To: 0x2e9a},
+ 169: {From: 0x38fa, To: 0x38f1},
+ 170: {From: 0x395c, To: 0x47e},
+ 171: {From: 0x3b4e, To: 0xd91},
+ 172: {From: 0x3b78, To: 0x137},
+ 173: {From: 0x3c99, To: 0x4bc},
+ 174: {From: 0x3fbd, To: 0x100},
+ 175: {From: 0x4208, To: 0xa91},
+ 176: {From: 0x42be, To: 0x573},
+ 177: {From: 0x42f9, To: 0x3f60},
+ 178: {From: 0x4378, To: 0x25a},
+ 179: {From: 0x43b8, To: 0xe6c},
+ 180: {From: 0x43cd, To: 0x10f},
+ 181: {From: 0x43d4, To: 0x4848},
+ 182: {From: 0x44af, To: 0x3322},
+ 183: {From: 0x44e3, To: 0x512},
+ 184: {From: 0x45ca, To: 0x2409},
+ 185: {From: 0x45dd, To: 0x26dc},
+ 186: {From: 0x4610, To: 0x48ae},
+ 187: {From: 0x46ae, To: 0x46a0},
+ 188: {From: 0x473e, To: 0x4745},
+ 189: {From: 0x4817, To: 0x3503},
+ 190: {From: 0x483b, To: 0x208b},
+ 191: {From: 0x4916, To: 0x31f},
+ 192: {From: 0x49a7, To: 0x523},
+}
+
+// Size: 193 bytes, 193 elements
+var AliasTypes = [193]AliasType{
+ // Entry 0 - 3F
+ 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 0, 0,
+ 1, 2, 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0,
+ 0, 2, 1, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1,
+ 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1,
+ // Entry 40 - 7F
+ 1, 2, 2, 0, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0,
+ 2, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 0,
+ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
+ // Entry 80 - BF
+ 1, 0, 0, 1, 0, 2, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 1, 1, 2, 0, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 0,
+ 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1,
+ // Entry C0 - FF
+ 1,
+}
+
+const (
+ _Latn = 91
+ _Hani = 57
+ _Hans = 59
+ _Hant = 60
+ _Qaaa = 149
+ _Qaai = 157
+ _Qabx = 198
+ _Zinh = 255
+ _Zyyy = 260
+ _Zzzz = 261
+)
+
+// script is an alphabetically sorted list of ISO 15924 codes. The index
+// of the script in the string, divided by 4, is the internal scriptID.
+const script tag.Index = "" + // Size: 1052 bytes
+ "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" +
+ "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" +
+ "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" +
+ "GuruHanbHangHaniHanoHansHantHatrHebrHiraHluwHmngHmnpHrktHungIndsItalJamo" +
+ "JavaJpanJurcKaliKanaKawiKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatf" +
+ "LatgLatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedf" +
+ "MendMercMeroMlymModiMongMoonMrooMteiMultMymrNagmNandNarbNbatNewaNkdbNkgb" +
+ "NkooNshuOgamOlckOrkhOryaOsgeOsmaOugrPalmPaucPcunPelmPermPhagPhliPhlpPhlv" +
+ "PhnxPiqdPlrdPrtiPsinQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaam" +
+ "QaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabe" +
+ "QabfQabgQabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabw" +
+ "QabxRanjRjngRohgRoroRunrSamrSaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogd" +
+ "SogoSoraSoyoSundSunuSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTelu" +
+ "TengTfngTglgThaaThaiTibtTirhTnsaTotoUgarVaiiVispVithWaraWchoWoleXpeoXsux" +
+ "YeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff"
+
+// suppressScript is an index from langID to the dominant script for that language,
+// if it exists. If a script is given, it should be suppressed from the language tag.
+// Size: 1330 bytes, 1330 elements
+var suppressScript = [1330]uint8{
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 40 - 7F
+ 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+ // Entry 80 - BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry C0 - FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 100 - 13F
+ 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xed, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x5b, 0x00,
+ // Entry 140 - 17F
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 180 - 1BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5b, 0x35, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x22, 0x00,
+ // Entry 1C0 - 1FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x5b, 0x00, 0x5b, 0x5b, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x5b, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ // Entry 200 - 23F
+ 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 240 - 27F
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x53, 0x00, 0x00, 0x54, 0x00, 0x22, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 280 - 2BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 2C0 - 2FF
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ // Entry 300 - 33F
+ 0x00, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x5b,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ // Entry 340 - 37F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x5b, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5b, 0x00,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 380 - 3BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ // Entry 3C0 - 3FF
+ 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 400 - 43F
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ // Entry 440 - 47F
+ 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe9, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ // Entry 480 - 4BF
+ 0x5b, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 4C0 - 4FF
+ 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 500 - 53F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x00, 0x00,
+}
+
+const (
+ _001 = 1
+ _419 = 31
+ _BR = 65
+ _CA = 73
+ _ES = 111
+ _GB = 124
+ _MD = 189
+ _PT = 239
+ _UK = 307
+ _US = 310
+ _ZZ = 358
+ _XA = 324
+ _XC = 326
+ _XK = 334
+)
+
+// isoRegionOffset needs to be added to the index of regionISO to obtain the regionID
+// for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for
+// the UN.M49 codes used for groups.)
+const isoRegionOffset = 32
+
+// regionTypes defines the status of a region for various standards.
+// Size: 359 bytes, 359 elements
+var regionTypes = [359]uint8{
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry 40 - 7F
+ 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06,
+ 0x04, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x04, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x00,
+ 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x00, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry 80 - BF
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x00, 0x04, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry C0 - FF
+ 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x04,
+ 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x00, 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ // Entry 100 - 13F
+ 0x05, 0x05, 0x05, 0x06, 0x00, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x02, 0x06, 0x04, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06,
+ // Entry 140 - 17F
+ 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06,
+ 0x06, 0x04, 0x06, 0x06, 0x04, 0x06, 0x05,
+}
+
+// regionISO holds a list of alphabetically sorted 2-letter ISO region codes.
+// Each 2-letter codes is followed by two bytes with the following meaning:
+// - [A-Z}{2}: the first letter of the 2-letter code plus these two
+// letters form the 3-letter ISO code.
+// - 0, n: index into altRegionISO3.
+const regionISO tag.Index = "" + // Size: 1312 bytes
+ "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" +
+ "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" +
+ "BUURBVVTBWWABYLRBZLZCAANCCCKCDODCFAFCGOGCHHECIIVCKOKCLHLCMMRCNHNCOOLCPPT" +
+ "CQ CRRICS\x00\x00CTTECUUBCVPVCWUWCXXRCYYPCZZEDDDRDEEUDGGADJJIDKNKDMMADO" +
+ "OMDYHYDZZAEA ECCUEESTEGGYEHSHERRIESSPETTHEU\x00\x03EZ FIINFJJIFKLKFMSM" +
+ "FOROFQ\x00\x18FRRAFXXXGAABGBBRGDRDGEEOGFUFGGGYGHHAGIIBGLRLGMMBGNINGPLPGQ" +
+ "NQGRRCGS\x00\x06GTTMGUUMGWNBGYUYHKKGHMMDHNNDHRRVHTTIHUUNHVVOIC IDDNIERL" +
+ "ILSRIMMNINNDIOOTIQRQIRRNISSLITTAJEEYJMAMJOORJPPNJTTNKEENKGGZKHHMKIIRKM" +
+ "\x00\x09KNNAKP\x00\x0cKRORKWWTKY\x00\x0fKZAZLAAOLBBNLCCALIIELKKALRBRLSSO" +
+ "LTTULUUXLVVALYBYMAARMCCOMDDAMENEMFAFMGDGMHHLMIIDMKKDMLLIMMMRMNNGMOACMPNP" +
+ "MQTQMRRTMSSRMTLTMUUSMVDVMWWIMXEXMYYSMZOZNAAMNCCLNEERNFFKNGGANHHBNIICNLLD" +
+ "NOORNPPLNQ\x00\x1eNRRUNTTZNUIUNZZLOMMNPAANPCCIPEERPFYFPGNGPHHLPKAKPLOLPM" +
+ "\x00\x12PNCNPRRIPSSEPTRTPUUSPWLWPYRYPZCZQAATQMMMQNNNQOOOQPPPQQQQQRRRQSSS" +
+ "QTTTQU\x00\x03QVVVQWWWQXXXQYYYQZZZREEURHHOROOURS\x00\x15RUUSRWWASAAUSBLB" +
+ "SCYCSDDNSEWESGGPSHHNSIVNSJJMSKVKSLLESMMRSNENSOOMSRURSSSDSTTPSUUNSVLVSXXM" +
+ "SYYRSZWZTAAATCCATDCDTF\x00\x18TGGOTHHATJJKTKKLTLLSTMKMTNUNTOONTPMPTRURTT" +
+ "TOTVUVTWWNTZZAUAKRUGGAUK UMMIUN USSAUYRYUZZBVAATVCCTVDDRVEENVGGBVIIRVN" +
+ "NMVUUTWFLFWKAKWSSMXAAAXBBBXCCCXDDDXEEEXFFFXGGGXHHHXIIIXJJJXKKKXLLLXMMMXN" +
+ "NNXOOOXPPPXQQQXRRRXSSSXTTTXUUUXVVVXWWWXXXXXYYYXZZZYDMDYEEMYT\x00\x1bYUUG" +
+ "ZAAFZMMBZRARZWWEZZZZ\xff\xff\xff\xff"
+
+// altRegionISO3 holds a list of 3-letter region codes that cannot be
+// mapped to 2-letter codes using the default algorithm. This is a short list.
+const altRegionISO3 string = "SCGQUUSGSCOMPRKCYMSPMSRBATFMYTATN"
+
+// altRegionIDs holds a list of regionIDs the positions of which match those
+// of the 3-letter ISO codes in altRegionISO3.
+// Size: 22 bytes, 11 elements
+var altRegionIDs = [11]uint16{
+ 0x0058, 0x0071, 0x0089, 0x00a9, 0x00ab, 0x00ae, 0x00eb, 0x0106,
+ 0x0122, 0x0160, 0x00dd,
+}
+
+// Size: 80 bytes, 20 elements
+var regionOldMap = [20]FromTo{
+ 0: {From: 0x44, To: 0xc5},
+ 1: {From: 0x59, To: 0xa8},
+ 2: {From: 0x60, To: 0x61},
+ 3: {From: 0x67, To: 0x3b},
+ 4: {From: 0x7a, To: 0x79},
+ 5: {From: 0x94, To: 0x37},
+ 6: {From: 0xa4, To: 0x134},
+ 7: {From: 0xc2, To: 0x134},
+ 8: {From: 0xd8, To: 0x140},
+ 9: {From: 0xdd, To: 0x2b},
+ 10: {From: 0xf0, To: 0x134},
+ 11: {From: 0xf3, To: 0xe3},
+ 12: {From: 0xfd, To: 0x71},
+ 13: {From: 0x104, To: 0x165},
+ 14: {From: 0x12b, To: 0x127},
+ 15: {From: 0x133, To: 0x7c},
+ 16: {From: 0x13b, To: 0x13f},
+ 17: {From: 0x142, To: 0x134},
+ 18: {From: 0x15e, To: 0x15f},
+ 19: {From: 0x164, To: 0x4b},
+}
+
+// m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are
+// codes indicating collections of regions.
+// Size: 718 bytes, 359 elements
+var m49 = [359]int16{
+ // Entry 0 - 3F
+ 0, 1, 2, 3, 5, 9, 11, 13,
+ 14, 15, 17, 18, 19, 21, 29, 30,
+ 34, 35, 39, 53, 54, 57, 61, 142,
+ 143, 145, 150, 151, 154, 155, 202, 419,
+ 958, 0, 20, 784, 4, 28, 660, 8,
+ 51, 530, 24, 10, 32, 16, 40, 36,
+ 533, 248, 31, 70, 52, 50, 56, 854,
+ 100, 48, 108, 204, 652, 60, 96, 68,
+ // Entry 40 - 7F
+ 535, 76, 44, 64, 104, 74, 72, 112,
+ 84, 124, 166, 180, 140, 178, 756, 384,
+ 184, 152, 120, 156, 170, 0, 0, 188,
+ 891, 296, 192, 132, 531, 162, 196, 203,
+ 278, 276, 0, 262, 208, 212, 214, 204,
+ 12, 0, 218, 233, 818, 732, 232, 724,
+ 231, 967, 0, 246, 242, 238, 583, 234,
+ 0, 250, 249, 266, 826, 308, 268, 254,
+ // Entry 80 - BF
+ 831, 288, 292, 304, 270, 324, 312, 226,
+ 300, 239, 320, 316, 624, 328, 344, 334,
+ 340, 191, 332, 348, 854, 0, 360, 372,
+ 376, 833, 356, 86, 368, 364, 352, 380,
+ 832, 388, 400, 392, 581, 404, 417, 116,
+ 296, 174, 659, 408, 410, 414, 136, 398,
+ 418, 422, 662, 438, 144, 430, 426, 440,
+ 442, 428, 434, 504, 492, 498, 499, 663,
+ // Entry C0 - FF
+ 450, 584, 581, 807, 466, 104, 496, 446,
+ 580, 474, 478, 500, 470, 480, 462, 454,
+ 484, 458, 508, 516, 540, 562, 574, 566,
+ 548, 558, 528, 578, 524, 10, 520, 536,
+ 570, 554, 512, 591, 0, 604, 258, 598,
+ 608, 586, 616, 666, 612, 630, 275, 620,
+ 581, 585, 600, 591, 634, 959, 960, 961,
+ 962, 963, 964, 965, 966, 967, 968, 969,
+ // Entry 100 - 13F
+ 970, 971, 972, 638, 716, 642, 688, 643,
+ 646, 682, 90, 690, 729, 752, 702, 654,
+ 705, 744, 703, 694, 674, 686, 706, 740,
+ 728, 678, 810, 222, 534, 760, 748, 0,
+ 796, 148, 260, 768, 764, 762, 772, 626,
+ 795, 788, 776, 626, 792, 780, 798, 158,
+ 834, 804, 800, 826, 581, 0, 840, 858,
+ 860, 336, 670, 704, 862, 92, 850, 704,
+ // Entry 140 - 17F
+ 548, 876, 581, 882, 973, 974, 975, 976,
+ 977, 978, 979, 980, 981, 982, 983, 984,
+ 985, 986, 987, 988, 989, 990, 991, 992,
+ 993, 994, 995, 996, 997, 998, 720, 887,
+ 175, 891, 710, 894, 180, 716, 999,
+}
+
+// m49Index gives indexes into fromM49 based on the three most significant bits
+// of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in
+//
+// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]]
+//
+// for an entry where the first 7 bits match the 7 lsb of the UN.M49 code.
+// The region code is stored in the 9 lsb of the indexed value.
+// Size: 18 bytes, 9 elements
+var m49Index = [9]int16{
+ 0, 59, 108, 143, 181, 220, 259, 291,
+ 333,
+}
+
+// fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details.
+// Size: 666 bytes, 333 elements
+var fromM49 = [333]uint16{
+ // Entry 0 - 3F
+ 0x0201, 0x0402, 0x0603, 0x0824, 0x0a04, 0x1027, 0x1205, 0x142b,
+ 0x1606, 0x1868, 0x1a07, 0x1c08, 0x1e09, 0x202d, 0x220a, 0x240b,
+ 0x260c, 0x2822, 0x2a0d, 0x302a, 0x3825, 0x3a0e, 0x3c0f, 0x3e32,
+ 0x402c, 0x4410, 0x4611, 0x482f, 0x4e12, 0x502e, 0x5842, 0x6039,
+ 0x6435, 0x6628, 0x6834, 0x6a13, 0x6c14, 0x7036, 0x7215, 0x783d,
+ 0x7a16, 0x8043, 0x883f, 0x8c33, 0x9046, 0x9445, 0x9841, 0xa848,
+ 0xac9b, 0xb50a, 0xb93d, 0xc03e, 0xc838, 0xd0c5, 0xd83a, 0xe047,
+ 0xe8a7, 0xf052, 0xf849, 0x085b, 0x10ae, 0x184c, 0x1c17, 0x1e18,
+ // Entry 40 - 7F
+ 0x20b4, 0x2219, 0x2921, 0x2c1a, 0x2e1b, 0x3051, 0x341c, 0x361d,
+ 0x3853, 0x3d2f, 0x445d, 0x4c4a, 0x5454, 0x5ca9, 0x5f60, 0x644d,
+ 0x684b, 0x7050, 0x7857, 0x7e91, 0x805a, 0x885e, 0x941e, 0x965f,
+ 0x983b, 0xa064, 0xa865, 0xac66, 0xb46a, 0xbd1b, 0xc487, 0xcc70,
+ 0xce70, 0xd06e, 0xd26b, 0xd477, 0xdc75, 0xde89, 0xe474, 0xec73,
+ 0xf031, 0xf27a, 0xf479, 0xfc7f, 0x04e6, 0x0922, 0x0c63, 0x147b,
+ 0x187e, 0x1c84, 0x26ee, 0x2861, 0x2c60, 0x3061, 0x4081, 0x4882,
+ 0x50a8, 0x5888, 0x6083, 0x687d, 0x7086, 0x788b, 0x808a, 0x8885,
+ // Entry 80 - BF
+ 0x908d, 0x9892, 0x9c8f, 0xa139, 0xa890, 0xb08e, 0xb893, 0xc09e,
+ 0xc89a, 0xd096, 0xd89d, 0xe09c, 0xe897, 0xf098, 0xf89f, 0x004f,
+ 0x08a1, 0x10a3, 0x1caf, 0x20a2, 0x28a5, 0x30ab, 0x34ac, 0x3cad,
+ 0x42a6, 0x44b0, 0x461f, 0x4cb1, 0x54b6, 0x58b9, 0x5cb5, 0x64ba,
+ 0x6cb3, 0x70b7, 0x74b8, 0x7cc7, 0x84c0, 0x8ccf, 0x94d1, 0x9cce,
+ 0xa4c4, 0xaccc, 0xb4c9, 0xbcca, 0xc0cd, 0xc8d0, 0xd8bc, 0xe0c6,
+ 0xe4bd, 0xe6be, 0xe8cb, 0xf0bb, 0xf8d2, 0x00e2, 0x08d3, 0x10de,
+ 0x18dc, 0x20da, 0x2429, 0x265c, 0x2a30, 0x2d1c, 0x2e40, 0x30df,
+ // Entry C0 - FF
+ 0x38d4, 0x4940, 0x54e1, 0x5cd9, 0x64d5, 0x6cd7, 0x74e0, 0x7cd6,
+ 0x84db, 0x88c8, 0x8b34, 0x8e76, 0x90c1, 0x92f1, 0x94e9, 0x9ee3,
+ 0xace7, 0xb0f2, 0xb8e5, 0xc0e8, 0xc8ec, 0xd0ea, 0xd8ef, 0xe08c,
+ 0xe527, 0xeced, 0xf4f4, 0xfd03, 0x0505, 0x0707, 0x0d08, 0x183c,
+ 0x1d0f, 0x26aa, 0x2826, 0x2cb2, 0x2ebf, 0x34eb, 0x3d3a, 0x4514,
+ 0x4d19, 0x5509, 0x5d15, 0x6106, 0x650b, 0x6d13, 0x7d0e, 0x7f12,
+ 0x813f, 0x8310, 0x8516, 0x8d62, 0x9965, 0xa15e, 0xa86f, 0xb118,
+ 0xb30c, 0xb86d, 0xc10c, 0xc917, 0xd111, 0xd91e, 0xe10d, 0xe84e,
+ // Entry 100 - 13F
+ 0xf11d, 0xf525, 0xf924, 0x0123, 0x0926, 0x112a, 0x192d, 0x2023,
+ 0x2929, 0x312c, 0x3728, 0x3920, 0x3d2e, 0x4132, 0x4931, 0x4ec3,
+ 0x551a, 0x646c, 0x747c, 0x7e80, 0x80a0, 0x8299, 0x8530, 0x9136,
+ 0xa53e, 0xac37, 0xb537, 0xb938, 0xbd3c, 0xd941, 0xe543, 0xed5f,
+ 0xef5f, 0xf658, 0xfd63, 0x7c20, 0x7ef5, 0x80f6, 0x82f7, 0x84f8,
+ 0x86f9, 0x88fa, 0x8afb, 0x8cfc, 0x8e71, 0x90fe, 0x92ff, 0x9500,
+ 0x9701, 0x9902, 0x9b44, 0x9d45, 0x9f46, 0xa147, 0xa348, 0xa549,
+ 0xa74a, 0xa94b, 0xab4c, 0xad4d, 0xaf4e, 0xb14f, 0xb350, 0xb551,
+ // Entry 140 - 17F
+ 0xb752, 0xb953, 0xbb54, 0xbd55, 0xbf56, 0xc157, 0xc358, 0xc559,
+ 0xc75a, 0xc95b, 0xcb5c, 0xcd5d, 0xcf66,
+}
+
+// Size: 2128 bytes
+var variantIndex = map[string]uint8{
+ "1606nict": 0x0,
+ "1694acad": 0x1,
+ "1901": 0x2,
+ "1959acad": 0x3,
+ "1994": 0x67,
+ "1996": 0x4,
+ "abl1943": 0x5,
+ "akuapem": 0x6,
+ "alalc97": 0x69,
+ "aluku": 0x7,
+ "ao1990": 0x8,
+ "aranes": 0x9,
+ "arevela": 0xa,
+ "arevmda": 0xb,
+ "arkaika": 0xc,
+ "asante": 0xd,
+ "auvern": 0xe,
+ "baku1926": 0xf,
+ "balanka": 0x10,
+ "barla": 0x11,
+ "basiceng": 0x12,
+ "bauddha": 0x13,
+ "bciav": 0x14,
+ "bcizbl": 0x15,
+ "biscayan": 0x16,
+ "biske": 0x62,
+ "bohoric": 0x17,
+ "boont": 0x18,
+ "bornholm": 0x19,
+ "cisaup": 0x1a,
+ "colb1945": 0x1b,
+ "cornu": 0x1c,
+ "creiss": 0x1d,
+ "dajnko": 0x1e,
+ "ekavsk": 0x1f,
+ "emodeng": 0x20,
+ "fonipa": 0x6a,
+ "fonkirsh": 0x6b,
+ "fonnapa": 0x6c,
+ "fonupa": 0x6d,
+ "fonxsamp": 0x6e,
+ "gallo": 0x21,
+ "gascon": 0x22,
+ "grclass": 0x23,
+ "grital": 0x24,
+ "grmistr": 0x25,
+ "hepburn": 0x26,
+ "heploc": 0x68,
+ "hognorsk": 0x27,
+ "hsistemo": 0x28,
+ "ijekavsk": 0x29,
+ "itihasa": 0x2a,
+ "ivanchov": 0x2b,
+ "jauer": 0x2c,
+ "jyutping": 0x2d,
+ "kkcor": 0x2e,
+ "kociewie": 0x2f,
+ "kscor": 0x30,
+ "laukika": 0x31,
+ "lemosin": 0x32,
+ "lengadoc": 0x33,
+ "lipaw": 0x63,
+ "ltg1929": 0x34,
+ "ltg2007": 0x35,
+ "luna1918": 0x36,
+ "metelko": 0x37,
+ "monoton": 0x38,
+ "ndyuka": 0x39,
+ "nedis": 0x3a,
+ "newfound": 0x3b,
+ "nicard": 0x3c,
+ "njiva": 0x64,
+ "nulik": 0x3d,
+ "osojs": 0x65,
+ "oxendict": 0x3e,
+ "pahawh2": 0x3f,
+ "pahawh3": 0x40,
+ "pahawh4": 0x41,
+ "pamaka": 0x42,
+ "peano": 0x43,
+ "petr1708": 0x44,
+ "pinyin": 0x45,
+ "polyton": 0x46,
+ "provenc": 0x47,
+ "puter": 0x48,
+ "rigik": 0x49,
+ "rozaj": 0x4a,
+ "rumgr": 0x4b,
+ "scotland": 0x4c,
+ "scouse": 0x4d,
+ "simple": 0x6f,
+ "solba": 0x66,
+ "sotav": 0x4e,
+ "spanglis": 0x4f,
+ "surmiran": 0x50,
+ "sursilv": 0x51,
+ "sutsilv": 0x52,
+ "synnejyl": 0x53,
+ "tarask": 0x54,
+ "tongyong": 0x55,
+ "tunumiit": 0x56,
+ "uccor": 0x57,
+ "ucrcor": 0x58,
+ "ulster": 0x59,
+ "unifon": 0x5a,
+ "vaidika": 0x5b,
+ "valencia": 0x5c,
+ "vallader": 0x5d,
+ "vecdruka": 0x5e,
+ "vivaraup": 0x5f,
+ "wadegile": 0x60,
+ "xsistemo": 0x61,
+}
+
+// variantNumSpecialized is the number of specialized variants in variants.
+const variantNumSpecialized = 105
+
+// nRegionGroups is the number of region groups.
+const nRegionGroups = 33
+
+type likelyLangRegion struct {
+ lang uint16
+ region uint16
+}
+
+// likelyScript is a lookup table, indexed by scriptID, for the most likely
+// languages and regions given a script.
+// Size: 1052 bytes, 263 elements
+var likelyScript = [263]likelyLangRegion{
+ 1: {lang: 0x14e, region: 0x85},
+ 3: {lang: 0x2a2, region: 0x107},
+ 4: {lang: 0x1f, region: 0x9a},
+ 5: {lang: 0x3a, region: 0x6c},
+ 7: {lang: 0x3b, region: 0x9d},
+ 8: {lang: 0x1d7, region: 0x28},
+ 9: {lang: 0x13, region: 0x9d},
+ 10: {lang: 0x5b, region: 0x96},
+ 11: {lang: 0x60, region: 0x52},
+ 12: {lang: 0xb9, region: 0xb5},
+ 13: {lang: 0x63, region: 0x96},
+ 14: {lang: 0xa5, region: 0x35},
+ 15: {lang: 0x3e9, region: 0x9a},
+ 17: {lang: 0x529, region: 0x12f},
+ 18: {lang: 0x3b1, region: 0x9a},
+ 19: {lang: 0x15e, region: 0x79},
+ 20: {lang: 0xc2, region: 0x96},
+ 21: {lang: 0x9d, region: 0xe8},
+ 22: {lang: 0xdb, region: 0x35},
+ 23: {lang: 0xf3, region: 0x49},
+ 24: {lang: 0x4f0, region: 0x12c},
+ 25: {lang: 0xe7, region: 0x13f},
+ 26: {lang: 0xe5, region: 0x136},
+ 29: {lang: 0xf1, region: 0x6c},
+ 31: {lang: 0x1a0, region: 0x5e},
+ 32: {lang: 0x3e2, region: 0x107},
+ 34: {lang: 0x1be, region: 0x9a},
+ 38: {lang: 0x15e, region: 0x79},
+ 41: {lang: 0x133, region: 0x6c},
+ 42: {lang: 0x431, region: 0x27},
+ 44: {lang: 0x27, region: 0x70},
+ 46: {lang: 0x210, region: 0x7e},
+ 47: {lang: 0xfe, region: 0x38},
+ 49: {lang: 0x19b, region: 0x9a},
+ 50: {lang: 0x19e, region: 0x131},
+ 51: {lang: 0x3e9, region: 0x9a},
+ 52: {lang: 0x136, region: 0x88},
+ 53: {lang: 0x1a4, region: 0x9a},
+ 54: {lang: 0x39d, region: 0x9a},
+ 55: {lang: 0x529, region: 0x12f},
+ 56: {lang: 0x254, region: 0xac},
+ 57: {lang: 0x529, region: 0x53},
+ 58: {lang: 0x1cb, region: 0xe8},
+ 59: {lang: 0x529, region: 0x53},
+ 60: {lang: 0x529, region: 0x12f},
+ 61: {lang: 0x2fd, region: 0x9c},
+ 62: {lang: 0x1bc, region: 0x98},
+ 63: {lang: 0x200, region: 0xa3},
+ 64: {lang: 0x1c5, region: 0x12c},
+ 65: {lang: 0x1ca, region: 0xb0},
+ 68: {lang: 0x1d5, region: 0x93},
+ 70: {lang: 0x142, region: 0x9f},
+ 71: {lang: 0x254, region: 0xac},
+ 72: {lang: 0x20e, region: 0x96},
+ 73: {lang: 0x200, region: 0xa3},
+ 75: {lang: 0x135, region: 0xc5},
+ 76: {lang: 0x200, region: 0xa3},
+ 78: {lang: 0x3bb, region: 0xe9},
+ 79: {lang: 0x24a, region: 0xa7},
+ 80: {lang: 0x3fa, region: 0x9a},
+ 83: {lang: 0x251, region: 0x9a},
+ 84: {lang: 0x254, region: 0xac},
+ 86: {lang: 0x88, region: 0x9a},
+ 87: {lang: 0x370, region: 0x124},
+ 88: {lang: 0x2b8, region: 0xb0},
+ 93: {lang: 0x29f, region: 0x9a},
+ 94: {lang: 0x2a8, region: 0x9a},
+ 95: {lang: 0x28f, region: 0x88},
+ 96: {lang: 0x1a0, region: 0x88},
+ 97: {lang: 0x2ac, region: 0x53},
+ 99: {lang: 0x4f4, region: 0x12c},
+ 100: {lang: 0x4f5, region: 0x12c},
+ 101: {lang: 0x1be, region: 0x9a},
+ 103: {lang: 0x337, region: 0x9d},
+ 104: {lang: 0x4f7, region: 0x53},
+ 105: {lang: 0xa9, region: 0x53},
+ 108: {lang: 0x2e8, region: 0x113},
+ 109: {lang: 0x4f8, region: 0x10c},
+ 110: {lang: 0x4f8, region: 0x10c},
+ 111: {lang: 0x304, region: 0x9a},
+ 112: {lang: 0x31b, region: 0x9a},
+ 113: {lang: 0x30b, region: 0x53},
+ 115: {lang: 0x31e, region: 0x35},
+ 116: {lang: 0x30e, region: 0x9a},
+ 117: {lang: 0x414, region: 0xe9},
+ 118: {lang: 0x331, region: 0xc5},
+ 121: {lang: 0x4f9, region: 0x109},
+ 122: {lang: 0x3b, region: 0xa2},
+ 123: {lang: 0x353, region: 0xdc},
+ 126: {lang: 0x2d0, region: 0x85},
+ 127: {lang: 0x52a, region: 0x53},
+ 128: {lang: 0x403, region: 0x97},
+ 129: {lang: 0x3ee, region: 0x9a},
+ 130: {lang: 0x39b, region: 0xc6},
+ 131: {lang: 0x395, region: 0x9a},
+ 132: {lang: 0x399, region: 0x136},
+ 133: {lang: 0x429, region: 0x116},
+ 135: {lang: 0x3b, region: 0x11d},
+ 136: {lang: 0xfd, region: 0xc5},
+ 139: {lang: 0x27d, region: 0x107},
+ 140: {lang: 0x2c9, region: 0x53},
+ 141: {lang: 0x39f, region: 0x9d},
+ 142: {lang: 0x39f, region: 0x53},
+ 144: {lang: 0x3ad, region: 0xb1},
+ 146: {lang: 0x1c6, region: 0x53},
+ 147: {lang: 0x4fd, region: 0x9d},
+ 200: {lang: 0x3cb, region: 0x96},
+ 203: {lang: 0x372, region: 0x10d},
+ 204: {lang: 0x420, region: 0x98},
+ 206: {lang: 0x4ff, region: 0x15f},
+ 207: {lang: 0x3f0, region: 0x9a},
+ 208: {lang: 0x45, region: 0x136},
+ 209: {lang: 0x139, region: 0x7c},
+ 210: {lang: 0x3e9, region: 0x9a},
+ 212: {lang: 0x3e9, region: 0x9a},
+ 213: {lang: 0x3fa, region: 0x9a},
+ 214: {lang: 0x40c, region: 0xb4},
+ 217: {lang: 0x433, region: 0x9a},
+ 218: {lang: 0xef, region: 0xc6},
+ 219: {lang: 0x43e, region: 0x96},
+ 221: {lang: 0x44d, region: 0x35},
+ 222: {lang: 0x44e, region: 0x9c},
+ 226: {lang: 0x45a, region: 0xe8},
+ 227: {lang: 0x11a, region: 0x9a},
+ 228: {lang: 0x45e, region: 0x53},
+ 229: {lang: 0x232, region: 0x53},
+ 230: {lang: 0x450, region: 0x9a},
+ 231: {lang: 0x4a5, region: 0x53},
+ 232: {lang: 0x9f, region: 0x13f},
+ 233: {lang: 0x461, region: 0x9a},
+ 235: {lang: 0x528, region: 0xbb},
+ 236: {lang: 0x153, region: 0xe8},
+ 237: {lang: 0x128, region: 0xce},
+ 238: {lang: 0x46b, region: 0x124},
+ 239: {lang: 0xa9, region: 0x53},
+ 240: {lang: 0x2ce, region: 0x9a},
+ 243: {lang: 0x4ad, region: 0x11d},
+ 244: {lang: 0x4be, region: 0xb5},
+ 247: {lang: 0x1ce, region: 0x9a},
+ 250: {lang: 0x3a9, region: 0x9d},
+ 251: {lang: 0x22, region: 0x9c},
+ 253: {lang: 0x1ea, region: 0x53},
+ 254: {lang: 0xef, region: 0xc6},
+}
+
+type likelyScriptRegion struct {
+ region uint16
+ script uint16
+ flags uint8
+}
+
+// likelyLang is a lookup table, indexed by langID, for the most likely
+// scripts and regions given incomplete information. If more entries exist for a
+// given language, region and script are the index and size respectively
+// of the list in likelyLangList.
+// Size: 7980 bytes, 1330 elements
+var likelyLang = [1330]likelyScriptRegion{
+ 0: {region: 0x136, script: 0x5b, flags: 0x0},
+ 1: {region: 0x70, script: 0x5b, flags: 0x0},
+ 2: {region: 0x166, script: 0x5b, flags: 0x0},
+ 3: {region: 0x166, script: 0x5b, flags: 0x0},
+ 4: {region: 0x166, script: 0x5b, flags: 0x0},
+ 5: {region: 0x7e, script: 0x20, flags: 0x0},
+ 6: {region: 0x166, script: 0x5b, flags: 0x0},
+ 7: {region: 0x166, script: 0x20, flags: 0x0},
+ 8: {region: 0x81, script: 0x5b, flags: 0x0},
+ 9: {region: 0x166, script: 0x5b, flags: 0x0},
+ 10: {region: 0x166, script: 0x5b, flags: 0x0},
+ 11: {region: 0x166, script: 0x5b, flags: 0x0},
+ 12: {region: 0x96, script: 0x5b, flags: 0x0},
+ 13: {region: 0x132, script: 0x5b, flags: 0x0},
+ 14: {region: 0x81, script: 0x5b, flags: 0x0},
+ 15: {region: 0x166, script: 0x5b, flags: 0x0},
+ 16: {region: 0x166, script: 0x5b, flags: 0x0},
+ 17: {region: 0x107, script: 0x20, flags: 0x0},
+ 18: {region: 0x166, script: 0x5b, flags: 0x0},
+ 19: {region: 0x9d, script: 0x9, flags: 0x0},
+ 20: {region: 0x129, script: 0x5, flags: 0x0},
+ 21: {region: 0x166, script: 0x5b, flags: 0x0},
+ 22: {region: 0x162, script: 0x5b, flags: 0x0},
+ 23: {region: 0x166, script: 0x5b, flags: 0x0},
+ 24: {region: 0x166, script: 0x5b, flags: 0x0},
+ 25: {region: 0x166, script: 0x5b, flags: 0x0},
+ 26: {region: 0x166, script: 0x5b, flags: 0x0},
+ 27: {region: 0x166, script: 0x5b, flags: 0x0},
+ 28: {region: 0x52, script: 0x5b, flags: 0x0},
+ 29: {region: 0x166, script: 0x5b, flags: 0x0},
+ 30: {region: 0x166, script: 0x5b, flags: 0x0},
+ 31: {region: 0x9a, script: 0x4, flags: 0x0},
+ 32: {region: 0x166, script: 0x5b, flags: 0x0},
+ 33: {region: 0x81, script: 0x5b, flags: 0x0},
+ 34: {region: 0x9c, script: 0xfb, flags: 0x0},
+ 35: {region: 0x166, script: 0x5b, flags: 0x0},
+ 36: {region: 0x166, script: 0x5b, flags: 0x0},
+ 37: {region: 0x14e, script: 0x5b, flags: 0x0},
+ 38: {region: 0x107, script: 0x20, flags: 0x0},
+ 39: {region: 0x70, script: 0x2c, flags: 0x0},
+ 40: {region: 0x166, script: 0x5b, flags: 0x0},
+ 41: {region: 0x166, script: 0x5b, flags: 0x0},
+ 42: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 43: {region: 0x166, script: 0x5b, flags: 0x0},
+ 45: {region: 0x166, script: 0x5b, flags: 0x0},
+ 46: {region: 0x166, script: 0x5b, flags: 0x0},
+ 47: {region: 0x166, script: 0x5b, flags: 0x0},
+ 48: {region: 0x166, script: 0x5b, flags: 0x0},
+ 49: {region: 0x166, script: 0x5b, flags: 0x0},
+ 50: {region: 0x166, script: 0x5b, flags: 0x0},
+ 51: {region: 0x96, script: 0x5b, flags: 0x0},
+ 52: {region: 0x166, script: 0x5, flags: 0x0},
+ 53: {region: 0x123, script: 0x5, flags: 0x0},
+ 54: {region: 0x166, script: 0x5b, flags: 0x0},
+ 55: {region: 0x166, script: 0x5b, flags: 0x0},
+ 56: {region: 0x166, script: 0x5b, flags: 0x0},
+ 57: {region: 0x166, script: 0x5b, flags: 0x0},
+ 58: {region: 0x6c, script: 0x5, flags: 0x0},
+ 59: {region: 0x0, script: 0x3, flags: 0x1},
+ 60: {region: 0x166, script: 0x5b, flags: 0x0},
+ 61: {region: 0x51, script: 0x5b, flags: 0x0},
+ 62: {region: 0x3f, script: 0x5b, flags: 0x0},
+ 63: {region: 0x68, script: 0x5, flags: 0x0},
+ 65: {region: 0xbb, script: 0x5, flags: 0x0},
+ 66: {region: 0x6c, script: 0x5, flags: 0x0},
+ 67: {region: 0x9a, script: 0xe, flags: 0x0},
+ 68: {region: 0x130, script: 0x5b, flags: 0x0},
+ 69: {region: 0x136, script: 0xd0, flags: 0x0},
+ 70: {region: 0x166, script: 0x5b, flags: 0x0},
+ 71: {region: 0x166, script: 0x5b, flags: 0x0},
+ 72: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 73: {region: 0x166, script: 0x5b, flags: 0x0},
+ 74: {region: 0x166, script: 0x5b, flags: 0x0},
+ 75: {region: 0x49, script: 0x5b, flags: 0x0},
+ 76: {region: 0x166, script: 0x5b, flags: 0x0},
+ 77: {region: 0x107, script: 0x20, flags: 0x0},
+ 78: {region: 0x166, script: 0x5, flags: 0x0},
+ 79: {region: 0x166, script: 0x5b, flags: 0x0},
+ 80: {region: 0x166, script: 0x5b, flags: 0x0},
+ 81: {region: 0x166, script: 0x5b, flags: 0x0},
+ 82: {region: 0x9a, script: 0x22, flags: 0x0},
+ 83: {region: 0x166, script: 0x5b, flags: 0x0},
+ 84: {region: 0x166, script: 0x5b, flags: 0x0},
+ 85: {region: 0x166, script: 0x5b, flags: 0x0},
+ 86: {region: 0x3f, script: 0x5b, flags: 0x0},
+ 87: {region: 0x166, script: 0x5b, flags: 0x0},
+ 88: {region: 0x3, script: 0x5, flags: 0x1},
+ 89: {region: 0x107, script: 0x20, flags: 0x0},
+ 90: {region: 0xe9, script: 0x5, flags: 0x0},
+ 91: {region: 0x96, script: 0x5b, flags: 0x0},
+ 92: {region: 0xdc, script: 0x22, flags: 0x0},
+ 93: {region: 0x2e, script: 0x5b, flags: 0x0},
+ 94: {region: 0x52, script: 0x5b, flags: 0x0},
+ 95: {region: 0x166, script: 0x5b, flags: 0x0},
+ 96: {region: 0x52, script: 0xb, flags: 0x0},
+ 97: {region: 0x166, script: 0x5b, flags: 0x0},
+ 98: {region: 0x166, script: 0x5b, flags: 0x0},
+ 99: {region: 0x96, script: 0x5b, flags: 0x0},
+ 100: {region: 0x166, script: 0x5b, flags: 0x0},
+ 101: {region: 0x52, script: 0x5b, flags: 0x0},
+ 102: {region: 0x166, script: 0x5b, flags: 0x0},
+ 103: {region: 0x166, script: 0x5b, flags: 0x0},
+ 104: {region: 0x166, script: 0x5b, flags: 0x0},
+ 105: {region: 0x166, script: 0x5b, flags: 0x0},
+ 106: {region: 0x4f, script: 0x5b, flags: 0x0},
+ 107: {region: 0x166, script: 0x5b, flags: 0x0},
+ 108: {region: 0x166, script: 0x5b, flags: 0x0},
+ 109: {region: 0x166, script: 0x5b, flags: 0x0},
+ 110: {region: 0x166, script: 0x2c, flags: 0x0},
+ 111: {region: 0x166, script: 0x5b, flags: 0x0},
+ 112: {region: 0x166, script: 0x5b, flags: 0x0},
+ 113: {region: 0x47, script: 0x20, flags: 0x0},
+ 114: {region: 0x166, script: 0x5b, flags: 0x0},
+ 115: {region: 0x166, script: 0x5b, flags: 0x0},
+ 116: {region: 0x10c, script: 0x5, flags: 0x0},
+ 117: {region: 0x163, script: 0x5b, flags: 0x0},
+ 118: {region: 0x166, script: 0x5b, flags: 0x0},
+ 119: {region: 0x96, script: 0x5b, flags: 0x0},
+ 120: {region: 0x166, script: 0x5b, flags: 0x0},
+ 121: {region: 0x130, script: 0x5b, flags: 0x0},
+ 122: {region: 0x52, script: 0x5b, flags: 0x0},
+ 123: {region: 0x9a, script: 0xe6, flags: 0x0},
+ 124: {region: 0xe9, script: 0x5, flags: 0x0},
+ 125: {region: 0x9a, script: 0x22, flags: 0x0},
+ 126: {region: 0x38, script: 0x20, flags: 0x0},
+ 127: {region: 0x9a, script: 0x22, flags: 0x0},
+ 128: {region: 0xe9, script: 0x5, flags: 0x0},
+ 129: {region: 0x12c, script: 0x34, flags: 0x0},
+ 131: {region: 0x9a, script: 0x22, flags: 0x0},
+ 132: {region: 0x166, script: 0x5b, flags: 0x0},
+ 133: {region: 0x9a, script: 0x22, flags: 0x0},
+ 134: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 135: {region: 0x166, script: 0x5b, flags: 0x0},
+ 136: {region: 0x9a, script: 0x22, flags: 0x0},
+ 137: {region: 0x166, script: 0x5b, flags: 0x0},
+ 138: {region: 0x140, script: 0x5b, flags: 0x0},
+ 139: {region: 0x166, script: 0x5b, flags: 0x0},
+ 140: {region: 0x166, script: 0x5b, flags: 0x0},
+ 141: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 142: {region: 0x166, script: 0x5b, flags: 0x0},
+ 143: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 144: {region: 0x166, script: 0x5b, flags: 0x0},
+ 145: {region: 0x166, script: 0x5b, flags: 0x0},
+ 146: {region: 0x166, script: 0x5b, flags: 0x0},
+ 147: {region: 0x166, script: 0x2c, flags: 0x0},
+ 148: {region: 0x9a, script: 0x22, flags: 0x0},
+ 149: {region: 0x96, script: 0x5b, flags: 0x0},
+ 150: {region: 0x166, script: 0x5b, flags: 0x0},
+ 151: {region: 0x166, script: 0x5b, flags: 0x0},
+ 152: {region: 0x115, script: 0x5b, flags: 0x0},
+ 153: {region: 0x166, script: 0x5b, flags: 0x0},
+ 154: {region: 0x166, script: 0x5b, flags: 0x0},
+ 155: {region: 0x52, script: 0x5b, flags: 0x0},
+ 156: {region: 0x166, script: 0x5b, flags: 0x0},
+ 157: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 158: {region: 0x166, script: 0x5b, flags: 0x0},
+ 159: {region: 0x13f, script: 0xe8, flags: 0x0},
+ 160: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 161: {region: 0x166, script: 0x5b, flags: 0x0},
+ 162: {region: 0x166, script: 0x5b, flags: 0x0},
+ 163: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 164: {region: 0x166, script: 0x5b, flags: 0x0},
+ 165: {region: 0x35, script: 0xe, flags: 0x0},
+ 166: {region: 0x166, script: 0x5b, flags: 0x0},
+ 167: {region: 0x166, script: 0x5b, flags: 0x0},
+ 168: {region: 0x166, script: 0x5b, flags: 0x0},
+ 169: {region: 0x53, script: 0xef, flags: 0x0},
+ 170: {region: 0x166, script: 0x5b, flags: 0x0},
+ 171: {region: 0x166, script: 0x5b, flags: 0x0},
+ 172: {region: 0x166, script: 0x5b, flags: 0x0},
+ 173: {region: 0x9a, script: 0xe, flags: 0x0},
+ 174: {region: 0x166, script: 0x5b, flags: 0x0},
+ 175: {region: 0x9d, script: 0x5, flags: 0x0},
+ 176: {region: 0x166, script: 0x5b, flags: 0x0},
+ 177: {region: 0x4f, script: 0x5b, flags: 0x0},
+ 178: {region: 0x79, script: 0x5b, flags: 0x0},
+ 179: {region: 0x9a, script: 0x22, flags: 0x0},
+ 180: {region: 0xe9, script: 0x5, flags: 0x0},
+ 181: {region: 0x9a, script: 0x22, flags: 0x0},
+ 182: {region: 0x166, script: 0x5b, flags: 0x0},
+ 183: {region: 0x33, script: 0x5b, flags: 0x0},
+ 184: {region: 0x166, script: 0x5b, flags: 0x0},
+ 185: {region: 0xb5, script: 0xc, flags: 0x0},
+ 186: {region: 0x52, script: 0x5b, flags: 0x0},
+ 187: {region: 0x166, script: 0x2c, flags: 0x0},
+ 188: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 189: {region: 0x166, script: 0x5b, flags: 0x0},
+ 190: {region: 0xe9, script: 0x22, flags: 0x0},
+ 191: {region: 0x107, script: 0x20, flags: 0x0},
+ 192: {region: 0x160, script: 0x5b, flags: 0x0},
+ 193: {region: 0x166, script: 0x5b, flags: 0x0},
+ 194: {region: 0x96, script: 0x5b, flags: 0x0},
+ 195: {region: 0x166, script: 0x5b, flags: 0x0},
+ 196: {region: 0x52, script: 0x5b, flags: 0x0},
+ 197: {region: 0x166, script: 0x5b, flags: 0x0},
+ 198: {region: 0x166, script: 0x5b, flags: 0x0},
+ 199: {region: 0x166, script: 0x5b, flags: 0x0},
+ 200: {region: 0x87, script: 0x5b, flags: 0x0},
+ 201: {region: 0x166, script: 0x5b, flags: 0x0},
+ 202: {region: 0x166, script: 0x5b, flags: 0x0},
+ 203: {region: 0x166, script: 0x5b, flags: 0x0},
+ 204: {region: 0x166, script: 0x5b, flags: 0x0},
+ 205: {region: 0x6e, script: 0x2c, flags: 0x0},
+ 206: {region: 0x166, script: 0x5b, flags: 0x0},
+ 207: {region: 0x166, script: 0x5b, flags: 0x0},
+ 208: {region: 0x52, script: 0x5b, flags: 0x0},
+ 209: {region: 0x166, script: 0x5b, flags: 0x0},
+ 210: {region: 0x166, script: 0x5b, flags: 0x0},
+ 211: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 212: {region: 0x166, script: 0x5b, flags: 0x0},
+ 213: {region: 0x166, script: 0x5b, flags: 0x0},
+ 214: {region: 0x166, script: 0x5b, flags: 0x0},
+ 215: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 216: {region: 0x166, script: 0x5b, flags: 0x0},
+ 217: {region: 0x166, script: 0x5b, flags: 0x0},
+ 218: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 219: {region: 0x35, script: 0x16, flags: 0x0},
+ 220: {region: 0x107, script: 0x20, flags: 0x0},
+ 221: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 222: {region: 0x166, script: 0x5b, flags: 0x0},
+ 223: {region: 0x132, script: 0x5b, flags: 0x0},
+ 224: {region: 0x8b, script: 0x5b, flags: 0x0},
+ 225: {region: 0x76, script: 0x5b, flags: 0x0},
+ 226: {region: 0x107, script: 0x20, flags: 0x0},
+ 227: {region: 0x136, script: 0x5b, flags: 0x0},
+ 228: {region: 0x49, script: 0x5b, flags: 0x0},
+ 229: {region: 0x136, script: 0x1a, flags: 0x0},
+ 230: {region: 0xa7, script: 0x5, flags: 0x0},
+ 231: {region: 0x13f, script: 0x19, flags: 0x0},
+ 232: {region: 0x166, script: 0x5b, flags: 0x0},
+ 233: {region: 0x9c, script: 0x5, flags: 0x0},
+ 234: {region: 0x166, script: 0x5b, flags: 0x0},
+ 235: {region: 0x166, script: 0x5b, flags: 0x0},
+ 236: {region: 0x166, script: 0x5b, flags: 0x0},
+ 237: {region: 0x166, script: 0x5b, flags: 0x0},
+ 238: {region: 0x166, script: 0x5b, flags: 0x0},
+ 239: {region: 0xc6, script: 0xda, flags: 0x0},
+ 240: {region: 0x79, script: 0x5b, flags: 0x0},
+ 241: {region: 0x6c, script: 0x1d, flags: 0x0},
+ 242: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 243: {region: 0x49, script: 0x17, flags: 0x0},
+ 244: {region: 0x131, script: 0x20, flags: 0x0},
+ 245: {region: 0x49, script: 0x17, flags: 0x0},
+ 246: {region: 0x49, script: 0x17, flags: 0x0},
+ 247: {region: 0x49, script: 0x17, flags: 0x0},
+ 248: {region: 0x49, script: 0x17, flags: 0x0},
+ 249: {region: 0x10b, script: 0x5b, flags: 0x0},
+ 250: {region: 0x5f, script: 0x5b, flags: 0x0},
+ 251: {region: 0xea, script: 0x5b, flags: 0x0},
+ 252: {region: 0x49, script: 0x17, flags: 0x0},
+ 253: {region: 0xc5, script: 0x88, flags: 0x0},
+ 254: {region: 0x8, script: 0x2, flags: 0x1},
+ 255: {region: 0x107, script: 0x20, flags: 0x0},
+ 256: {region: 0x7c, script: 0x5b, flags: 0x0},
+ 257: {region: 0x64, script: 0x5b, flags: 0x0},
+ 258: {region: 0x166, script: 0x5b, flags: 0x0},
+ 259: {region: 0x166, script: 0x5b, flags: 0x0},
+ 260: {region: 0x166, script: 0x5b, flags: 0x0},
+ 261: {region: 0x166, script: 0x5b, flags: 0x0},
+ 262: {region: 0x136, script: 0x5b, flags: 0x0},
+ 263: {region: 0x107, script: 0x20, flags: 0x0},
+ 264: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 265: {region: 0x166, script: 0x5b, flags: 0x0},
+ 266: {region: 0x166, script: 0x5b, flags: 0x0},
+ 267: {region: 0x9a, script: 0x5, flags: 0x0},
+ 268: {region: 0x166, script: 0x5b, flags: 0x0},
+ 269: {region: 0x61, script: 0x5b, flags: 0x0},
+ 270: {region: 0x166, script: 0x5b, flags: 0x0},
+ 271: {region: 0x49, script: 0x5b, flags: 0x0},
+ 272: {region: 0x166, script: 0x5b, flags: 0x0},
+ 273: {region: 0x166, script: 0x5b, flags: 0x0},
+ 274: {region: 0x166, script: 0x5b, flags: 0x0},
+ 275: {region: 0x166, script: 0x5, flags: 0x0},
+ 276: {region: 0x49, script: 0x5b, flags: 0x0},
+ 277: {region: 0x166, script: 0x5b, flags: 0x0},
+ 278: {region: 0x166, script: 0x5b, flags: 0x0},
+ 279: {region: 0xd5, script: 0x5b, flags: 0x0},
+ 280: {region: 0x4f, script: 0x5b, flags: 0x0},
+ 281: {region: 0x166, script: 0x5b, flags: 0x0},
+ 282: {region: 0x9a, script: 0x5, flags: 0x0},
+ 283: {region: 0x166, script: 0x5b, flags: 0x0},
+ 284: {region: 0x166, script: 0x5b, flags: 0x0},
+ 285: {region: 0x166, script: 0x5b, flags: 0x0},
+ 286: {region: 0x166, script: 0x2c, flags: 0x0},
+ 287: {region: 0x61, script: 0x5b, flags: 0x0},
+ 288: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 289: {region: 0xd1, script: 0x5b, flags: 0x0},
+ 290: {region: 0x166, script: 0x5b, flags: 0x0},
+ 291: {region: 0xdc, script: 0x22, flags: 0x0},
+ 292: {region: 0x52, script: 0x5b, flags: 0x0},
+ 293: {region: 0x166, script: 0x5b, flags: 0x0},
+ 294: {region: 0x166, script: 0x5b, flags: 0x0},
+ 295: {region: 0x166, script: 0x5b, flags: 0x0},
+ 296: {region: 0xce, script: 0xed, flags: 0x0},
+ 297: {region: 0x166, script: 0x5b, flags: 0x0},
+ 298: {region: 0x166, script: 0x5b, flags: 0x0},
+ 299: {region: 0x115, script: 0x5b, flags: 0x0},
+ 300: {region: 0x37, script: 0x5b, flags: 0x0},
+ 301: {region: 0x43, script: 0xef, flags: 0x0},
+ 302: {region: 0x166, script: 0x5b, flags: 0x0},
+ 303: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 304: {region: 0x81, script: 0x5b, flags: 0x0},
+ 305: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 306: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 307: {region: 0x6c, script: 0x29, flags: 0x0},
+ 308: {region: 0x166, script: 0x5b, flags: 0x0},
+ 309: {region: 0xc5, script: 0x4b, flags: 0x0},
+ 310: {region: 0x88, script: 0x34, flags: 0x0},
+ 311: {region: 0x166, script: 0x5b, flags: 0x0},
+ 312: {region: 0x166, script: 0x5b, flags: 0x0},
+ 313: {region: 0xa, script: 0x2, flags: 0x1},
+ 314: {region: 0x166, script: 0x5b, flags: 0x0},
+ 315: {region: 0x166, script: 0x5b, flags: 0x0},
+ 316: {region: 0x1, script: 0x5b, flags: 0x0},
+ 317: {region: 0x166, script: 0x5b, flags: 0x0},
+ 318: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 319: {region: 0x136, script: 0x5b, flags: 0x0},
+ 320: {region: 0x6b, script: 0x5b, flags: 0x0},
+ 321: {region: 0x166, script: 0x5b, flags: 0x0},
+ 322: {region: 0x9f, script: 0x46, flags: 0x0},
+ 323: {region: 0x166, script: 0x5b, flags: 0x0},
+ 324: {region: 0x166, script: 0x5b, flags: 0x0},
+ 325: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 326: {region: 0x52, script: 0x5b, flags: 0x0},
+ 327: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 328: {region: 0x9d, script: 0x5, flags: 0x0},
+ 329: {region: 0x166, script: 0x5b, flags: 0x0},
+ 330: {region: 0x166, script: 0x5b, flags: 0x0},
+ 331: {region: 0x166, script: 0x5b, flags: 0x0},
+ 332: {region: 0x166, script: 0x5b, flags: 0x0},
+ 333: {region: 0x87, script: 0x5b, flags: 0x0},
+ 334: {region: 0xc, script: 0x2, flags: 0x1},
+ 335: {region: 0x166, script: 0x5b, flags: 0x0},
+ 336: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 337: {region: 0x73, script: 0x5b, flags: 0x0},
+ 338: {region: 0x10c, script: 0x5, flags: 0x0},
+ 339: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 340: {region: 0x10d, script: 0x5b, flags: 0x0},
+ 341: {region: 0x74, script: 0x5b, flags: 0x0},
+ 342: {region: 0x166, script: 0x5b, flags: 0x0},
+ 343: {region: 0x166, script: 0x5b, flags: 0x0},
+ 344: {region: 0x77, script: 0x5b, flags: 0x0},
+ 345: {region: 0x166, script: 0x5b, flags: 0x0},
+ 346: {region: 0x3b, script: 0x5b, flags: 0x0},
+ 347: {region: 0x166, script: 0x5b, flags: 0x0},
+ 348: {region: 0x166, script: 0x5b, flags: 0x0},
+ 349: {region: 0x166, script: 0x5b, flags: 0x0},
+ 350: {region: 0x79, script: 0x5b, flags: 0x0},
+ 351: {region: 0x136, script: 0x5b, flags: 0x0},
+ 352: {region: 0x79, script: 0x5b, flags: 0x0},
+ 353: {region: 0x61, script: 0x5b, flags: 0x0},
+ 354: {region: 0x61, script: 0x5b, flags: 0x0},
+ 355: {region: 0x52, script: 0x5, flags: 0x0},
+ 356: {region: 0x141, script: 0x5b, flags: 0x0},
+ 357: {region: 0x166, script: 0x5b, flags: 0x0},
+ 358: {region: 0x85, script: 0x5b, flags: 0x0},
+ 359: {region: 0x166, script: 0x5b, flags: 0x0},
+ 360: {region: 0xd5, script: 0x5b, flags: 0x0},
+ 361: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 362: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 363: {region: 0x166, script: 0x5b, flags: 0x0},
+ 364: {region: 0x10c, script: 0x5b, flags: 0x0},
+ 365: {region: 0xda, script: 0x5b, flags: 0x0},
+ 366: {region: 0x97, script: 0x5b, flags: 0x0},
+ 367: {region: 0x81, script: 0x5b, flags: 0x0},
+ 368: {region: 0x166, script: 0x5b, flags: 0x0},
+ 369: {region: 0xbd, script: 0x5b, flags: 0x0},
+ 370: {region: 0x166, script: 0x5b, flags: 0x0},
+ 371: {region: 0x166, script: 0x5b, flags: 0x0},
+ 372: {region: 0x166, script: 0x5b, flags: 0x0},
+ 373: {region: 0x53, script: 0x3b, flags: 0x0},
+ 374: {region: 0x166, script: 0x5b, flags: 0x0},
+ 375: {region: 0x96, script: 0x5b, flags: 0x0},
+ 376: {region: 0x166, script: 0x5b, flags: 0x0},
+ 377: {region: 0x166, script: 0x5b, flags: 0x0},
+ 378: {region: 0x9a, script: 0x22, flags: 0x0},
+ 379: {region: 0x166, script: 0x5b, flags: 0x0},
+ 380: {region: 0x9d, script: 0x5, flags: 0x0},
+ 381: {region: 0x7f, script: 0x5b, flags: 0x0},
+ 382: {region: 0x7c, script: 0x5b, flags: 0x0},
+ 383: {region: 0x166, script: 0x5b, flags: 0x0},
+ 384: {region: 0x166, script: 0x5b, flags: 0x0},
+ 385: {region: 0x166, script: 0x5b, flags: 0x0},
+ 386: {region: 0x166, script: 0x5b, flags: 0x0},
+ 387: {region: 0x166, script: 0x5b, flags: 0x0},
+ 388: {region: 0x166, script: 0x5b, flags: 0x0},
+ 389: {region: 0x70, script: 0x2c, flags: 0x0},
+ 390: {region: 0x166, script: 0x5b, flags: 0x0},
+ 391: {region: 0xdc, script: 0x22, flags: 0x0},
+ 392: {region: 0x166, script: 0x5b, flags: 0x0},
+ 393: {region: 0xa8, script: 0x5b, flags: 0x0},
+ 394: {region: 0x166, script: 0x5b, flags: 0x0},
+ 395: {region: 0xe9, script: 0x5, flags: 0x0},
+ 396: {region: 0x166, script: 0x5b, flags: 0x0},
+ 397: {region: 0xe9, script: 0x5, flags: 0x0},
+ 398: {region: 0x166, script: 0x5b, flags: 0x0},
+ 399: {region: 0x166, script: 0x5b, flags: 0x0},
+ 400: {region: 0x6f, script: 0x5b, flags: 0x0},
+ 401: {region: 0x9d, script: 0x5, flags: 0x0},
+ 402: {region: 0x166, script: 0x5b, flags: 0x0},
+ 403: {region: 0x166, script: 0x2c, flags: 0x0},
+ 404: {region: 0xf2, script: 0x5b, flags: 0x0},
+ 405: {region: 0x166, script: 0x5b, flags: 0x0},
+ 406: {region: 0x166, script: 0x5b, flags: 0x0},
+ 407: {region: 0x166, script: 0x5b, flags: 0x0},
+ 408: {region: 0x166, script: 0x2c, flags: 0x0},
+ 409: {region: 0x166, script: 0x5b, flags: 0x0},
+ 410: {region: 0x9a, script: 0x22, flags: 0x0},
+ 411: {region: 0x9a, script: 0xe9, flags: 0x0},
+ 412: {region: 0x96, script: 0x5b, flags: 0x0},
+ 413: {region: 0xda, script: 0x5b, flags: 0x0},
+ 414: {region: 0x131, script: 0x32, flags: 0x0},
+ 415: {region: 0x166, script: 0x5b, flags: 0x0},
+ 416: {region: 0xe, script: 0x2, flags: 0x1},
+ 417: {region: 0x9a, script: 0xe, flags: 0x0},
+ 418: {region: 0x166, script: 0x5b, flags: 0x0},
+ 419: {region: 0x4e, script: 0x5b, flags: 0x0},
+ 420: {region: 0x9a, script: 0x35, flags: 0x0},
+ 421: {region: 0x41, script: 0x5b, flags: 0x0},
+ 422: {region: 0x54, script: 0x5b, flags: 0x0},
+ 423: {region: 0x166, script: 0x5b, flags: 0x0},
+ 424: {region: 0x81, script: 0x5b, flags: 0x0},
+ 425: {region: 0x166, script: 0x5b, flags: 0x0},
+ 426: {region: 0x166, script: 0x5b, flags: 0x0},
+ 427: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 428: {region: 0x99, script: 0x5b, flags: 0x0},
+ 429: {region: 0x166, script: 0x5b, flags: 0x0},
+ 430: {region: 0xdc, script: 0x22, flags: 0x0},
+ 431: {region: 0x166, script: 0x5b, flags: 0x0},
+ 432: {region: 0x166, script: 0x5, flags: 0x0},
+ 433: {region: 0x49, script: 0x5b, flags: 0x0},
+ 434: {region: 0x166, script: 0x5, flags: 0x0},
+ 435: {region: 0x166, script: 0x5b, flags: 0x0},
+ 436: {region: 0x10, script: 0x3, flags: 0x1},
+ 437: {region: 0x166, script: 0x5b, flags: 0x0},
+ 438: {region: 0x53, script: 0x3b, flags: 0x0},
+ 439: {region: 0x166, script: 0x5b, flags: 0x0},
+ 440: {region: 0x136, script: 0x5b, flags: 0x0},
+ 441: {region: 0x24, script: 0x5, flags: 0x0},
+ 442: {region: 0x166, script: 0x5b, flags: 0x0},
+ 443: {region: 0x166, script: 0x2c, flags: 0x0},
+ 444: {region: 0x98, script: 0x3e, flags: 0x0},
+ 445: {region: 0x166, script: 0x5b, flags: 0x0},
+ 446: {region: 0x9a, script: 0x22, flags: 0x0},
+ 447: {region: 0x166, script: 0x5b, flags: 0x0},
+ 448: {region: 0x74, script: 0x5b, flags: 0x0},
+ 449: {region: 0x166, script: 0x5b, flags: 0x0},
+ 450: {region: 0x166, script: 0x5b, flags: 0x0},
+ 451: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 452: {region: 0x166, script: 0x5b, flags: 0x0},
+ 453: {region: 0x12c, script: 0x40, flags: 0x0},
+ 454: {region: 0x53, script: 0x92, flags: 0x0},
+ 455: {region: 0x166, script: 0x5b, flags: 0x0},
+ 456: {region: 0xe9, script: 0x5, flags: 0x0},
+ 457: {region: 0x9a, script: 0x22, flags: 0x0},
+ 458: {region: 0xb0, script: 0x41, flags: 0x0},
+ 459: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 460: {region: 0xe9, script: 0x5, flags: 0x0},
+ 461: {region: 0xe7, script: 0x5b, flags: 0x0},
+ 462: {region: 0x9a, script: 0x22, flags: 0x0},
+ 463: {region: 0x9a, script: 0x22, flags: 0x0},
+ 464: {region: 0x166, script: 0x5b, flags: 0x0},
+ 465: {region: 0x91, script: 0x5b, flags: 0x0},
+ 466: {region: 0x61, script: 0x5b, flags: 0x0},
+ 467: {region: 0x53, script: 0x3b, flags: 0x0},
+ 468: {region: 0x92, script: 0x5b, flags: 0x0},
+ 469: {region: 0x93, script: 0x5b, flags: 0x0},
+ 470: {region: 0x166, script: 0x5b, flags: 0x0},
+ 471: {region: 0x28, script: 0x8, flags: 0x0},
+ 472: {region: 0xd3, script: 0x5b, flags: 0x0},
+ 473: {region: 0x79, script: 0x5b, flags: 0x0},
+ 474: {region: 0x166, script: 0x5b, flags: 0x0},
+ 475: {region: 0x166, script: 0x5b, flags: 0x0},
+ 476: {region: 0xd1, script: 0x5b, flags: 0x0},
+ 477: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 478: {region: 0x166, script: 0x5b, flags: 0x0},
+ 479: {region: 0x166, script: 0x5b, flags: 0x0},
+ 480: {region: 0x166, script: 0x5b, flags: 0x0},
+ 481: {region: 0x96, script: 0x5b, flags: 0x0},
+ 482: {region: 0x166, script: 0x5b, flags: 0x0},
+ 483: {region: 0x166, script: 0x5b, flags: 0x0},
+ 484: {region: 0x166, script: 0x5b, flags: 0x0},
+ 486: {region: 0x123, script: 0x5b, flags: 0x0},
+ 487: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 488: {region: 0x166, script: 0x5b, flags: 0x0},
+ 489: {region: 0x166, script: 0x5b, flags: 0x0},
+ 490: {region: 0x53, script: 0xfd, flags: 0x0},
+ 491: {region: 0x166, script: 0x5b, flags: 0x0},
+ 492: {region: 0x136, script: 0x5b, flags: 0x0},
+ 493: {region: 0x166, script: 0x5b, flags: 0x0},
+ 494: {region: 0x49, script: 0x5b, flags: 0x0},
+ 495: {region: 0x166, script: 0x5b, flags: 0x0},
+ 496: {region: 0x166, script: 0x5b, flags: 0x0},
+ 497: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 498: {region: 0x166, script: 0x5b, flags: 0x0},
+ 499: {region: 0x96, script: 0x5b, flags: 0x0},
+ 500: {region: 0x107, script: 0x20, flags: 0x0},
+ 501: {region: 0x1, script: 0x5b, flags: 0x0},
+ 502: {region: 0x166, script: 0x5b, flags: 0x0},
+ 503: {region: 0x166, script: 0x5b, flags: 0x0},
+ 504: {region: 0x9e, script: 0x5b, flags: 0x0},
+ 505: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 506: {region: 0x49, script: 0x17, flags: 0x0},
+ 507: {region: 0x98, script: 0x3e, flags: 0x0},
+ 508: {region: 0x166, script: 0x5b, flags: 0x0},
+ 509: {region: 0x166, script: 0x5b, flags: 0x0},
+ 510: {region: 0x107, script: 0x5b, flags: 0x0},
+ 511: {region: 0x166, script: 0x5b, flags: 0x0},
+ 512: {region: 0xa3, script: 0x49, flags: 0x0},
+ 513: {region: 0x166, script: 0x5b, flags: 0x0},
+ 514: {region: 0xa1, script: 0x5b, flags: 0x0},
+ 515: {region: 0x1, script: 0x5b, flags: 0x0},
+ 516: {region: 0x166, script: 0x5b, flags: 0x0},
+ 517: {region: 0x166, script: 0x5b, flags: 0x0},
+ 518: {region: 0x166, script: 0x5b, flags: 0x0},
+ 519: {region: 0x52, script: 0x5b, flags: 0x0},
+ 520: {region: 0x131, script: 0x3e, flags: 0x0},
+ 521: {region: 0x166, script: 0x5b, flags: 0x0},
+ 522: {region: 0x130, script: 0x5b, flags: 0x0},
+ 523: {region: 0xdc, script: 0x22, flags: 0x0},
+ 524: {region: 0x166, script: 0x5b, flags: 0x0},
+ 525: {region: 0x64, script: 0x5b, flags: 0x0},
+ 526: {region: 0x96, script: 0x5b, flags: 0x0},
+ 527: {region: 0x96, script: 0x5b, flags: 0x0},
+ 528: {region: 0x7e, script: 0x2e, flags: 0x0},
+ 529: {region: 0x138, script: 0x20, flags: 0x0},
+ 530: {region: 0x68, script: 0x5b, flags: 0x0},
+ 531: {region: 0xc5, script: 0x5b, flags: 0x0},
+ 532: {region: 0x166, script: 0x5b, flags: 0x0},
+ 533: {region: 0x166, script: 0x5b, flags: 0x0},
+ 534: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 535: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 536: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 537: {region: 0x107, script: 0x20, flags: 0x0},
+ 538: {region: 0x166, script: 0x5b, flags: 0x0},
+ 539: {region: 0x166, script: 0x5b, flags: 0x0},
+ 540: {region: 0x166, script: 0x5b, flags: 0x0},
+ 541: {region: 0x166, script: 0x5b, flags: 0x0},
+ 542: {region: 0xd5, script: 0x5, flags: 0x0},
+ 543: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 544: {region: 0x165, script: 0x5b, flags: 0x0},
+ 545: {region: 0x166, script: 0x5b, flags: 0x0},
+ 546: {region: 0x166, script: 0x5b, flags: 0x0},
+ 547: {region: 0x130, script: 0x5b, flags: 0x0},
+ 548: {region: 0x123, script: 0x5, flags: 0x0},
+ 549: {region: 0x166, script: 0x5b, flags: 0x0},
+ 550: {region: 0x124, script: 0xee, flags: 0x0},
+ 551: {region: 0x5b, script: 0x5b, flags: 0x0},
+ 552: {region: 0x52, script: 0x5b, flags: 0x0},
+ 553: {region: 0x166, script: 0x5b, flags: 0x0},
+ 554: {region: 0x4f, script: 0x5b, flags: 0x0},
+ 555: {region: 0x9a, script: 0x22, flags: 0x0},
+ 556: {region: 0x9a, script: 0x22, flags: 0x0},
+ 557: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 558: {region: 0x96, script: 0x5b, flags: 0x0},
+ 559: {region: 0x166, script: 0x5b, flags: 0x0},
+ 560: {region: 0x41, script: 0x5b, flags: 0x0},
+ 561: {region: 0x9a, script: 0x5b, flags: 0x0},
+ 562: {region: 0x53, script: 0xe5, flags: 0x0},
+ 563: {region: 0x9a, script: 0x22, flags: 0x0},
+ 564: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 565: {region: 0x166, script: 0x5b, flags: 0x0},
+ 566: {region: 0x9a, script: 0x76, flags: 0x0},
+ 567: {region: 0xe9, script: 0x5, flags: 0x0},
+ 568: {region: 0x166, script: 0x5b, flags: 0x0},
+ 569: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 570: {region: 0x166, script: 0x5b, flags: 0x0},
+ 571: {region: 0x12c, script: 0x5b, flags: 0x0},
+ 572: {region: 0x166, script: 0x5b, flags: 0x0},
+ 573: {region: 0xd3, script: 0x5b, flags: 0x0},
+ 574: {region: 0x166, script: 0x5b, flags: 0x0},
+ 575: {region: 0xb0, script: 0x58, flags: 0x0},
+ 576: {region: 0x166, script: 0x5b, flags: 0x0},
+ 577: {region: 0x166, script: 0x5b, flags: 0x0},
+ 578: {region: 0x13, script: 0x6, flags: 0x1},
+ 579: {region: 0x166, script: 0x5b, flags: 0x0},
+ 580: {region: 0x52, script: 0x5b, flags: 0x0},
+ 581: {region: 0x83, script: 0x5b, flags: 0x0},
+ 582: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 583: {region: 0x166, script: 0x5b, flags: 0x0},
+ 584: {region: 0x166, script: 0x5b, flags: 0x0},
+ 585: {region: 0x166, script: 0x5b, flags: 0x0},
+ 586: {region: 0xa7, script: 0x4f, flags: 0x0},
+ 587: {region: 0x2a, script: 0x5b, flags: 0x0},
+ 588: {region: 0x166, script: 0x5b, flags: 0x0},
+ 589: {region: 0x166, script: 0x5b, flags: 0x0},
+ 590: {region: 0x166, script: 0x5b, flags: 0x0},
+ 591: {region: 0x166, script: 0x5b, flags: 0x0},
+ 592: {region: 0x166, script: 0x5b, flags: 0x0},
+ 593: {region: 0x9a, script: 0x53, flags: 0x0},
+ 594: {region: 0x8c, script: 0x5b, flags: 0x0},
+ 595: {region: 0x166, script: 0x5b, flags: 0x0},
+ 596: {region: 0xac, script: 0x54, flags: 0x0},
+ 597: {region: 0x107, script: 0x20, flags: 0x0},
+ 598: {region: 0x9a, script: 0x22, flags: 0x0},
+ 599: {region: 0x166, script: 0x5b, flags: 0x0},
+ 600: {region: 0x76, script: 0x5b, flags: 0x0},
+ 601: {region: 0x166, script: 0x5b, flags: 0x0},
+ 602: {region: 0xb5, script: 0x5b, flags: 0x0},
+ 603: {region: 0x166, script: 0x5b, flags: 0x0},
+ 604: {region: 0x166, script: 0x5b, flags: 0x0},
+ 605: {region: 0x166, script: 0x5b, flags: 0x0},
+ 606: {region: 0x166, script: 0x5b, flags: 0x0},
+ 607: {region: 0x166, script: 0x5b, flags: 0x0},
+ 608: {region: 0x166, script: 0x5b, flags: 0x0},
+ 609: {region: 0x166, script: 0x5b, flags: 0x0},
+ 610: {region: 0x166, script: 0x2c, flags: 0x0},
+ 611: {region: 0x166, script: 0x5b, flags: 0x0},
+ 612: {region: 0x107, script: 0x20, flags: 0x0},
+ 613: {region: 0x113, script: 0x5b, flags: 0x0},
+ 614: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 615: {region: 0x107, script: 0x5b, flags: 0x0},
+ 616: {region: 0x166, script: 0x5b, flags: 0x0},
+ 617: {region: 0x9a, script: 0x22, flags: 0x0},
+ 618: {region: 0x9a, script: 0x5, flags: 0x0},
+ 619: {region: 0x130, script: 0x5b, flags: 0x0},
+ 620: {region: 0x166, script: 0x5b, flags: 0x0},
+ 621: {region: 0x52, script: 0x5b, flags: 0x0},
+ 622: {region: 0x61, script: 0x5b, flags: 0x0},
+ 623: {region: 0x166, script: 0x5b, flags: 0x0},
+ 624: {region: 0x166, script: 0x5b, flags: 0x0},
+ 625: {region: 0x166, script: 0x2c, flags: 0x0},
+ 626: {region: 0x166, script: 0x5b, flags: 0x0},
+ 627: {region: 0x166, script: 0x5b, flags: 0x0},
+ 628: {region: 0x19, script: 0x3, flags: 0x1},
+ 629: {region: 0x166, script: 0x5b, flags: 0x0},
+ 630: {region: 0x166, script: 0x5b, flags: 0x0},
+ 631: {region: 0x166, script: 0x5b, flags: 0x0},
+ 632: {region: 0x166, script: 0x5b, flags: 0x0},
+ 633: {region: 0x107, script: 0x20, flags: 0x0},
+ 634: {region: 0x166, script: 0x5b, flags: 0x0},
+ 635: {region: 0x166, script: 0x5b, flags: 0x0},
+ 636: {region: 0x166, script: 0x5b, flags: 0x0},
+ 637: {region: 0x107, script: 0x20, flags: 0x0},
+ 638: {region: 0x166, script: 0x5b, flags: 0x0},
+ 639: {region: 0x96, script: 0x5b, flags: 0x0},
+ 640: {region: 0xe9, script: 0x5, flags: 0x0},
+ 641: {region: 0x7c, script: 0x5b, flags: 0x0},
+ 642: {region: 0x166, script: 0x5b, flags: 0x0},
+ 643: {region: 0x166, script: 0x5b, flags: 0x0},
+ 644: {region: 0x166, script: 0x5b, flags: 0x0},
+ 645: {region: 0x166, script: 0x2c, flags: 0x0},
+ 646: {region: 0x124, script: 0xee, flags: 0x0},
+ 647: {region: 0xe9, script: 0x5, flags: 0x0},
+ 648: {region: 0x166, script: 0x5b, flags: 0x0},
+ 649: {region: 0x166, script: 0x5b, flags: 0x0},
+ 650: {region: 0x1c, script: 0x5, flags: 0x1},
+ 651: {region: 0x166, script: 0x5b, flags: 0x0},
+ 652: {region: 0x166, script: 0x5b, flags: 0x0},
+ 653: {region: 0x166, script: 0x5b, flags: 0x0},
+ 654: {region: 0x139, script: 0x5b, flags: 0x0},
+ 655: {region: 0x88, script: 0x5f, flags: 0x0},
+ 656: {region: 0x98, script: 0x3e, flags: 0x0},
+ 657: {region: 0x130, script: 0x5b, flags: 0x0},
+ 658: {region: 0xe9, script: 0x5, flags: 0x0},
+ 659: {region: 0x132, script: 0x5b, flags: 0x0},
+ 660: {region: 0x166, script: 0x5b, flags: 0x0},
+ 661: {region: 0xb8, script: 0x5b, flags: 0x0},
+ 662: {region: 0x107, script: 0x20, flags: 0x0},
+ 663: {region: 0x166, script: 0x5b, flags: 0x0},
+ 664: {region: 0x96, script: 0x5b, flags: 0x0},
+ 665: {region: 0x166, script: 0x5b, flags: 0x0},
+ 666: {region: 0x53, script: 0xee, flags: 0x0},
+ 667: {region: 0x166, script: 0x5b, flags: 0x0},
+ 668: {region: 0x166, script: 0x5b, flags: 0x0},
+ 669: {region: 0x166, script: 0x5b, flags: 0x0},
+ 670: {region: 0x166, script: 0x5b, flags: 0x0},
+ 671: {region: 0x9a, script: 0x5d, flags: 0x0},
+ 672: {region: 0x166, script: 0x5b, flags: 0x0},
+ 673: {region: 0x166, script: 0x5b, flags: 0x0},
+ 674: {region: 0x107, script: 0x20, flags: 0x0},
+ 675: {region: 0x132, script: 0x5b, flags: 0x0},
+ 676: {region: 0x166, script: 0x5b, flags: 0x0},
+ 677: {region: 0xda, script: 0x5b, flags: 0x0},
+ 678: {region: 0x166, script: 0x5b, flags: 0x0},
+ 679: {region: 0x166, script: 0x5b, flags: 0x0},
+ 680: {region: 0x21, script: 0x2, flags: 0x1},
+ 681: {region: 0x166, script: 0x5b, flags: 0x0},
+ 682: {region: 0x166, script: 0x5b, flags: 0x0},
+ 683: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 684: {region: 0x53, script: 0x61, flags: 0x0},
+ 685: {region: 0x96, script: 0x5b, flags: 0x0},
+ 686: {region: 0x9d, script: 0x5, flags: 0x0},
+ 687: {region: 0x136, script: 0x5b, flags: 0x0},
+ 688: {region: 0x166, script: 0x5b, flags: 0x0},
+ 689: {region: 0x166, script: 0x5b, flags: 0x0},
+ 690: {region: 0x9a, script: 0xe9, flags: 0x0},
+ 691: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 692: {region: 0x166, script: 0x5b, flags: 0x0},
+ 693: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 694: {region: 0x166, script: 0x5b, flags: 0x0},
+ 695: {region: 0x166, script: 0x5b, flags: 0x0},
+ 696: {region: 0xb0, script: 0x58, flags: 0x0},
+ 697: {region: 0x166, script: 0x5b, flags: 0x0},
+ 698: {region: 0x166, script: 0x5b, flags: 0x0},
+ 699: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 700: {region: 0x166, script: 0x5b, flags: 0x0},
+ 701: {region: 0x166, script: 0x5b, flags: 0x0},
+ 702: {region: 0x163, script: 0x5b, flags: 0x0},
+ 703: {region: 0x9d, script: 0x5, flags: 0x0},
+ 704: {region: 0xb7, script: 0x5b, flags: 0x0},
+ 705: {region: 0xb9, script: 0x5b, flags: 0x0},
+ 706: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 707: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 708: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 709: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 710: {region: 0x9d, script: 0x5, flags: 0x0},
+ 711: {region: 0xb9, script: 0x5b, flags: 0x0},
+ 712: {region: 0x124, script: 0xee, flags: 0x0},
+ 713: {region: 0x53, script: 0x3b, flags: 0x0},
+ 714: {region: 0x12c, script: 0x5b, flags: 0x0},
+ 715: {region: 0x96, script: 0x5b, flags: 0x0},
+ 716: {region: 0x52, script: 0x5b, flags: 0x0},
+ 717: {region: 0x9a, script: 0x22, flags: 0x0},
+ 718: {region: 0x9a, script: 0x22, flags: 0x0},
+ 719: {region: 0x96, script: 0x5b, flags: 0x0},
+ 720: {region: 0x23, script: 0x3, flags: 0x1},
+ 721: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 722: {region: 0x166, script: 0x5b, flags: 0x0},
+ 723: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 724: {region: 0x166, script: 0x5b, flags: 0x0},
+ 725: {region: 0x166, script: 0x5b, flags: 0x0},
+ 726: {region: 0x166, script: 0x5b, flags: 0x0},
+ 727: {region: 0x166, script: 0x5b, flags: 0x0},
+ 728: {region: 0x166, script: 0x5b, flags: 0x0},
+ 729: {region: 0x166, script: 0x5b, flags: 0x0},
+ 730: {region: 0x166, script: 0x5b, flags: 0x0},
+ 731: {region: 0x166, script: 0x5b, flags: 0x0},
+ 732: {region: 0x166, script: 0x5b, flags: 0x0},
+ 733: {region: 0x166, script: 0x5b, flags: 0x0},
+ 734: {region: 0x166, script: 0x5b, flags: 0x0},
+ 735: {region: 0x166, script: 0x5, flags: 0x0},
+ 736: {region: 0x107, script: 0x20, flags: 0x0},
+ 737: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 738: {region: 0x166, script: 0x5b, flags: 0x0},
+ 739: {region: 0x96, script: 0x5b, flags: 0x0},
+ 740: {region: 0x166, script: 0x2c, flags: 0x0},
+ 741: {region: 0x166, script: 0x5b, flags: 0x0},
+ 742: {region: 0x166, script: 0x5b, flags: 0x0},
+ 743: {region: 0x166, script: 0x5b, flags: 0x0},
+ 744: {region: 0x113, script: 0x5b, flags: 0x0},
+ 745: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 746: {region: 0x166, script: 0x5b, flags: 0x0},
+ 747: {region: 0x166, script: 0x5b, flags: 0x0},
+ 748: {region: 0x124, script: 0x5, flags: 0x0},
+ 749: {region: 0xcd, script: 0x5b, flags: 0x0},
+ 750: {region: 0x166, script: 0x5b, flags: 0x0},
+ 751: {region: 0x166, script: 0x5b, flags: 0x0},
+ 752: {region: 0x166, script: 0x5b, flags: 0x0},
+ 753: {region: 0xc0, script: 0x5b, flags: 0x0},
+ 754: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 755: {region: 0x166, script: 0x5b, flags: 0x0},
+ 756: {region: 0x52, script: 0x5b, flags: 0x0},
+ 757: {region: 0xdc, script: 0x22, flags: 0x0},
+ 758: {region: 0x130, script: 0x5b, flags: 0x0},
+ 759: {region: 0xc1, script: 0x5b, flags: 0x0},
+ 760: {region: 0x166, script: 0x5b, flags: 0x0},
+ 761: {region: 0x166, script: 0x5b, flags: 0x0},
+ 762: {region: 0xe1, script: 0x5b, flags: 0x0},
+ 763: {region: 0x166, script: 0x5b, flags: 0x0},
+ 764: {region: 0x96, script: 0x5b, flags: 0x0},
+ 765: {region: 0x9c, script: 0x3d, flags: 0x0},
+ 766: {region: 0x166, script: 0x5b, flags: 0x0},
+ 767: {region: 0xc3, script: 0x20, flags: 0x0},
+ 768: {region: 0x166, script: 0x5, flags: 0x0},
+ 769: {region: 0x166, script: 0x5b, flags: 0x0},
+ 770: {region: 0x166, script: 0x5b, flags: 0x0},
+ 771: {region: 0x166, script: 0x5b, flags: 0x0},
+ 772: {region: 0x9a, script: 0x6f, flags: 0x0},
+ 773: {region: 0x166, script: 0x5b, flags: 0x0},
+ 774: {region: 0x166, script: 0x5b, flags: 0x0},
+ 775: {region: 0x10c, script: 0x5b, flags: 0x0},
+ 776: {region: 0x166, script: 0x5b, flags: 0x0},
+ 777: {region: 0x166, script: 0x5b, flags: 0x0},
+ 778: {region: 0x166, script: 0x5b, flags: 0x0},
+ 779: {region: 0x26, script: 0x3, flags: 0x1},
+ 780: {region: 0x166, script: 0x5b, flags: 0x0},
+ 781: {region: 0x166, script: 0x5b, flags: 0x0},
+ 782: {region: 0x9a, script: 0xe, flags: 0x0},
+ 783: {region: 0xc5, script: 0x76, flags: 0x0},
+ 785: {region: 0x166, script: 0x5b, flags: 0x0},
+ 786: {region: 0x49, script: 0x5b, flags: 0x0},
+ 787: {region: 0x49, script: 0x5b, flags: 0x0},
+ 788: {region: 0x37, script: 0x5b, flags: 0x0},
+ 789: {region: 0x166, script: 0x5b, flags: 0x0},
+ 790: {region: 0x166, script: 0x5b, flags: 0x0},
+ 791: {region: 0x166, script: 0x5b, flags: 0x0},
+ 792: {region: 0x166, script: 0x5b, flags: 0x0},
+ 793: {region: 0x166, script: 0x5b, flags: 0x0},
+ 794: {region: 0x166, script: 0x5b, flags: 0x0},
+ 795: {region: 0x9a, script: 0x22, flags: 0x0},
+ 796: {region: 0xdc, script: 0x22, flags: 0x0},
+ 797: {region: 0x107, script: 0x20, flags: 0x0},
+ 798: {region: 0x35, script: 0x73, flags: 0x0},
+ 799: {region: 0x29, script: 0x3, flags: 0x1},
+ 800: {region: 0xcc, script: 0x5b, flags: 0x0},
+ 801: {region: 0x166, script: 0x5b, flags: 0x0},
+ 802: {region: 0x166, script: 0x5b, flags: 0x0},
+ 803: {region: 0x166, script: 0x5b, flags: 0x0},
+ 804: {region: 0x9a, script: 0x22, flags: 0x0},
+ 805: {region: 0x52, script: 0x5b, flags: 0x0},
+ 807: {region: 0x166, script: 0x5b, flags: 0x0},
+ 808: {region: 0x136, script: 0x5b, flags: 0x0},
+ 809: {region: 0x166, script: 0x5b, flags: 0x0},
+ 810: {region: 0x166, script: 0x5b, flags: 0x0},
+ 811: {region: 0xe9, script: 0x5, flags: 0x0},
+ 812: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 813: {region: 0x9a, script: 0x22, flags: 0x0},
+ 814: {region: 0x96, script: 0x5b, flags: 0x0},
+ 815: {region: 0x165, script: 0x5b, flags: 0x0},
+ 816: {region: 0x166, script: 0x5b, flags: 0x0},
+ 817: {region: 0xc5, script: 0x76, flags: 0x0},
+ 818: {region: 0x166, script: 0x5b, flags: 0x0},
+ 819: {region: 0x166, script: 0x2c, flags: 0x0},
+ 820: {region: 0x107, script: 0x20, flags: 0x0},
+ 821: {region: 0x166, script: 0x5b, flags: 0x0},
+ 822: {region: 0x132, script: 0x5b, flags: 0x0},
+ 823: {region: 0x9d, script: 0x67, flags: 0x0},
+ 824: {region: 0x166, script: 0x5b, flags: 0x0},
+ 825: {region: 0x166, script: 0x5b, flags: 0x0},
+ 826: {region: 0x9d, script: 0x5, flags: 0x0},
+ 827: {region: 0x166, script: 0x5b, flags: 0x0},
+ 828: {region: 0x166, script: 0x5b, flags: 0x0},
+ 829: {region: 0x166, script: 0x5b, flags: 0x0},
+ 830: {region: 0xde, script: 0x5b, flags: 0x0},
+ 831: {region: 0x166, script: 0x5b, flags: 0x0},
+ 832: {region: 0x166, script: 0x5b, flags: 0x0},
+ 834: {region: 0x166, script: 0x5b, flags: 0x0},
+ 835: {region: 0x53, script: 0x3b, flags: 0x0},
+ 836: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 837: {region: 0xd3, script: 0x5b, flags: 0x0},
+ 838: {region: 0x166, script: 0x5b, flags: 0x0},
+ 839: {region: 0xdb, script: 0x5b, flags: 0x0},
+ 840: {region: 0x166, script: 0x5b, flags: 0x0},
+ 841: {region: 0x166, script: 0x5b, flags: 0x0},
+ 842: {region: 0x166, script: 0x5b, flags: 0x0},
+ 843: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 844: {region: 0x166, script: 0x5b, flags: 0x0},
+ 845: {region: 0x166, script: 0x5b, flags: 0x0},
+ 846: {region: 0x165, script: 0x5b, flags: 0x0},
+ 847: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 848: {region: 0x61, script: 0x5b, flags: 0x0},
+ 849: {region: 0xdc, script: 0x22, flags: 0x0},
+ 850: {region: 0x166, script: 0x5b, flags: 0x0},
+ 851: {region: 0xdc, script: 0x22, flags: 0x0},
+ 852: {region: 0x166, script: 0x5b, flags: 0x0},
+ 853: {region: 0x166, script: 0x5b, flags: 0x0},
+ 854: {region: 0xd3, script: 0x5b, flags: 0x0},
+ 855: {region: 0x166, script: 0x5b, flags: 0x0},
+ 856: {region: 0x166, script: 0x5b, flags: 0x0},
+ 857: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 858: {region: 0x166, script: 0x5b, flags: 0x0},
+ 859: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 860: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 861: {region: 0x166, script: 0x5b, flags: 0x0},
+ 862: {region: 0x166, script: 0x5b, flags: 0x0},
+ 863: {region: 0x96, script: 0x5b, flags: 0x0},
+ 864: {region: 0x166, script: 0x5b, flags: 0x0},
+ 865: {region: 0xe0, script: 0x5b, flags: 0x0},
+ 866: {region: 0x166, script: 0x5b, flags: 0x0},
+ 867: {region: 0x166, script: 0x5b, flags: 0x0},
+ 868: {region: 0x9a, script: 0x5b, flags: 0x0},
+ 869: {region: 0x166, script: 0x5b, flags: 0x0},
+ 870: {region: 0x166, script: 0x5b, flags: 0x0},
+ 871: {region: 0xda, script: 0x5b, flags: 0x0},
+ 872: {region: 0x52, script: 0x5b, flags: 0x0},
+ 873: {region: 0x166, script: 0x5b, flags: 0x0},
+ 874: {region: 0xdb, script: 0x5b, flags: 0x0},
+ 875: {region: 0x166, script: 0x5b, flags: 0x0},
+ 876: {region: 0x52, script: 0x5b, flags: 0x0},
+ 877: {region: 0x166, script: 0x5b, flags: 0x0},
+ 878: {region: 0x166, script: 0x5b, flags: 0x0},
+ 879: {region: 0xdb, script: 0x5b, flags: 0x0},
+ 880: {region: 0x124, script: 0x57, flags: 0x0},
+ 881: {region: 0x9a, script: 0x22, flags: 0x0},
+ 882: {region: 0x10d, script: 0xcb, flags: 0x0},
+ 883: {region: 0x166, script: 0x5b, flags: 0x0},
+ 884: {region: 0x166, script: 0x5b, flags: 0x0},
+ 885: {region: 0x85, script: 0x7e, flags: 0x0},
+ 886: {region: 0x162, script: 0x5b, flags: 0x0},
+ 887: {region: 0x166, script: 0x5b, flags: 0x0},
+ 888: {region: 0x49, script: 0x17, flags: 0x0},
+ 889: {region: 0x166, script: 0x5b, flags: 0x0},
+ 890: {region: 0x162, script: 0x5b, flags: 0x0},
+ 891: {region: 0x166, script: 0x5b, flags: 0x0},
+ 892: {region: 0x166, script: 0x5b, flags: 0x0},
+ 893: {region: 0x166, script: 0x5b, flags: 0x0},
+ 894: {region: 0x166, script: 0x5b, flags: 0x0},
+ 895: {region: 0x166, script: 0x5b, flags: 0x0},
+ 896: {region: 0x118, script: 0x5b, flags: 0x0},
+ 897: {region: 0x166, script: 0x5b, flags: 0x0},
+ 898: {region: 0x166, script: 0x5b, flags: 0x0},
+ 899: {region: 0x136, script: 0x5b, flags: 0x0},
+ 900: {region: 0x166, script: 0x5b, flags: 0x0},
+ 901: {region: 0x53, script: 0x5b, flags: 0x0},
+ 902: {region: 0x166, script: 0x5b, flags: 0x0},
+ 903: {region: 0xcf, script: 0x5b, flags: 0x0},
+ 904: {region: 0x130, script: 0x5b, flags: 0x0},
+ 905: {region: 0x132, script: 0x5b, flags: 0x0},
+ 906: {region: 0x81, script: 0x5b, flags: 0x0},
+ 907: {region: 0x79, script: 0x5b, flags: 0x0},
+ 908: {region: 0x166, script: 0x5b, flags: 0x0},
+ 910: {region: 0x166, script: 0x5b, flags: 0x0},
+ 911: {region: 0x166, script: 0x5b, flags: 0x0},
+ 912: {region: 0x70, script: 0x5b, flags: 0x0},
+ 913: {region: 0x166, script: 0x5b, flags: 0x0},
+ 914: {region: 0x166, script: 0x5b, flags: 0x0},
+ 915: {region: 0x166, script: 0x5b, flags: 0x0},
+ 916: {region: 0x166, script: 0x5b, flags: 0x0},
+ 917: {region: 0x9a, script: 0x83, flags: 0x0},
+ 918: {region: 0x166, script: 0x5b, flags: 0x0},
+ 919: {region: 0x166, script: 0x5, flags: 0x0},
+ 920: {region: 0x7e, script: 0x20, flags: 0x0},
+ 921: {region: 0x136, script: 0x84, flags: 0x0},
+ 922: {region: 0x166, script: 0x5, flags: 0x0},
+ 923: {region: 0xc6, script: 0x82, flags: 0x0},
+ 924: {region: 0x166, script: 0x5b, flags: 0x0},
+ 925: {region: 0x2c, script: 0x3, flags: 0x1},
+ 926: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 927: {region: 0x2f, script: 0x2, flags: 0x1},
+ 928: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 929: {region: 0x30, script: 0x5b, flags: 0x0},
+ 930: {region: 0xf1, script: 0x5b, flags: 0x0},
+ 931: {region: 0x166, script: 0x5b, flags: 0x0},
+ 932: {region: 0x79, script: 0x5b, flags: 0x0},
+ 933: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 934: {region: 0x136, script: 0x5b, flags: 0x0},
+ 935: {region: 0x49, script: 0x5b, flags: 0x0},
+ 936: {region: 0x166, script: 0x5b, flags: 0x0},
+ 937: {region: 0x9d, script: 0xfa, flags: 0x0},
+ 938: {region: 0x166, script: 0x5b, flags: 0x0},
+ 939: {region: 0x61, script: 0x5b, flags: 0x0},
+ 940: {region: 0x166, script: 0x5, flags: 0x0},
+ 941: {region: 0xb1, script: 0x90, flags: 0x0},
+ 943: {region: 0x166, script: 0x5b, flags: 0x0},
+ 944: {region: 0x166, script: 0x5b, flags: 0x0},
+ 945: {region: 0x9a, script: 0x12, flags: 0x0},
+ 946: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 947: {region: 0xea, script: 0x5b, flags: 0x0},
+ 948: {region: 0x166, script: 0x5b, flags: 0x0},
+ 949: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 950: {region: 0x166, script: 0x5b, flags: 0x0},
+ 951: {region: 0x166, script: 0x5b, flags: 0x0},
+ 952: {region: 0x88, script: 0x34, flags: 0x0},
+ 953: {region: 0x76, script: 0x5b, flags: 0x0},
+ 954: {region: 0x166, script: 0x5b, flags: 0x0},
+ 955: {region: 0xe9, script: 0x4e, flags: 0x0},
+ 956: {region: 0x9d, script: 0x5, flags: 0x0},
+ 957: {region: 0x1, script: 0x5b, flags: 0x0},
+ 958: {region: 0x24, script: 0x5, flags: 0x0},
+ 959: {region: 0x166, script: 0x5b, flags: 0x0},
+ 960: {region: 0x41, script: 0x5b, flags: 0x0},
+ 961: {region: 0x166, script: 0x5b, flags: 0x0},
+ 962: {region: 0x7b, script: 0x5b, flags: 0x0},
+ 963: {region: 0x166, script: 0x5b, flags: 0x0},
+ 964: {region: 0xe5, script: 0x5b, flags: 0x0},
+ 965: {region: 0x8a, script: 0x5b, flags: 0x0},
+ 966: {region: 0x6a, script: 0x5b, flags: 0x0},
+ 967: {region: 0x166, script: 0x5b, flags: 0x0},
+ 968: {region: 0x9a, script: 0x22, flags: 0x0},
+ 969: {region: 0x166, script: 0x5b, flags: 0x0},
+ 970: {region: 0x103, script: 0x5b, flags: 0x0},
+ 971: {region: 0x96, script: 0x5b, flags: 0x0},
+ 972: {region: 0x166, script: 0x5b, flags: 0x0},
+ 973: {region: 0x166, script: 0x5b, flags: 0x0},
+ 974: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 975: {region: 0x166, script: 0x5, flags: 0x0},
+ 976: {region: 0x9a, script: 0x5b, flags: 0x0},
+ 977: {region: 0x31, script: 0x2, flags: 0x1},
+ 978: {region: 0xdc, script: 0x22, flags: 0x0},
+ 979: {region: 0x35, script: 0xe, flags: 0x0},
+ 980: {region: 0x4e, script: 0x5b, flags: 0x0},
+ 981: {region: 0x73, script: 0x5b, flags: 0x0},
+ 982: {region: 0x4e, script: 0x5b, flags: 0x0},
+ 983: {region: 0x9d, script: 0x5, flags: 0x0},
+ 984: {region: 0x10d, script: 0x5b, flags: 0x0},
+ 985: {region: 0x3a, script: 0x5b, flags: 0x0},
+ 986: {region: 0x166, script: 0x5b, flags: 0x0},
+ 987: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 988: {region: 0x105, script: 0x5b, flags: 0x0},
+ 989: {region: 0x96, script: 0x5b, flags: 0x0},
+ 990: {region: 0x130, script: 0x5b, flags: 0x0},
+ 991: {region: 0x166, script: 0x5b, flags: 0x0},
+ 992: {region: 0x166, script: 0x5b, flags: 0x0},
+ 993: {region: 0x74, script: 0x5b, flags: 0x0},
+ 994: {region: 0x107, script: 0x20, flags: 0x0},
+ 995: {region: 0x131, script: 0x20, flags: 0x0},
+ 996: {region: 0x10a, script: 0x5b, flags: 0x0},
+ 997: {region: 0x108, script: 0x5b, flags: 0x0},
+ 998: {region: 0x130, script: 0x5b, flags: 0x0},
+ 999: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1000: {region: 0xa3, script: 0x4c, flags: 0x0},
+ 1001: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1002: {region: 0x81, script: 0x5b, flags: 0x0},
+ 1003: {region: 0x107, script: 0x20, flags: 0x0},
+ 1004: {region: 0xa5, script: 0x5b, flags: 0x0},
+ 1005: {region: 0x96, script: 0x5b, flags: 0x0},
+ 1006: {region: 0x9a, script: 0x5b, flags: 0x0},
+ 1007: {region: 0x115, script: 0x5b, flags: 0x0},
+ 1008: {region: 0x9a, script: 0xcf, flags: 0x0},
+ 1009: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1010: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1011: {region: 0x130, script: 0x5b, flags: 0x0},
+ 1012: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 1013: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1014: {region: 0x166, script: 0x5, flags: 0x0},
+ 1015: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 1016: {region: 0x7c, script: 0x5b, flags: 0x0},
+ 1017: {region: 0x49, script: 0x5b, flags: 0x0},
+ 1018: {region: 0x33, script: 0x4, flags: 0x1},
+ 1019: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 1020: {region: 0x9d, script: 0x5, flags: 0x0},
+ 1021: {region: 0xdb, script: 0x5b, flags: 0x0},
+ 1022: {region: 0x4f, script: 0x5b, flags: 0x0},
+ 1023: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 1024: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 1025: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 1026: {region: 0x4c, script: 0x5b, flags: 0x0},
+ 1027: {region: 0x97, script: 0x80, flags: 0x0},
+ 1028: {region: 0xb7, script: 0x5b, flags: 0x0},
+ 1029: {region: 0x166, script: 0x2c, flags: 0x0},
+ 1030: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1032: {region: 0xbb, script: 0xeb, flags: 0x0},
+ 1033: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1034: {region: 0xc5, script: 0x76, flags: 0x0},
+ 1035: {region: 0x166, script: 0x5, flags: 0x0},
+ 1036: {region: 0xb4, script: 0xd6, flags: 0x0},
+ 1037: {region: 0x70, script: 0x5b, flags: 0x0},
+ 1038: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1039: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1040: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1041: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1042: {region: 0x112, script: 0x5b, flags: 0x0},
+ 1043: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1044: {region: 0xe9, script: 0x5, flags: 0x0},
+ 1045: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1046: {region: 0x110, script: 0x5b, flags: 0x0},
+ 1047: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1048: {region: 0xea, script: 0x5b, flags: 0x0},
+ 1049: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1050: {region: 0x96, script: 0x5b, flags: 0x0},
+ 1051: {region: 0x143, script: 0x5b, flags: 0x0},
+ 1052: {region: 0x10d, script: 0x5b, flags: 0x0},
+ 1054: {region: 0x10d, script: 0x5b, flags: 0x0},
+ 1055: {region: 0x73, script: 0x5b, flags: 0x0},
+ 1056: {region: 0x98, script: 0xcc, flags: 0x0},
+ 1057: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1058: {region: 0x73, script: 0x5b, flags: 0x0},
+ 1059: {region: 0x165, script: 0x5b, flags: 0x0},
+ 1060: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1061: {region: 0xc4, script: 0x5b, flags: 0x0},
+ 1062: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1063: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1064: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1065: {region: 0x116, script: 0x5b, flags: 0x0},
+ 1066: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1067: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1068: {region: 0x124, script: 0xee, flags: 0x0},
+ 1069: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1070: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1071: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1072: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1073: {region: 0x27, script: 0x5b, flags: 0x0},
+ 1074: {region: 0x37, script: 0x5, flags: 0x1},
+ 1075: {region: 0x9a, script: 0xd9, flags: 0x0},
+ 1076: {region: 0x117, script: 0x5b, flags: 0x0},
+ 1077: {region: 0x115, script: 0x5b, flags: 0x0},
+ 1078: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1079: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1080: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1081: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1082: {region: 0x6e, script: 0x5b, flags: 0x0},
+ 1083: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1084: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1085: {region: 0x61, script: 0x5b, flags: 0x0},
+ 1086: {region: 0x96, script: 0x5b, flags: 0x0},
+ 1087: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1088: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1089: {region: 0x130, script: 0x5b, flags: 0x0},
+ 1090: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1091: {region: 0x85, script: 0x5b, flags: 0x0},
+ 1092: {region: 0x10d, script: 0x5b, flags: 0x0},
+ 1093: {region: 0x130, script: 0x5b, flags: 0x0},
+ 1094: {region: 0x160, script: 0x5, flags: 0x0},
+ 1095: {region: 0x4b, script: 0x5b, flags: 0x0},
+ 1096: {region: 0x61, script: 0x5b, flags: 0x0},
+ 1097: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1098: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1099: {region: 0x96, script: 0x5b, flags: 0x0},
+ 1100: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1101: {region: 0x35, script: 0xe, flags: 0x0},
+ 1102: {region: 0x9c, script: 0xde, flags: 0x0},
+ 1103: {region: 0xea, script: 0x5b, flags: 0x0},
+ 1104: {region: 0x9a, script: 0xe6, flags: 0x0},
+ 1105: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1106: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1107: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1108: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1109: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1110: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1111: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1112: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1113: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1114: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 1115: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1116: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1117: {region: 0x9a, script: 0x53, flags: 0x0},
+ 1118: {region: 0x53, script: 0xe4, flags: 0x0},
+ 1119: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1120: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1121: {region: 0x9a, script: 0xe9, flags: 0x0},
+ 1122: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1123: {region: 0x113, script: 0x5b, flags: 0x0},
+ 1124: {region: 0x132, script: 0x5b, flags: 0x0},
+ 1125: {region: 0x127, script: 0x5b, flags: 0x0},
+ 1126: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1127: {region: 0x3c, script: 0x3, flags: 0x1},
+ 1128: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1129: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1130: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1131: {region: 0x124, script: 0xee, flags: 0x0},
+ 1132: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1133: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1134: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1135: {region: 0x70, script: 0x2c, flags: 0x0},
+ 1136: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1137: {region: 0x6e, script: 0x2c, flags: 0x0},
+ 1138: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1139: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1140: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1141: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 1142: {region: 0x128, script: 0x5b, flags: 0x0},
+ 1143: {region: 0x126, script: 0x5b, flags: 0x0},
+ 1144: {region: 0x32, script: 0x5b, flags: 0x0},
+ 1145: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1146: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 1147: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1148: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1149: {region: 0x32, script: 0x5b, flags: 0x0},
+ 1150: {region: 0xd5, script: 0x5b, flags: 0x0},
+ 1151: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1152: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1153: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1154: {region: 0x12a, script: 0x5b, flags: 0x0},
+ 1155: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1156: {region: 0xcf, script: 0x5b, flags: 0x0},
+ 1157: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1158: {region: 0xe7, script: 0x5b, flags: 0x0},
+ 1159: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1160: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1161: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1162: {region: 0x12c, script: 0x5b, flags: 0x0},
+ 1163: {region: 0x12c, script: 0x5b, flags: 0x0},
+ 1164: {region: 0x12f, script: 0x5b, flags: 0x0},
+ 1165: {region: 0x166, script: 0x5, flags: 0x0},
+ 1166: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1167: {region: 0x88, script: 0x34, flags: 0x0},
+ 1168: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1169: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 1170: {region: 0x43, script: 0xef, flags: 0x0},
+ 1171: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1172: {region: 0x107, script: 0x20, flags: 0x0},
+ 1173: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1174: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1175: {region: 0x132, script: 0x5b, flags: 0x0},
+ 1176: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1177: {region: 0x124, script: 0xee, flags: 0x0},
+ 1178: {region: 0x32, script: 0x5b, flags: 0x0},
+ 1179: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1180: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1181: {region: 0xcf, script: 0x5b, flags: 0x0},
+ 1182: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1183: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1184: {region: 0x12e, script: 0x5b, flags: 0x0},
+ 1185: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1187: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1188: {region: 0xd5, script: 0x5b, flags: 0x0},
+ 1189: {region: 0x53, script: 0xe7, flags: 0x0},
+ 1190: {region: 0xe6, script: 0x5b, flags: 0x0},
+ 1191: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1192: {region: 0x107, script: 0x20, flags: 0x0},
+ 1193: {region: 0xbb, script: 0x5b, flags: 0x0},
+ 1194: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1195: {region: 0x107, script: 0x20, flags: 0x0},
+ 1196: {region: 0x3f, script: 0x4, flags: 0x1},
+ 1197: {region: 0x11d, script: 0xf3, flags: 0x0},
+ 1198: {region: 0x131, script: 0x20, flags: 0x0},
+ 1199: {region: 0x76, script: 0x5b, flags: 0x0},
+ 1200: {region: 0x2a, script: 0x5b, flags: 0x0},
+ 1202: {region: 0x43, script: 0x3, flags: 0x1},
+ 1203: {region: 0x9a, script: 0xe, flags: 0x0},
+ 1204: {region: 0xe9, script: 0x5, flags: 0x0},
+ 1205: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1206: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1207: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1208: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1209: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1210: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1211: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1212: {region: 0x46, script: 0x4, flags: 0x1},
+ 1213: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1214: {region: 0xb5, script: 0xf4, flags: 0x0},
+ 1215: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1216: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1217: {region: 0x9f, script: 0x5b, flags: 0x0},
+ 1218: {region: 0x107, script: 0x5b, flags: 0x0},
+ 1219: {region: 0x13f, script: 0x5b, flags: 0x0},
+ 1220: {region: 0x11c, script: 0x5b, flags: 0x0},
+ 1221: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1222: {region: 0x36, script: 0x5b, flags: 0x0},
+ 1223: {region: 0x61, script: 0x5b, flags: 0x0},
+ 1224: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 1225: {region: 0x1, script: 0x5b, flags: 0x0},
+ 1226: {region: 0x107, script: 0x5b, flags: 0x0},
+ 1227: {region: 0x6b, script: 0x5b, flags: 0x0},
+ 1228: {region: 0x130, script: 0x5b, flags: 0x0},
+ 1229: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1230: {region: 0x36, script: 0x5b, flags: 0x0},
+ 1231: {region: 0x4e, script: 0x5b, flags: 0x0},
+ 1232: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1233: {region: 0x70, script: 0x2c, flags: 0x0},
+ 1234: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1235: {region: 0xe8, script: 0x5b, flags: 0x0},
+ 1236: {region: 0x2f, script: 0x5b, flags: 0x0},
+ 1237: {region: 0x9a, script: 0xe9, flags: 0x0},
+ 1238: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1239: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1240: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1241: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1242: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1243: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1244: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1245: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1246: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1247: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1248: {region: 0x141, script: 0x5b, flags: 0x0},
+ 1249: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1250: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1251: {region: 0xa9, script: 0x5, flags: 0x0},
+ 1252: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1253: {region: 0x115, script: 0x5b, flags: 0x0},
+ 1254: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1255: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1256: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1257: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1258: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1259: {region: 0x53, script: 0x3b, flags: 0x0},
+ 1260: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1261: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1262: {region: 0x41, script: 0x5b, flags: 0x0},
+ 1263: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1264: {region: 0x12c, script: 0x18, flags: 0x0},
+ 1265: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1266: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1267: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1268: {region: 0x12c, script: 0x63, flags: 0x0},
+ 1269: {region: 0x12c, script: 0x64, flags: 0x0},
+ 1270: {region: 0x7e, script: 0x2e, flags: 0x0},
+ 1271: {region: 0x53, script: 0x68, flags: 0x0},
+ 1272: {region: 0x10c, script: 0x6d, flags: 0x0},
+ 1273: {region: 0x109, script: 0x79, flags: 0x0},
+ 1274: {region: 0x9a, script: 0x22, flags: 0x0},
+ 1275: {region: 0x132, script: 0x5b, flags: 0x0},
+ 1276: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1277: {region: 0x9d, script: 0x93, flags: 0x0},
+ 1278: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1279: {region: 0x15f, script: 0xce, flags: 0x0},
+ 1280: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1281: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1282: {region: 0xdc, script: 0x22, flags: 0x0},
+ 1283: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1284: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1285: {region: 0xd2, script: 0x5b, flags: 0x0},
+ 1286: {region: 0x76, script: 0x5b, flags: 0x0},
+ 1287: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1288: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1289: {region: 0x52, script: 0x5b, flags: 0x0},
+ 1290: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1291: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1292: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1293: {region: 0x52, script: 0x5b, flags: 0x0},
+ 1294: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1295: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1296: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1297: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1298: {region: 0x1, script: 0x3e, flags: 0x0},
+ 1299: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1300: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1301: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1302: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1303: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1304: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 1305: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1306: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1307: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1308: {region: 0x41, script: 0x5b, flags: 0x0},
+ 1309: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1310: {region: 0xd0, script: 0x5b, flags: 0x0},
+ 1311: {region: 0x4a, script: 0x3, flags: 0x1},
+ 1312: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1313: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1314: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1315: {region: 0x53, script: 0x5b, flags: 0x0},
+ 1316: {region: 0x10c, script: 0x5b, flags: 0x0},
+ 1318: {region: 0xa9, script: 0x5, flags: 0x0},
+ 1319: {region: 0xda, script: 0x5b, flags: 0x0},
+ 1320: {region: 0xbb, script: 0xeb, flags: 0x0},
+ 1321: {region: 0x4d, script: 0x14, flags: 0x1},
+ 1322: {region: 0x53, script: 0x7f, flags: 0x0},
+ 1323: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1324: {region: 0x123, script: 0x5b, flags: 0x0},
+ 1325: {region: 0xd1, script: 0x5b, flags: 0x0},
+ 1326: {region: 0x166, script: 0x5b, flags: 0x0},
+ 1327: {region: 0x162, script: 0x5b, flags: 0x0},
+ 1329: {region: 0x12c, script: 0x5b, flags: 0x0},
+}
+
+// likelyLangList holds lists info associated with likelyLang.
+// Size: 582 bytes, 97 elements
+var likelyLangList = [97]likelyScriptRegion{
+ 0: {region: 0x9d, script: 0x7, flags: 0x0},
+ 1: {region: 0xa2, script: 0x7a, flags: 0x2},
+ 2: {region: 0x11d, script: 0x87, flags: 0x2},
+ 3: {region: 0x32, script: 0x5b, flags: 0x0},
+ 4: {region: 0x9c, script: 0x5, flags: 0x4},
+ 5: {region: 0x9d, script: 0x5, flags: 0x4},
+ 6: {region: 0x107, script: 0x20, flags: 0x4},
+ 7: {region: 0x9d, script: 0x5, flags: 0x2},
+ 8: {region: 0x107, script: 0x20, flags: 0x0},
+ 9: {region: 0x38, script: 0x2f, flags: 0x2},
+ 10: {region: 0x136, script: 0x5b, flags: 0x0},
+ 11: {region: 0x7c, script: 0xd1, flags: 0x2},
+ 12: {region: 0x115, script: 0x5b, flags: 0x0},
+ 13: {region: 0x85, script: 0x1, flags: 0x2},
+ 14: {region: 0x5e, script: 0x1f, flags: 0x0},
+ 15: {region: 0x88, script: 0x60, flags: 0x2},
+ 16: {region: 0xd7, script: 0x5b, flags: 0x0},
+ 17: {region: 0x52, script: 0x5, flags: 0x4},
+ 18: {region: 0x10c, script: 0x5, flags: 0x4},
+ 19: {region: 0xaf, script: 0x20, flags: 0x0},
+ 20: {region: 0x24, script: 0x5, flags: 0x4},
+ 21: {region: 0x53, script: 0x5, flags: 0x4},
+ 22: {region: 0x9d, script: 0x5, flags: 0x4},
+ 23: {region: 0xc6, script: 0x5, flags: 0x4},
+ 24: {region: 0x53, script: 0x5, flags: 0x2},
+ 25: {region: 0x12c, script: 0x5b, flags: 0x0},
+ 26: {region: 0xb1, script: 0x5, flags: 0x4},
+ 27: {region: 0x9c, script: 0x5, flags: 0x2},
+ 28: {region: 0xa6, script: 0x20, flags: 0x0},
+ 29: {region: 0x53, script: 0x5, flags: 0x4},
+ 30: {region: 0x12c, script: 0x5b, flags: 0x4},
+ 31: {region: 0x53, script: 0x5, flags: 0x2},
+ 32: {region: 0x12c, script: 0x5b, flags: 0x2},
+ 33: {region: 0xdc, script: 0x22, flags: 0x0},
+ 34: {region: 0x9a, script: 0x5e, flags: 0x2},
+ 35: {region: 0x84, script: 0x5b, flags: 0x0},
+ 36: {region: 0x85, script: 0x7e, flags: 0x4},
+ 37: {region: 0x85, script: 0x7e, flags: 0x2},
+ 38: {region: 0xc6, script: 0x20, flags: 0x0},
+ 39: {region: 0x53, script: 0x71, flags: 0x4},
+ 40: {region: 0x53, script: 0x71, flags: 0x2},
+ 41: {region: 0xd1, script: 0x5b, flags: 0x0},
+ 42: {region: 0x4a, script: 0x5, flags: 0x4},
+ 43: {region: 0x96, script: 0x5, flags: 0x4},
+ 44: {region: 0x9a, script: 0x36, flags: 0x0},
+ 45: {region: 0xe9, script: 0x5, flags: 0x4},
+ 46: {region: 0xe9, script: 0x5, flags: 0x2},
+ 47: {region: 0x9d, script: 0x8d, flags: 0x0},
+ 48: {region: 0x53, script: 0x8e, flags: 0x2},
+ 49: {region: 0xbb, script: 0xeb, flags: 0x0},
+ 50: {region: 0xda, script: 0x5b, flags: 0x4},
+ 51: {region: 0xe9, script: 0x5, flags: 0x0},
+ 52: {region: 0x9a, script: 0x22, flags: 0x2},
+ 53: {region: 0x9a, script: 0x50, flags: 0x2},
+ 54: {region: 0x9a, script: 0xd5, flags: 0x2},
+ 55: {region: 0x106, script: 0x20, flags: 0x0},
+ 56: {region: 0xbe, script: 0x5b, flags: 0x4},
+ 57: {region: 0x105, script: 0x5b, flags: 0x4},
+ 58: {region: 0x107, script: 0x5b, flags: 0x4},
+ 59: {region: 0x12c, script: 0x5b, flags: 0x4},
+ 60: {region: 0x125, script: 0x20, flags: 0x0},
+ 61: {region: 0xe9, script: 0x5, flags: 0x4},
+ 62: {region: 0xe9, script: 0x5, flags: 0x2},
+ 63: {region: 0x53, script: 0x5, flags: 0x0},
+ 64: {region: 0xaf, script: 0x20, flags: 0x4},
+ 65: {region: 0xc6, script: 0x20, flags: 0x4},
+ 66: {region: 0xaf, script: 0x20, flags: 0x2},
+ 67: {region: 0x9a, script: 0xe, flags: 0x0},
+ 68: {region: 0xdc, script: 0x22, flags: 0x4},
+ 69: {region: 0xdc, script: 0x22, flags: 0x2},
+ 70: {region: 0x138, script: 0x5b, flags: 0x0},
+ 71: {region: 0x24, script: 0x5, flags: 0x4},
+ 72: {region: 0x53, script: 0x20, flags: 0x4},
+ 73: {region: 0x24, script: 0x5, flags: 0x2},
+ 74: {region: 0x8e, script: 0x3c, flags: 0x0},
+ 75: {region: 0x53, script: 0x3b, flags: 0x4},
+ 76: {region: 0x53, script: 0x3b, flags: 0x2},
+ 77: {region: 0x53, script: 0x3b, flags: 0x0},
+ 78: {region: 0x2f, script: 0x3c, flags: 0x4},
+ 79: {region: 0x3e, script: 0x3c, flags: 0x4},
+ 80: {region: 0x7c, script: 0x3c, flags: 0x4},
+ 81: {region: 0x7f, script: 0x3c, flags: 0x4},
+ 82: {region: 0x8e, script: 0x3c, flags: 0x4},
+ 83: {region: 0x96, script: 0x3c, flags: 0x4},
+ 84: {region: 0xc7, script: 0x3c, flags: 0x4},
+ 85: {region: 0xd1, script: 0x3c, flags: 0x4},
+ 86: {region: 0xe3, script: 0x3c, flags: 0x4},
+ 87: {region: 0xe6, script: 0x3c, flags: 0x4},
+ 88: {region: 0xe8, script: 0x3c, flags: 0x4},
+ 89: {region: 0x117, script: 0x3c, flags: 0x4},
+ 90: {region: 0x124, script: 0x3c, flags: 0x4},
+ 91: {region: 0x12f, script: 0x3c, flags: 0x4},
+ 92: {region: 0x136, script: 0x3c, flags: 0x4},
+ 93: {region: 0x13f, script: 0x3c, flags: 0x4},
+ 94: {region: 0x12f, script: 0x11, flags: 0x2},
+ 95: {region: 0x12f, script: 0x37, flags: 0x2},
+ 96: {region: 0x12f, script: 0x3c, flags: 0x2},
+}
+
+type likelyLangScript struct {
+ lang uint16
+ script uint16
+ flags uint8
+}
+
+// likelyRegion is a lookup table, indexed by regionID, for the most likely
+// languages and scripts given incomplete information. If more entries exist
+// for a given regionID, lang and script are the index and size respectively
+// of the list in likelyRegionList.
+// TODO: exclude containers and user-definable regions from the list.
+// Size: 2154 bytes, 359 elements
+var likelyRegion = [359]likelyLangScript{
+ 34: {lang: 0xd7, script: 0x5b, flags: 0x0},
+ 35: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 36: {lang: 0x0, script: 0x2, flags: 0x1},
+ 39: {lang: 0x2, script: 0x2, flags: 0x1},
+ 40: {lang: 0x4, script: 0x2, flags: 0x1},
+ 42: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 43: {lang: 0x0, script: 0x5b, flags: 0x0},
+ 44: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 45: {lang: 0x41b, script: 0x5b, flags: 0x0},
+ 46: {lang: 0x10d, script: 0x5b, flags: 0x0},
+ 48: {lang: 0x367, script: 0x5b, flags: 0x0},
+ 49: {lang: 0x444, script: 0x5b, flags: 0x0},
+ 50: {lang: 0x58, script: 0x5b, flags: 0x0},
+ 51: {lang: 0x6, script: 0x2, flags: 0x1},
+ 53: {lang: 0xa5, script: 0xe, flags: 0x0},
+ 54: {lang: 0x367, script: 0x5b, flags: 0x0},
+ 55: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 56: {lang: 0x7e, script: 0x20, flags: 0x0},
+ 57: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 58: {lang: 0x3d9, script: 0x5b, flags: 0x0},
+ 59: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 60: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 62: {lang: 0x31f, script: 0x5b, flags: 0x0},
+ 63: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 64: {lang: 0x3a1, script: 0x5b, flags: 0x0},
+ 65: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 67: {lang: 0x8, script: 0x2, flags: 0x1},
+ 69: {lang: 0x0, script: 0x5b, flags: 0x0},
+ 71: {lang: 0x71, script: 0x20, flags: 0x0},
+ 73: {lang: 0x512, script: 0x3e, flags: 0x2},
+ 74: {lang: 0x31f, script: 0x5, flags: 0x2},
+ 75: {lang: 0x445, script: 0x5b, flags: 0x0},
+ 76: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 77: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 78: {lang: 0x10d, script: 0x5b, flags: 0x0},
+ 79: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 81: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 82: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 83: {lang: 0xa, script: 0x4, flags: 0x1},
+ 84: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 85: {lang: 0x0, script: 0x5b, flags: 0x0},
+ 87: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 90: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 91: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 92: {lang: 0x3a1, script: 0x5b, flags: 0x0},
+ 94: {lang: 0xe, script: 0x2, flags: 0x1},
+ 95: {lang: 0xfa, script: 0x5b, flags: 0x0},
+ 97: {lang: 0x10d, script: 0x5b, flags: 0x0},
+ 99: {lang: 0x1, script: 0x5b, flags: 0x0},
+ 100: {lang: 0x101, script: 0x5b, flags: 0x0},
+ 102: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 104: {lang: 0x10, script: 0x2, flags: 0x1},
+ 105: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 106: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 107: {lang: 0x140, script: 0x5b, flags: 0x0},
+ 108: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 109: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 110: {lang: 0x46f, script: 0x2c, flags: 0x0},
+ 111: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 112: {lang: 0x12, script: 0x2, flags: 0x1},
+ 114: {lang: 0x10d, script: 0x5b, flags: 0x0},
+ 115: {lang: 0x151, script: 0x5b, flags: 0x0},
+ 116: {lang: 0x1c0, script: 0x22, flags: 0x2},
+ 119: {lang: 0x158, script: 0x5b, flags: 0x0},
+ 121: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 123: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 124: {lang: 0x14, script: 0x2, flags: 0x1},
+ 126: {lang: 0x16, script: 0x3, flags: 0x1},
+ 127: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 129: {lang: 0x21, script: 0x5b, flags: 0x0},
+ 131: {lang: 0x245, script: 0x5b, flags: 0x0},
+ 133: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 134: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 135: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 136: {lang: 0x19, script: 0x2, flags: 0x1},
+ 137: {lang: 0x0, script: 0x5b, flags: 0x0},
+ 138: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 140: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 142: {lang: 0x529, script: 0x3c, flags: 0x0},
+ 143: {lang: 0x0, script: 0x5b, flags: 0x0},
+ 144: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 145: {lang: 0x1d1, script: 0x5b, flags: 0x0},
+ 146: {lang: 0x1d4, script: 0x5b, flags: 0x0},
+ 147: {lang: 0x1d5, script: 0x5b, flags: 0x0},
+ 149: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 150: {lang: 0x1b, script: 0x2, flags: 0x1},
+ 152: {lang: 0x1bc, script: 0x3e, flags: 0x0},
+ 154: {lang: 0x1d, script: 0x3, flags: 0x1},
+ 156: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 157: {lang: 0x20, script: 0x2, flags: 0x1},
+ 158: {lang: 0x1f8, script: 0x5b, flags: 0x0},
+ 159: {lang: 0x1f9, script: 0x5b, flags: 0x0},
+ 162: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 163: {lang: 0x200, script: 0x49, flags: 0x0},
+ 165: {lang: 0x445, script: 0x5b, flags: 0x0},
+ 166: {lang: 0x28a, script: 0x20, flags: 0x0},
+ 167: {lang: 0x22, script: 0x3, flags: 0x1},
+ 169: {lang: 0x25, script: 0x2, flags: 0x1},
+ 171: {lang: 0x254, script: 0x54, flags: 0x0},
+ 172: {lang: 0x254, script: 0x54, flags: 0x0},
+ 173: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 175: {lang: 0x3e2, script: 0x20, flags: 0x0},
+ 176: {lang: 0x27, script: 0x2, flags: 0x1},
+ 177: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 179: {lang: 0x10d, script: 0x5b, flags: 0x0},
+ 180: {lang: 0x40c, script: 0xd6, flags: 0x0},
+ 182: {lang: 0x43b, script: 0x5b, flags: 0x0},
+ 183: {lang: 0x2c0, script: 0x5b, flags: 0x0},
+ 184: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 185: {lang: 0x2c7, script: 0x5b, flags: 0x0},
+ 186: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 187: {lang: 0x29, script: 0x2, flags: 0x1},
+ 188: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 189: {lang: 0x2b, script: 0x2, flags: 0x1},
+ 190: {lang: 0x432, script: 0x5b, flags: 0x0},
+ 191: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 192: {lang: 0x2f1, script: 0x5b, flags: 0x0},
+ 195: {lang: 0x2d, script: 0x2, flags: 0x1},
+ 196: {lang: 0xa0, script: 0x5b, flags: 0x0},
+ 197: {lang: 0x2f, script: 0x2, flags: 0x1},
+ 198: {lang: 0x31, script: 0x2, flags: 0x1},
+ 199: {lang: 0x33, script: 0x2, flags: 0x1},
+ 201: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 202: {lang: 0x35, script: 0x2, flags: 0x1},
+ 204: {lang: 0x320, script: 0x5b, flags: 0x0},
+ 205: {lang: 0x37, script: 0x3, flags: 0x1},
+ 206: {lang: 0x128, script: 0xed, flags: 0x0},
+ 208: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 209: {lang: 0x31f, script: 0x5b, flags: 0x0},
+ 210: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 211: {lang: 0x16, script: 0x5b, flags: 0x0},
+ 212: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 213: {lang: 0x1b4, script: 0x5b, flags: 0x0},
+ 215: {lang: 0x1b4, script: 0x5, flags: 0x2},
+ 217: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 218: {lang: 0x367, script: 0x5b, flags: 0x0},
+ 219: {lang: 0x347, script: 0x5b, flags: 0x0},
+ 220: {lang: 0x351, script: 0x22, flags: 0x0},
+ 226: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 227: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 229: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 230: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 231: {lang: 0x486, script: 0x5b, flags: 0x0},
+ 232: {lang: 0x153, script: 0x5b, flags: 0x0},
+ 233: {lang: 0x3a, script: 0x3, flags: 0x1},
+ 234: {lang: 0x3b3, script: 0x5b, flags: 0x0},
+ 235: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 237: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 238: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 239: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 241: {lang: 0x3a2, script: 0x5b, flags: 0x0},
+ 242: {lang: 0x194, script: 0x5b, flags: 0x0},
+ 244: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 259: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 261: {lang: 0x3d, script: 0x2, flags: 0x1},
+ 262: {lang: 0x432, script: 0x20, flags: 0x0},
+ 263: {lang: 0x3f, script: 0x2, flags: 0x1},
+ 264: {lang: 0x3e5, script: 0x5b, flags: 0x0},
+ 265: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 267: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 268: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 269: {lang: 0x41, script: 0x2, flags: 0x1},
+ 272: {lang: 0x416, script: 0x5b, flags: 0x0},
+ 273: {lang: 0x347, script: 0x5b, flags: 0x0},
+ 274: {lang: 0x43, script: 0x2, flags: 0x1},
+ 276: {lang: 0x1f9, script: 0x5b, flags: 0x0},
+ 277: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 278: {lang: 0x429, script: 0x5b, flags: 0x0},
+ 279: {lang: 0x367, script: 0x5b, flags: 0x0},
+ 281: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 283: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 285: {lang: 0x45, script: 0x2, flags: 0x1},
+ 289: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 290: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 291: {lang: 0x47, script: 0x2, flags: 0x1},
+ 292: {lang: 0x49, script: 0x3, flags: 0x1},
+ 293: {lang: 0x4c, script: 0x2, flags: 0x1},
+ 294: {lang: 0x477, script: 0x5b, flags: 0x0},
+ 295: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 296: {lang: 0x476, script: 0x5b, flags: 0x0},
+ 297: {lang: 0x4e, script: 0x2, flags: 0x1},
+ 298: {lang: 0x482, script: 0x5b, flags: 0x0},
+ 300: {lang: 0x50, script: 0x4, flags: 0x1},
+ 302: {lang: 0x4a0, script: 0x5b, flags: 0x0},
+ 303: {lang: 0x54, script: 0x2, flags: 0x1},
+ 304: {lang: 0x445, script: 0x5b, flags: 0x0},
+ 305: {lang: 0x56, script: 0x3, flags: 0x1},
+ 306: {lang: 0x445, script: 0x5b, flags: 0x0},
+ 310: {lang: 0x512, script: 0x3e, flags: 0x2},
+ 311: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 312: {lang: 0x4bc, script: 0x5b, flags: 0x0},
+ 313: {lang: 0x1f9, script: 0x5b, flags: 0x0},
+ 316: {lang: 0x13e, script: 0x5b, flags: 0x0},
+ 319: {lang: 0x4c3, script: 0x5b, flags: 0x0},
+ 320: {lang: 0x8a, script: 0x5b, flags: 0x0},
+ 321: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 323: {lang: 0x41b, script: 0x5b, flags: 0x0},
+ 334: {lang: 0x59, script: 0x2, flags: 0x1},
+ 351: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 352: {lang: 0x5b, script: 0x2, flags: 0x1},
+ 357: {lang: 0x423, script: 0x5b, flags: 0x0},
+}
+
+// likelyRegionList holds lists info associated with likelyRegion.
+// Size: 558 bytes, 93 elements
+var likelyRegionList = [93]likelyLangScript{
+ 0: {lang: 0x148, script: 0x5, flags: 0x0},
+ 1: {lang: 0x476, script: 0x5b, flags: 0x0},
+ 2: {lang: 0x431, script: 0x5b, flags: 0x0},
+ 3: {lang: 0x2ff, script: 0x20, flags: 0x0},
+ 4: {lang: 0x1d7, script: 0x8, flags: 0x0},
+ 5: {lang: 0x274, script: 0x5b, flags: 0x0},
+ 6: {lang: 0xb7, script: 0x5b, flags: 0x0},
+ 7: {lang: 0x432, script: 0x20, flags: 0x0},
+ 8: {lang: 0x12d, script: 0xef, flags: 0x0},
+ 9: {lang: 0x351, script: 0x22, flags: 0x0},
+ 10: {lang: 0x529, script: 0x3b, flags: 0x0},
+ 11: {lang: 0x4ac, script: 0x5, flags: 0x0},
+ 12: {lang: 0x523, script: 0x5b, flags: 0x0},
+ 13: {lang: 0x29a, script: 0xee, flags: 0x0},
+ 14: {lang: 0x136, script: 0x34, flags: 0x0},
+ 15: {lang: 0x48a, script: 0x5b, flags: 0x0},
+ 16: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 17: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 18: {lang: 0x27, script: 0x2c, flags: 0x0},
+ 19: {lang: 0x139, script: 0x5b, flags: 0x0},
+ 20: {lang: 0x26a, script: 0x5, flags: 0x2},
+ 21: {lang: 0x512, script: 0x3e, flags: 0x2},
+ 22: {lang: 0x210, script: 0x2e, flags: 0x0},
+ 23: {lang: 0x5, script: 0x20, flags: 0x0},
+ 24: {lang: 0x274, script: 0x5b, flags: 0x0},
+ 25: {lang: 0x136, script: 0x34, flags: 0x0},
+ 26: {lang: 0x2ff, script: 0x20, flags: 0x0},
+ 27: {lang: 0x1e1, script: 0x5b, flags: 0x0},
+ 28: {lang: 0x31f, script: 0x5, flags: 0x0},
+ 29: {lang: 0x1be, script: 0x22, flags: 0x0},
+ 30: {lang: 0x4b4, script: 0x5, flags: 0x0},
+ 31: {lang: 0x236, script: 0x76, flags: 0x0},
+ 32: {lang: 0x148, script: 0x5, flags: 0x0},
+ 33: {lang: 0x476, script: 0x5b, flags: 0x0},
+ 34: {lang: 0x24a, script: 0x4f, flags: 0x0},
+ 35: {lang: 0xe6, script: 0x5, flags: 0x0},
+ 36: {lang: 0x226, script: 0xee, flags: 0x0},
+ 37: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 38: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 39: {lang: 0x2b8, script: 0x58, flags: 0x0},
+ 40: {lang: 0x226, script: 0xee, flags: 0x0},
+ 41: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 42: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 43: {lang: 0x3dc, script: 0x5b, flags: 0x0},
+ 44: {lang: 0x4ae, script: 0x20, flags: 0x0},
+ 45: {lang: 0x2ff, script: 0x20, flags: 0x0},
+ 46: {lang: 0x431, script: 0x5b, flags: 0x0},
+ 47: {lang: 0x331, script: 0x76, flags: 0x0},
+ 48: {lang: 0x213, script: 0x5b, flags: 0x0},
+ 49: {lang: 0x30b, script: 0x20, flags: 0x0},
+ 50: {lang: 0x242, script: 0x5, flags: 0x0},
+ 51: {lang: 0x529, script: 0x3c, flags: 0x0},
+ 52: {lang: 0x3c0, script: 0x5b, flags: 0x0},
+ 53: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 54: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 55: {lang: 0x2ed, script: 0x5b, flags: 0x0},
+ 56: {lang: 0x4b4, script: 0x5, flags: 0x0},
+ 57: {lang: 0x88, script: 0x22, flags: 0x0},
+ 58: {lang: 0x4b4, script: 0x5, flags: 0x0},
+ 59: {lang: 0x4b4, script: 0x5, flags: 0x0},
+ 60: {lang: 0xbe, script: 0x22, flags: 0x0},
+ 61: {lang: 0x3dc, script: 0x5b, flags: 0x0},
+ 62: {lang: 0x7e, script: 0x20, flags: 0x0},
+ 63: {lang: 0x3e2, script: 0x20, flags: 0x0},
+ 64: {lang: 0x267, script: 0x5b, flags: 0x0},
+ 65: {lang: 0x444, script: 0x5b, flags: 0x0},
+ 66: {lang: 0x512, script: 0x3e, flags: 0x0},
+ 67: {lang: 0x412, script: 0x5b, flags: 0x0},
+ 68: {lang: 0x4ae, script: 0x20, flags: 0x0},
+ 69: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 70: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 71: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 72: {lang: 0x35, script: 0x5, flags: 0x0},
+ 73: {lang: 0x46b, script: 0xee, flags: 0x0},
+ 74: {lang: 0x2ec, script: 0x5, flags: 0x0},
+ 75: {lang: 0x30f, script: 0x76, flags: 0x0},
+ 76: {lang: 0x467, script: 0x20, flags: 0x0},
+ 77: {lang: 0x148, script: 0x5, flags: 0x0},
+ 78: {lang: 0x3a, script: 0x5, flags: 0x0},
+ 79: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 80: {lang: 0x48a, script: 0x5b, flags: 0x0},
+ 81: {lang: 0x58, script: 0x5, flags: 0x0},
+ 82: {lang: 0x219, script: 0x20, flags: 0x0},
+ 83: {lang: 0x81, script: 0x34, flags: 0x0},
+ 84: {lang: 0x529, script: 0x3c, flags: 0x0},
+ 85: {lang: 0x48c, script: 0x5b, flags: 0x0},
+ 86: {lang: 0x4ae, script: 0x20, flags: 0x0},
+ 87: {lang: 0x512, script: 0x3e, flags: 0x0},
+ 88: {lang: 0x3b3, script: 0x5b, flags: 0x0},
+ 89: {lang: 0x431, script: 0x5b, flags: 0x0},
+ 90: {lang: 0x432, script: 0x20, flags: 0x0},
+ 91: {lang: 0x15e, script: 0x5b, flags: 0x0},
+ 92: {lang: 0x446, script: 0x5, flags: 0x0},
+}
+
+type likelyTag struct {
+ lang uint16
+ region uint16
+ script uint16
+}
+
+// Size: 198 bytes, 33 elements
+var likelyRegionGroup = [33]likelyTag{
+ 1: {lang: 0x139, region: 0xd7, script: 0x5b},
+ 2: {lang: 0x139, region: 0x136, script: 0x5b},
+ 3: {lang: 0x3c0, region: 0x41, script: 0x5b},
+ 4: {lang: 0x139, region: 0x2f, script: 0x5b},
+ 5: {lang: 0x139, region: 0xd7, script: 0x5b},
+ 6: {lang: 0x13e, region: 0xd0, script: 0x5b},
+ 7: {lang: 0x445, region: 0x130, script: 0x5b},
+ 8: {lang: 0x3a, region: 0x6c, script: 0x5},
+ 9: {lang: 0x445, region: 0x4b, script: 0x5b},
+ 10: {lang: 0x139, region: 0x162, script: 0x5b},
+ 11: {lang: 0x139, region: 0x136, script: 0x5b},
+ 12: {lang: 0x139, region: 0x136, script: 0x5b},
+ 13: {lang: 0x13e, region: 0x5a, script: 0x5b},
+ 14: {lang: 0x529, region: 0x53, script: 0x3b},
+ 15: {lang: 0x1be, region: 0x9a, script: 0x22},
+ 16: {lang: 0x1e1, region: 0x96, script: 0x5b},
+ 17: {lang: 0x1f9, region: 0x9f, script: 0x5b},
+ 18: {lang: 0x139, region: 0x2f, script: 0x5b},
+ 19: {lang: 0x139, region: 0xe7, script: 0x5b},
+ 20: {lang: 0x139, region: 0x8b, script: 0x5b},
+ 21: {lang: 0x41b, region: 0x143, script: 0x5b},
+ 22: {lang: 0x529, region: 0x53, script: 0x3b},
+ 23: {lang: 0x4bc, region: 0x138, script: 0x5b},
+ 24: {lang: 0x3a, region: 0x109, script: 0x5},
+ 25: {lang: 0x3e2, region: 0x107, script: 0x20},
+ 26: {lang: 0x3e2, region: 0x107, script: 0x20},
+ 27: {lang: 0x139, region: 0x7c, script: 0x5b},
+ 28: {lang: 0x10d, region: 0x61, script: 0x5b},
+ 29: {lang: 0x139, region: 0xd7, script: 0x5b},
+ 30: {lang: 0x13e, region: 0x1f, script: 0x5b},
+ 31: {lang: 0x139, region: 0x9b, script: 0x5b},
+ 32: {lang: 0x139, region: 0x7c, script: 0x5b},
+}
+
+// Size: 264 bytes, 33 elements
+var regionContainment = [33]uint64{
+ // Entry 0 - 1F
+ 0x00000001ffffffff, 0x00000000200007a2, 0x0000000000003044, 0x0000000000000008,
+ 0x00000000803c0010, 0x0000000000000020, 0x0000000000000040, 0x0000000000000080,
+ 0x0000000000000100, 0x0000000000000200, 0x0000000000000400, 0x000000004000384c,
+ 0x0000000000001000, 0x0000000000002000, 0x0000000000004000, 0x0000000000008000,
+ 0x0000000000010000, 0x0000000000020000, 0x0000000000040000, 0x0000000000080000,
+ 0x0000000000100000, 0x0000000000200000, 0x0000000001c1c000, 0x0000000000800000,
+ 0x0000000001000000, 0x000000001e020000, 0x0000000004000000, 0x0000000008000000,
+ 0x0000000010000000, 0x00000000200006a0, 0x0000000040002048, 0x0000000080000000,
+ // Entry 20 - 3F
+ 0x0000000100000000,
+}
+
+// regionInclusion maps region identifiers to sets of regions in regionInclusionBits,
+// where each set holds all groupings that are directly connected in a region
+// containment graph.
+// Size: 359 bytes, 359 elements
+var regionInclusion = [359]uint8{
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x23,
+ 0x24, 0x26, 0x27, 0x22, 0x28, 0x29, 0x2a, 0x2b,
+ 0x26, 0x2c, 0x24, 0x23, 0x26, 0x25, 0x2a, 0x2d,
+ 0x2e, 0x24, 0x2f, 0x2d, 0x26, 0x30, 0x31, 0x28,
+ // Entry 40 - 7F
+ 0x26, 0x28, 0x26, 0x25, 0x31, 0x22, 0x32, 0x33,
+ 0x34, 0x30, 0x22, 0x27, 0x27, 0x27, 0x35, 0x2d,
+ 0x29, 0x28, 0x27, 0x36, 0x28, 0x22, 0x21, 0x34,
+ 0x23, 0x21, 0x26, 0x2d, 0x26, 0x22, 0x37, 0x2e,
+ 0x35, 0x2a, 0x22, 0x2f, 0x38, 0x26, 0x26, 0x21,
+ 0x39, 0x39, 0x28, 0x38, 0x39, 0x39, 0x2f, 0x3a,
+ 0x2f, 0x20, 0x21, 0x38, 0x3b, 0x28, 0x3c, 0x2c,
+ 0x21, 0x2a, 0x35, 0x27, 0x38, 0x26, 0x24, 0x28,
+ // Entry 80 - BF
+ 0x2c, 0x2d, 0x23, 0x30, 0x2d, 0x2d, 0x26, 0x27,
+ 0x3a, 0x22, 0x34, 0x3c, 0x2d, 0x28, 0x36, 0x22,
+ 0x34, 0x3a, 0x26, 0x2e, 0x21, 0x39, 0x31, 0x38,
+ 0x24, 0x2c, 0x25, 0x22, 0x24, 0x25, 0x2c, 0x3a,
+ 0x2c, 0x26, 0x24, 0x36, 0x21, 0x2f, 0x3d, 0x31,
+ 0x3c, 0x2f, 0x26, 0x36, 0x36, 0x24, 0x26, 0x3d,
+ 0x31, 0x24, 0x26, 0x35, 0x25, 0x2d, 0x32, 0x38,
+ 0x2a, 0x38, 0x39, 0x39, 0x35, 0x33, 0x23, 0x26,
+ // Entry C0 - FF
+ 0x2f, 0x3c, 0x21, 0x23, 0x2d, 0x31, 0x36, 0x36,
+ 0x3c, 0x26, 0x2d, 0x26, 0x3a, 0x2f, 0x25, 0x2f,
+ 0x34, 0x31, 0x2f, 0x32, 0x3b, 0x2d, 0x2b, 0x2d,
+ 0x21, 0x34, 0x2a, 0x2c, 0x25, 0x21, 0x3c, 0x24,
+ 0x29, 0x2b, 0x24, 0x34, 0x21, 0x28, 0x29, 0x3b,
+ 0x31, 0x25, 0x2e, 0x30, 0x29, 0x26, 0x24, 0x3a,
+ 0x21, 0x3c, 0x28, 0x21, 0x24, 0x21, 0x21, 0x1f,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ // Entry 100 - 13F
+ 0x21, 0x21, 0x21, 0x2f, 0x21, 0x2e, 0x23, 0x33,
+ 0x2f, 0x24, 0x3b, 0x2f, 0x39, 0x38, 0x31, 0x2d,
+ 0x3a, 0x2c, 0x2e, 0x2d, 0x23, 0x2d, 0x2f, 0x28,
+ 0x2f, 0x27, 0x33, 0x34, 0x26, 0x24, 0x32, 0x22,
+ 0x26, 0x27, 0x22, 0x2d, 0x31, 0x3d, 0x29, 0x31,
+ 0x3d, 0x39, 0x29, 0x31, 0x24, 0x26, 0x29, 0x36,
+ 0x2f, 0x33, 0x2f, 0x21, 0x22, 0x21, 0x30, 0x28,
+ 0x3d, 0x23, 0x26, 0x21, 0x28, 0x26, 0x26, 0x31,
+ // Entry 140 - 17F
+ 0x3b, 0x29, 0x21, 0x29, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x24,
+ 0x2f, 0x23, 0x32, 0x2f, 0x27, 0x2f, 0x21,
+}
+
+// regionInclusionBits is an array of bit vectors where every vector represents
+// a set of region groupings. These sets are used to compute the distance
+// between two regions for the purpose of language matching.
+// Size: 584 bytes, 73 elements
+var regionInclusionBits = [73]uint64{
+ // Entry 0 - 1F
+ 0x0000000102400813, 0x00000000200007a3, 0x0000000000003844, 0x0000000040000808,
+ 0x00000000803c0011, 0x0000000020000022, 0x0000000040000844, 0x0000000020000082,
+ 0x0000000000000102, 0x0000000020000202, 0x0000000020000402, 0x000000004000384d,
+ 0x0000000000001804, 0x0000000040002804, 0x0000000000404000, 0x0000000000408000,
+ 0x0000000000410000, 0x0000000002020000, 0x0000000000040010, 0x0000000000080010,
+ 0x0000000000100010, 0x0000000000200010, 0x0000000001c1c001, 0x0000000000c00000,
+ 0x0000000001400000, 0x000000001e020001, 0x0000000006000000, 0x000000000a000000,
+ 0x0000000012000000, 0x00000000200006a2, 0x0000000040002848, 0x0000000080000010,
+ // Entry 20 - 3F
+ 0x0000000100000001, 0x0000000000000001, 0x0000000080000000, 0x0000000000020000,
+ 0x0000000001000000, 0x0000000000008000, 0x0000000000002000, 0x0000000000000200,
+ 0x0000000000000008, 0x0000000000200000, 0x0000000110000000, 0x0000000000040000,
+ 0x0000000008000000, 0x0000000000000020, 0x0000000104000000, 0x0000000000000080,
+ 0x0000000000001000, 0x0000000000010000, 0x0000000000000400, 0x0000000004000000,
+ 0x0000000000000040, 0x0000000010000000, 0x0000000000004000, 0x0000000101000000,
+ 0x0000000108000000, 0x0000000000000100, 0x0000000100020000, 0x0000000000080000,
+ 0x0000000000100000, 0x0000000000800000, 0x00000001ffffffff, 0x0000000122400fb3,
+ // Entry 40 - 5F
+ 0x00000001827c0813, 0x000000014240385f, 0x0000000103c1c813, 0x000000011e420813,
+ 0x0000000112000001, 0x0000000106000001, 0x0000000101400001, 0x000000010a000001,
+ 0x0000000102020001,
+}
+
+// regionInclusionNext marks, for each entry in regionInclusionBits, the set of
+// all groups that are reachable from the groups set in the respective entry.
+// Size: 73 bytes, 73 elements
+var regionInclusionNext = [73]uint8{
+ // Entry 0 - 3F
+ 0x3e, 0x3f, 0x0b, 0x0b, 0x40, 0x01, 0x0b, 0x01,
+ 0x01, 0x01, 0x01, 0x41, 0x0b, 0x0b, 0x16, 0x16,
+ 0x16, 0x19, 0x04, 0x04, 0x04, 0x04, 0x42, 0x16,
+ 0x16, 0x43, 0x19, 0x19, 0x19, 0x01, 0x0b, 0x04,
+ 0x00, 0x00, 0x1f, 0x11, 0x18, 0x0f, 0x0d, 0x09,
+ 0x03, 0x15, 0x44, 0x12, 0x1b, 0x05, 0x45, 0x07,
+ 0x0c, 0x10, 0x0a, 0x1a, 0x06, 0x1c, 0x0e, 0x46,
+ 0x47, 0x08, 0x48, 0x13, 0x14, 0x17, 0x3e, 0x3e,
+ // Entry 40 - 7F
+ 0x3e, 0x3e, 0x3e, 0x3e, 0x43, 0x43, 0x42, 0x43,
+ 0x43,
+}
+
+type parentRel struct {
+ lang uint16
+ script uint16
+ maxScript uint16
+ toRegion uint16
+ fromRegion []uint16
+}
+
+// Size: 414 bytes, 5 elements
+var parents = [5]parentRel{
+ 0: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5d, 0x5e, 0x62, 0x65, 0x6e, 0x74, 0x75, 0x76, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x84, 0x8d, 0x8e, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0xa0, 0xa1, 0xa5, 0xa8, 0xaa, 0xae, 0xb2, 0xb5, 0xb6, 0xc0, 0xc7, 0xcb, 0xcc, 0xcd, 0xcf, 0xd1, 0xd3, 0xd6, 0xd7, 0xde, 0xe0, 0xe1, 0xe7, 0xe8, 0xe9, 0xec, 0xf1, 0x108, 0x10a, 0x10b, 0x10c, 0x10e, 0x10f, 0x113, 0x118, 0x11c, 0x11e, 0x120, 0x126, 0x12a, 0x12d, 0x12e, 0x130, 0x132, 0x13a, 0x13d, 0x140, 0x143, 0x162, 0x163, 0x165}},
+ 1: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x61, 0x64, 0x73, 0xda, 0x10d, 0x110}},
+ 2: {lang: 0x13e, script: 0x0, maxScript: 0x5b, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x57, 0x5a, 0x66, 0x6a, 0x8a, 0x90, 0xd0, 0xd9, 0xe3, 0xe5, 0xed, 0xf2, 0x11b, 0x136, 0x137, 0x13c}},
+ 3: {lang: 0x3c0, script: 0x0, maxScript: 0x5b, toRegion: 0xef, fromRegion: []uint16{0x2a, 0x4e, 0x5b, 0x87, 0x8c, 0xb8, 0xc7, 0xd2, 0x119, 0x127}},
+ 4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8e, fromRegion: []uint16{0xc7}},
+}
+
+// Total table size 30466 bytes (29KiB); checksum: 7544152B
diff --git a/vendor/golang.org/x/text/internal/language/tags.go b/vendor/golang.org/x/text/internal/language/tags.go
new file mode 100644
index 000000000..e7afd3188
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/language/tags.go
@@ -0,0 +1,48 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
+// It simplifies safe initialization of Tag values.
+func MustParse(s string) Tag {
+ t, err := Parse(s)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// MustParseBase is like ParseBase, but panics if the given base cannot be parsed.
+// It simplifies safe initialization of Base values.
+func MustParseBase(s string) Language {
+ b, err := ParseBase(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+// MustParseScript is like ParseScript, but panics if the given script cannot be
+// parsed. It simplifies safe initialization of Script values.
+func MustParseScript(s string) Script {
+ scr, err := ParseScript(s)
+ if err != nil {
+ panic(err)
+ }
+ return scr
+}
+
+// MustParseRegion is like ParseRegion, but panics if the given region cannot be
+// parsed. It simplifies safe initialization of Region values.
+func MustParseRegion(s string) Region {
+ r, err := ParseRegion(s)
+ if err != nil {
+ panic(err)
+ }
+ return r
+}
+
+// Und is the root language.
+var Und Tag
diff --git a/vendor/golang.org/x/text/internal/match.go b/vendor/golang.org/x/text/internal/match.go
new file mode 100644
index 000000000..1cc004a6d
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/match.go
@@ -0,0 +1,67 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+// This file contains matchers that implement CLDR inheritance.
+//
+// See https://unicode.org/reports/tr35/#Locale_Inheritance.
+//
+// Some of the inheritance described in this document is already handled by
+// the cldr package.
+
+import (
+ "golang.org/x/text/language"
+)
+
+// TODO: consider if (some of the) matching algorithm needs to be public after
+// getting some feel about what is generic and what is specific.
+
+// NewInheritanceMatcher returns a matcher that matches based on the inheritance
+// chain.
+//
+// The matcher uses canonicalization and the parent relationship to find a
+// match. The resulting match will always be either Und or a language with the
+// same language and script as the requested language. It will not match
+// languages for which there is understood to be mutual or one-directional
+// intelligibility.
+//
+// A Match will indicate an Exact match if the language matches after
+// canonicalization and High if the matched tag is a parent.
+func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher {
+ tags := &InheritanceMatcher{make(map[language.Tag]int)}
+ for i, tag := range t {
+ ct, err := language.All.Canonicalize(tag)
+ if err != nil {
+ ct = tag
+ }
+ tags.index[ct] = i
+ }
+ return tags
+}
+
+type InheritanceMatcher struct {
+ index map[language.Tag]int
+}
+
+func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) {
+ for _, t := range want {
+ ct, err := language.All.Canonicalize(t)
+ if err != nil {
+ ct = t
+ }
+ conf := language.Exact
+ for {
+ if index, ok := m.index[ct]; ok {
+ return ct, index, conf
+ }
+ if ct == language.Und {
+ break
+ }
+ ct = ct.Parent()
+ conf = language.High
+ }
+ }
+ return language.Und, 0, language.No
+}
diff --git a/vendor/golang.org/x/text/internal/tag/tag.go b/vendor/golang.org/x/text/internal/tag/tag.go
new file mode 100644
index 000000000..b5d348891
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/tag/tag.go
@@ -0,0 +1,100 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tag contains functionality handling tags and related data.
+package tag // import "golang.org/x/text/internal/tag"
+
+import "sort"
+
+// An Index converts tags to a compact numeric value.
+//
+// All elements are of size 4. Tags may be up to 4 bytes long. Excess bytes can
+// be used to store additional information about the tag.
+type Index string
+
+// Elem returns the element data at the given index.
+func (s Index) Elem(x int) string {
+ return string(s[x*4 : x*4+4])
+}
+
+// Index reports the index of the given key or -1 if it could not be found.
+// Only the first len(key) bytes from the start of the 4-byte entries will be
+// considered for the search and the first match in Index will be returned.
+func (s Index) Index(key []byte) int {
+ n := len(key)
+ // search the index of the first entry with an equal or higher value than
+ // key in s.
+ index := sort.Search(len(s)/4, func(i int) bool {
+ return cmp(s[i*4:i*4+n], key) != -1
+ })
+ i := index * 4
+ if cmp(s[i:i+len(key)], key) != 0 {
+ return -1
+ }
+ return index
+}
+
+// Next finds the next occurrence of key after index x, which must have been
+// obtained from a call to Index using the same key. It returns x+1 or -1.
+func (s Index) Next(key []byte, x int) int {
+ if x++; x*4 < len(s) && cmp(s[x*4:x*4+len(key)], key) == 0 {
+ return x
+ }
+ return -1
+}
+
+// cmp returns an integer comparing a and b lexicographically.
+func cmp(a Index, b []byte) int {
+ n := len(a)
+ if len(b) < n {
+ n = len(b)
+ }
+ for i, c := range b[:n] {
+ switch {
+ case a[i] > c:
+ return 1
+ case a[i] < c:
+ return -1
+ }
+ }
+ switch {
+ case len(a) < len(b):
+ return -1
+ case len(a) > len(b):
+ return 1
+ }
+ return 0
+}
+
+// Compare returns an integer comparing a and b lexicographically.
+func Compare(a string, b []byte) int {
+ return cmp(Index(a), b)
+}
+
+// FixCase reformats b to the same pattern of cases as form.
+// If returns false if string b is malformed.
+func FixCase(form string, b []byte) bool {
+ if len(form) != len(b) {
+ return false
+ }
+ for i, c := range b {
+ if form[i] <= 'Z' {
+ if c >= 'a' {
+ c -= 'z' - 'Z'
+ }
+ if c < 'A' || 'Z' < c {
+ return false
+ }
+ } else {
+ if c <= 'Z' {
+ c += 'z' - 'Z'
+ }
+ if c < 'a' || 'z' < c {
+ return false
+ }
+ }
+ b[i] = c
+ }
+ return true
+}
diff --git a/vendor/golang.org/x/text/language/coverage.go b/vendor/golang.org/x/text/language/coverage.go
new file mode 100644
index 000000000..a24fd1a4d
--- /dev/null
+++ b/vendor/golang.org/x/text/language/coverage.go
@@ -0,0 +1,187 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "fmt"
+ "sort"
+
+ "golang.org/x/text/internal/language"
+)
+
+// The Coverage interface is used to define the level of coverage of an
+// internationalization service. Note that not all types are supported by all
+// services. As lists may be generated on the fly, it is recommended that users
+// of a Coverage cache the results.
+type Coverage interface {
+ // Tags returns the list of supported tags.
+ Tags() []Tag
+
+ // BaseLanguages returns the list of supported base languages.
+ BaseLanguages() []Base
+
+ // Scripts returns the list of supported scripts.
+ Scripts() []Script
+
+ // Regions returns the list of supported regions.
+ Regions() []Region
+}
+
+var (
+ // Supported defines a Coverage that lists all supported subtags. Tags
+ // always returns nil.
+ Supported Coverage = allSubtags{}
+)
+
+// TODO:
+// - Support Variants, numbering systems.
+// - CLDR coverage levels.
+// - Set of common tags defined in this package.
+
+type allSubtags struct{}
+
+// Regions returns the list of supported regions. As all regions are in a
+// consecutive range, it simply returns a slice of numbers in increasing order.
+// The "undefined" region is not returned.
+func (s allSubtags) Regions() []Region {
+ reg := make([]Region, language.NumRegions)
+ for i := range reg {
+ reg[i] = Region{language.Region(i + 1)}
+ }
+ return reg
+}
+
+// Scripts returns the list of supported scripts. As all scripts are in a
+// consecutive range, it simply returns a slice of numbers in increasing order.
+// The "undefined" script is not returned.
+func (s allSubtags) Scripts() []Script {
+ scr := make([]Script, language.NumScripts)
+ for i := range scr {
+ scr[i] = Script{language.Script(i + 1)}
+ }
+ return scr
+}
+
+// BaseLanguages returns the list of all supported base languages. It generates
+// the list by traversing the internal structures.
+func (s allSubtags) BaseLanguages() []Base {
+ bs := language.BaseLanguages()
+ base := make([]Base, len(bs))
+ for i, b := range bs {
+ base[i] = Base{b}
+ }
+ return base
+}
+
+// Tags always returns nil.
+func (s allSubtags) Tags() []Tag {
+ return nil
+}
+
+// coverage is used by NewCoverage which is used as a convenient way for
+// creating Coverage implementations for partially defined data. Very often a
+// package will only need to define a subset of slices. coverage provides a
+// convenient way to do this. Moreover, packages using NewCoverage, instead of
+// their own implementation, will not break if later new slice types are added.
+type coverage struct {
+ tags func() []Tag
+ bases func() []Base
+ scripts func() []Script
+ regions func() []Region
+}
+
+func (s *coverage) Tags() []Tag {
+ if s.tags == nil {
+ return nil
+ }
+ return s.tags()
+}
+
+// bases implements sort.Interface and is used to sort base languages.
+type bases []Base
+
+func (b bases) Len() int {
+ return len(b)
+}
+
+func (b bases) Swap(i, j int) {
+ b[i], b[j] = b[j], b[i]
+}
+
+func (b bases) Less(i, j int) bool {
+ return b[i].langID < b[j].langID
+}
+
+// BaseLanguages returns the result from calling s.bases if it is specified or
+// otherwise derives the set of supported base languages from tags.
+func (s *coverage) BaseLanguages() []Base {
+ if s.bases == nil {
+ tags := s.Tags()
+ if len(tags) == 0 {
+ return nil
+ }
+ a := make([]Base, len(tags))
+ for i, t := range tags {
+ a[i] = Base{language.Language(t.lang())}
+ }
+ sort.Sort(bases(a))
+ k := 0
+ for i := 1; i < len(a); i++ {
+ if a[k] != a[i] {
+ k++
+ a[k] = a[i]
+ }
+ }
+ return a[:k+1]
+ }
+ return s.bases()
+}
+
+func (s *coverage) Scripts() []Script {
+ if s.scripts == nil {
+ return nil
+ }
+ return s.scripts()
+}
+
+func (s *coverage) Regions() []Region {
+ if s.regions == nil {
+ return nil
+ }
+ return s.regions()
+}
+
+// NewCoverage returns a Coverage for the given lists. It is typically used by
+// packages providing internationalization services to define their level of
+// coverage. A list may be of type []T or func() []T, where T is either Tag,
+// Base, Script or Region. The returned Coverage derives the value for Bases
+// from Tags if no func or slice for []Base is specified. For other unspecified
+// types the returned Coverage will return nil for the respective methods.
+func NewCoverage(list ...interface{}) Coverage {
+ s := &coverage{}
+ for _, x := range list {
+ switch v := x.(type) {
+ case func() []Base:
+ s.bases = v
+ case func() []Script:
+ s.scripts = v
+ case func() []Region:
+ s.regions = v
+ case func() []Tag:
+ s.tags = v
+ case []Base:
+ s.bases = func() []Base { return v }
+ case []Script:
+ s.scripts = func() []Script { return v }
+ case []Region:
+ s.regions = func() []Region { return v }
+ case []Tag:
+ s.tags = func() []Tag { return v }
+ default:
+ panic(fmt.Sprintf("language: unsupported set type %T", v))
+ }
+ }
+ return s
+}
diff --git a/vendor/golang.org/x/text/language/doc.go b/vendor/golang.org/x/text/language/doc.go
new file mode 100644
index 000000000..212b77c90
--- /dev/null
+++ b/vendor/golang.org/x/text/language/doc.go
@@ -0,0 +1,98 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package language implements BCP 47 language tags and related functionality.
+//
+// The most important function of package language is to match a list of
+// user-preferred languages to a list of supported languages.
+// It alleviates the developer of dealing with the complexity of this process
+// and provides the user with the best experience
+// (see https://blog.golang.org/matchlang).
+//
+// # Matching preferred against supported languages
+//
+// A Matcher for an application that supports English, Australian English,
+// Danish, and standard Mandarin can be created as follows:
+//
+// var matcher = language.NewMatcher([]language.Tag{
+// language.English, // The first language is used as fallback.
+// language.MustParse("en-AU"),
+// language.Danish,
+// language.Chinese,
+// })
+//
+// This list of supported languages is typically implied by the languages for
+// which there exists translations of the user interface.
+//
+// User-preferred languages usually come as a comma-separated list of BCP 47
+// language tags.
+// The MatchString finds best matches for such strings:
+//
+// handler(w http.ResponseWriter, r *http.Request) {
+// lang, _ := r.Cookie("lang")
+// accept := r.Header.Get("Accept-Language")
+// tag, _ := language.MatchStrings(matcher, lang.String(), accept)
+//
+// // tag should now be used for the initialization of any
+// // locale-specific service.
+// }
+//
+// The Matcher's Match method can be used to match Tags directly.
+//
+// Matchers are aware of the intricacies of equivalence between languages, such
+// as deprecated subtags, legacy tags, macro languages, mutual
+// intelligibility between scripts and languages, and transparently passing
+// BCP 47 user configuration.
+// For instance, it will know that a reader of Bokmål Danish can read Norwegian
+// and will know that Cantonese ("yue") is a good match for "zh-HK".
+//
+// # Using match results
+//
+// To guarantee a consistent user experience to the user it is important to
+// use the same language tag for the selection of any locale-specific services.
+// For example, it is utterly confusing to substitute spelled-out numbers
+// or dates in one language in text of another language.
+// More subtly confusing is using the wrong sorting order or casing
+// algorithm for a certain language.
+//
+// All the packages in x/text that provide locale-specific services
+// (e.g. collate, cases) should be initialized with the tag that was
+// obtained at the start of an interaction with the user.
+//
+// Note that Tag that is returned by Match and MatchString may differ from any
+// of the supported languages, as it may contain carried over settings from
+// the user tags.
+// This may be inconvenient when your application has some additional
+// locale-specific data for your supported languages.
+// Match and MatchString both return the index of the matched supported tag
+// to simplify associating such data with the matched tag.
+//
+// # Canonicalization
+//
+// If one uses the Matcher to compare languages one does not need to
+// worry about canonicalization.
+//
+// The meaning of a Tag varies per application. The language package
+// therefore delays canonicalization and preserves information as much
+// as possible. The Matcher, however, will always take into account that
+// two different tags may represent the same language.
+//
+// By default, only legacy and deprecated tags are converted into their
+// canonical equivalent. All other information is preserved. This approach makes
+// the confidence scores more accurate and allows matchers to distinguish
+// between variants that are otherwise lost.
+//
+// As a consequence, two tags that should be treated as identical according to
+// BCP 47 or CLDR, like "en-Latn" and "en", will be represented differently. The
+// Matcher handles such distinctions, though, and is aware of the
+// equivalence relations. The CanonType type can be used to alter the
+// canonicalization form.
+//
+// # References
+//
+// BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47
+package language // import "golang.org/x/text/language"
+
+// TODO: explanation on how to match languages for your own locale-specific
+// service.
diff --git a/vendor/golang.org/x/text/language/language.go b/vendor/golang.org/x/text/language/language.go
new file mode 100644
index 000000000..4d9c66121
--- /dev/null
+++ b/vendor/golang.org/x/text/language/language.go
@@ -0,0 +1,605 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go -output tables.go
+
+package language
+
+// TODO: Remove above NOTE after:
+// - verifying that tables are dropped correctly (most notably matcher tables).
+
+import (
+ "strings"
+
+ "golang.org/x/text/internal/language"
+ "golang.org/x/text/internal/language/compact"
+)
+
+// Tag represents a BCP 47 language tag. It is used to specify an instance of a
+// specific language or locale. All language tag values are guaranteed to be
+// well-formed.
+type Tag compact.Tag
+
+func makeTag(t language.Tag) (tag Tag) {
+ return Tag(compact.Make(t))
+}
+
+func (t *Tag) tag() language.Tag {
+ return (*compact.Tag)(t).Tag()
+}
+
+func (t *Tag) isCompact() bool {
+ return (*compact.Tag)(t).IsCompact()
+}
+
+// TODO: improve performance.
+func (t *Tag) lang() language.Language { return t.tag().LangID }
+func (t *Tag) region() language.Region { return t.tag().RegionID }
+func (t *Tag) script() language.Script { return t.tag().ScriptID }
+
+// Make is a convenience wrapper for Parse that omits the error.
+// In case of an error, a sensible default is returned.
+func Make(s string) Tag {
+ return Default.Make(s)
+}
+
+// Make is a convenience wrapper for c.Parse that omits the error.
+// In case of an error, a sensible default is returned.
+func (c CanonType) Make(s string) Tag {
+ t, _ := c.Parse(s)
+ return t
+}
+
+// Raw returns the raw base language, script and region, without making an
+// attempt to infer their values.
+func (t Tag) Raw() (b Base, s Script, r Region) {
+ tt := t.tag()
+ return Base{tt.LangID}, Script{tt.ScriptID}, Region{tt.RegionID}
+}
+
+// IsRoot returns true if t is equal to language "und".
+func (t Tag) IsRoot() bool {
+ return compact.Tag(t).IsRoot()
+}
+
+// CanonType can be used to enable or disable various types of canonicalization.
+type CanonType int
+
+const (
+ // Replace deprecated base languages with their preferred replacements.
+ DeprecatedBase CanonType = 1 << iota
+ // Replace deprecated scripts with their preferred replacements.
+ DeprecatedScript
+ // Replace deprecated regions with their preferred replacements.
+ DeprecatedRegion
+ // Remove redundant scripts.
+ SuppressScript
+ // Normalize legacy encodings. This includes legacy languages defined in
+ // CLDR as well as bibliographic codes defined in ISO-639.
+ Legacy
+ // Map the dominant language of a macro language group to the macro language
+ // subtag. For example cmn -> zh.
+ Macro
+ // The CLDR flag should be used if full compatibility with CLDR is required.
+ // There are a few cases where language.Tag may differ from CLDR. To follow all
+ // of CLDR's suggestions, use All|CLDR.
+ CLDR
+
+ // Raw can be used to Compose or Parse without Canonicalization.
+ Raw CanonType = 0
+
+ // Replace all deprecated tags with their preferred replacements.
+ Deprecated = DeprecatedBase | DeprecatedScript | DeprecatedRegion
+
+ // All canonicalizations recommended by BCP 47.
+ BCP47 = Deprecated | SuppressScript
+
+ // All canonicalizations.
+ All = BCP47 | Legacy | Macro
+
+ // Default is the canonicalization used by Parse, Make and Compose. To
+ // preserve as much information as possible, canonicalizations that remove
+ // potentially valuable information are not included. The Matcher is
+ // designed to recognize similar tags that would be the same if
+ // they were canonicalized using All.
+ Default = Deprecated | Legacy
+
+ canonLang = DeprecatedBase | Legacy | Macro
+
+ // TODO: LikelyScript, LikelyRegion: suppress similar to ICU.
+)
+
+// canonicalize returns the canonicalized equivalent of the tag and
+// whether there was any change.
+func canonicalize(c CanonType, t language.Tag) (language.Tag, bool) {
+ if c == Raw {
+ return t, false
+ }
+ changed := false
+ if c&SuppressScript != 0 {
+ if t.LangID.SuppressScript() == t.ScriptID {
+ t.ScriptID = 0
+ changed = true
+ }
+ }
+ if c&canonLang != 0 {
+ for {
+ if l, aliasType := t.LangID.Canonicalize(); l != t.LangID {
+ switch aliasType {
+ case language.Legacy:
+ if c&Legacy != 0 {
+ if t.LangID == _sh && t.ScriptID == 0 {
+ t.ScriptID = _Latn
+ }
+ t.LangID = l
+ changed = true
+ }
+ case language.Macro:
+ if c&Macro != 0 {
+ // We deviate here from CLDR. The mapping "nb" -> "no"
+ // qualifies as a typical Macro language mapping. However,
+ // for legacy reasons, CLDR maps "no", the macro language
+ // code for Norwegian, to the dominant variant "nb". This
+ // change is currently under consideration for CLDR as well.
+ // See https://unicode.org/cldr/trac/ticket/2698 and also
+ // https://unicode.org/cldr/trac/ticket/1790 for some of the
+ // practical implications. TODO: this check could be removed
+ // if CLDR adopts this change.
+ if c&CLDR == 0 || t.LangID != _nb {
+ changed = true
+ t.LangID = l
+ }
+ }
+ case language.Deprecated:
+ if c&DeprecatedBase != 0 {
+ if t.LangID == _mo && t.RegionID == 0 {
+ t.RegionID = _MD
+ }
+ t.LangID = l
+ changed = true
+ // Other canonicalization types may still apply.
+ continue
+ }
+ }
+ } else if c&Legacy != 0 && t.LangID == _no && c&CLDR != 0 {
+ t.LangID = _nb
+ changed = true
+ }
+ break
+ }
+ }
+ if c&DeprecatedScript != 0 {
+ if t.ScriptID == _Qaai {
+ changed = true
+ t.ScriptID = _Zinh
+ }
+ }
+ if c&DeprecatedRegion != 0 {
+ if r := t.RegionID.Canonicalize(); r != t.RegionID {
+ changed = true
+ t.RegionID = r
+ }
+ }
+ return t, changed
+}
+
+// Canonicalize returns the canonicalized equivalent of the tag.
+func (c CanonType) Canonicalize(t Tag) (Tag, error) {
+ // First try fast path.
+ if t.isCompact() {
+ if _, changed := canonicalize(c, compact.Tag(t).Tag()); !changed {
+ return t, nil
+ }
+ }
+ // It is unlikely that one will canonicalize a tag after matching. So do
+ // a slow but simple approach here.
+ if tag, changed := canonicalize(c, t.tag()); changed {
+ tag.RemakeString()
+ return makeTag(tag), nil
+ }
+ return t, nil
+
+}
+
+// Confidence indicates the level of certainty for a given return value.
+// For example, Serbian may be written in Cyrillic or Latin script.
+// The confidence level indicates whether a value was explicitly specified,
+// whether it is typically the only possible value, or whether there is
+// an ambiguity.
+type Confidence int
+
+const (
+ No Confidence = iota // full confidence that there was no match
+ Low // most likely value picked out of a set of alternatives
+ High // value is generally assumed to be the correct match
+ Exact // exact match or explicitly specified value
+)
+
+var confName = []string{"No", "Low", "High", "Exact"}
+
+func (c Confidence) String() string {
+ return confName[c]
+}
+
+// String returns the canonical string representation of the language tag.
+func (t Tag) String() string {
+ return t.tag().String()
+}
+
+// MarshalText implements encoding.TextMarshaler.
+func (t Tag) MarshalText() (text []byte, err error) {
+ return t.tag().MarshalText()
+}
+
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (t *Tag) UnmarshalText(text []byte) error {
+ var tag language.Tag
+ err := tag.UnmarshalText(text)
+ *t = makeTag(tag)
+ return err
+}
+
+// Base returns the base language of the language tag. If the base language is
+// unspecified, an attempt will be made to infer it from the context.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Base() (Base, Confidence) {
+ if b := t.lang(); b != 0 {
+ return Base{b}, Exact
+ }
+ tt := t.tag()
+ c := High
+ if tt.ScriptID == 0 && !tt.RegionID.IsCountry() {
+ c = Low
+ }
+ if tag, err := tt.Maximize(); err == nil && tag.LangID != 0 {
+ return Base{tag.LangID}, c
+ }
+ return Base{0}, No
+}
+
+// Script infers the script for the language tag. If it was not explicitly given, it will infer
+// a most likely candidate.
+// If more than one script is commonly used for a language, the most likely one
+// is returned with a low confidence indication. For example, it returns (Cyrl, Low)
+// for Serbian.
+// If a script cannot be inferred (Zzzz, No) is returned. We do not use Zyyy (undetermined)
+// as one would suspect from the IANA registry for BCP 47. In a Unicode context Zyyy marks
+// common characters (like 1, 2, 3, '.', etc.) and is therefore more like multiple scripts.
+// See https://www.unicode.org/reports/tr24/#Values for more details. Zzzz is also used for
+// unknown value in CLDR. (Zzzz, Exact) is returned if Zzzz was explicitly specified.
+// Note that an inferred script is never guaranteed to be the correct one. Latin is
+// almost exclusively used for Afrikaans, but Arabic has been used for some texts
+// in the past. Also, the script that is commonly used may change over time.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Script() (Script, Confidence) {
+ if scr := t.script(); scr != 0 {
+ return Script{scr}, Exact
+ }
+ tt := t.tag()
+ sc, c := language.Script(_Zzzz), No
+ if scr := tt.LangID.SuppressScript(); scr != 0 {
+ // Note: it is not always the case that a language with a suppress
+ // script value is only written in one script (e.g. kk, ms, pa).
+ if tt.RegionID == 0 {
+ return Script{scr}, High
+ }
+ sc, c = scr, High
+ }
+ if tag, err := tt.Maximize(); err == nil {
+ if tag.ScriptID != sc {
+ sc, c = tag.ScriptID, Low
+ }
+ } else {
+ tt, _ = canonicalize(Deprecated|Macro, tt)
+ if tag, err := tt.Maximize(); err == nil && tag.ScriptID != sc {
+ sc, c = tag.ScriptID, Low
+ }
+ }
+ return Script{sc}, c
+}
+
+// Region returns the region for the language tag. If it was not explicitly given, it will
+// infer a most likely candidate from the context.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Region() (Region, Confidence) {
+ if r := t.region(); r != 0 {
+ return Region{r}, Exact
+ }
+ tt := t.tag()
+ if tt, err := tt.Maximize(); err == nil {
+ return Region{tt.RegionID}, Low // TODO: differentiate between high and low.
+ }
+ tt, _ = canonicalize(Deprecated|Macro, tt)
+ if tag, err := tt.Maximize(); err == nil {
+ return Region{tag.RegionID}, Low
+ }
+ return Region{_ZZ}, No // TODO: return world instead of undetermined?
+}
+
+// Variants returns the variants specified explicitly for this language tag.
+// or nil if no variant was specified.
+func (t Tag) Variants() []Variant {
+ if !compact.Tag(t).MayHaveVariants() {
+ return nil
+ }
+ v := []Variant{}
+ x, str := "", t.tag().Variants()
+ for str != "" {
+ x, str = nextToken(str)
+ v = append(v, Variant{x})
+ }
+ return v
+}
+
+// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
+// specific language are substituted with fields from the parent language.
+// The parent for a language may change for newer versions of CLDR.
+//
+// Parent returns a tag for a less specific language that is mutually
+// intelligible or Und if there is no such language. This may not be the same as
+// simply stripping the last BCP 47 subtag. For instance, the parent of "zh-TW"
+// is "zh-Hant", and the parent of "zh-Hant" is "und".
+func (t Tag) Parent() Tag {
+ return Tag(compact.Tag(t).Parent())
+}
+
+// nextToken returns token t and the rest of the string.
+func nextToken(s string) (t, tail string) {
+ p := strings.Index(s[1:], "-")
+ if p == -1 {
+ return s[1:], ""
+ }
+ p++
+ return s[1:p], s[p:]
+}
+
+// Extension is a single BCP 47 extension.
+type Extension struct {
+ s string
+}
+
+// String returns the string representation of the extension, including the
+// type tag.
+func (e Extension) String() string {
+ return e.s
+}
+
+// ParseExtension parses s as an extension and returns it on success.
+func ParseExtension(s string) (e Extension, err error) {
+ ext, err := language.ParseExtension(s)
+ return Extension{ext}, err
+}
+
+// Type returns the one-byte extension type of e. It returns 0 for the zero
+// exception.
+func (e Extension) Type() byte {
+ if e.s == "" {
+ return 0
+ }
+ return e.s[0]
+}
+
+// Tokens returns the list of tokens of e.
+func (e Extension) Tokens() []string {
+ return strings.Split(e.s, "-")
+}
+
+// Extension returns the extension of type x for tag t. It will return
+// false for ok if t does not have the requested extension. The returned
+// extension will be invalid in this case.
+func (t Tag) Extension(x byte) (ext Extension, ok bool) {
+ if !compact.Tag(t).MayHaveExtensions() {
+ return Extension{}, false
+ }
+ e, ok := t.tag().Extension(x)
+ return Extension{e}, ok
+}
+
+// Extensions returns all extensions of t.
+func (t Tag) Extensions() []Extension {
+ if !compact.Tag(t).MayHaveExtensions() {
+ return nil
+ }
+ e := []Extension{}
+ for _, ext := range t.tag().Extensions() {
+ e = append(e, Extension{ext})
+ }
+ return e
+}
+
+// TypeForKey returns the type associated with the given key, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// TypeForKey will traverse the inheritance chain to get the correct value.
+//
+// If there are multiple types associated with a key, only the first will be
+// returned. If there is no type associated with a key, it returns the empty
+// string.
+func (t Tag) TypeForKey(key string) string {
+ if !compact.Tag(t).MayHaveExtensions() {
+ if key != "rg" && key != "va" {
+ return ""
+ }
+ }
+ return t.tag().TypeForKey(key)
+}
+
+// SetTypeForKey returns a new Tag with the key set to type, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// An empty value removes an existing pair with the same key.
+func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
+ tt, err := t.tag().SetTypeForKey(key, value)
+ return makeTag(tt), err
+}
+
+// NumCompactTags is the number of compact tags. The maximum tag is
+// NumCompactTags-1.
+const NumCompactTags = compact.NumCompactTags
+
+// CompactIndex returns an index, where 0 <= index < NumCompactTags, for tags
+// for which data exists in the text repository.The index will change over time
+// and should not be stored in persistent storage. If t does not match a compact
+// index, exact will be false and the compact index will be returned for the
+// first match after repeatedly taking the Parent of t.
+func CompactIndex(t Tag) (index int, exact bool) {
+ id, exact := compact.LanguageID(compact.Tag(t))
+ return int(id), exact
+}
+
+var root = language.Tag{}
+
+// Base is an ISO 639 language code, used for encoding the base language
+// of a language tag.
+type Base struct {
+ langID language.Language
+}
+
+// ParseBase parses a 2- or 3-letter ISO 639 code.
+// It returns a ValueError if s is a well-formed but unknown language identifier
+// or another error if another error occurred.
+func ParseBase(s string) (Base, error) {
+ l, err := language.ParseBase(s)
+ return Base{l}, err
+}
+
+// String returns the BCP 47 representation of the base language.
+func (b Base) String() string {
+ return b.langID.String()
+}
+
+// ISO3 returns the ISO 639-3 language code.
+func (b Base) ISO3() string {
+ return b.langID.ISO3()
+}
+
+// IsPrivateUse reports whether this language code is reserved for private use.
+func (b Base) IsPrivateUse() bool {
+ return b.langID.IsPrivateUse()
+}
+
+// Script is a 4-letter ISO 15924 code for representing scripts.
+// It is idiomatically represented in title case.
+type Script struct {
+ scriptID language.Script
+}
+
+// ParseScript parses a 4-letter ISO 15924 code.
+// It returns a ValueError if s is a well-formed but unknown script identifier
+// or another error if another error occurred.
+func ParseScript(s string) (Script, error) {
+ sc, err := language.ParseScript(s)
+ return Script{sc}, err
+}
+
+// String returns the script code in title case.
+// It returns "Zzzz" for an unspecified script.
+func (s Script) String() string {
+ return s.scriptID.String()
+}
+
+// IsPrivateUse reports whether this script code is reserved for private use.
+func (s Script) IsPrivateUse() bool {
+ return s.scriptID.IsPrivateUse()
+}
+
+// Region is an ISO 3166-1 or UN M.49 code for representing countries and regions.
+type Region struct {
+ regionID language.Region
+}
+
+// EncodeM49 returns the Region for the given UN M.49 code.
+// It returns an error if r is not a valid code.
+func EncodeM49(r int) (Region, error) {
+ rid, err := language.EncodeM49(r)
+ return Region{rid}, err
+}
+
+// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code.
+// It returns a ValueError if s is a well-formed but unknown region identifier
+// or another error if another error occurred.
+func ParseRegion(s string) (Region, error) {
+ r, err := language.ParseRegion(s)
+ return Region{r}, err
+}
+
+// String returns the BCP 47 representation for the region.
+// It returns "ZZ" for an unspecified region.
+func (r Region) String() string {
+ return r.regionID.String()
+}
+
+// ISO3 returns the 3-letter ISO code of r.
+// Note that not all regions have a 3-letter ISO code.
+// In such cases this method returns "ZZZ".
+func (r Region) ISO3() string {
+ return r.regionID.ISO3()
+}
+
+// M49 returns the UN M.49 encoding of r, or 0 if this encoding
+// is not defined for r.
+func (r Region) M49() int {
+ return r.regionID.M49()
+}
+
+// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This
+// may include private-use tags that are assigned by CLDR and used in this
+// implementation. So IsPrivateUse and IsCountry can be simultaneously true.
+func (r Region) IsPrivateUse() bool {
+ return r.regionID.IsPrivateUse()
+}
+
+// IsCountry returns whether this region is a country or autonomous area. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsCountry() bool {
+ return r.regionID.IsCountry()
+}
+
+// IsGroup returns whether this region defines a collection of regions. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsGroup() bool {
+ return r.regionID.IsGroup()
+}
+
+// Contains returns whether Region c is contained by Region r. It returns true
+// if c == r.
+func (r Region) Contains(c Region) bool {
+ return r.regionID.Contains(c.regionID)
+}
+
+// TLD returns the country code top-level domain (ccTLD). UK is returned for GB.
+// In all other cases it returns either the region itself or an error.
+//
+// This method may return an error for a region for which there exists a
+// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The
+// region will already be canonicalized it was obtained from a Tag that was
+// obtained using any of the default methods.
+func (r Region) TLD() (Region, error) {
+ tld, err := r.regionID.TLD()
+ return Region{tld}, err
+}
+
+// Canonicalize returns the region or a possible replacement if the region is
+// deprecated. It will not return a replacement for deprecated regions that
+// are split into multiple regions.
+func (r Region) Canonicalize() Region {
+ return Region{r.regionID.Canonicalize()}
+}
+
+// Variant represents a registered variant of a language as defined by BCP 47.
+type Variant struct {
+ variant string
+}
+
+// ParseVariant parses and returns a Variant. An error is returned if s is not
+// a valid variant.
+func ParseVariant(s string) (Variant, error) {
+ v, err := language.ParseVariant(s)
+ return Variant{v.String()}, err
+}
+
+// String returns the string representation of the variant.
+func (v Variant) String() string {
+ return v.variant
+}
diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go
new file mode 100644
index 000000000..1153baf29
--- /dev/null
+++ b/vendor/golang.org/x/text/language/match.go
@@ -0,0 +1,735 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "errors"
+ "strings"
+
+ "golang.org/x/text/internal/language"
+)
+
+// A MatchOption configures a Matcher.
+type MatchOption func(*matcher)
+
+// PreferSameScript will, in the absence of a match, result in the first
+// preferred tag with the same script as a supported tag to match this supported
+// tag. The default is currently true, but this may change in the future.
+func PreferSameScript(preferSame bool) MatchOption {
+ return func(m *matcher) { m.preferSameScript = preferSame }
+}
+
+// TODO(v1.0.0): consider making Matcher a concrete type, instead of interface.
+// There doesn't seem to be too much need for multiple types.
+// Making it a concrete type allows MatchStrings to be a method, which will
+// improve its discoverability.
+
+// MatchStrings parses and matches the given strings until one of them matches
+// the language in the Matcher. A string may be an Accept-Language header as
+// handled by ParseAcceptLanguage. The default language is returned if no
+// other language matched.
+func MatchStrings(m Matcher, lang ...string) (tag Tag, index int) {
+ for _, accept := range lang {
+ desired, _, err := ParseAcceptLanguage(accept)
+ if err != nil {
+ continue
+ }
+ if tag, index, conf := m.Match(desired...); conf != No {
+ return tag, index
+ }
+ }
+ tag, index, _ = m.Match()
+ return
+}
+
+// Matcher is the interface that wraps the Match method.
+//
+// Match returns the best match for any of the given tags, along with
+// a unique index associated with the returned tag and a confidence
+// score.
+type Matcher interface {
+ Match(t ...Tag) (tag Tag, index int, c Confidence)
+}
+
+// Comprehends reports the confidence score for a speaker of a given language
+// to being able to comprehend the written form of an alternative language.
+func Comprehends(speaker, alternative Tag) Confidence {
+ _, _, c := NewMatcher([]Tag{alternative}).Match(speaker)
+ return c
+}
+
+// NewMatcher returns a Matcher that matches an ordered list of preferred tags
+// against a list of supported tags based on written intelligibility, closeness
+// of dialect, equivalence of subtags and various other rules. It is initialized
+// with the list of supported tags. The first element is used as the default
+// value in case no match is found.
+//
+// Its Match method matches the first of the given Tags to reach a certain
+// confidence threshold. The tags passed to Match should therefore be specified
+// in order of preference. Extensions are ignored for matching.
+//
+// The index returned by the Match method corresponds to the index of the
+// matched tag in t, but is augmented with the Unicode extension ('u')of the
+// corresponding preferred tag. This allows user locale options to be passed
+// transparently.
+func NewMatcher(t []Tag, options ...MatchOption) Matcher {
+ return newMatcher(t, options)
+}
+
+func (m *matcher) Match(want ...Tag) (t Tag, index int, c Confidence) {
+ var tt language.Tag
+ match, w, c := m.getBest(want...)
+ if match != nil {
+ tt, index = match.tag, match.index
+ } else {
+ // TODO: this should be an option
+ tt = m.default_.tag
+ if m.preferSameScript {
+ outer:
+ for _, w := range want {
+ script, _ := w.Script()
+ if script.scriptID == 0 {
+ // Don't do anything if there is no script, such as with
+ // private subtags.
+ continue
+ }
+ for i, h := range m.supported {
+ if script.scriptID == h.maxScript {
+ tt, index = h.tag, i
+ break outer
+ }
+ }
+ }
+ }
+ // TODO: select first language tag based on script.
+ }
+ if w.RegionID != tt.RegionID && w.RegionID != 0 {
+ if w.RegionID != 0 && tt.RegionID != 0 && tt.RegionID.Contains(w.RegionID) {
+ tt.RegionID = w.RegionID
+ tt.RemakeString()
+ } else if r := w.RegionID.String(); len(r) == 2 {
+ // TODO: also filter macro and deprecated.
+ tt, _ = tt.SetTypeForKey("rg", strings.ToLower(r)+"zzzz")
+ }
+ }
+ // Copy options from the user-provided tag into the result tag. This is hard
+ // to do after the fact, so we do it here.
+ // TODO: add in alternative variants to -u-va-.
+ // TODO: add preferred region to -u-rg-.
+ if e := w.Extensions(); len(e) > 0 {
+ b := language.Builder{}
+ b.SetTag(tt)
+ for _, e := range e {
+ b.AddExt(e)
+ }
+ tt = b.Make()
+ }
+ return makeTag(tt), index, c
+}
+
+// ErrMissingLikelyTagsData indicates no information was available
+// to compute likely values of missing tags.
+var ErrMissingLikelyTagsData = errors.New("missing likely tags data")
+
+// func (t *Tag) setTagsFrom(id Tag) {
+// t.LangID = id.LangID
+// t.ScriptID = id.ScriptID
+// t.RegionID = id.RegionID
+// }
+
+// Tag Matching
+// CLDR defines an algorithm for finding the best match between two sets of language
+// tags. The basic algorithm defines how to score a possible match and then find
+// the match with the best score
+// (see https://www.unicode.org/reports/tr35/#LanguageMatching).
+// Using scoring has several disadvantages. The scoring obfuscates the importance of
+// the various factors considered, making the algorithm harder to understand. Using
+// scoring also requires the full score to be computed for each pair of tags.
+//
+// We will use a different algorithm which aims to have the following properties:
+// - clarity on the precedence of the various selection factors, and
+// - improved performance by allowing early termination of a comparison.
+//
+// Matching algorithm (overview)
+// Input:
+// - supported: a set of supported tags
+// - default: the default tag to return in case there is no match
+// - desired: list of desired tags, ordered by preference, starting with
+// the most-preferred.
+//
+// Algorithm:
+// 1) Set the best match to the lowest confidence level
+// 2) For each tag in "desired":
+// a) For each tag in "supported":
+// 1) compute the match between the two tags.
+// 2) if the match is better than the previous best match, replace it
+// with the new match. (see next section)
+// b) if the current best match is Exact and pin is true the result will be
+// frozen to the language found thusfar, although better matches may
+// still be found for the same language.
+// 3) If the best match so far is below a certain threshold, return "default".
+//
+// Ranking:
+// We use two phases to determine whether one pair of tags are a better match
+// than another pair of tags. First, we determine a rough confidence level. If the
+// levels are different, the one with the highest confidence wins.
+// Second, if the rough confidence levels are identical, we use a set of tie-breaker
+// rules.
+//
+// The confidence level of matching a pair of tags is determined by finding the
+// lowest confidence level of any matches of the corresponding subtags (the
+// result is deemed as good as its weakest link).
+// We define the following levels:
+// Exact - An exact match of a subtag, before adding likely subtags.
+// MaxExact - An exact match of a subtag, after adding likely subtags.
+// [See Note 2].
+// High - High level of mutual intelligibility between different subtag
+// variants.
+// Low - Low level of mutual intelligibility between different subtag
+// variants.
+// No - No mutual intelligibility.
+//
+// The following levels can occur for each type of subtag:
+// Base: Exact, MaxExact, High, Low, No
+// Script: Exact, MaxExact [see Note 3], Low, No
+// Region: Exact, MaxExact, High
+// Variant: Exact, High
+// Private: Exact, No
+//
+// Any result with a confidence level of Low or higher is deemed a possible match.
+// Once a desired tag matches any of the supported tags with a level of MaxExact
+// or higher, the next desired tag is not considered (see Step 2.b).
+// Note that CLDR provides languageMatching data that defines close equivalence
+// classes for base languages, scripts and regions.
+//
+// Tie-breaking
+// If we get the same confidence level for two matches, we apply a sequence of
+// tie-breaking rules. The first that succeeds defines the result. The rules are
+// applied in the following order.
+// 1) Original language was defined and was identical.
+// 2) Original region was defined and was identical.
+// 3) Distance between two maximized regions was the smallest.
+// 4) Original script was defined and was identical.
+// 5) Distance from want tag to have tag using the parent relation [see Note 5.]
+// If there is still no winner after these rules are applied, the first match
+// found wins.
+//
+// Notes:
+// [2] In practice, as matching of Exact is done in a separate phase from
+// matching the other levels, we reuse the Exact level to mean MaxExact in
+// the second phase. As a consequence, we only need the levels defined by
+// the Confidence type. The MaxExact confidence level is mapped to High in
+// the public API.
+// [3] We do not differentiate between maximized script values that were derived
+// from suppressScript versus most likely tag data. We determined that in
+// ranking the two, one ranks just after the other. Moreover, the two cannot
+// occur concurrently. As a consequence, they are identical for practical
+// purposes.
+// [4] In case of deprecated, macro-equivalents and legacy mappings, we assign
+// the MaxExact level to allow iw vs he to still be a closer match than
+// en-AU vs en-US, for example.
+// [5] In CLDR a locale inherits fields that are unspecified for this locale
+// from its parent. Therefore, if a locale is a parent of another locale,
+// it is a strong measure for closeness, especially when no other tie
+// breaker rule applies. One could also argue it is inconsistent, for
+// example, when pt-AO matches pt (which CLDR equates with pt-BR), even
+// though its parent is pt-PT according to the inheritance rules.
+//
+// Implementation Details:
+// There are several performance considerations worth pointing out. Most notably,
+// we preprocess as much as possible (within reason) at the time of creation of a
+// matcher. This includes:
+// - creating a per-language map, which includes data for the raw base language
+// and its canonicalized variant (if applicable),
+// - expanding entries for the equivalence classes defined in CLDR's
+// languageMatch data.
+// The per-language map ensures that typically only a very small number of tags
+// need to be considered. The pre-expansion of canonicalized subtags and
+// equivalence classes reduces the amount of map lookups that need to be done at
+// runtime.
+
+// matcher keeps a set of supported language tags, indexed by language.
+type matcher struct {
+ default_ *haveTag
+ supported []*haveTag
+ index map[language.Language]*matchHeader
+ passSettings bool
+ preferSameScript bool
+}
+
+// matchHeader has the lists of tags for exact matches and matches based on
+// maximized and canonicalized tags for a given language.
+type matchHeader struct {
+ haveTags []*haveTag
+ original bool
+}
+
+// haveTag holds a supported Tag and its maximized script and region. The maximized
+// or canonicalized language is not stored as it is not needed during matching.
+type haveTag struct {
+ tag language.Tag
+
+ // index of this tag in the original list of supported tags.
+ index int
+
+ // conf is the maximum confidence that can result from matching this haveTag.
+ // When conf < Exact this means it was inserted after applying a CLDR equivalence rule.
+ conf Confidence
+
+ // Maximized region and script.
+ maxRegion language.Region
+ maxScript language.Script
+
+ // altScript may be checked as an alternative match to maxScript. If altScript
+ // matches, the confidence level for this match is Low. Theoretically there
+ // could be multiple alternative scripts. This does not occur in practice.
+ altScript language.Script
+
+ // nextMax is the index of the next haveTag with the same maximized tags.
+ nextMax uint16
+}
+
+func makeHaveTag(tag language.Tag, index int) (haveTag, language.Language) {
+ max := tag
+ if tag.LangID != 0 || tag.RegionID != 0 || tag.ScriptID != 0 {
+ max, _ = canonicalize(All, max)
+ max, _ = max.Maximize()
+ max.RemakeString()
+ }
+ return haveTag{tag, index, Exact, max.RegionID, max.ScriptID, altScript(max.LangID, max.ScriptID), 0}, max.LangID
+}
+
+// altScript returns an alternative script that may match the given script with
+// a low confidence. At the moment, the langMatch data allows for at most one
+// script to map to another and we rely on this to keep the code simple.
+func altScript(l language.Language, s language.Script) language.Script {
+ for _, alt := range matchScript {
+ // TODO: also match cases where language is not the same.
+ if (language.Language(alt.wantLang) == l || language.Language(alt.haveLang) == l) &&
+ language.Script(alt.haveScript) == s {
+ return language.Script(alt.wantScript)
+ }
+ }
+ return 0
+}
+
+// addIfNew adds a haveTag to the list of tags only if it is a unique tag.
+// Tags that have the same maximized values are linked by index.
+func (h *matchHeader) addIfNew(n haveTag, exact bool) {
+ h.original = h.original || exact
+ // Don't add new exact matches.
+ for _, v := range h.haveTags {
+ if equalsRest(v.tag, n.tag) {
+ return
+ }
+ }
+ // Allow duplicate maximized tags, but create a linked list to allow quickly
+ // comparing the equivalents and bail out.
+ for i, v := range h.haveTags {
+ if v.maxScript == n.maxScript &&
+ v.maxRegion == n.maxRegion &&
+ v.tag.VariantOrPrivateUseTags() == n.tag.VariantOrPrivateUseTags() {
+ for h.haveTags[i].nextMax != 0 {
+ i = int(h.haveTags[i].nextMax)
+ }
+ h.haveTags[i].nextMax = uint16(len(h.haveTags))
+ break
+ }
+ }
+ h.haveTags = append(h.haveTags, &n)
+}
+
+// header returns the matchHeader for the given language. It creates one if
+// it doesn't already exist.
+func (m *matcher) header(l language.Language) *matchHeader {
+ if h := m.index[l]; h != nil {
+ return h
+ }
+ h := &matchHeader{}
+ m.index[l] = h
+ return h
+}
+
+func toConf(d uint8) Confidence {
+ if d <= 10 {
+ return High
+ }
+ if d < 30 {
+ return Low
+ }
+ return No
+}
+
+// newMatcher builds an index for the given supported tags and returns it as
+// a matcher. It also expands the index by considering various equivalence classes
+// for a given tag.
+func newMatcher(supported []Tag, options []MatchOption) *matcher {
+ m := &matcher{
+ index: make(map[language.Language]*matchHeader),
+ preferSameScript: true,
+ }
+ for _, o := range options {
+ o(m)
+ }
+ if len(supported) == 0 {
+ m.default_ = &haveTag{}
+ return m
+ }
+ // Add supported languages to the index. Add exact matches first to give
+ // them precedence.
+ for i, tag := range supported {
+ tt := tag.tag()
+ pair, _ := makeHaveTag(tt, i)
+ m.header(tt.LangID).addIfNew(pair, true)
+ m.supported = append(m.supported, &pair)
+ }
+ m.default_ = m.header(supported[0].lang()).haveTags[0]
+ // Keep these in two different loops to support the case that two equivalent
+ // languages are distinguished, such as iw and he.
+ for i, tag := range supported {
+ tt := tag.tag()
+ pair, max := makeHaveTag(tt, i)
+ if max != tt.LangID {
+ m.header(max).addIfNew(pair, true)
+ }
+ }
+
+ // update is used to add indexes in the map for equivalent languages.
+ // update will only add entries to original indexes, thus not computing any
+ // transitive relations.
+ update := func(want, have uint16, conf Confidence) {
+ if hh := m.index[language.Language(have)]; hh != nil {
+ if !hh.original {
+ return
+ }
+ hw := m.header(language.Language(want))
+ for _, ht := range hh.haveTags {
+ v := *ht
+ if conf < v.conf {
+ v.conf = conf
+ }
+ v.nextMax = 0 // this value needs to be recomputed
+ if v.altScript != 0 {
+ v.altScript = altScript(language.Language(want), v.maxScript)
+ }
+ hw.addIfNew(v, conf == Exact && hh.original)
+ }
+ }
+ }
+
+ // Add entries for languages with mutual intelligibility as defined by CLDR's
+ // languageMatch data.
+ for _, ml := range matchLang {
+ update(ml.want, ml.have, toConf(ml.distance))
+ if !ml.oneway {
+ update(ml.have, ml.want, toConf(ml.distance))
+ }
+ }
+
+ // Add entries for possible canonicalizations. This is an optimization to
+ // ensure that only one map lookup needs to be done at runtime per desired tag.
+ // First we match deprecated equivalents. If they are perfect equivalents
+ // (their canonicalization simply substitutes a different language code, but
+ // nothing else), the match confidence is Exact, otherwise it is High.
+ for i, lm := range language.AliasMap {
+ // If deprecated codes match and there is no fiddling with the script
+ // or region, we consider it an exact match.
+ conf := Exact
+ if language.AliasTypes[i] != language.Macro {
+ if !isExactEquivalent(language.Language(lm.From)) {
+ conf = High
+ }
+ update(lm.To, lm.From, conf)
+ }
+ update(lm.From, lm.To, conf)
+ }
+ return m
+}
+
+// getBest gets the best matching tag in m for any of the given tags, taking into
+// account the order of preference of the given tags.
+func (m *matcher) getBest(want ...Tag) (got *haveTag, orig language.Tag, c Confidence) {
+ best := bestMatch{}
+ for i, ww := range want {
+ w := ww.tag()
+ var max language.Tag
+ // Check for exact match first.
+ h := m.index[w.LangID]
+ if w.LangID != 0 {
+ if h == nil {
+ continue
+ }
+ // Base language is defined.
+ max, _ = canonicalize(Legacy|Deprecated|Macro, w)
+ // A region that is added through canonicalization is stronger than
+ // a maximized region: set it in the original (e.g. mo -> ro-MD).
+ if w.RegionID != max.RegionID {
+ w.RegionID = max.RegionID
+ }
+ // TODO: should we do the same for scripts?
+ // See test case: en, sr, nl ; sh ; sr
+ max, _ = max.Maximize()
+ } else {
+ // Base language is not defined.
+ if h != nil {
+ for i := range h.haveTags {
+ have := h.haveTags[i]
+ if equalsRest(have.tag, w) {
+ return have, w, Exact
+ }
+ }
+ }
+ if w.ScriptID == 0 && w.RegionID == 0 {
+ // We skip all tags matching und for approximate matching, including
+ // private tags.
+ continue
+ }
+ max, _ = w.Maximize()
+ if h = m.index[max.LangID]; h == nil {
+ continue
+ }
+ }
+ pin := true
+ for _, t := range want[i+1:] {
+ if w.LangID == t.lang() {
+ pin = false
+ break
+ }
+ }
+ // Check for match based on maximized tag.
+ for i := range h.haveTags {
+ have := h.haveTags[i]
+ best.update(have, w, max.ScriptID, max.RegionID, pin)
+ if best.conf == Exact {
+ for have.nextMax != 0 {
+ have = h.haveTags[have.nextMax]
+ best.update(have, w, max.ScriptID, max.RegionID, pin)
+ }
+ return best.have, best.want, best.conf
+ }
+ }
+ }
+ if best.conf <= No {
+ if len(want) != 0 {
+ return nil, want[0].tag(), No
+ }
+ return nil, language.Tag{}, No
+ }
+ return best.have, best.want, best.conf
+}
+
+// bestMatch accumulates the best match so far.
+type bestMatch struct {
+ have *haveTag
+ want language.Tag
+ conf Confidence
+ pinnedRegion language.Region
+ pinLanguage bool
+ sameRegionGroup bool
+ // Cached results from applying tie-breaking rules.
+ origLang bool
+ origReg bool
+ paradigmReg bool
+ regGroupDist uint8
+ origScript bool
+}
+
+// update updates the existing best match if the new pair is considered to be a
+// better match. To determine if the given pair is a better match, it first
+// computes the rough confidence level. If this surpasses the current match, it
+// will replace it and update the tie-breaker rule cache. If there is a tie, it
+// proceeds with applying a series of tie-breaker rules. If there is no
+// conclusive winner after applying the tie-breaker rules, it leaves the current
+// match as the preferred match.
+//
+// If pin is true and have and tag are a strong match, it will henceforth only
+// consider matches for this language. This corresponds to the idea that most
+// users have a strong preference for the first defined language. A user can
+// still prefer a second language over a dialect of the preferred language by
+// explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should
+// be false.
+func (m *bestMatch) update(have *haveTag, tag language.Tag, maxScript language.Script, maxRegion language.Region, pin bool) {
+ // Bail if the maximum attainable confidence is below that of the current best match.
+ c := have.conf
+ if c < m.conf {
+ return
+ }
+ // Don't change the language once we already have found an exact match.
+ if m.pinLanguage && tag.LangID != m.want.LangID {
+ return
+ }
+ // Pin the region group if we are comparing tags for the same language.
+ if tag.LangID == m.want.LangID && m.sameRegionGroup {
+ _, sameGroup := regionGroupDist(m.pinnedRegion, have.maxRegion, have.maxScript, m.want.LangID)
+ if !sameGroup {
+ return
+ }
+ }
+ if c == Exact && have.maxScript == maxScript {
+ // If there is another language and then another entry of this language,
+ // don't pin anything, otherwise pin the language.
+ m.pinLanguage = pin
+ }
+ if equalsRest(have.tag, tag) {
+ } else if have.maxScript != maxScript {
+ // There is usually very little comprehension between different scripts.
+ // In a few cases there may still be Low comprehension. This possibility
+ // is pre-computed and stored in have.altScript.
+ if Low < m.conf || have.altScript != maxScript {
+ return
+ }
+ c = Low
+ } else if have.maxRegion != maxRegion {
+ if High < c {
+ // There is usually a small difference between languages across regions.
+ c = High
+ }
+ }
+
+ // We store the results of the computations of the tie-breaker rules along
+ // with the best match. There is no need to do the checks once we determine
+ // we have a winner, but we do still need to do the tie-breaker computations.
+ // We use "beaten" to keep track if we still need to do the checks.
+ beaten := false // true if the new pair defeats the current one.
+ if c != m.conf {
+ if c < m.conf {
+ return
+ }
+ beaten = true
+ }
+
+ // Tie-breaker rules:
+ // We prefer if the pre-maximized language was specified and identical.
+ origLang := have.tag.LangID == tag.LangID && tag.LangID != 0
+ if !beaten && m.origLang != origLang {
+ if m.origLang {
+ return
+ }
+ beaten = true
+ }
+
+ // We prefer if the pre-maximized region was specified and identical.
+ origReg := have.tag.RegionID == tag.RegionID && tag.RegionID != 0
+ if !beaten && m.origReg != origReg {
+ if m.origReg {
+ return
+ }
+ beaten = true
+ }
+
+ regGroupDist, sameGroup := regionGroupDist(have.maxRegion, maxRegion, maxScript, tag.LangID)
+ if !beaten && m.regGroupDist != regGroupDist {
+ if regGroupDist > m.regGroupDist {
+ return
+ }
+ beaten = true
+ }
+
+ paradigmReg := isParadigmLocale(tag.LangID, have.maxRegion)
+ if !beaten && m.paradigmReg != paradigmReg {
+ if !paradigmReg {
+ return
+ }
+ beaten = true
+ }
+
+ // Next we prefer if the pre-maximized script was specified and identical.
+ origScript := have.tag.ScriptID == tag.ScriptID && tag.ScriptID != 0
+ if !beaten && m.origScript != origScript {
+ if m.origScript {
+ return
+ }
+ beaten = true
+ }
+
+ // Update m to the newly found best match.
+ if beaten {
+ m.have = have
+ m.want = tag
+ m.conf = c
+ m.pinnedRegion = maxRegion
+ m.sameRegionGroup = sameGroup
+ m.origLang = origLang
+ m.origReg = origReg
+ m.paradigmReg = paradigmReg
+ m.origScript = origScript
+ m.regGroupDist = regGroupDist
+ }
+}
+
+func isParadigmLocale(lang language.Language, r language.Region) bool {
+ for _, e := range paradigmLocales {
+ if language.Language(e[0]) == lang && (r == language.Region(e[1]) || r == language.Region(e[2])) {
+ return true
+ }
+ }
+ return false
+}
+
+// regionGroupDist computes the distance between two regions based on their
+// CLDR grouping.
+func regionGroupDist(a, b language.Region, script language.Script, lang language.Language) (dist uint8, same bool) {
+ const defaultDistance = 4
+
+ aGroup := uint(regionToGroups[a]) << 1
+ bGroup := uint(regionToGroups[b]) << 1
+ for _, ri := range matchRegion {
+ if language.Language(ri.lang) == lang && (ri.script == 0 || language.Script(ri.script) == script) {
+ group := uint(1 << (ri.group &^ 0x80))
+ if 0x80&ri.group == 0 {
+ if aGroup&bGroup&group != 0 { // Both regions are in the group.
+ return ri.distance, ri.distance == defaultDistance
+ }
+ } else {
+ if (aGroup|bGroup)&group == 0 { // Both regions are not in the group.
+ return ri.distance, ri.distance == defaultDistance
+ }
+ }
+ }
+ }
+ return defaultDistance, true
+}
+
+// equalsRest compares everything except the language.
+func equalsRest(a, b language.Tag) bool {
+ // TODO: don't include extensions in this comparison. To do this efficiently,
+ // though, we should handle private tags separately.
+ return a.ScriptID == b.ScriptID && a.RegionID == b.RegionID && a.VariantOrPrivateUseTags() == b.VariantOrPrivateUseTags()
+}
+
+// isExactEquivalent returns true if canonicalizing the language will not alter
+// the script or region of a tag.
+func isExactEquivalent(l language.Language) bool {
+ for _, o := range notEquivalent {
+ if o == l {
+ return false
+ }
+ }
+ return true
+}
+
+var notEquivalent []language.Language
+
+func init() {
+ // Create a list of all languages for which canonicalization may alter the
+ // script or region.
+ for _, lm := range language.AliasMap {
+ tag := language.Tag{LangID: language.Language(lm.From)}
+ if tag, _ = canonicalize(All, tag); tag.ScriptID != 0 || tag.RegionID != 0 {
+ notEquivalent = append(notEquivalent, language.Language(lm.From))
+ }
+ }
+ // Maximize undefined regions of paradigm locales.
+ for i, v := range paradigmLocales {
+ t := language.Tag{LangID: language.Language(v[0])}
+ max, _ := t.Maximize()
+ if v[1] == 0 {
+ paradigmLocales[i][1] = uint16(max.RegionID)
+ }
+ if v[2] == 0 {
+ paradigmLocales[i][2] = uint16(max.RegionID)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go
new file mode 100644
index 000000000..053336e28
--- /dev/null
+++ b/vendor/golang.org/x/text/language/parse.go
@@ -0,0 +1,256 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "errors"
+ "sort"
+ "strconv"
+ "strings"
+
+ "golang.org/x/text/internal/language"
+)
+
+// ValueError is returned by any of the parsing functions when the
+// input is well-formed but the respective subtag is not recognized
+// as a valid value.
+type ValueError interface {
+ error
+
+ // Subtag returns the subtag for which the error occurred.
+ Subtag() string
+}
+
+// Parse parses the given BCP 47 string and returns a valid Tag. If parsing
+// failed it returns an error and any part of the tag that could be parsed.
+// If parsing succeeded but an unknown value was found, it returns
+// ValueError. The Tag returned in this case is just stripped of the unknown
+// value. All other values are preserved. It accepts tags in the BCP 47 format
+// and extensions to this standard defined in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// The resulting tag is canonicalized using the default canonicalization type.
+func Parse(s string) (t Tag, err error) {
+ return Default.Parse(s)
+}
+
+// Parse parses the given BCP 47 string and returns a valid Tag. If parsing
+// failed it returns an error and any part of the tag that could be parsed.
+// If parsing succeeded but an unknown value was found, it returns
+// ValueError. The Tag returned in this case is just stripped of the unknown
+// value. All other values are preserved. It accepts tags in the BCP 47 format
+// and extensions to this standard defined in
+// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// The resulting tag is canonicalized using the canonicalization type c.
+func (c CanonType) Parse(s string) (t Tag, err error) {
+ defer func() {
+ if recover() != nil {
+ t = Tag{}
+ err = language.ErrSyntax
+ }
+ }()
+
+ tt, err := language.Parse(s)
+ if err != nil {
+ return makeTag(tt), err
+ }
+ tt, changed := canonicalize(c, tt)
+ if changed {
+ tt.RemakeString()
+ }
+ return makeTag(tt), nil
+}
+
+// Compose creates a Tag from individual parts, which may be of type Tag, Base,
+// Script, Region, Variant, []Variant, Extension, []Extension or error. If a
+// Base, Script or Region or slice of type Variant or Extension is passed more
+// than once, the latter will overwrite the former. Variants and Extensions are
+// accumulated, but if two extensions of the same type are passed, the latter
+// will replace the former. For -u extensions, though, the key-type pairs are
+// added, where later values overwrite older ones. A Tag overwrites all former
+// values and typically only makes sense as the first argument. The resulting
+// tag is returned after canonicalizing using the Default CanonType. If one or
+// more errors are encountered, one of the errors is returned.
+func Compose(part ...interface{}) (t Tag, err error) {
+ return Default.Compose(part...)
+}
+
+// Compose creates a Tag from individual parts, which may be of type Tag, Base,
+// Script, Region, Variant, []Variant, Extension, []Extension or error. If a
+// Base, Script or Region or slice of type Variant or Extension is passed more
+// than once, the latter will overwrite the former. Variants and Extensions are
+// accumulated, but if two extensions of the same type are passed, the latter
+// will replace the former. For -u extensions, though, the key-type pairs are
+// added, where later values overwrite older ones. A Tag overwrites all former
+// values and typically only makes sense as the first argument. The resulting
+// tag is returned after canonicalizing using CanonType c. If one or more errors
+// are encountered, one of the errors is returned.
+func (c CanonType) Compose(part ...interface{}) (t Tag, err error) {
+ defer func() {
+ if recover() != nil {
+ t = Tag{}
+ err = language.ErrSyntax
+ }
+ }()
+
+ var b language.Builder
+ if err = update(&b, part...); err != nil {
+ return und, err
+ }
+ b.Tag, _ = canonicalize(c, b.Tag)
+ return makeTag(b.Make()), err
+}
+
+var errInvalidArgument = errors.New("invalid Extension or Variant")
+
+func update(b *language.Builder, part ...interface{}) (err error) {
+ for _, x := range part {
+ switch v := x.(type) {
+ case Tag:
+ b.SetTag(v.tag())
+ case Base:
+ b.Tag.LangID = v.langID
+ case Script:
+ b.Tag.ScriptID = v.scriptID
+ case Region:
+ b.Tag.RegionID = v.regionID
+ case Variant:
+ if v.variant == "" {
+ err = errInvalidArgument
+ break
+ }
+ b.AddVariant(v.variant)
+ case Extension:
+ if v.s == "" {
+ err = errInvalidArgument
+ break
+ }
+ b.SetExt(v.s)
+ case []Variant:
+ b.ClearVariants()
+ for _, v := range v {
+ b.AddVariant(v.variant)
+ }
+ case []Extension:
+ b.ClearExtensions()
+ for _, e := range v {
+ b.SetExt(e.s)
+ }
+ // TODO: support parsing of raw strings based on morphology or just extensions?
+ case error:
+ if v != nil {
+ err = v
+ }
+ }
+ }
+ return
+}
+
+var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight")
+var errTagListTooLarge = errors.New("tag list exceeds max length")
+
+// ParseAcceptLanguage parses the contents of an Accept-Language header as
+// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and
+// a list of corresponding quality weights. It is more permissive than RFC 2616
+// and may return non-nil slices even if the input is not valid.
+// The Tags will be sorted by highest weight first and then by first occurrence.
+// Tags with a weight of zero will be dropped. An error will be returned if the
+// input could not be parsed.
+func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) {
+ defer func() {
+ if recover() != nil {
+ tag = nil
+ q = nil
+ err = language.ErrSyntax
+ }
+ }()
+
+ if strings.Count(s, "-") > 1000 {
+ return nil, nil, errTagListTooLarge
+ }
+
+ var entry string
+ for s != "" {
+ if entry, s = split(s, ','); entry == "" {
+ continue
+ }
+
+ entry, weight := split(entry, ';')
+
+ // Scan the language.
+ t, err := Parse(entry)
+ if err != nil {
+ id, ok := acceptFallback[entry]
+ if !ok {
+ return nil, nil, err
+ }
+ t = makeTag(language.Tag{LangID: id})
+ }
+
+ // Scan the optional weight.
+ w := 1.0
+ if weight != "" {
+ weight = consume(weight, 'q')
+ weight = consume(weight, '=')
+ // consume returns the empty string when a token could not be
+ // consumed, resulting in an error for ParseFloat.
+ if w, err = strconv.ParseFloat(weight, 32); err != nil {
+ return nil, nil, errInvalidWeight
+ }
+ // Drop tags with a quality weight of 0.
+ if w <= 0 {
+ continue
+ }
+ }
+
+ tag = append(tag, t)
+ q = append(q, float32(w))
+ }
+ sort.Stable(&tagSort{tag, q})
+ return tag, q, nil
+}
+
+// consume removes a leading token c from s and returns the result or the empty
+// string if there is no such token.
+func consume(s string, c byte) string {
+ if s == "" || s[0] != c {
+ return ""
+ }
+ return strings.TrimSpace(s[1:])
+}
+
+func split(s string, c byte) (head, tail string) {
+ if i := strings.IndexByte(s, c); i >= 0 {
+ return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+1:])
+ }
+ return strings.TrimSpace(s), ""
+}
+
+// Add hack mapping to deal with a small number of cases that occur
+// in Accept-Language (with reasonable frequency).
+var acceptFallback = map[string]language.Language{
+ "english": _en,
+ "deutsch": _de,
+ "italian": _it,
+ "french": _fr,
+ "*": _mul, // defined in the spec to match all languages.
+}
+
+type tagSort struct {
+ tag []Tag
+ q []float32
+}
+
+func (s *tagSort) Len() int {
+ return len(s.q)
+}
+
+func (s *tagSort) Less(i, j int) bool {
+ return s.q[i] > s.q[j]
+}
+
+func (s *tagSort) Swap(i, j int) {
+ s.tag[i], s.tag[j] = s.tag[j], s.tag[i]
+ s.q[i], s.q[j] = s.q[j], s.q[i]
+}
diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go
new file mode 100644
index 000000000..a6573dcb2
--- /dev/null
+++ b/vendor/golang.org/x/text/language/tables.go
@@ -0,0 +1,298 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package language
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "32"
+
+const (
+ _de = 269
+ _en = 313
+ _fr = 350
+ _it = 505
+ _mo = 784
+ _no = 879
+ _nb = 839
+ _pt = 960
+ _sh = 1031
+ _mul = 806
+ _und = 0
+)
+const (
+ _001 = 1
+ _419 = 31
+ _BR = 65
+ _CA = 73
+ _ES = 111
+ _GB = 124
+ _MD = 189
+ _PT = 239
+ _UK = 307
+ _US = 310
+ _ZZ = 358
+ _XA = 324
+ _XC = 326
+ _XK = 334
+)
+const (
+ _Latn = 91
+ _Hani = 57
+ _Hans = 59
+ _Hant = 60
+ _Qaaa = 149
+ _Qaai = 157
+ _Qabx = 198
+ _Zinh = 255
+ _Zyyy = 260
+ _Zzzz = 261
+)
+
+var regionToGroups = []uint8{ // 359 elements
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04,
+ // Entry 40 - 7F
+ 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00,
+ 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
+ // Entry 80 - BF
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04,
+ // Entry C0 - FF
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x01, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 100 - 13F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04,
+ 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00,
+ // Entry 140 - 17F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+} // Size: 383 bytes
+
+var paradigmLocales = [][3]uint16{ // 3 elements
+ 0: [3]uint16{0x139, 0x0, 0x7c},
+ 1: [3]uint16{0x13e, 0x0, 0x1f},
+ 2: [3]uint16{0x3c0, 0x41, 0xef},
+} // Size: 42 bytes
+
+type mutualIntelligibility struct {
+ want uint16
+ have uint16
+ distance uint8
+ oneway bool
+}
+type scriptIntelligibility struct {
+ wantLang uint16
+ haveLang uint16
+ wantScript uint8
+ haveScript uint8
+ distance uint8
+}
+type regionIntelligibility struct {
+ lang uint16
+ script uint8
+ group uint8
+ distance uint8
+}
+
+// matchLang holds pairs of langIDs of base languages that are typically
+// mutually intelligible. Each pair is associated with a confidence and
+// whether the intelligibility goes one or both ways.
+var matchLang = []mutualIntelligibility{ // 113 elements
+ 0: {want: 0x1d1, have: 0xb7, distance: 0x4, oneway: false},
+ 1: {want: 0x407, have: 0xb7, distance: 0x4, oneway: false},
+ 2: {want: 0x407, have: 0x1d1, distance: 0x4, oneway: false},
+ 3: {want: 0x407, have: 0x432, distance: 0x4, oneway: false},
+ 4: {want: 0x43a, have: 0x1, distance: 0x4, oneway: false},
+ 5: {want: 0x1a3, have: 0x10d, distance: 0x4, oneway: true},
+ 6: {want: 0x295, have: 0x10d, distance: 0x4, oneway: true},
+ 7: {want: 0x101, have: 0x36f, distance: 0x8, oneway: false},
+ 8: {want: 0x101, have: 0x347, distance: 0x8, oneway: false},
+ 9: {want: 0x5, have: 0x3e2, distance: 0xa, oneway: true},
+ 10: {want: 0xd, have: 0x139, distance: 0xa, oneway: true},
+ 11: {want: 0x16, have: 0x367, distance: 0xa, oneway: true},
+ 12: {want: 0x21, have: 0x139, distance: 0xa, oneway: true},
+ 13: {want: 0x56, have: 0x13e, distance: 0xa, oneway: true},
+ 14: {want: 0x58, have: 0x3e2, distance: 0xa, oneway: true},
+ 15: {want: 0x71, have: 0x3e2, distance: 0xa, oneway: true},
+ 16: {want: 0x75, have: 0x139, distance: 0xa, oneway: true},
+ 17: {want: 0x82, have: 0x1be, distance: 0xa, oneway: true},
+ 18: {want: 0xa5, have: 0x139, distance: 0xa, oneway: true},
+ 19: {want: 0xb2, have: 0x15e, distance: 0xa, oneway: true},
+ 20: {want: 0xdd, have: 0x153, distance: 0xa, oneway: true},
+ 21: {want: 0xe5, have: 0x139, distance: 0xa, oneway: true},
+ 22: {want: 0xe9, have: 0x3a, distance: 0xa, oneway: true},
+ 23: {want: 0xf0, have: 0x15e, distance: 0xa, oneway: true},
+ 24: {want: 0xf9, have: 0x15e, distance: 0xa, oneway: true},
+ 25: {want: 0x100, have: 0x139, distance: 0xa, oneway: true},
+ 26: {want: 0x130, have: 0x139, distance: 0xa, oneway: true},
+ 27: {want: 0x13c, have: 0x139, distance: 0xa, oneway: true},
+ 28: {want: 0x140, have: 0x151, distance: 0xa, oneway: true},
+ 29: {want: 0x145, have: 0x13e, distance: 0xa, oneway: true},
+ 30: {want: 0x158, have: 0x101, distance: 0xa, oneway: true},
+ 31: {want: 0x16d, have: 0x367, distance: 0xa, oneway: true},
+ 32: {want: 0x16e, have: 0x139, distance: 0xa, oneway: true},
+ 33: {want: 0x16f, have: 0x139, distance: 0xa, oneway: true},
+ 34: {want: 0x17e, have: 0x139, distance: 0xa, oneway: true},
+ 35: {want: 0x190, have: 0x13e, distance: 0xa, oneway: true},
+ 36: {want: 0x194, have: 0x13e, distance: 0xa, oneway: true},
+ 37: {want: 0x1a4, have: 0x1be, distance: 0xa, oneway: true},
+ 38: {want: 0x1b4, have: 0x139, distance: 0xa, oneway: true},
+ 39: {want: 0x1b8, have: 0x139, distance: 0xa, oneway: true},
+ 40: {want: 0x1d4, have: 0x15e, distance: 0xa, oneway: true},
+ 41: {want: 0x1d7, have: 0x3e2, distance: 0xa, oneway: true},
+ 42: {want: 0x1d9, have: 0x139, distance: 0xa, oneway: true},
+ 43: {want: 0x1e7, have: 0x139, distance: 0xa, oneway: true},
+ 44: {want: 0x1f8, have: 0x139, distance: 0xa, oneway: true},
+ 45: {want: 0x20e, have: 0x1e1, distance: 0xa, oneway: true},
+ 46: {want: 0x210, have: 0x139, distance: 0xa, oneway: true},
+ 47: {want: 0x22d, have: 0x15e, distance: 0xa, oneway: true},
+ 48: {want: 0x242, have: 0x3e2, distance: 0xa, oneway: true},
+ 49: {want: 0x24a, have: 0x139, distance: 0xa, oneway: true},
+ 50: {want: 0x251, have: 0x139, distance: 0xa, oneway: true},
+ 51: {want: 0x265, have: 0x139, distance: 0xa, oneway: true},
+ 52: {want: 0x274, have: 0x48a, distance: 0xa, oneway: true},
+ 53: {want: 0x28a, have: 0x3e2, distance: 0xa, oneway: true},
+ 54: {want: 0x28e, have: 0x1f9, distance: 0xa, oneway: true},
+ 55: {want: 0x2a3, have: 0x139, distance: 0xa, oneway: true},
+ 56: {want: 0x2b5, have: 0x15e, distance: 0xa, oneway: true},
+ 57: {want: 0x2b8, have: 0x139, distance: 0xa, oneway: true},
+ 58: {want: 0x2be, have: 0x139, distance: 0xa, oneway: true},
+ 59: {want: 0x2c3, have: 0x15e, distance: 0xa, oneway: true},
+ 60: {want: 0x2ed, have: 0x139, distance: 0xa, oneway: true},
+ 61: {want: 0x2f1, have: 0x15e, distance: 0xa, oneway: true},
+ 62: {want: 0x2fa, have: 0x139, distance: 0xa, oneway: true},
+ 63: {want: 0x2ff, have: 0x7e, distance: 0xa, oneway: true},
+ 64: {want: 0x304, have: 0x139, distance: 0xa, oneway: true},
+ 65: {want: 0x30b, have: 0x3e2, distance: 0xa, oneway: true},
+ 66: {want: 0x31b, have: 0x1be, distance: 0xa, oneway: true},
+ 67: {want: 0x31f, have: 0x1e1, distance: 0xa, oneway: true},
+ 68: {want: 0x320, have: 0x139, distance: 0xa, oneway: true},
+ 69: {want: 0x331, have: 0x139, distance: 0xa, oneway: true},
+ 70: {want: 0x351, have: 0x139, distance: 0xa, oneway: true},
+ 71: {want: 0x36a, have: 0x347, distance: 0xa, oneway: false},
+ 72: {want: 0x36a, have: 0x36f, distance: 0xa, oneway: true},
+ 73: {want: 0x37a, have: 0x139, distance: 0xa, oneway: true},
+ 74: {want: 0x387, have: 0x139, distance: 0xa, oneway: true},
+ 75: {want: 0x389, have: 0x139, distance: 0xa, oneway: true},
+ 76: {want: 0x38b, have: 0x15e, distance: 0xa, oneway: true},
+ 77: {want: 0x390, have: 0x139, distance: 0xa, oneway: true},
+ 78: {want: 0x395, have: 0x139, distance: 0xa, oneway: true},
+ 79: {want: 0x39d, have: 0x139, distance: 0xa, oneway: true},
+ 80: {want: 0x3a5, have: 0x139, distance: 0xa, oneway: true},
+ 81: {want: 0x3be, have: 0x139, distance: 0xa, oneway: true},
+ 82: {want: 0x3c4, have: 0x13e, distance: 0xa, oneway: true},
+ 83: {want: 0x3d4, have: 0x10d, distance: 0xa, oneway: true},
+ 84: {want: 0x3d9, have: 0x139, distance: 0xa, oneway: true},
+ 85: {want: 0x3e5, have: 0x15e, distance: 0xa, oneway: true},
+ 86: {want: 0x3e9, have: 0x1be, distance: 0xa, oneway: true},
+ 87: {want: 0x3fa, have: 0x139, distance: 0xa, oneway: true},
+ 88: {want: 0x40c, have: 0x139, distance: 0xa, oneway: true},
+ 89: {want: 0x423, have: 0x139, distance: 0xa, oneway: true},
+ 90: {want: 0x429, have: 0x139, distance: 0xa, oneway: true},
+ 91: {want: 0x431, have: 0x139, distance: 0xa, oneway: true},
+ 92: {want: 0x43b, have: 0x139, distance: 0xa, oneway: true},
+ 93: {want: 0x43e, have: 0x1e1, distance: 0xa, oneway: true},
+ 94: {want: 0x445, have: 0x139, distance: 0xa, oneway: true},
+ 95: {want: 0x450, have: 0x139, distance: 0xa, oneway: true},
+ 96: {want: 0x461, have: 0x139, distance: 0xa, oneway: true},
+ 97: {want: 0x467, have: 0x3e2, distance: 0xa, oneway: true},
+ 98: {want: 0x46f, have: 0x139, distance: 0xa, oneway: true},
+ 99: {want: 0x476, have: 0x3e2, distance: 0xa, oneway: true},
+ 100: {want: 0x3883, have: 0x139, distance: 0xa, oneway: true},
+ 101: {want: 0x480, have: 0x139, distance: 0xa, oneway: true},
+ 102: {want: 0x482, have: 0x139, distance: 0xa, oneway: true},
+ 103: {want: 0x494, have: 0x3e2, distance: 0xa, oneway: true},
+ 104: {want: 0x49d, have: 0x139, distance: 0xa, oneway: true},
+ 105: {want: 0x4ac, have: 0x529, distance: 0xa, oneway: true},
+ 106: {want: 0x4b4, have: 0x139, distance: 0xa, oneway: true},
+ 107: {want: 0x4bc, have: 0x3e2, distance: 0xa, oneway: true},
+ 108: {want: 0x4e5, have: 0x15e, distance: 0xa, oneway: true},
+ 109: {want: 0x4f2, have: 0x139, distance: 0xa, oneway: true},
+ 110: {want: 0x512, have: 0x139, distance: 0xa, oneway: true},
+ 111: {want: 0x518, have: 0x139, distance: 0xa, oneway: true},
+ 112: {want: 0x52f, have: 0x139, distance: 0xa, oneway: true},
+} // Size: 702 bytes
+
+// matchScript holds pairs of scriptIDs where readers of one script
+// can typically also read the other. Each is associated with a confidence.
+var matchScript = []scriptIntelligibility{ // 26 elements
+ 0: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5b, haveScript: 0x20, distance: 0x5},
+ 1: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5b, distance: 0x5},
+ 2: {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
+ 3: {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5b, distance: 0xa},
+ 4: {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x20, distance: 0xa},
+ 5: {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5b, distance: 0xa},
+ 6: {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4f, haveScript: 0x5b, distance: 0xa},
+ 7: {wantLang: 0x251, haveLang: 0x139, wantScript: 0x53, haveScript: 0x5b, distance: 0xa},
+ 8: {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x58, haveScript: 0x5b, distance: 0xa},
+ 9: {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6f, haveScript: 0x5b, distance: 0xa},
+ 10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x76, haveScript: 0x5b, distance: 0xa},
+ 11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5b, distance: 0xa},
+ 12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x83, haveScript: 0x5b, distance: 0xa},
+ 13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5b, distance: 0xa},
+ 14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
+ 15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
+ 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd6, haveScript: 0x5b, distance: 0xa},
+ 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5b, distance: 0xa},
+ 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe9, haveScript: 0x5b, distance: 0xa},
+ 19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5b, distance: 0xa},
+ 20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
+ 21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
+ 22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
+ 23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5b, distance: 0xa},
+ 24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3b, haveScript: 0x3c, distance: 0xf},
+ 25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3c, haveScript: 0x3b, distance: 0x13},
+} // Size: 232 bytes
+
+var matchRegion = []regionIntelligibility{ // 15 elements
+ 0: {lang: 0x3a, script: 0x0, group: 0x4, distance: 0x4},
+ 1: {lang: 0x3a, script: 0x0, group: 0x84, distance: 0x4},
+ 2: {lang: 0x139, script: 0x0, group: 0x1, distance: 0x4},
+ 3: {lang: 0x139, script: 0x0, group: 0x81, distance: 0x4},
+ 4: {lang: 0x13e, script: 0x0, group: 0x3, distance: 0x4},
+ 5: {lang: 0x13e, script: 0x0, group: 0x83, distance: 0x4},
+ 6: {lang: 0x3c0, script: 0x0, group: 0x3, distance: 0x4},
+ 7: {lang: 0x3c0, script: 0x0, group: 0x83, distance: 0x4},
+ 8: {lang: 0x529, script: 0x3c, group: 0x2, distance: 0x4},
+ 9: {lang: 0x529, script: 0x3c, group: 0x82, distance: 0x4},
+ 10: {lang: 0x3a, script: 0x0, group: 0x80, distance: 0x5},
+ 11: {lang: 0x139, script: 0x0, group: 0x80, distance: 0x5},
+ 12: {lang: 0x13e, script: 0x0, group: 0x80, distance: 0x5},
+ 13: {lang: 0x3c0, script: 0x0, group: 0x80, distance: 0x5},
+ 14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
+} // Size: 114 bytes
+
+// Total table size 1473 bytes (1KiB); checksum: 7BB90B5C
diff --git a/vendor/golang.org/x/text/language/tags.go b/vendor/golang.org/x/text/language/tags.go
new file mode 100644
index 000000000..42ea79266
--- /dev/null
+++ b/vendor/golang.org/x/text/language/tags.go
@@ -0,0 +1,145 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import "golang.org/x/text/internal/language/compact"
+
+// TODO: Various sets of commonly use tags and regions.
+
+// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
+// It simplifies safe initialization of Tag values.
+func MustParse(s string) Tag {
+ t, err := Parse(s)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
+// It simplifies safe initialization of Tag values.
+func (c CanonType) MustParse(s string) Tag {
+ t, err := c.Parse(s)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// MustParseBase is like ParseBase, but panics if the given base cannot be parsed.
+// It simplifies safe initialization of Base values.
+func MustParseBase(s string) Base {
+ b, err := ParseBase(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+// MustParseScript is like ParseScript, but panics if the given script cannot be
+// parsed. It simplifies safe initialization of Script values.
+func MustParseScript(s string) Script {
+ scr, err := ParseScript(s)
+ if err != nil {
+ panic(err)
+ }
+ return scr
+}
+
+// MustParseRegion is like ParseRegion, but panics if the given region cannot be
+// parsed. It simplifies safe initialization of Region values.
+func MustParseRegion(s string) Region {
+ r, err := ParseRegion(s)
+ if err != nil {
+ panic(err)
+ }
+ return r
+}
+
+var (
+ und = Tag{}
+
+ Und Tag = Tag{}
+
+ Afrikaans Tag = Tag(compact.Afrikaans)
+ Amharic Tag = Tag(compact.Amharic)
+ Arabic Tag = Tag(compact.Arabic)
+ ModernStandardArabic Tag = Tag(compact.ModernStandardArabic)
+ Azerbaijani Tag = Tag(compact.Azerbaijani)
+ Bulgarian Tag = Tag(compact.Bulgarian)
+ Bengali Tag = Tag(compact.Bengali)
+ Catalan Tag = Tag(compact.Catalan)
+ Czech Tag = Tag(compact.Czech)
+ Danish Tag = Tag(compact.Danish)
+ German Tag = Tag(compact.German)
+ Greek Tag = Tag(compact.Greek)
+ English Tag = Tag(compact.English)
+ AmericanEnglish Tag = Tag(compact.AmericanEnglish)
+ BritishEnglish Tag = Tag(compact.BritishEnglish)
+ Spanish Tag = Tag(compact.Spanish)
+ EuropeanSpanish Tag = Tag(compact.EuropeanSpanish)
+ LatinAmericanSpanish Tag = Tag(compact.LatinAmericanSpanish)
+ Estonian Tag = Tag(compact.Estonian)
+ Persian Tag = Tag(compact.Persian)
+ Finnish Tag = Tag(compact.Finnish)
+ Filipino Tag = Tag(compact.Filipino)
+ French Tag = Tag(compact.French)
+ CanadianFrench Tag = Tag(compact.CanadianFrench)
+ Gujarati Tag = Tag(compact.Gujarati)
+ Hebrew Tag = Tag(compact.Hebrew)
+ Hindi Tag = Tag(compact.Hindi)
+ Croatian Tag = Tag(compact.Croatian)
+ Hungarian Tag = Tag(compact.Hungarian)
+ Armenian Tag = Tag(compact.Armenian)
+ Indonesian Tag = Tag(compact.Indonesian)
+ Icelandic Tag = Tag(compact.Icelandic)
+ Italian Tag = Tag(compact.Italian)
+ Japanese Tag = Tag(compact.Japanese)
+ Georgian Tag = Tag(compact.Georgian)
+ Kazakh Tag = Tag(compact.Kazakh)
+ Khmer Tag = Tag(compact.Khmer)
+ Kannada Tag = Tag(compact.Kannada)
+ Korean Tag = Tag(compact.Korean)
+ Kirghiz Tag = Tag(compact.Kirghiz)
+ Lao Tag = Tag(compact.Lao)
+ Lithuanian Tag = Tag(compact.Lithuanian)
+ Latvian Tag = Tag(compact.Latvian)
+ Macedonian Tag = Tag(compact.Macedonian)
+ Malayalam Tag = Tag(compact.Malayalam)
+ Mongolian Tag = Tag(compact.Mongolian)
+ Marathi Tag = Tag(compact.Marathi)
+ Malay Tag = Tag(compact.Malay)
+ Burmese Tag = Tag(compact.Burmese)
+ Nepali Tag = Tag(compact.Nepali)
+ Dutch Tag = Tag(compact.Dutch)
+ Norwegian Tag = Tag(compact.Norwegian)
+ Punjabi Tag = Tag(compact.Punjabi)
+ Polish Tag = Tag(compact.Polish)
+ Portuguese Tag = Tag(compact.Portuguese)
+ BrazilianPortuguese Tag = Tag(compact.BrazilianPortuguese)
+ EuropeanPortuguese Tag = Tag(compact.EuropeanPortuguese)
+ Romanian Tag = Tag(compact.Romanian)
+ Russian Tag = Tag(compact.Russian)
+ Sinhala Tag = Tag(compact.Sinhala)
+ Slovak Tag = Tag(compact.Slovak)
+ Slovenian Tag = Tag(compact.Slovenian)
+ Albanian Tag = Tag(compact.Albanian)
+ Serbian Tag = Tag(compact.Serbian)
+ SerbianLatin Tag = Tag(compact.SerbianLatin)
+ Swedish Tag = Tag(compact.Swedish)
+ Swahili Tag = Tag(compact.Swahili)
+ Tamil Tag = Tag(compact.Tamil)
+ Telugu Tag = Tag(compact.Telugu)
+ Thai Tag = Tag(compact.Thai)
+ Turkish Tag = Tag(compact.Turkish)
+ Ukrainian Tag = Tag(compact.Ukrainian)
+ Urdu Tag = Tag(compact.Urdu)
+ Uzbek Tag = Tag(compact.Uzbek)
+ Vietnamese Tag = Tag(compact.Vietnamese)
+ Chinese Tag = Tag(compact.Chinese)
+ SimplifiedChinese Tag = Tag(compact.SimplifiedChinese)
+ TraditionalChinese Tag = Tag(compact.TraditionalChinese)
+ Zulu Tag = Tag(compact.Zulu)
+)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 78e45c80e..a9c8c2219 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -55,6 +55,9 @@ dario.cat/mergo
# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0
## explicit; go 1.24.0
github.com/Azure/azure-sdk-for-go/sdk/azcore
+github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource
+github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy
+github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime
github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud
github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported
github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log
@@ -71,6 +74,10 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime
github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming
github.com/Azure/azure-sdk-for-go/sdk/azcore/to
github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing
+# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
+## explicit; go 1.23.0
+github.com/Azure/azure-sdk-for-go/sdk/azidentity
+github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal
# github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2
## explicit; go 1.23.0
github.com/Azure/azure-sdk-for-go/sdk/internal/diag
@@ -99,6 +106,30 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/service
## explicit; go 1.16
github.com/Azure/go-ansiterm
github.com/Azure/go-ansiterm/winterm
+# github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0
+## explicit; go 1.18
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity
+github.com/AzureAD/microsoft-authentication-library-for-go/apps/public
# github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0
## explicit; go 1.24.0
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp
@@ -268,6 +299,9 @@ github.com/aws/smithy-go/tracing
github.com/aws/smithy-go/transport/http
github.com/aws/smithy-go/transport/http/internal/io
github.com/aws/smithy-go/waiter
+# github.com/ccoveille/go-safecast/v2 v2.0.0
+## explicit; go 1.21
+github.com/ccoveille/go-safecast/v2
# github.com/cenkalti/backoff/v4 v4.3.0
## explicit; go 1.18
github.com/cenkalti/backoff/v4
@@ -303,6 +337,9 @@ github.com/cpuguy83/dockercfg
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
+# github.com/deckarep/golang-set/v2 v2.6.0
+## explicit; go 1.18
+github.com/deckarep/golang-set/v2
# github.com/distribution/reference v0.6.0
## explicit; go 1.20
github.com/distribution/reference
@@ -399,6 +436,7 @@ github.com/go-viper/mapstructure/v2
github.com/go-viper/mapstructure/v2/internal/errors
# github.com/golang-jwt/jwt/v5 v5.3.1
## explicit; go 1.21
+github.com/golang-jwt/jwt/v5
# github.com/golang/snappy v1.0.0
## explicit
github.com/golang/snappy
@@ -468,6 +506,7 @@ github.com/klauspost/compress/internal/le
github.com/klauspost/compress/internal/race
github.com/klauspost/compress/internal/snapref
github.com/klauspost/compress/s2
+github.com/klauspost/compress/snappy
github.com/klauspost/compress/zstd
github.com/klauspost/compress/zstd/internal/xxhash
# github.com/klauspost/cpuid/v2 v2.3.0
@@ -479,6 +518,10 @@ github.com/klauspost/crc32
# github.com/klauspost/pgzip v1.2.6
## explicit
github.com/klauspost/pgzip
+# github.com/kylelemons/godebug v1.1.0
+## explicit; go 1.11
+github.com/kylelemons/godebug/diff
+github.com/kylelemons/godebug/pretty
# github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0
## explicit; go 1.16
github.com/lufia/plan9stats
@@ -561,8 +604,9 @@ github.com/moby/sys/userns
## explicit; go 1.18
github.com/moby/term
github.com/moby/term/windows
-# github.com/mongodb/mongo-tools v0.0.0-20240723193119-837c2bc263f4
-## explicit; go 1.21
+# github.com/mongodb/mongo-tools v0.0.0-20260424130528-bbe4099afe32
+## explicit; go 1.25.9
+github.com/mongodb/mongo-tools/common
github.com/mongodb/mongo-tools/common/archive
github.com/mongodb/mongo-tools/common/auth
github.com/mongodb/mongo-tools/common/bsonutil
@@ -579,11 +623,9 @@ github.com/mongodb/mongo-tools/common/progress
github.com/mongodb/mongo-tools/common/text
github.com/mongodb/mongo-tools/common/txn
github.com/mongodb/mongo-tools/common/util
+github.com/mongodb/mongo-tools/common/wcwrapper
github.com/mongodb/mongo-tools/mongorestore
github.com/mongodb/mongo-tools/mongorestore/ns
-# github.com/montanaflynn/stats v0.7.1
-## explicit; go 1.13
-github.com/montanaflynn/stats
# github.com/opencontainers/go-digest v1.0.0
## explicit; go 1.13
github.com/opencontainers/go-digest
@@ -605,6 +647,9 @@ github.com/philhofer/fwd
## explicit
github.com/pierrec/lz4
github.com/pierrec/lz4/internal/xxh32
+# github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
+## explicit; go 1.14
+github.com/pkg/browser
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
@@ -630,6 +675,12 @@ github.com/rs/xid
## explicit; go 1.23.0
github.com/sagikazarmark/locafero
github.com/sagikazarmark/locafero/internal/queue
+# github.com/samber/lo v1.49.1
+## explicit; go 1.18
+github.com/samber/lo
+github.com/samber/lo/internal/constraints
+github.com/samber/lo/internal/rand
+github.com/samber/lo/mutable
# github.com/shirou/gopsutil/v4 v4.26.3
## explicit; go 1.24.0
github.com/shirou/gopsutil/v4/common
@@ -723,61 +774,58 @@ github.com/youmark/pkcs8
# github.com/yusufpapurcu/wmi v1.2.4
## explicit; go 1.16
github.com/yusufpapurcu/wmi
-# go.mongodb.org/mongo-driver v1.17.9
-## explicit; go 1.18
-go.mongodb.org/mongo-driver/bson
-go.mongodb.org/mongo-driver/bson/bsoncodec
-go.mongodb.org/mongo-driver/bson/bsonoptions
-go.mongodb.org/mongo-driver/bson/bsonrw
-go.mongodb.org/mongo-driver/bson/bsontype
-go.mongodb.org/mongo-driver/bson/primitive
-go.mongodb.org/mongo-driver/event
-go.mongodb.org/mongo-driver/internal/assert
-go.mongodb.org/mongo-driver/internal/aws
-go.mongodb.org/mongo-driver/internal/aws/awserr
-go.mongodb.org/mongo-driver/internal/aws/credentials
-go.mongodb.org/mongo-driver/internal/aws/signer/v4
-go.mongodb.org/mongo-driver/internal/bsonutil
-go.mongodb.org/mongo-driver/internal/codecutil
-go.mongodb.org/mongo-driver/internal/credproviders
-go.mongodb.org/mongo-driver/internal/csfle
-go.mongodb.org/mongo-driver/internal/csot
-go.mongodb.org/mongo-driver/internal/driverutil
-go.mongodb.org/mongo-driver/internal/handshake
-go.mongodb.org/mongo-driver/internal/httputil
-go.mongodb.org/mongo-driver/internal/integtest
-go.mongodb.org/mongo-driver/internal/logger
-go.mongodb.org/mongo-driver/internal/ptrutil
-go.mongodb.org/mongo-driver/internal/rand
-go.mongodb.org/mongo-driver/internal/randutil
-go.mongodb.org/mongo-driver/internal/require
-go.mongodb.org/mongo-driver/internal/uuid
-go.mongodb.org/mongo-driver/mongo
-go.mongodb.org/mongo-driver/mongo/address
-go.mongodb.org/mongo-driver/mongo/description
-go.mongodb.org/mongo-driver/mongo/integration/mtest
-go.mongodb.org/mongo-driver/mongo/options
-go.mongodb.org/mongo-driver/mongo/readconcern
-go.mongodb.org/mongo-driver/mongo/readpref
-go.mongodb.org/mongo-driver/mongo/writeconcern
-go.mongodb.org/mongo-driver/tag
-go.mongodb.org/mongo-driver/version
-go.mongodb.org/mongo-driver/x/bsonx/bsoncore
-go.mongodb.org/mongo-driver/x/mongo/driver
-go.mongodb.org/mongo-driver/x/mongo/driver/auth
-go.mongodb.org/mongo-driver/x/mongo/driver/auth/creds
-go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi
-go.mongodb.org/mongo-driver/x/mongo/driver/connstring
-go.mongodb.org/mongo-driver/x/mongo/driver/dns
-go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt
-go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options
-go.mongodb.org/mongo-driver/x/mongo/driver/ocsp
-go.mongodb.org/mongo-driver/x/mongo/driver/operation
-go.mongodb.org/mongo-driver/x/mongo/driver/session
-go.mongodb.org/mongo-driver/x/mongo/driver/topology
-go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage
-# go.mongodb.org/mongo-driver/v2 v2.5.0
+# go.mongodb.org/mongo-driver/v2 v2.6.0
## explicit; go 1.19
+go.mongodb.org/mongo-driver/v2/bson
+go.mongodb.org/mongo-driver/v2/event
+go.mongodb.org/mongo-driver/v2/internal/aws
+go.mongodb.org/mongo-driver/v2/internal/aws/awserr
+go.mongodb.org/mongo-driver/v2/internal/aws/credentials
+go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4
+go.mongodb.org/mongo-driver/v2/internal/binaryutil
+go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil
+go.mongodb.org/mongo-driver/v2/internal/bsonutil
+go.mongodb.org/mongo-driver/v2/internal/codecutil
+go.mongodb.org/mongo-driver/v2/internal/credproviders
+go.mongodb.org/mongo-driver/v2/internal/csfle
+go.mongodb.org/mongo-driver/v2/internal/csot
+go.mongodb.org/mongo-driver/v2/internal/decimal128
+go.mongodb.org/mongo-driver/v2/internal/driverutil
+go.mongodb.org/mongo-driver/v2/internal/handshake
+go.mongodb.org/mongo-driver/v2/internal/httputil
+go.mongodb.org/mongo-driver/v2/internal/logger
+go.mongodb.org/mongo-driver/v2/internal/mongoutil
+go.mongodb.org/mongo-driver/v2/internal/optionsutil
+go.mongodb.org/mongo-driver/v2/internal/ptrutil
+go.mongodb.org/mongo-driver/v2/internal/rand
+go.mongodb.org/mongo-driver/v2/internal/randutil
+go.mongodb.org/mongo-driver/v2/internal/serverselector
+go.mongodb.org/mongo-driver/v2/internal/uuid
+go.mongodb.org/mongo-driver/v2/mongo
+go.mongodb.org/mongo-driver/v2/mongo/address
+go.mongodb.org/mongo-driver/v2/mongo/options
+go.mongodb.org/mongo-driver/v2/mongo/readconcern
+go.mongodb.org/mongo-driver/v2/mongo/readpref
+go.mongodb.org/mongo-driver/v2/mongo/writeconcern
+go.mongodb.org/mongo-driver/v2/tag
+go.mongodb.org/mongo-driver/v2/version
+go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore
+go.mongodb.org/mongo-driver/v2/x/mongo/driver
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/description
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/session
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage
+go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions
# go.opentelemetry.io/auto/sdk v1.2.1
## explicit; go 1.24.0
go.opentelemetry.io/auto/sdk
@@ -856,12 +904,14 @@ golang.org/x/crypto/internal/alias
golang.org/x/crypto/internal/poly1305
golang.org/x/crypto/ocsp
golang.org/x/crypto/pbkdf2
+golang.org/x/crypto/pkcs12
+golang.org/x/crypto/pkcs12/internal/rc2
golang.org/x/crypto/scrypt
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
-golang.org/x/crypto/ssh/terminal
# golang.org/x/exp v0.0.0-20260209203927-2842357ff358
## explicit; go 1.24.0
+golang.org/x/exp/maps
golang.org/x/exp/slices
# golang.org/x/mod v0.33.0
## explicit; go 1.24.0
@@ -906,11 +956,17 @@ golang.org/x/sys/windows/registry
golang.org/x/term
# golang.org/x/text v0.35.0
## explicit; go 1.25.0
+golang.org/x/text/cases
golang.org/x/text/encoding
golang.org/x/text/encoding/internal
golang.org/x/text/encoding/internal/identifier
golang.org/x/text/encoding/unicode
+golang.org/x/text/internal
+golang.org/x/text/internal/language
+golang.org/x/text/internal/language/compact
+golang.org/x/text/internal/tag
golang.org/x/text/internal/utf8internal
+golang.org/x/text/language
golang.org/x/text/runes
golang.org/x/text/secure/bidirule
golang.org/x/text/transform