feat: implement field endpoints
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
package onspring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"iter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
fieldsPath = "/fields"
|
||||
)
|
||||
|
||||
// FieldsEndpoint provides access to fields in an Onspring instance.
|
||||
type FieldsEndpoint struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Field represents an Onspring field
|
||||
type Field struct {
|
||||
Id int `json:"id"`
|
||||
AppId int `json:"appId"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
IsRequired bool `json:"isRequired"`
|
||||
IsUnique bool `json:"isUnique"`
|
||||
TypeData any `json:"-"`
|
||||
}
|
||||
|
||||
// FormulaField represents a formula field type in Onspring
|
||||
type FormulaField struct {
|
||||
OutputType string `json:"outputType"`
|
||||
Values []string `json:"values"`
|
||||
}
|
||||
|
||||
// ReferenceField represents a reference field type in Onspring
|
||||
type ReferenceField struct {
|
||||
Multiplicity string `json:"multiplicity"`
|
||||
ReferenceAppId string `json:"referenceAppId"`
|
||||
}
|
||||
|
||||
// ListField represents a list field type in Onspring
|
||||
type ListField struct {
|
||||
Multiplicity string `json:"multiplicity"`
|
||||
Values []string `json:"values"`
|
||||
ListId int `json:"listId"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for Field.
|
||||
// This allows for custom deserialization logic based on the 'Type' field.
|
||||
func (f *Field) UnmarshalJSON(data []byte) error {
|
||||
type Alias Field
|
||||
|
||||
aux := &struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(f),
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, aux); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch f.Type {
|
||||
case "Formula":
|
||||
var formulaField FormulaField
|
||||
|
||||
if err := json.Unmarshal(data, &formulaField); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.TypeData = formulaField
|
||||
case "Reference":
|
||||
var referenceField ReferenceField
|
||||
|
||||
if err := json.Unmarshal(data, &referenceField); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.TypeData = referenceField
|
||||
case "List":
|
||||
var listField ListField
|
||||
|
||||
if err := json.Unmarshal(data, &listField); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.TypeData = listField
|
||||
default:
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldBatch represents a batch of Onspring fields
|
||||
type FieldBatch struct {
|
||||
Count int `json:"count"`
|
||||
Items []Field `json:"items"`
|
||||
}
|
||||
|
||||
// Get retrieves a field from the Onspring API.
|
||||
//
|
||||
// Parameters:
|
||||
// - ctx: The context for the request
|
||||
// - id: The id of the field to retrieve
|
||||
//
|
||||
// Returns:
|
||||
// - Field: A field
|
||||
// - error: An error if the request fails
|
||||
func (f *FieldsEndpoint) Get(ctx context.Context, id int) (Field, error) {
|
||||
path := fmt.Sprintf("%s/id/%d", fieldsPath, id)
|
||||
req, requestCreationErr := f.client.newRequest(ctx, http.MethodGet, path, nil, nil)
|
||||
|
||||
var field Field
|
||||
|
||||
if requestCreationErr != nil {
|
||||
return field, requestCreationErr
|
||||
}
|
||||
|
||||
responseErr := f.client.doWithJsonResponse(req, &field)
|
||||
|
||||
if responseErr != nil {
|
||||
return field, responseErr
|
||||
}
|
||||
|
||||
return field, nil
|
||||
}
|
||||
|
||||
// GetMany retrieves a batch of fields from the Onspring API.
|
||||
//
|
||||
// Parameters:
|
||||
// - ctx: The context for the request
|
||||
// - ids: The ids of the fields to retrieve
|
||||
//
|
||||
// Returns:
|
||||
// - FieldBatch: A batch of fields
|
||||
// - error: An error if the request fails
|
||||
func (f *FieldsEndpoint) GetMany(ctx context.Context, ids []int) (FieldBatch, error) {
|
||||
path := fmt.Sprintf("%s/batch-get", fieldsPath)
|
||||
req, requestCreationErr := f.client.newRequest(ctx, http.MethodPost, path, nil, ids)
|
||||
|
||||
var fieldBatch FieldBatch
|
||||
|
||||
if requestCreationErr != nil {
|
||||
return fieldBatch, requestCreationErr
|
||||
}
|
||||
|
||||
responseErr := f.client.doWithJsonResponse(req, &fieldBatch)
|
||||
|
||||
if responseErr != nil {
|
||||
return fieldBatch, responseErr
|
||||
}
|
||||
|
||||
return fieldBatch, nil
|
||||
}
|
||||
|
||||
// List retrieves a paginated list of fields from the Onspring API.
|
||||
//
|
||||
// Parameters:
|
||||
// - ctx: The context for the request
|
||||
// - appId: The id of the app to retrieve fields for
|
||||
// - pagingOpts: Optional paging configuration functions (e.g., ForPageNumber, WithPageSize)
|
||||
//
|
||||
// Returns:
|
||||
// - Page[Field]: A page of fields with pagination metadata
|
||||
// - error: An error if the request fails
|
||||
func (f *FieldsEndpoint) List(ctx context.Context, appId int, pagingOpts ...PagingOption) (Page[Field], error) {
|
||||
pagingRequest := createPagingRequest(pagingOpts)
|
||||
path := fmt.Sprintf("%s/appId/%d", fieldsPath, appId)
|
||||
|
||||
req, requestCreationErr := f.client.newRequest(ctx, http.MethodGet, path, pagingRequest.ToParams(), nil)
|
||||
|
||||
var page Page[Field]
|
||||
|
||||
if requestCreationErr != nil {
|
||||
return page, requestCreationErr
|
||||
}
|
||||
|
||||
responseErr := f.client.doWithJsonResponse(req, &page)
|
||||
|
||||
if responseErr != nil {
|
||||
return page, responseErr
|
||||
}
|
||||
|
||||
return page, nil
|
||||
}
|
||||
|
||||
// ListAll returns an iterator that yields all Fields for an app across all pages.
|
||||
// It automatically handles pagination by making sequential calls to List
|
||||
// until all items have been retrieved or the caller stops the iteration.
|
||||
//
|
||||
// The iterator yields each Field and any error encountered during fetching.
|
||||
// If an error occurs during a page request, the error is yielded and
|
||||
// iteration terminates.
|
||||
//
|
||||
// Parameters:
|
||||
// - ctx: The context for the request
|
||||
// - appId: The id of the app to retrieve fields for
|
||||
// - pagingOpts: Optional paging configuration functions (e.g., ForPageNumber, WithPageSize)
|
||||
//
|
||||
// Returns:
|
||||
// - iter.Seq2[Field, error]: An iterator yielding:
|
||||
// - Field: The individual field record.
|
||||
// - error: An error if a specific page request fails during iteration.
|
||||
func (f *FieldsEndpoint) ListAll(ctx context.Context, appId int, pagingOpts ...PagingOption) iter.Seq2[Field, error] {
|
||||
return func(yield func(Field, error) bool) {
|
||||
pagingRequest := createPagingRequest(pagingOpts)
|
||||
|
||||
for {
|
||||
page, err := f.List(ctx, appId, ForPageNumber(pagingRequest.PageNumber), WithPageSize(pagingRequest.PageSize))
|
||||
|
||||
if err != nil {
|
||||
yield(Field{}, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range page.Items {
|
||||
if !yield(item, nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if page.PageNumber >= page.TotalPages {
|
||||
break
|
||||
}
|
||||
|
||||
pagingRequest.PageNumber++
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user