MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / expandPattern

Function expandPattern

db/functions/function.go:305–353  ·  view source on GitHub ↗

Expands patterns of the form `${param}` in `pattern`, looking up each such `param` in the `args` map and substituting its value. (`\$` is replaced with `$`.) It is an error if any `param` has no value, or if its value is not a string or integer.

(pattern string, args map[string]any, user auth.User)

Source from the content-addressed store, hash-verified

303// (`\$` is replaced with `$`.)
304// It is an error if any `param` has no value, or if its value is not a string or integer.
305func expandPattern(pattern string, args map[string]any, user auth.User) (string, error) {
306 if strings.IndexByte(pattern, '$') < 0 {
307 return pattern, nil
308 }
309 var err error
310 channel := kChannelPropertyRegexp.ReplaceAllStringFunc(pattern, func(matched string) string {
311 if err != nil {
312 return ""
313 } else if matched == "\\$" {
314 return "$"
315 } else if !strings.HasPrefix(matched, "${") || !strings.HasSuffix(matched, "}") {
316 err = base.HTTPErrorf(http.StatusInternalServerError, "missing curly-brace in pattern %q", matched)
317 return ""
318 }
319 arg := matched[2 : len(matched)-1]
320
321 // Look up the argument:
322 if strings.HasPrefix(arg, "args.") {
323 var rval reflect.Value
324 rval, err = evalKeyPath(args, arg[5:])
325 if err != nil {
326 return ""
327 }
328
329 // Convert `rval` to a string:
330 for rval.Kind() == reflect.Interface {
331 rval = rval.Elem()
332 }
333 if rval.Kind() == reflect.String {
334 return rval.String()
335 } else if rval.CanInt() || rval.CanUint() || rval.CanFloat() || rval.Kind() == reflect.Bool {
336 return fmt.Sprintf("%v", rval)
337 } else {
338 err = base.HTTPErrorf(http.StatusBadRequest, "argument %q must be a string or number or boolean, not %v", arg, rval.Kind())
339 return ""
340 }
341 } else if arg == "context.user.name" {
342 if user == nil {
343 return ""
344 } else {
345 return user.Name()
346 }
347 } else {
348 err = base.HTTPErrorf(http.StatusInternalServerError, "invalid variable expression %q", matched)
349 return ""
350 }
351 })
352 return channel, err
353}
354
355// Evaluates a "key path", like "points[3].x.y" on a JSON-based map.
356func evalKeyPath(root map[string]any, keyPath string) (reflect.Value, error) {

Callers 3

validateAllowMethod · 0.85
authorizeMethod · 0.85
TestUserFunctionAllowFunction · 0.85

Calls 4

HTTPErrorfFunction · 0.92
evalKeyPathFunction · 0.85
StringMethod · 0.65
NameMethod · 0.65

Tested by 1

TestUserFunctionAllowFunction · 0.68