Conditions | 16 |
Total Lines | 104 |
Code Lines | 58 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like engines.*LookupEngine.LookupSubject often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | package engines |
||
190 | func (engine *LookupEngine) LookupSubject(ctx context.Context, request *base.PermissionLookupSubjectRequest) (response *base.PermissionLookupSubjectResponse, err error) { |
||
191 | size := request.GetPageSize() |
||
192 | if size == 0 { |
||
193 | size = 1000 |
||
194 | } |
||
195 | |||
196 | var ids []string |
||
197 | var ct string |
||
198 | |||
199 | // Use the schema-based subject filter to get the list of subjects with the requested permission. |
||
200 | ids, err = NewSubjectFilter(engine.schemaReader, engine.dataReader, SubjectFilterConcurrencyLimit(engine.concurrencyLimit)).SubjectFilter(ctx, request) |
||
201 | if err != nil { |
||
202 | return nil, err |
||
203 | } |
||
204 | |||
205 | // Initialize excludedIds to be used in the query |
||
206 | var excludedIds []string |
||
207 | |||
208 | // Check if the wildcard '<>' is present in the ids.Ids or if it's formatted like "<>-1,2,3" |
||
209 | for _, id := range ids { |
||
210 | if id == ALL { |
||
211 | // Handle '<>' case: no exclusions, include all resources |
||
212 | excludedIds = nil |
||
213 | break |
||
214 | } else if strings.HasPrefix(id, ALL+"-") { |
||
215 | // Handle '<>-1,2,3' case: parse exclusions after '-' |
||
216 | excludedIds = strings.Split(strings.TrimPrefix(id, ALL+"-"), ",") |
||
217 | break |
||
218 | } |
||
219 | } |
||
220 | |||
221 | // If '<>' was found, query all subjects with exclusions if provided |
||
222 | if excludedIds != nil || slices.Contains(ids, ALL) { |
||
223 | resp, pct, err := engine.dataReader.QueryUniqueSubjectReferences( |
||
224 | ctx, |
||
225 | request.GetTenantId(), |
||
226 | request.GetSubjectReference(), |
||
227 | excludedIds, // Pass the exclusions if any |
||
228 | request.GetMetadata().GetSnapToken(), |
||
229 | database.NewPagination(database.Size(size), database.Token(request.GetContinuousToken())), |
||
230 | ) |
||
231 | if err != nil { |
||
232 | return nil, err |
||
233 | } |
||
234 | ct = pct.String() |
||
235 | |||
236 | // Return the list of entity IDs that have the required permission. |
||
237 | return &base.PermissionLookupSubjectResponse{ |
||
238 | SubjectIds: resp, |
||
239 | ContinuousToken: ct, |
||
240 | }, nil |
||
241 | } |
||
242 | |||
243 | start := "" |
||
244 | |||
245 | // Sort the IDs |
||
246 | sort.Strings(ids) |
||
247 | |||
248 | // Handle continuous token if present |
||
249 | if request.GetContinuousToken() != "" { |
||
250 | var t database.ContinuousToken |
||
251 | t, err := utils.EncodedContinuousToken{Value: request.GetContinuousToken()}.Decode() |
||
252 | if err != nil { |
||
253 | return nil, err |
||
254 | } |
||
255 | start = t.(utils.ContinuousToken).Value |
||
256 | } |
||
257 | |||
258 | // Since the incoming 'ids' are already filtered based on the continuous token, |
||
259 | // there is no need to decode or handle the continuous token manually. |
||
260 | // The startIndex is initialized to 0. |
||
261 | startIndex := 0 |
||
262 | |||
263 | if start != "" { |
||
264 | // Locate the position in the sorted list where the ID equals or exceeds the token value |
||
265 | for i, id := range ids { |
||
266 | if id >= start { |
||
267 | startIndex = i |
||
268 | break |
||
269 | } |
||
270 | } |
||
271 | } |
||
272 | |||
273 | // Convert size to int for compatibility with startIndex |
||
274 | pageSize := int(size) |
||
275 | |||
276 | // Calculate the end index based on the page size |
||
277 | end := startIndex + pageSize |
||
278 | if end > len(ids) { |
||
279 | end = len(ids) |
||
280 | } |
||
281 | |||
282 | // Generate the next continuous token if there are more results |
||
283 | if end < len(ids) { |
||
284 | ct = utils.NewContinuousToken(ids[end]).Encode().String() |
||
285 | } else { |
||
286 | ct = "" |
||
287 | } |
||
288 | |||
289 | // Return the paginated list of IDs |
||
290 | return &base.PermissionLookupSubjectResponse{ |
||
291 | SubjectIds: ids[startIndex:end], // Slice the IDs based on pagination |
||
292 | ContinuousToken: ct, // Return the next continuous token |
||
293 | }, nil |
||
294 | } |
||
322 |