datasource.gno

2.75 Kb ยท 103 lines
  1// Package datasource defines generic interfaces for datasources.
  2//
  3// Datasources contain a set of records which can optionally be
  4// taggable. Tags can optionally be used to filter records by taxonomy.
  5//
  6// Datasources can help in cases where the data sent during
  7// communication between different realms needs to be generic
  8// to avoid direct dependencies.
  9package datasource
 10
 11import "errors"
 12
 13// ErrInvalidRecord indicates that a datasource contains invalid records.
 14var ErrInvalidRecord = errors.New("datasource records is not valid")
 15
 16type (
 17	// Fields defines an interface for read-only fields.
 18	Fields interface {
 19		// Has checks whether a field exists.
 20		Has(name string) bool
 21
 22		// Get retrieves the value associated with the given field.
 23		Get(name string) (value any, found bool)
 24	}
 25
 26	// Record defines a datasource record.
 27	Record interface {
 28		// ID returns the unique record's identifier.
 29		ID() string
 30
 31		// String returns a string representation of the record.
 32		String() string
 33
 34		// Fields returns record fields and values.
 35		Fields() (Fields, error)
 36	}
 37
 38	// TaggableRecord defines a datasource record that supports tags.
 39	// Tags can be used to build a taxonomy to filter records by category.
 40	TaggableRecord interface {
 41		// Tags returns a list of tags for the record.
 42		Tags() []string
 43	}
 44
 45	// ContentRecord defines a datasource record that can return content.
 46	ContentRecord interface {
 47		// Content returns the record content.
 48		Content() (string, error)
 49	}
 50
 51	// Iterator defines an iterator of datasource records.
 52	Iterator interface {
 53		// Next returns true when a new record is available.
 54		Next() bool
 55
 56		// Err returns any error raised when reading records.
 57		Err() error
 58
 59		// Record returns the current record.
 60		Record() Record
 61	}
 62
 63	// Datasource defines a generic datasource.
 64	Datasource interface {
 65		// Records returns a new datasource records iterator.
 66		Records(Query) Iterator
 67
 68		// Size returns the total number of records in the datasource.
 69		// When -1 is returned it means datasource doesn't support size.
 70		Size() int
 71
 72		// Record returns a single datasource record.
 73		Record(id string) (Record, error)
 74	}
 75)
 76
 77// NewIterator returns a new record iterator for a datasource query.
 78func NewIterator(ds Datasource, options ...QueryOption) Iterator {
 79	return ds.Records(NewQuery(options...))
 80}
 81
 82// QueryRecords return a slice of records for a datasource query.
 83func QueryRecords(ds Datasource, options ...QueryOption) ([]Record, error) {
 84	var (
 85		records []Record
 86		query   = NewQuery(options...)
 87		iter    = ds.Records(query)
 88	)
 89
 90	for i := 0; i < query.Count && iter.Next(); i++ {
 91		r := iter.Record()
 92		if r == nil {
 93			return nil, ErrInvalidRecord
 94		}
 95
 96		records = append(records, r)
 97	}
 98
 99	if err := iter.Err(); err != nil {
100		return nil, err
101	}
102	return records, nil
103}