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

Method QuerySingleAttribute

internal/storage/postgres/data_reader.go:204–260  ·  view source on GitHub ↗

QuerySingleAttribute retrieves a single attribute from the storage based on the given filter.

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

Source from the content-addressed store, hash-verified

202
203// QuerySingleAttribute retrieves a single attribute from the storage based on the given filter.
204func (r *DataReader) QuerySingleAttribute(ctx context.Context, tenantID string, filter *base.AttributeFilter, snap string) (attribute *base.Attribute, err error) {
205 // Start a new trace span and end it when the function exits.
206 ctx, span := internal.Tracer.Start(ctx, "data-reader.query-single-attribute")
207 defer span.End()
208
209 slog.DebugContext(ctx, "querying single attribute for tenant_id", slog.String("tenant_id", tenantID))
210
211 // Decode the snapshot value.
212 var st token.SnapToken
213 st, err = snapshot.EncodedToken{Value: snap}.Decode()
214 if err != nil {
215 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INTERNAL)
216 }
217
218 // Build the relationships query based on the provided filter and snapshot value.
219 var args []interface{}
220 builder := r.database.Builder.Select("entity_type, entity_id, attribute, value").From(AttributesTable).Where(squirrel.Eq{"tenant_id": tenantID})
221 builder = utils.AttributesFilterQueryForSelectBuilder(builder, filter)
222 builder = utils.SnapshotQuery(builder, st.(snapshot.Token).Value.Uint, st.(snapshot.Token).Snapshot)
223
224 // Generate the SQL query and arguments.
225 var query string
226 query, args, err = builder.ToSql()
227 if err != nil {
228 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SQL_BUILDER)
229 }
230
231 slog.DebugContext(ctx, "generated sql query", slog.String("query", query), "with args", slog.Any("arguments", args))
232 // Execute query
233 row := r.database.ReadPool.QueryRow(ctx, query, args...)
234
235 rt := storage.Attribute{}
236
237 // Suppose you have a struct `rt` with a field `Value` of type `*anypb.Any`.
238 var valueStr string
239
240 // Scan the row from the database into the fields of `rt` and `valueStr`.
241 err = row.Scan(&rt.EntityType, &rt.EntityID, &rt.Attribute, &valueStr)
242 if err != nil {
243 if errors.Is(err, pgx.ErrNoRows) {
244 return nil, nil
245 } else {
246 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SCAN)
247 }
248 }
249
250 // Unmarshal the JSON data from `valueStr` into `rt.Value`.
251 rt.Value = &anypb.Any{}
252 err = protojson.Unmarshal([]byte(valueStr), rt.Value)
253 if err != nil {
254 return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INTERNAL)
255 }
256
257 slog.DebugContext(ctx, "successfully retrieved Single attribute from the database")
258 // Return attribute
259 return rt.ToAttribute(), nil
260}
261

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 8

ToAttributeMethod · 0.95
HandleErrorFunction · 0.92
SnapshotQueryFunction · 0.92
StartMethod · 0.80
StringMethod · 0.65
DecodeMethod · 0.65
ScanMethod · 0.45

Tested by

no test coverage detected