github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/errorutil/tenant_deprecated_wrapper.go (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package errorutil
    12  
    13  // TenantSQLDeprecatedWrapper is a helper to annotate uses of components that
    14  // are in the progress of being phased out due to work towards multi-tenancy.
    15  // It is usually usually used under a layer of abstraction that is aware of
    16  // the wrapped object's type.
    17  //
    18  // Deprecated objects are broadly objects that reach deeply into the KV layer
    19  // and which will be inaccessible from a SQL tenant server. Their uses in SQL
    20  // fall into two categories:
    21  //
    22  //   - functionality essential for multi-tenancy, i.e. a use which will
    23  //     have to be removed before we can start SQL tenant servers.
    24  //   - non-essential functionality, which will be disabled when run in
    25  //     a SQL tenant server. It may or may not be a long-term goal to remove
    26  //     this usage; this is determined on a case-by-case basis.
    27  //
    28  // As work towards multi-tenancy is taking place, semi-dedicated SQL tenant
    29  // servers are supported. These are essentially SQL tenant servers that get
    30  // to reach into the KV layer as needed while the first category above is
    31  // being whittled down.
    32  //
    33  // This wrapper aids that process by offering two methods corresponding to
    34  // the categories above:
    35  //
    36  // Deprecated() trades in a reference to Github issue (tracking the removal of
    37  // an essential usage) for the wrapped object; OptionalErr() returns the wrapped
    38  // object only if the wrapper was set up to allow this.
    39  //
    40  // Note that the wrapped object will in fact always have to be present as long
    41  // as calls to Deprecated() exist. However, when running semi-dedicated SQL
    42  // tenants, the wrapper should be set up with exposed=false so that it can
    43  // pretend that the object is in fact not available.
    44  //
    45  // Finally, once all Deprecated() calls have been removed, it is possible to
    46  // treat the wrapper as a pure option type, i.e. wrap a nil value with
    47  // exposed=false.
    48  type TenantSQLDeprecatedWrapper struct {
    49  	v       interface{}
    50  	exposed bool
    51  }
    52  
    53  // MakeTenantSQLDeprecatedWrapper wraps an arbitrary object. When the 'exposed'
    54  // parameter is set to true, Optional() will return the object.
    55  func MakeTenantSQLDeprecatedWrapper(v interface{}, exposed bool) TenantSQLDeprecatedWrapper {
    56  	return TenantSQLDeprecatedWrapper{v: v, exposed: exposed}
    57  }
    58  
    59  // Optional returns the wrapped object if it is available (meaning that the
    60  // wrapper was set up to make it available). This should be called by
    61  // functionality that relies on the wrapped object but can be disabled when this
    62  // is desired.
    63  //
    64  // Optional functionality should be used sparingly as it increases the
    65  // maintenance and testing burden. It is preferable to use OptionalErr()
    66  // (and return the error) where possible.
    67  func (w TenantSQLDeprecatedWrapper) Optional() (interface{}, bool) {
    68  	if !w.exposed {
    69  		return nil, false
    70  	}
    71  	return w.v, true
    72  }
    73  
    74  // OptionalErr calls Optional and returns an error (referring to the optionally
    75  // supplied Github issues) if the wrapped object is not available.
    76  func (w TenantSQLDeprecatedWrapper) OptionalErr(issue int) (interface{}, error) {
    77  	v, ok := w.Optional()
    78  	if !ok {
    79  		return nil, UnsupportedUnderClusterVirtualization(issue)
    80  	}
    81  	return v, nil
    82  }