Skip to main content
Rather than scattering inline SOQL through the codebase, each package wraps its queries in per-object DB classes, kept in a db/ folder (for example UserDB, AccountDB). A DB class declares the fields it loads in one place and delegates to FCORE_BASE.CacheService, so every consumer in a transaction shares one cached query. Query through the DB class for an object whenever one exists. The conventional method shapes are getById, getByIds, and getBy[Field].

A Full DB Class (UserDB)

This is the actual UserDB class from the Platform package (fusioncore-platform/force-app/main/default/classes/db/UserDB.cls). It is declared public inherited sharing, declares the fields it queries in one private method, and delegates to FCORE_BASE.CacheServiceWithoutSharing:
This is the canonical pattern:
  • The fields are declared once in getFieldsToQuery() as a List<SObjectField>. To load another field, you add it here and every consumer picks it up.
  • getById delegates to the cache’s getByIds with a single-element Set<Id> and returns the first match, or null when nothing is found.
  • Consumers never write inline SOQL for User — they call UserDB.getById(...), and the cache ensures the query runs at most once per transaction.

Singleton DB Classes for Small Tables

For small, frequently-read reference tables, the DB class is instead a singleton that loads every row once on construction and serves lookups from in-memory maps. This is the actual CurrencyTypeDB class (fusioncore-platform/force-app/main/default/classes/db/CurrencyTypeDB.cls). Note that it is public inherited sharing (not global), it caches all rows in its private constructor via queryAndCacheAll(), and it guards on UserInfo.isMultiCurrencyOrganization():
This is the singleton pattern:
  • A private constructor plus getInstance() gives a lazy singleton — the first caller constructs the instance, and everyone after reuses it.
  • All rows are loaded once into currencyIsoCodeToCurrencyType (keyed by ISO code) when the instance is constructed.
  • Lookups — getByIsoCode, getByIsoCodes, and getCorporate — are served from memory with zero further SOQL.
  • The multi-currency guard in queryAll() returns an empty list in single-currency orgs, where CurrencyType is not queryable.
Call sites get the instance and read straight from memory:

Which Pattern to Use

  • Use a per-object DB class that delegates to the cache (like UserDB) for general records queried by Id.
  • Use a singleton that loads all rows (like CurrencyTypeDB) for small reference tables read repeatedly across a transaction.