MCPcopy
hub / github.com/pocketbase/pocketbase / expandRecords

Method expandRecords

core/record_query_expand.go:57–256  ·  view source on GitHub ↗

notes: - if fetchFunc is nil, dao.FindRecordsByIds will be used - all records are expected to be from the same collection - if maxNestedRels(6) is reached, the function returns nil ignoring the remaining expand path

(records []*Record, expandPath string, fetchFunc ExpandFetchFunc, recursionLevel int)

Source from the content-addressed store, hash-verified

55// - all records are expected to be from the same collection
56// - if maxNestedRels(6) is reached, the function returns nil ignoring the remaining expand path
57func (app *BaseApp) expandRecords(records []*Record, expandPath string, fetchFunc ExpandFetchFunc, recursionLevel int) error {
58 if fetchFunc == nil {
59 // load a default fetchFunc
60 fetchFunc = func(relCollection *Collection, relIds []string) ([]*Record, error) {
61 return app.FindRecordsByIds(relCollection.Id, relIds)
62 }
63 }
64
65 if expandPath == "" || recursionLevel > maxNestedRels || len(records) == 0 {
66 return nil
67 }
68
69 mainCollection := records[0].Collection()
70
71 var relField *RelationField
72 var relCollection *Collection
73
74 parts := strings.SplitN(expandPath, ".", 2)
75 var matches []string
76
77 // @todo remove the old syntax support
78 if strings.Contains(parts[0], "(") {
79 matches = indirectExpandRegexOld.FindStringSubmatch(parts[0])
80 if len(matches) == 3 {
81 log.Printf(
82 "%s expand format is deprecated and will be removed in the future. Consider replacing it with %s_via_%s.\n",
83 matches[0],
84 matches[1],
85 matches[2],
86 )
87 }
88 } else {
89 matches = indirectExpandRegex.FindStringSubmatch(parts[0])
90 }
91
92 if len(matches) == 3 {
93 indirectRel, _ := getCollectionByModelOrIdentifier(app, matches[1])
94 if indirectRel == nil {
95 return fmt.Errorf("couldn't find back-related collection %q", matches[1])
96 }
97
98 indirectRelField, _ := indirectRel.Fields.GetByName(matches[2]).(*RelationField)
99 if indirectRelField == nil || indirectRelField.CollectionId != mainCollection.Id {
100 return fmt.Errorf("couldn't find back-relation field %q in collection %q", matches[2], indirectRel.Name)
101 }
102
103 // add the related id(s) as a dynamic relation field value to
104 // allow further expand checks at later stage in a more unified manner
105 prepErr := func() error {
106 q := app.ConcurrentDB().Select("id").
107 From(indirectRel.Name).
108 Limit(1000) // the limit is arbitrary chosen and may change in the future
109
110 if indirectRelField.IsMultiple() {
111 q.AndWhere(dbx.Exists(dbx.NewExp(fmt.Sprintf(
112 "SELECT 1 FROM %s je WHERE je.value = {:id}",
113 dbutils.JSONEach(indirectRelField.Name),
114 ))))

Callers 1

ExpandRecordsMethod · 0.95

Calls 15

FindRecordsByIdsMethod · 0.95
ConcurrentDBMethod · 0.95
IsMultipleMethod · 0.95
JSONEachFunction · 0.92
CollectionMethod · 0.80
GetByNameMethod · 0.80
SelectMethod · 0.80
GetStringSliceMethod · 0.80
SetExpandMethod · 0.80
ExpandMethod · 0.80

Tested by

no test coverage detected