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

Method ReadAttributes

internal/storage/memory/data_reader.go:274–328  ·  view source on GitHub ↗

ReadAttributes reads attributes from the database taking into account the pagination.

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

Source from the content-addressed store, hash-verified

272
273// ReadAttributes reads attributes from the database taking into account the pagination.
274func (r *DataReader) ReadAttributes(_ context.Context, tenantID string, filter *base.AttributeFilter, _ string, pagination database.Pagination) (collection *database.AttributeCollection, ct database.EncodedContinuousToken, err error) {
275 txn := r.database.DB.Txn(false)
276 defer txn.Abort()
277
278 var lowerBound uint64
279 if pagination.Token() != "" {
280 var t database.ContinuousToken
281 t, err = utils.EncodedContinuousToken{Value: pagination.Token()}.Decode()
282 if err != nil {
283 return nil, database.NewNoopContinuousToken().Encode(), err
284 }
285 lowerBound, err = strconv.ParseUint(t.(utils.ContinuousToken).Value, 10, 64)
286 if err != nil {
287 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_INVALID_CONTINUOUS_TOKEN.String())
288 }
289 }
290
291 // Get the index and arguments based on the filter.
292 index, args := utils.GetAttributesIndexNameAndArgsByFilters(tenantID, filter)
293
294 // Get the result iterator using lower bound.
295 var result memdb.ResultIterator
296 result, err = txn.LowerBound(constants.AttributesTable, index, args...)
297 if err != nil {
298 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_EXECUTION.String())
299 }
300
301 // Filter the result iterator and add the attributes to the array.
302 attr := make([]storage.Attribute, 0, 10)
303 fit := memdb.NewFilterIterator(result, utils.FilterAttributesQuery(tenantID, filter))
304 for obj := fit.Next(); obj != nil; obj = fit.Next() {
305 a, ok := obj.(storage.Attribute)
306 if !ok {
307 return nil, database.NewNoopContinuousToken().Encode(), errors.New(base.ErrorCode_ERROR_CODE_TYPE_CONVERSATION.String())
308 }
309 attr = append(attr, a)
310 }
311
312 // Sort the attributes and append them to the collection.
313 sort.Slice(attr, func(i, j int) bool {
314 return attr[i].ID < attr[j].ID
315 })
316
317 attributes := make([]*base.Attribute, 0, pagination.PageSize()+1)
318 for _, t := range attr {
319 if t.ID >= lowerBound {
320 attributes = append(attributes, t.ToAttribute())
321 if pagination.PageSize() != 0 && len(attributes) > int(pagination.PageSize()) {
322 return database.NewAttributeCollection(attributes[:pagination.PageSize()]...), utils.NewContinuousToken(strconv.FormatUint(t.ID, 10)).Encode(), nil
323 }
324 }
325 }
326
327 return database.NewAttributeCollection(attributes...), database.NewNoopContinuousToken().Encode(), nil
328}
329
330// QueryUniqueSubjectReferences is a function that searches for unique subject references in a given database.
331func (r *DataReader) QueryUniqueSubjectReferences(_ context.Context, tenantID string, subjectReference *base.RelationReference, excluded []string, _ string, pagination database.Pagination) (ids []string, _ database.EncodedContinuousToken, 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
FilterAttributesQueryFunction · 0.92
NewAttributeCollectionFunction · 0.92
NewContinuousTokenFunction · 0.92
TokenMethod · 0.80
PageSizeMethod · 0.80
ToAttributeMethod · 0.80
DecodeMethod · 0.65
EncodeMethod · 0.65
StringMethod · 0.65

Tested by

no test coverage detected