// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
"net/http"
"time"
"github.com/go-faster/errors"
ht "github.com/ogen-go/ogen/http"
"github.com/ogen-go/ogen/middleware"
"github.com/ogen-go/ogen/ogenerrors"
"github.com/ogen-go/ogen/otelogen"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
"go.opentelemetry.io/otel/trace"
)
type codeRecorder struct {
http.ResponseWriter
status int
}
func (c *codeRecorder) WriteHeader(status int) {
c.status = status
c.ResponseWriter.WriteHeader(status)
}
func (c *codeRecorder) Unwrap() http.ResponseWriter {
return c.ResponseWriter
}
// handleCreateRecordsRequest handles createRecords operation.
//
// Create records in a table.
//
// POST /{baseId}/{tableIdOrName}
func (s *Server) handleCreateRecordsRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("createRecords"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/{baseId}/{tableIdOrName}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateRecordsOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: CreateRecordsOperation,
ID: "createRecords",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, CreateRecordsOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeCreateRecordsParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
request, rawBody, close, err := s.decodeCreateRecordsRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response *CreateRecordsResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: CreateRecordsOperation,
OperationSummary: "Create records in a table",
OperationID: "createRecords",
Body: request,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableIdOrName",
In: "path",
}: params.TableIdOrName,
},
Raw: r,
}
type (
Request = *CreateRecordsReq
Params = CreateRecordsParams
Response = *CreateRecordsResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackCreateRecordsParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.CreateRecords(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.CreateRecords(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeCreateRecordsResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleCreateTableRequest handles createTable operation.
//
// Create a new table in a base.
//
// POST /meta/bases/{baseId}/tables
func (s *Server) handleCreateTableRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("createTable"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/meta/bases/{baseId}/tables"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateTableOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: CreateTableOperation,
ID: "createTable",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, CreateTableOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeCreateTableParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
request, rawBody, close, err := s.decodeCreateTableRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response *Table
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: CreateTableOperation,
OperationSummary: "Create a new table in a base",
OperationID: "createTable",
Body: request,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
},
Raw: r,
}
type (
Request = *CreateTableReq
Params = CreateTableParams
Response = *Table
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackCreateTableParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.CreateTable(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.CreateTable(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeCreateTableResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleDeleteRecordsRequest handles deleteRecords operation.
//
// Delete records from a table.
//
// DELETE /{baseId}/{tableIdOrName}
func (s *Server) handleDeleteRecordsRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("deleteRecords"),
semconv.HTTPRequestMethodKey.String("DELETE"),
semconv.HTTPRouteKey.String("/{baseId}/{tableIdOrName}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteRecordsOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: DeleteRecordsOperation,
ID: "deleteRecords",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, DeleteRecordsOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeDeleteRecordsParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
var response *DeleteRecordsResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: DeleteRecordsOperation,
OperationSummary: "Delete records from a table",
OperationID: "deleteRecords",
Body: nil,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableIdOrName",
In: "path",
}: params.TableIdOrName,
{
Name: "records[]",
In: "query",
}: params.Records,
},
Raw: r,
}
type (
Request = struct{}
Params = DeleteRecordsParams
Response = *DeleteRecordsResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackDeleteRecordsParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.DeleteRecords(ctx, params)
return response, err
},
)
} else {
response, err = s.h.DeleteRecords(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeDeleteRecordsResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleGetRecordRequest handles getRecord operation.
//
// Get a single record.
//
// GET /{baseId}/{tableIdOrName}/{recordId}
func (s *Server) handleGetRecordRequest(args [3]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("getRecord"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/{baseId}/{tableIdOrName}/{recordId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), GetRecordOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: GetRecordOperation,
ID: "getRecord",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, GetRecordOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeGetRecordParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
var response *Record
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: GetRecordOperation,
OperationSummary: "Get a single record",
OperationID: "getRecord",
Body: nil,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableIdOrName",
In: "path",
}: params.TableIdOrName,
{
Name: "recordId",
In: "path",
}: params.RecordId,
},
Raw: r,
}
type (
Request = struct{}
Params = GetRecordParams
Response = *Record
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackGetRecordParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.GetRecord(ctx, params)
return response, err
},
)
} else {
response, err = s.h.GetRecord(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeGetRecordResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleListBasesRequest handles listBases operation.
//
// List all accessible bases.
//
// GET /meta/bases
func (s *Server) handleListBasesRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listBases"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/meta/bases"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ListBasesOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ListBasesOperation,
ID: "listBases",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, ListBasesOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
var rawBody []byte
var response *BaseListResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ListBasesOperation,
OperationSummary: "List all accessible bases",
OperationID: "listBases",
Body: nil,
RawBody: rawBody,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = struct{}
Params = struct{}
Response = *BaseListResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ListBases(ctx)
return response, err
},
)
} else {
response, err = s.h.ListBases(ctx)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeListBasesResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleListRecordsRequest handles listRecords operation.
//
// List records in a table.
//
// GET /{baseId}/{tableIdOrName}
func (s *Server) handleListRecordsRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listRecords"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/{baseId}/{tableIdOrName}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ListRecordsOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ListRecordsOperation,
ID: "listRecords",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, ListRecordsOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeListRecordsParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
var response *RecordListResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ListRecordsOperation,
OperationSummary: "List records in a table",
OperationID: "listRecords",
Body: nil,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableIdOrName",
In: "path",
}: params.TableIdOrName,
{
Name: "filterByFormula",
In: "query",
}: params.FilterByFormula,
{
Name: "maxRecords",
In: "query",
}: params.MaxRecords,
{
Name: "pageSize",
In: "query",
}: params.PageSize,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "view",
In: "query",
}: params.View,
{
Name: "sort[0][field]",
In: "query",
}: params.Sort0Field,
{
Name: "sort[0][direction]",
In: "query",
}: params.Sort0Direction,
{
Name: "sort[1][field]",
In: "query",
}: params.Sort1Field,
{
Name: "sort[1][direction]",
In: "query",
}: params.Sort1Direction,
{
Name: "sort[2][field]",
In: "query",
}: params.Sort2Field,
{
Name: "sort[2][direction]",
In: "query",
}: params.Sort2Direction,
},
Raw: r,
}
type (
Request = struct{}
Params = ListRecordsParams
Response = *RecordListResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackListRecordsParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ListRecords(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ListRecords(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeListRecordsResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleListTablesRequest handles listTables operation.
//
// Get tables schema for a base.
//
// GET /meta/bases/{baseId}/tables
func (s *Server) handleListTablesRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listTables"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/meta/bases/{baseId}/tables"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ListTablesOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ListTablesOperation,
ID: "listTables",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, ListTablesOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeListTablesParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
var response *TableListResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ListTablesOperation,
OperationSummary: "Get tables schema for a base",
OperationID: "listTables",
Body: nil,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
},
Raw: r,
}
type (
Request = struct{}
Params = ListTablesParams
Response = *TableListResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackListTablesParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ListTables(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ListTables(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeListTablesResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleUpdateRecordsRequest handles updateRecords operation.
//
// Update records in a table.
//
// PATCH /{baseId}/{tableIdOrName}
func (s *Server) handleUpdateRecordsRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("updateRecords"),
semconv.HTTPRequestMethodKey.String("PATCH"),
semconv.HTTPRouteKey.String("/{baseId}/{tableIdOrName}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateRecordsOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: UpdateRecordsOperation,
ID: "updateRecords",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, UpdateRecordsOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeUpdateRecordsParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
request, rawBody, close, err := s.decodeUpdateRecordsRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response *UpdateRecordsResponse
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: UpdateRecordsOperation,
OperationSummary: "Update records in a table",
OperationID: "updateRecords",
Body: request,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableIdOrName",
In: "path",
}: params.TableIdOrName,
},
Raw: r,
}
type (
Request = *UpdateRecordsReq
Params = UpdateRecordsParams
Response = *UpdateRecordsResponse
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackUpdateRecordsParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.UpdateRecords(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.UpdateRecords(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeUpdateRecordsResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleUpdateTableRequest handles updateTable operation.
//
// Update table metadata.
//
// PATCH /meta/bases/{baseId}/tables/{tableId}
func (s *Server) handleUpdateTableRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("updateTable"),
semconv.HTTPRequestMethodKey.String("PATCH"),
semconv.HTTPRouteKey.String("/meta/bases/{baseId}/tables/{tableId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateTableOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code < 100 || code >= 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: UpdateTableOperation,
ID: "updateTable",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityBearerAuth(ctx, UpdateTableOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "BearerAuth",
Err: err,
}
defer recordError("Security:BearerAuth", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeUpdateTableParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var rawBody []byte
request, rawBody, close, err := s.decodeUpdateTableRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response *Table
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: UpdateTableOperation,
OperationSummary: "Update table metadata",
OperationID: "updateTable",
Body: request,
RawBody: rawBody,
Params: middleware.Parameters{
{
Name: "baseId",
In: "path",
}: params.BaseId,
{
Name: "tableId",
In: "path",
}: params.TableId,
},
Raw: r,
}
type (
Request = *UpdateTableReq
Params = UpdateTableParams
Response = *Table
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackUpdateTableParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.UpdateTable(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.UpdateTable(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeUpdateTableResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}