---
title: Search application info logs
summary: Builds a dynamic filtered query over App_Info, always excludes EPAY/DirectDeposit by default, and returns up to 300 rows plus a matching total count.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Application.LogView
reference_type: package
operation_id: OP-LV-07
trigger: Caller invokes a clsAppInfoCollection.GetAppInfoCollection overload with zero or more filters
---

# Search application info logs

`clsAppInfoCollection` exposes two `GetAppInfoCollection` factory overloads that share the same criteria-driven retrieve used by [Search application error logs](error-search.md), with three differences specific to the info side: a scoped full-text search (`SearchType`), a default `EPAY`/`DirectDeposit` exclusion, and no sort-field support in the built SQL.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-LV-07 |
| **Trigger** | Caller calls `GetAppInfoCollection(inDataportal, inCreateDate)` or `GetAppInfoCollection(inDataportal, inCriteria)` |
| **Inputs** | `IDataPortalInfo`; optional `CreateDate`, `StartDate`/`EndDate` range, `MachineName`, `AppName`, `Environment`, `UserName`, `SearchText`, `SearchType` (`MessageAndData`/`MessageOnly`/`DataOnly`), `ExcludeEpayAndDD` (defaults to `True`) on the `Criteria` object |
| **Outputs** | `clsAppInfoCollection` populated with up to 300 `clsAppInfo` child objects; `TotalCount` set to the full matching row count |
| **Primary components** | `clsAppInfoCollection.GetAppInfoCollection` (two overloads), `clsAppInfoCollection.Criteria.BuildWhere`, `clsAppInfoCollection.Criteria.GetSearchValue`, `clsAppInfoCollection.BeforeRetrieve`, `clsAppInfoCollection.AfterRetrieve` |
| **Entry point** | `Application\SAIF.Application.LogView\clsAppInfoCollection.vb` |

## Steps

1. **Select an entry overload.** The date-only overload wraps `inCreateDate` in a new `Criteria`; the caller-supplied-criteria overload passes a pre-built `Criteria` straight through. Both ultimately call `inDataportal.DataAccessLayer.RetrieveObject(...)`.
2. **Build the `WHERE` clause (`BuildWhere`).**
   - Date filtering: same range-vs-single-date pattern as the error side — an inclusive `Create_Date` range when both `StartDate` and `EndDate` are set, otherwise a date-only-cast equality on `CreateDate` when set.
   - Machine/app filters: if `MachineName` or `AppName` is non-empty and not `[ALL]`, add an equality predicate ([BR-002](../business-rules.md#br-002-all-sentinel-suppresses-selected-filters)).
   - Environment filter: if non-empty and not `[ALL]`, split on `;` into a quoted `IN (...)` list ([BR-003](../business-rules.md#br-003-semicolon-delimited-filters-expand-to-sql-in-lists)).
   - User filter: `;`-delimited values become an `IN (...)` list; a single value uses `like @UserName`.
   - Full-text filter: if `SearchText` is non-empty, branch on `SearchType` and append `CONTAINS((Message_Text, Data_Text), @SEARCHTEXT)`, `CONTAINS((Message_Text), @SEARCHTEXT)`, or `CONTAINS((Data_Text), @SEARCHTEXT)` accordingly ([BR-009](../business-rules.md#br-009-info-search-full-text-scope-is-restricted-by-searchtype), [BR-004](../business-rules.md#br-004-search-text-is-normalized-for-full-text-queries)).
   - EPAY/DirectDeposit exclusion: if `ExcludeEpayAndDD` is `True` (the default), append `and not (App_Name in ('EPAY','DirectDeposit'))` ([BR-008](../business-rules.md#br-008-audit-searches-exclude-epay-and-directdeposit)).
   - Any leading `AND` produced by the assembly is trimmed from the final string.
3. **Normalize the search text (`GetSearchValue`), when `SearchText` is supplied.** Identical logic to the error-side normalization: strip quotes, tokenize on spaces/commas/semicolons, preserve recognized logic-operator tokens (`AND`, `&`, `OR`, `|`, `&!`) unquoted, and quote every other token — joining plain tokens with `AND` when no explicit operator is present ([BR-004](../business-rules.md#br-004-search-text-is-normalized-for-full-text-queries)).
4. **Configure the retrieve requests (`BeforeRetrieve`).** Two data requests are queued: a `ResultSet` request using `RetrieveSQL` (`SELECT TOP 300 ...`) ([SQL-007](../sql/SQL-007-saif-application-logview.md), [App_Info](../database-tables.md#app_info)) ([BR-001](../business-rules.md#br-001-search-results-are-capped-at-300-rows)), and a `Scalar` request using `RetrieveSQLCount` (`SELECT count(*) ...`) ([SQL-008](../sql/SQL-008-saif-application-logview.md), [App_Info](../database-tables.md#app_info)). Each parameter (`@CreateDate`, `@MachineName`, `@Username`, `@AppName`, `@SEARCHTEXT`) is bound only when the corresponding criteria value is populated and (for `MachineName`/`AppName`) not `[ALL]`.
   - Unlike the error-side collection, `clsAppInfoCollection.Criteria.RetrieveSQL` builds no `ORDER BY` clause at all, so result ordering for info searches is whatever the database returns without an explicit sort.*
5. **Load the results (`AfterRetrieve`).** For every row in the first result set, create a new `clsAppInfo`, call `Load(...)` on it, and add it to the collection via `MyBase.Add`. Set `TotalCount` from the second (scalar count) request. Clear `MyCriteria.IsDirty`.
6. **Save the collection, if edited.** `clsAppInfoCollection.Save()` overrides the base `Save()` to call `Me.ApplyEdit()` before delegating to `MyBase.Save()` — relevant only if the collection's items were edited in place rather than used purely for read-only search results.*

## Process flow

The following diagram visualizes the filter-build, execute, and load sequence, including the default audit-noise exclusion.

```mermaid
flowchart TD
	Start([Caller calls GetAppInfoCollection]) --> Build[BuildWhere: date, machine,<br>app, environment, user predicates]
	Build --> Search{SearchText supplied?}
	Search -->|Yes| Scope[Branch on SearchType:<br>Message+Data, Message only, or Data only]
	Scope --> Normalize[GetSearchValue: strip quotes,<br>tokenize, preserve logic operators]
	Search -->|No| Exclude
	Normalize --> Exclude{ExcludeEpayAndDD?}
	Exclude -->|Yes, default| AddExclude[Append EPAY/DirectDeposit exclusion]
	Exclude -->|No| Rows
	AddExclude --> Rows[Execute TOP 300 row query,<br>no ORDER BY]
	Rows --> Count[Execute matching COUNT query]
	Count --> Load[Load each row into a<br>new clsAppInfo; set TotalCount]
	Load --> Done([Collection and TotalCount returned])
```

## Failure and edge-case behavior

- The row query is hard-capped at 300 rows ([BR-001](../business-rules.md#br-001-search-results-are-capped-at-300-rows)) even when `TotalCount` reports more matches.
- `clsAppInfoCollection.Criteria.RetrieveSQL` has no `BuildOrder`/`ORDER BY` clause, unlike the error-side collection, so info search result ordering is not explicitly controlled by this library.*
- `ExcludeEpayAndDD` defaults to `True`, so standard searches silently omit `EPAY` and `DirectDeposit` audit rows unless a caller explicitly sets the property to `False` ([BR-008](../business-rules.md#br-008-audit-searches-exclude-epay-and-directdeposit)).
- `SearchType` defaults to `MessageAndData`; callers who intend a narrower search must set it explicitly before the criteria is built ([BR-009](../business-rules.md#br-009-info-search-full-text-scope-is-restricted-by-searchtype)).
- `SearchText` normalization strips all quote characters from the raw input before tokenizing, identical to the error-side behavior.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- `Application\SAIF.Application.LogView\clsAppInfoCollection.vb`
- `Application\SAIF.Application.LogView\modLogViewExtensions.vb`
