StaticInstanceProtectedCreateCreate a new RecordGeoCode row. If the insert fails due to a unique constraint (race condition from concurrent batch geocoding), falls back to loading the existing row.
ProtectedFindFind an existing RecordGeoCode row for a given entity/record/location type.
When existingGeoCodesMap is provided (batch mode), checks the in-memory map first.
If a match is found, loads the full entity object by ID (single PK lookup — much cheaper
than a filtered query). Falls back to a per-record RunView query when no map is provided
(single-record mode, e.g., called from the AfterSave hook).
OptionalexistingGeoCodesMap: Map<string, ExistingGeoCodeInfo>ProtectedGeocodePerform the actual geocoding using a priority-based strategy:
Optionalprovider: IGeocodingProviderThe resolved geocoding provider to use for strategy 2. When null, strategy 2 is skipped and we fall through to reference data.
The Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.
ProtectedProcessProcess a single field mapping for a single entity record.
OptionalexistingGeoCodesMap: Map<string, ExistingGeoCodeInfo>Optional pre-loaded map for O(1) lookup instead of per-record SQL query
Optionalprovider: IGeocodingProviderThe geocode result if geocoding was performed successfully, or null if no geocoding was needed (hash unchanged) or the attempt failed.
Check if any geo field mappings have changed and dispatch geocoding if needed. Called from the GenericDatabaseProvider OnSaveCompleted hook.
This method never throws — all errors are captured in RecordGeoCode rows.
The entity instance that was just saved
The user context for data operations
Optionalmappings: GeoFieldMapping[]Field-to-location mappings (if not provided, derived from EntityField.ExtendedType metadata)
OptionalexistingGeoCodesMap: Map<string, ExistingGeoCodeInfo>Optional pre-loaded map of existing RecordGeoCode rows keyed by
RecordID|LocationType. When provided, eliminates per-record SQL queries in
FindExistingGeoCode(). Used by the scheduled geocoding job for batch processing.
OptionalproviderName: stringThe geocode result from the first successfully geocoded mapping, or null if no geocoding was performed (e.g., hash unchanged) or all attempts failed. The caller can use this to patch virtual lat/lng fields on the entity's SP result before finalizeSave() loads it into the entity object.
ProtectedUpdateUpdate a RecordGeoCode row with failure information (transient error, eligible for retry).
ProtectedUpdateMark a RecordGeoCode row as not geocodable — the address can't be resolved to coordinates (e.g., "Conference Room B", "TBD"). Won't be retried by the bulk job. If the source record's address fields change, the hash mismatch in SyncIfChanged will trigger a fresh attempt.
ProtectedUpdateUpdate a RecordGeoCode row with successful geocoding results.
StaticBuildBuild the composite key used for ExistingGeoCodeInfo map lookups.
Format: RecordID|LocationType
StaticBuildDerive geo field mappings from EntityField.ExtendedType metadata. Finds all fields with Geo* ExtendedType values and groups them into a Primary location mapping.
The entity metadata to inspect
Array of geo field mappings (empty if no geo fields found)
Protected StaticgetReturns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.
OptionalclassName: stringStaticHasCheck if an entity has any geo fields defined in its metadata.
The entity metadata to check
true if the entity has at least one field with a Geo* ExtendedType
Singleton service that manages the geocoding lifecycle for entity records. Called by CodeGen-generated AfterSave hooks on geo-enabled entities.
Responsibilities:
All geocoding is fire-and-forget — errors are captured in RecordGeoCode and retried by the scheduled geocoding job. Never throws.