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}