---
title: Retrieve or create a single application info record
summary: Allocates a new transient App_Info object or loads exactly one existing row by sequence number.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Application.LogView
reference_type: package
operation_id: OP-LV-06
trigger: Caller invokes clsAppInfo.NewAppInfo to allocate a transient object or clsAppInfo.GetAppInfo to retrieve one by sequence number
---

# Retrieve or create a single application info record

`clsAppInfo` exposes two single-object factory methods that both go through the criteria-driven BOF data portal but diverge at the `CreateObject` vs. `RetrieveObject` call: `NewAppInfo` allocates a fresh, non-persisted instance seeded with a caller-supplied sequence number, while `GetAppInfo` performs the same result-count-validated retrieve pattern used by [Retrieve a single application error](error-retrieval.md).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-LV-06 |
| **Trigger** | Caller calls `clsAppInfo.NewAppInfo(inDataportal, inAppInfoSeqNum)` or `clsAppInfo.GetAppInfo(inDataportal, inAppInfoSeqNum)` |
| **Inputs** | `IDataPortalInfo`, `AppInfoSeqNum` |
| **Outputs** | New (unsaved) `clsAppInfo` for `NewAppInfo`; populated `clsAppInfo` for `GetAppInfo` on success, or an unhandled `ApplicationException("Invalid Results")` when the retrieved row count is not exactly one |
| **Primary components** | `clsAppInfo.NewAppInfo`, `clsAppInfo.GetAppInfo`, `clsAppInfo.BeforeRetrieve`, `clsAppInfo.AfterRetrieve` |
| **Entry point** | `Application\SAIF.Application.LogView\clsAppInfo.vb` |

## Steps

1. **Branch on the requested mode.**
   - `NewAppInfo`: builds a `clsAppInfo.Criteria(inDataportal, inAppInfoSeqNum)` and calls `inDataportal.DataAccessLayer.CreateObject(...)`, running the `Create()` lifecycle to seed a fresh, non-persisted object with the criteria's sequence number available but no row loaded from the database.
   - `GetAppInfo`: builds the same shape of `Criteria` and calls `inDataportal.DataAccessLayer.RetrieveObject(...)` instead, driving the retrieve lifecycle.
2. **Configure the retrieve request (`BeforeRetrieve`), `GetAppInfo` path only.** A data request is built with `SQLStatement = MyCriteria.RetrieveSQL` and the parameter `@AppInfoSeqNum` bound from the criteria, targeting [App_Info](../database-tables.md#app_info). The single-object `RetrieveSQL` property on `clsAppInfo.Criteria` is a blank (single-space) string in source, so the actual retrieval SQL text is not documented here.**
3. **Evaluate the result (`AfterRetrieve`), `GetAppInfo` path only.**
   - If the result set contains exactly one row: call `Fill(Results(0))` to populate every field (`AppInfoSeqNum`, `AppName`, `CreateDate`, `DataText`, `Environment`, `MachineName`, `MessageText`, `PageName`, `PurgeDate`, `UserName`), then `MarkOld()` ([BR-005](../business-rules.md#br-005-single-object-retrieval-requires-exactly-one-row)).
     - On failure: throw `ApplicationException("Invalid Results")`, matching the behavior on the error side of the library.
4. **Return the object.** `NewAppInfo` returns the freshly created, unsaved instance; `GetAppInfo` returns the populated, marked-old instance from `AfterRetrieve`.

## Process flow

The following diagram visualizes the branch between transient creation and validated retrieval.

```mermaid
flowchart TD
	Start([Caller calls NewAppInfo<br>or GetAppInfo]) --> Which{Which factory method?}
	Which -->|NewAppInfo| Create[CreateObject: run Create lifecycle,<br>seed empty/default fields]
	Which -->|GetAppInfo| Retrieve[BeforeRetrieve: bind @AppInfoSeqNum]
	Retrieve --> Exec[Execute retrieve request]
	Exec --> Count{Result count = 1?}
	Count -->|Yes| Fill[Fill object fields, MarkOld]
	Count -->|No| Throw([Throw ApplicationException<br>Invalid Results])
	Create --> DoneNew([New unsaved clsAppInfo returned])
	Fill --> DoneGet([Populated clsAppInfo returned])
```

## Failure and edge-case behavior

- The single-object `RetrieveSQL` in `clsAppInfo.Criteria` is a blank placeholder string, mirroring the same gap on the error side; the underlying query behavior for `GetAppInfo` cannot be confirmed from source.**
- A zero-row match and a multi-row match are both treated identically as an `ApplicationException("Invalid Results")` ([BR-005](../business-rules.md#br-005-single-object-retrieval-requires-exactly-one-row)) — callers must wrap `GetAppInfo` in exception handling.
- `NewAppInfo` does not call `Save()`; the caller must populate fields and save separately to actually persist a row, following the pattern in [Log an application info event](info-logging.md).*

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.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. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `Application\SAIF.Application.LogView\clsAppInfo.vb`
