MCPcopy Create free account
hub / github.com/Permify/permify / ReadRelationships

Method ReadRelationships

internal/storage/memory/data_reader.go:116–169  ·  view source on GitHub ↗

ReadRelationships reads relationships from the database taking into account the pagination.

(_ context.Context, tenantID string, filter *base.TupleFilter, _ string, pagination database.Pagination)

Source from the content-addressed store, hash-verified

114
115// ReadRelationships reads relationships from the database taking into account the pagination.
116func (r *DataReader) ReadRelationships(_ context.Context, tenantID string, filter *base.TupleFilter, _ string, pagination database.Pagination) (collection *database.TupleCollection, ct database.EncodedContinuousToken, err error) {
117 txn := r.database.DB.Txn(false)
118 defer txn.Abort()
119
120 var lowerBound uint64
121 if pagination.Token() != "" {
122 var t database.ContinuousToken
123 t, err = utils.EncodedContinuousToken{Value: pagination.Token()}.Decode()
124 if err != nil {
125 return nil, database.NewNoopContinuousToken().Encode(), err
126 }
127 lowerBound, err = strconv.ParseUint(t.(utils.ContinuousToken).Value, 10, 64)
128 if err != nil {
129 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_INVALID_CONTINUOUS_TOKEN.String())
130 }
131 }
132
133 index, args := utils.GetRelationTuplesIndexNameAndArgsByFilters(tenantID, filter)
134
135 // Get the result iterator using lower bound.
136 var result memdb.ResultIterator
137 result, err = txn.LowerBound(constants.RelationTuplesTable, index, args...) // Query with lower bound
138 if err != nil {
139 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_EXECUTION.String())
140 }
141
142 // Filter the result iterator and add the tuples to the array.
143 tup := make([]storage.RelationTuple, 0, 10)
144 fit := memdb.NewFilterIterator(result, utils.FilterRelationTuplesQuery(tenantID, filter))
145 for obj := fit.Next(); obj != nil; obj = fit.Next() {
146 t, ok := obj.(storage.RelationTuple)
147 if !ok {
148 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_TYPE_CONVERSATION.String())
149 }
150 tup = append(tup, t)
151 }
152
153 // Sort the tuples and append them to the collection.
154 sort.Slice(tup, func(i, j int) bool {
155 return tup[i].ID < tup[j].ID
156 })
157
158 tuples := make([]*base.Tuple, 0, pagination.PageSize()+1)
159 for _, t := range tup {
160 if t.ID >= lowerBound {
161 tuples = append(tuples, t.ToTuple())
162 if pagination.PageSize() != 0 && len(tuples) > int(pagination.PageSize()) {
163 return database.NewTupleCollection(tuples[:pagination.PageSize()]...), utils.NewContinuousToken(strconv.FormatUint(t.ID, 10)).Encode(), nil
164 }
165 }
166 }
167
168 return database.NewTupleCollection(tuples...), database.NewNoopContinuousToken().Encode(), nil
169}
170
171// QuerySingleAttribute queries the database for a single attribute based on the provided filter.
172func (r *DataReader) QuerySingleAttribute(_ context.Context, tenantID string, filter *base.AttributeFilter, _ string) (attribute *base.Attribute, err error) {

Callers

nothing calls this directly

Implementers 5

NoopDataReaderinternal/storage/storage.go
DataReaderinternal/storage/proxies/circuitbreake
DataReaderinternal/storage/proxies/singleflight/
DataReaderinternal/storage/postgres/data_reader.
DataReaderinternal/storage/memory/data_reader.go

Calls 11

NewNoopContinuousTokenFunction · 0.92
NewTupleCollectionFunction · 0.92
NewContinuousTokenFunction · 0.92
TokenMethod · 0.80
PageSizeMethod · 0.80
ToTupleMethod · 0.80
DecodeMethod · 0.65
EncodeMethod · 0.65
StringMethod · 0.65

Tested by

no test coverage detected