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

Method QueryAttributes

internal/storage/postgres/data_reader.go:263–349  ·  view source on GitHub ↗

QueryAttributes reads multiple attributes from the storage based on the given filter.

(ctx context.Context, tenantID string, filter *base.AttributeFilter, snap string, pagination database.CursorPagination)

Source from the content-addressed store, hash-verified

261
262// QueryAttributes reads multiple attributes from the storage based on the given filter.
263func (r *DataReader) QueryAttributes(ctx context.Context, tenantID string, filter *base.AttributeFilter, snap string, pagination database.CursorPagination) (it *database.AttributeIterator, err error) {
264 // Start a new trace span and end it when the function exits.
265 ctx, span := internal.Tracer.Start(ctx, "data-reader.query-attributes")
266 defer span.End()
267 // Log query operation
268 slog.DebugContext(ctx, "querying Attributes for tenant_id", slog.String("tenant_id", tenantID))
269 // Decode snapshot token
270 // Decode the snapshot value.
271 var st token.SnapToken
272 st, err = snapshot.EncodedToken{Value: snap}.Decode()
273 if err != nil {
274 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INTERNAL)
275 }
276
277 // Build the attributes query based on the provided filter and snapshot value.
278 var args []interface{}
279 builder := r.database.Builder.Select("entity_type, entity_id, attribute, value").From(AttributesTable).Where(squirrel.Eq{"tenant_id": tenantID})
280 builder = utils.AttributesFilterQueryForSelectBuilder(builder, filter)
281 builder = utils.SnapshotQuery(builder, st.(snapshot.Token).Value.Uint, st.(snapshot.Token).Snapshot)
282
283 if pagination.Cursor() != "" {
284 var t database.ContinuousToken
285 t, err = utils.EncodedContinuousToken{Value: pagination.Cursor()}.Decode()
286 if err != nil {
287 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INVALID_CONTINUOUS_TOKEN)
288 }
289 builder = builder.Where(squirrel.GtOrEq{pagination.Sort(): t.(utils.ContinuousToken).Value})
290 }
291
292 if pagination.Sort() != "" {
293 builder = builder.OrderBy(pagination.Sort())
294 }
295
296 // Apply limit if specified in pagination
297 limit := pagination.Limit()
298 if limit > 0 {
299 builder = builder.Limit(uint64(limit))
300 }
301
302 // Generate the SQL query and arguments.
303 var query string
304 query, args, err = builder.ToSql()
305 if err != nil {
306 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SQL_BUILDER)
307 }
308 // Log generated query
309 slog.DebugContext(ctx, "generated sql query", slog.String("query", query), "with args", slog.Any("arguments", args))
310 // Execute the SQL query and retrieve the result rows.
311 var rows pgx.Rows
312 rows, err = r.database.ReadPool.Query(ctx, query, args...)
313 if err != nil {
314 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_EXECUTION)
315 }
316 defer rows.Close()
317
318 // Process the result rows and store the attributes in an AttributeCollection.
319 collection := database.NewAttributeCollection()
320 for rows.Next() {

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 15

AddMethod · 0.95
ToAttributeMethod · 0.95
HandleErrorFunction · 0.92
SnapshotQueryFunction · 0.92
NewAttributeCollectionFunction · 0.92
StartMethod · 0.80
CursorMethod · 0.80
SortMethod · 0.80
StringMethod · 0.65
DecodeMethod · 0.65

Tested by

no test coverage detected