SQL Server implementation of the MemberJunction data provider interfaces.

This class provides comprehensive database functionality including:

  • CRUD operations for entities
  • Metadata management and caching
  • View and query execution
  • Transaction support
  • SQL logging capabilities
  • Record change tracking
  • AI integration hooks

Example

const config = new SQLServerProviderConfigData(dataSource);
const provider = new SQLServerDataProvider(config);
await provider.Config();

Hierarchy (view full)

Implements

Constructors

Properties

Accessors

Methods

BeginTransaction BuildDatasetFilterFromConfig CacheDataset CheckToSeeIfRefreshNeeded CheckUserReadPermissions ClearDatasetCache CloneAllMetadata CommitTransaction CompleteMergeLogging Config ConvertItemFiltersToUniqueKey CopyMetadataFromGlobalProvider CreateAuditLogRecord CreateSqlLogger CreateTransactionGroup CreateUserDescriptionOfChanges Delete DiffObjects Dispose DisposeAllSqlLoggingSessions EntityStatusCheck ExecuteSQL ExecuteSQLBatch GetActiveSqlLoggingSessions GetAllMetadata GetAndCacheDatasetByName GetApplicationMetadata GetAuditLogTypeMetadata GetAuthorizationMetadata GetCachedDataset GetColumnsForDatasetItem GetCreateUpdateSPName GetCurrentUser GetDatasetByName GetDatasetCacheKey GetDatasetItem GetDatasetItemSQL GetDatasetStatusByName GetDeleteSQL GetDeleteSQLWithDetails GetEntityAIActions GetEntityDependencies GetEntityObject GetEntityRecordName GetEntityRecordNameSQL GetEntityRecordNames GetHardLinkDependencySQL GetLatestMetadataUpdates GetLocalDatasetTimestamp GetLogRecordChangeSQL GetRecordChanges GetRecordDependencies GetRecordDependencyLinkSQL GetRecordDuplicates GetRecordFavoriteID GetRecordFavoriteStatus GetSaveSQL GetSaveSQLWithDetails GetSoftLinkDependencySQL GetUserMetadata HandleEntityAIActions HandleEntityActions InternalRunQueries InternalRunQuery InternalRunView InternalRunViews IsDatasetCacheUpToDate IsDatasetCached Load LoadLocalMetadataFromStorage LocalMetadataObsolete LogRecordChange MapTransactionResultToNewValues MergeRecords NeedsDatetimeOffsetAdjustment PostProcessEntityMetadata PostProcessRunView PostProcessRunViews PostRunQueries PostRunQuery PostRunView PostRunViews PreProcessRunView PreProcessRunViews PreRunQueries PreRunQuery PreRunView PreRunViews ProcessEntityRows Refresh RefreshIfNeeded RefreshRemoteMetadataTimestamps RemoveLocalMetadataFromStorage RenderViewWhereClause RollbackTransaction RunQueries RunQueriesWithCacheCheck RunQuery RunReport RunView RunViews RunViewsWithCacheCheck Save SaveLocalMetadataToStorage SetRecordFavoriteStatus StartMergeLogging TransformSimpleObjectToEntityObject UpdateLocalMetadata _internalExecuteSQL _internalExecuteSQLInstance _logSqlStatement applyQueryPagination auditQueryExecution buildWhereClauseForCacheCheck cacheQueryResults checkQueryCache createViewUserSearchSQL escapeQuotesInProperties executeQueryWithTiming executeSQLForUserViewRunLogging extractMaxUpdatedAt findAndValidateQuery findQuery generateSPParams generateSetStatementValue generateSingleSPParam getAllEntityColumnsSQL getBatchedQueryCacheStatus getBatchedServerCacheStatus getRunTimeViewFieldArray getRunTimeViewFieldString initializeQueueProcessor isCacheCurrent mergeCachedAndFreshResults mergeQueryCachedAndFreshResults packageSPParam processDeferredTasks processQueryParameters resolveCategoryPath resolveQueryInfo runFullQueryAndReturn runFullQueryAndReturnForQuery testDatetimeOffsetHandling trimString validateUserProvidedSQLClause ExecuteSQLBatchStatic ExecuteSQLWithPool LogSQLStatement _internalExecuteSQLStatic

Constructors

Properties

_bAllowRefresh: boolean = true
_datetimeOffsetTestComplete: boolean = false
_deferredTasks: {
    data: any;
    options: any;
    type: string;
    user: UserInfo;
}[] = []

Type declaration

  • data: any
  • options: any
  • type: string
  • user: UserInfo
_localStorageProvider: ILocalStorageProvider
_needsDatetimeOffsetAdjustment: boolean = false
_pool: ConnectionPool
_preRunQueriesResultType: {
    allCached: boolean;
    cacheStatusMap?: Map<number, {
        result?: RunQueryResult;
        status: "hit" | "miss" | "disabled" | "expired";
    }>;
    cachedResults?: RunQueryResult[];
    telemetryEventId?: string;
    uncachedParams?: RunQueryParams[];
}

Result from PreRunQueries hook containing cache status for batch operations

Type declaration

  • allCached: boolean
  • Optional cacheStatusMap?: Map<number, {
        result?: RunQueryResult;
        status: "hit" | "miss" | "disabled" | "expired";
    }>
  • Optional cachedResults?: RunQueryResult[]
  • Optional telemetryEventId?: string
  • Optional uncachedParams?: RunQueryParams[]
_preRunQueryResultType: {
    cacheStatus: "hit" | "miss" | "disabled" | "expired";
    cachedResult?: RunQueryResult;
    fingerprint?: string;
    telemetryEventId?: string;
}

Result from PreRunQuery hook containing cache status and optional cached result

Type declaration

  • cacheStatus: "hit" | "miss" | "disabled" | "expired"
  • Optional cachedResult?: RunQueryResult
  • Optional fingerprint?: string
  • Optional telemetryEventId?: string
_preRunViewResultType: {
    cacheStatus: "hit" | "miss" | "disabled" | "expired";
    cachedResult?: RunViewResult;
    fingerprint?: string;
    telemetryEventId?: string;
}

Result from PreRunView hook containing cache status and optional cached result

Type declaration

  • cacheStatus: "hit" | "miss" | "disabled" | "expired"
  • Optional cachedResult?: RunViewResult
  • Optional fingerprint?: string
  • Optional telemetryEventId?: string
_preRunViewsResultType: {
    allCached: boolean;
    cacheStatusMap?: Map<number, {
        result?: RunViewResult;
        status: "hit" | "miss" | "disabled" | "expired";
    }>;
    cachedResults?: RunViewResult[];
    smartCacheCheckParams?: RunViewWithCacheCheckParams[];
    telemetryEventId?: string;
    uncachedParams?: RunViewParams[];
    useSmartCacheCheck?: boolean;
}

Result from PreRunViews hook containing cache status for batch operations

Type declaration

  • allCached: boolean
  • Optional cacheStatusMap?: Map<number, {
        result?: RunViewResult;
        status: "hit" | "miss" | "disabled" | "expired";
    }>
  • Optional cachedResults?: RunViewResult[]
  • Optional smartCacheCheckParams?: RunViewWithCacheCheckParams[]

    When CacheLocal is enabled, contains the cache check params to send to server

  • Optional telemetryEventId?: string
  • Optional uncachedParams?: RunViewParams[]
  • Optional useSmartCacheCheck?: boolean

    When CacheLocal is enabled, indicates we should use smart cache check

_queueSubscription: any
_recordDupeDetector: DuplicateRecordDetector
_savepointCounter: number = 0
_savepointStack: string[] = []
_sqlLoggingSessions: Map<string, SqlLoggingSessionImpl> = ...
_sqlQueue$: Subject<{
    context: SQLExecutionContext;
    id: string;
    options?: InternalSQLOptions;
    parameters: any;
    query: string;
    reject: ((error) => void);
    resolve: ((value) => void);
}> = ...

Type declaration

  • context: SQLExecutionContext
  • id: string
  • Optional options?: InternalSQLOptions
  • parameters: any
  • query: string
  • reject: ((error) => void)
      • (error): void
      • Parameters

        • error: any

        Returns void

  • resolve: ((value) => void)
      • (value): void
      • Parameters

        • value: IResult<any>

        Returns void

_transaction: Transaction
_transactionDepth: number = 0
_transactionState$: BehaviorSubject<boolean> = ...
queryCache: QueryCache = ...
_mjMetadataDatasetName: string

Accessors

  • get AllExplorerNavigationItems(): ExplorerNavigationItem[]
  • Gets all explorer navigation items including inactive ones.

    Returns ExplorerNavigationItem[]

    Array of all ExplorerNavigationItem objects

  • get AllMetadata(): AllMetadata
  • Returns the currently loaded local metadata from within the instance

    Returns AllMetadata

  • get Applications(): ApplicationInfo[]
  • Gets all application metadata in the system.

    Returns ApplicationInfo[]

    Array of ApplicationInfo objects representing all applications

  • get AuditLogTypes(): AuditLogTypeInfo[]
  • Gets all audit log types defined for tracking system activities.

    Returns AuditLogTypeInfo[]

    Array of AuditLogTypeInfo objects

  • get Authorizations(): AuthorizationInfo[]
  • Gets all authorization definitions in the system.

    Returns AuthorizationInfo[]

    Array of AuthorizationInfo objects defining permissions

  • get CurrentUser(): UserInfo
  • Gets the current user's information including roles and permissions.

    Returns UserInfo

    UserInfo object for the authenticated user

  • get DatabaseConnection(): any
  • Gets the underlying SQL Server connection pool

    Returns any

    The mssql ConnectionPool object

  • get Entities(): EntityInfo[]
  • Gets all entity metadata in the system.

    Returns EntityInfo[]

    Array of EntityInfo objects representing all entities

  • get InstanceConnectionString(): string
  • For the SQLServerDataProvider the unique instance connection string which is used to identify, uniquely, a given connection is the following format: mssql://host:port/instanceName?/database instanceName is only inserted if it is provided in the options

    Returns string

  • get LatestLocalMetadata(): MetadataInfo[]
  • Gets the latest metadata timestamps from local cache. Used for comparison with remote timestamps.

    Returns MetadataInfo[]

    Array of locally cached metadata timestamps

  • get LatestRemoteMetadata(): MetadataInfo[]
  • Gets the latest metadata timestamps from the remote server. Used to determine if local cache is out of date.

    Returns MetadataInfo[]

    Array of metadata timestamp information

  • get Libraries(): LibraryInfo[]
  • Gets all library definitions in the system.

    Returns LibraryInfo[]

    Array of LibraryInfo objects representing code libraries

  • get LocalStoragePrefix(): string
  • This property will return the prefix to use for local storage keys. This is useful if you have multiple instances of a provider running in the same environment and you want to keep their local storage keys separate. The default implementation returns an empty string, but subclasses can override this to return a unique string based on the connection or other distinct identifier.

    Returns string

  • get PreRunQueriesResult(): {
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunQueryResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunQueryResult[];
        telemetryEventId?: string;
        uncachedParams?: RunQueryParams[];
    }
  • Returns {
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunQueryResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunQueryResult[];
        telemetryEventId?: string;
        uncachedParams?: RunQueryParams[];
    }

    • allCached: boolean
    • Optional cacheStatusMap?: Map<number, {
          result?: RunQueryResult;
          status: "hit" | "miss" | "disabled" | "expired";
      }>
    • Optional cachedResults?: RunQueryResult[]
    • Optional telemetryEventId?: string
    • Optional uncachedParams?: RunQueryParams[]
  • get PreRunQueryResult(): {
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunQueryResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }
  • Returns {
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunQueryResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }

    • cacheStatus: "hit" | "miss" | "disabled" | "expired"
    • Optional cachedResult?: RunQueryResult
    • Optional fingerprint?: string
    • Optional telemetryEventId?: string
  • get PreRunViewResult(): {
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunViewResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }
  • Returns {
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunViewResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }

    • cacheStatus: "hit" | "miss" | "disabled" | "expired"
    • Optional cachedResult?: RunViewResult
    • Optional fingerprint?: string
    • Optional telemetryEventId?: string
  • get PreRunViewsResult(): {
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunViewResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunViewResult[];
        smartCacheCheckParams?: RunViewWithCacheCheckParams[];
        telemetryEventId?: string;
        uncachedParams?: RunViewParams[];
        useSmartCacheCheck?: boolean;
    }
  • Returns {
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunViewResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunViewResult[];
        smartCacheCheckParams?: RunViewWithCacheCheckParams[];
        telemetryEventId?: string;
        uncachedParams?: RunViewParams[];
        useSmartCacheCheck?: boolean;
    }

    • allCached: boolean
    • Optional cacheStatusMap?: Map<number, {
          result?: RunViewResult;
          status: "hit" | "miss" | "disabled" | "expired";
      }>
    • Optional cachedResults?: RunViewResult[]
    • Optional smartCacheCheckParams?: RunViewWithCacheCheckParams[]

      When CacheLocal is enabled, contains the cache check params to send to server

    • Optional telemetryEventId?: string
    • Optional uncachedParams?: RunViewParams[]
    • Optional useSmartCacheCheck?: boolean

      When CacheLocal is enabled, indicates we should use smart cache check

  • get Queries(): QueryInfo[]
  • Gets all saved queries in the system.

    Returns QueryInfo[]

    Array of QueryInfo objects representing stored queries

  • get QueryCategories(): QueryCategoryInfo[]
  • Gets all query category definitions.

    Returns QueryCategoryInfo[]

    Array of QueryCategoryInfo objects for query organization

  • get QueryEntities(): QueryEntityInfo[]
  • Gets all query entity associations.

    Returns QueryEntityInfo[]

    Array of QueryEntityInfo objects linking queries to entities

  • get QueryFields(): QueryFieldInfo[]
  • Gets all query field definitions.

    Returns QueryFieldInfo[]

    Array of QueryFieldInfo objects defining query result columns

  • get QueryParameters(): QueryParameterInfo[]
  • Gets all query parameter definitions.

    Returns QueryParameterInfo[]

    Array of QueryParameterInfo objects for parameterized queries

  • get QueryPermissions(): QueryPermissionInfo[]
  • Gets all query permission assignments.

    Returns QueryPermissionInfo[]

    Array of QueryPermissionInfo objects defining query access

  • get Roles(): RoleInfo[]
  • Gets all security roles defined in the system.

    Returns RoleInfo[]

    Array of RoleInfo objects representing all roles

  • get RowLevelSecurityFilters(): RowLevelSecurityFilterInfo[]
  • Gets all row-level security filters defined in the system.

    Returns RowLevelSecurityFilterInfo[]

    Array of RowLevelSecurityFilterInfo objects for data access control

  • get VisibleExplorerNavigationItems(): ExplorerNavigationItem[]
  • Gets only active explorer navigation items sorted by sequence. Results are cached for performance.

    Returns ExplorerNavigationItem[]

    Array of active ExplorerNavigationItem objects

  • get transactionState$(): Observable<boolean>
  • Observable that emits the current transaction state (true when active, false when not) External code can subscribe to this to know when transactions start and end

    Returns Observable<boolean>

    Example

    provider.transactionState$.subscribe(isActive => {
    console.log('Transaction active:', isActive);
    });

Methods

  • If the specified datasetName is cached, this method will clear the cache. If itemFilters are provided, the combination of datasetName and the filters are used to determine a match in the cache

    Parameters

    Returns Promise<void>

  • Converts dataset item filters into a unique string key for caching.

    Parameters

    Returns string

    JSON-formatted string representing the filters

  • Copies metadata from the global provider to the local instance. This is used to ensure that the local instance has the latest metadata information available without having to reload it from the server.

    Returns boolean

  • Creates a new SQL logging session that will capture all SQL operations to a file. Returns a disposable session object that must be disposed to stop logging.

    Parameters

    • filePath: string

      Full path to the file where SQL statements will be logged

    • Optional options: SqlLoggingOptions

      Optional configuration for the logging session

    Returns Promise<SqlLoggingSession>

    Promise - Disposable session object

    Example

    // Basic usage
    const session = await provider.CreateSqlLogger('./logs/metadata-sync.sql');
    try {
    // Perform operations that will be logged
    await provider.ExecuteSQL('INSERT INTO ...');
    } finally {
    await session.dispose(); // Stop logging
    }

    // With migration formatting
    const session = await provider.CreateSqlLogger('./migrations/changes.sql', {
    formatAsMigration: true,
    description: 'MetadataSync push operation'
    });
  • This method will create a human-readable string that describes the changes object that was created using the DiffObjects() method

    Parameters

    • changesObject: any

      JavaScript object that has properties for each changed field that in turn have field, oldValue and newValue as sub-properties

    • maxValueLength: number = 200

      If not specified, default value of 200 characters applies where any values after the maxValueLength is cut off. The actual values are stored in the ChangesJSON and FullRecordJSON in the RecordChange table, this is only for the human-display

    • cutOffText: string = '...'

      If specified, and if maxValueLength applies to any of the values being included in the description, this cutOffText param will be appended to the end of the cut off string to indicate to the human reader that the value is partial.

    Returns string

  • Creates a changes object by comparing two javascript objects, identifying fields that have different values. Each property in the returned object represents a changed field, with the field name as the key.

    Parameters

    • oldData: any

      The original data object to compare from

    • newData: any

      The new data object to compare to

    • entityInfo: EntityInfo

      Entity metadata used to validate fields and determine comparison logic

    • quoteToEscape: string

      The quote character to escape in string values (typically "'")

    Returns Record<string, FieldChange>

    A Record mapping field names to FieldChange objects containing the field name, old value, and new value. Returns null if either oldData or newData is null/undefined. Only includes fields that have actually changed and are not read-only.

    Remarks

    • Read-only fields are never considered changed
    • null and undefined are treated as equivalent
    • Date fields are compared by timestamp
    • String and object values have quotes properly escaped for SQL
    • Objects/arrays are recursively escaped using escapeQuotesInProperties

    Example

    const changes = provider.DiffObjects(
    { name: "John's Co", revenue: 1000 },
    { name: "John's Co", revenue: 2000 },
    entityInfo,
    "'"
    );
    // Returns: { revenue: { field: "revenue", oldValue: 1000, newValue: 2000 } }
  • Used to check to see if the entity in question is active or not If it is not active, it will throw an exception or log a warning depending on the status of the entity being either Deprecated or Disabled.

    Parameters

    Returns Promise<void>

  • Executes multiple SQL queries in a single batch for optimal performance. All queries are combined into a single SQL statement and executed together. This is particularly useful for bulk operations where you need to execute many similar queries and want to minimize round trips to the database.

    Parameters

    • queries: string[]

      Array of SQL queries to execute

    • Optional parameters: any[][]

      Optional array of parameter arrays, one for each query

    • Optional options: ExecuteSQLBatchOptions

      Optional execution options for logging and description

    • Optional contextUser: UserInfo

    Returns Promise<any[][]>

    Promise<any[][]> - Array of result arrays, one for each query

  • Gets information about all active SQL logging sessions. Useful for monitoring and debugging.

    Returns {
        filePath: string;
        id: string;
        options: SqlLoggingOptions;
        startTime: Date;
        statementCount: number;
    }[]

    Array of session information objects

  • Retrieves all metadata from the server and constructs typed instances. Uses the MJ_Metadata dataset for efficient bulk loading.

    Parameters

    Returns Promise<AllMetadata>

    Complete metadata collection with all relationships

  • Gets column info for a dataset item, which might be * for all columns or if a Columns field was provided in the DatasetItem table, attempts to use those columns assuming they are valid.

    Parameters

    • item: any
    • datasetName: string

    Returns string

  • Constructs the SQL query for a dataset item.

    Parameters

    • item: any

      The dataset item metadata

    • itemFilters: any

      Optional filters to apply

    • datasetName: string

      Name of the dataset (for error logging)

    Returns string

    The SQL query string, or null if columns are invalid

  • This function generates both the full SQL (with record change metadata) and the simple stored procedure call for delete

    Parameters

    Returns {
        fullSQL: string;
        simpleSQL: string;
    }

    Object with fullSQL and simpleSQL properties

    • fullSQL: string
    • simpleSQL: string
  • Creates a new instance of a BaseEntity subclass for the specified entity and automatically calls NewRecord() to initialize it. This method serves as the core implementation for entity instantiation in the MemberJunction framework.

    Type Parameters

    Parameters

    • entityName: string

      The name of the entity to create (must exist in metadata)

    • Optional contextUser: UserInfo

      Optional user context for permissions and audit tracking

    Returns Promise<T>

    Promise resolving to the newly created entity instance with NewRecord() called

    Throws

    Error if entity name is not found in metadata or if instantiation fails

  • Creates a new instance of a BaseEntity subclass and loads an existing record using the provided key. This overload provides a convenient way to instantiate and load in a single operation.

    Type Parameters

    Parameters

    • entityName: string

      The name of the entity to create (must exist in metadata)

    • loadKey: CompositeKey

      CompositeKey containing the primary key value(s) for the record to load

    • Optional contextUser: UserInfo

      Optional user context for permissions and audit tracking

    Returns Promise<T>

    Promise resolving to the entity instance with the specified record loaded

    Throws

    Error if entity name is not found, instantiation fails, or record cannot be loaded

  • Returns the timestamp of the local cached version of a given datasetName or null if there is no local cache for the specified dataset

    Parameters

    • datasetName: string

      the name of the dataset to check

    • Optional itemFilters: DatasetItemFilterType[]

      optional filters to apply to the dataset

    Returns Promise<Date>

  • Returns a list of dependencies - records that are linked to the specified Entity/RecordID combination. A dependency is as defined by the relationships in the database. The MemberJunction metadata that is used for this simply reflects the foreign key relationships that exist in the database. The CodeGen tool is what detects all of the relationships and generates the metadata that is used by MemberJunction. The metadata in question is within the EntityField table and specifically the RelatedEntity and RelatedEntityField columns. In turn, this method uses that metadata and queries the database to determine the dependencies. To get the list of entity dependencies you can use the utility method GetEntityDependencies(), which doesn't check for dependencies on a specific record, but rather gets the metadata in one shot that can be used for dependency checking.

    Parameters

    • entityName: string

      the name of the entity to check

    • compositeKey: CompositeKey
    • Optional contextUser: UserInfo

    Returns Promise<RecordDependency[]>

  • Generates the SQL Statement that will Save a record to the database.

    This method is used by the Save() method of this class, but it is marked as public because it is also used by the SQLServerTransactionGroup to regenerate Save SQL if any values were changed by the transaction group due to transaction variables being set into the object.

    Parameters

    • entity: BaseEntity<unknown>

      The entity to generate save SQL for

    • bNewRecord: boolean

      Whether this is a new record (create) or existing record (update)

    • spName: string

      The stored procedure name to call

    • user: UserInfo

      The user context for the operation

    Returns Promise<string>

    The full SQL statement for the save operation

    Security

    This method handles field-level encryption transparently. Fields marked with Encrypt=true will have their values encrypted before being included in the SQL statement.

  • This function generates both the full SQL (with record change metadata) and the simple stored procedure call

    Parameters

    Returns Promise<{
        fullSQL: string;
        simpleSQL: string;
    }>

    Object with fullSQL and simpleSQL properties

    Security

    This method handles field-level encryption transparently. Fields marked with Encrypt=true will have their values encrypted before being included in the SQL statement.

  • This function will generate SQL statements for all of the possible soft links that are not traditional foreign keys but exist in entities where there is a column that has the EntityIDFieldName set to a column name (not null). We need to get a list of all such soft link fields across ALL entities and then generate queries for each possible soft link in the same format as the hard links

    Parameters

    Returns string

  • Handles Entity AI Actions. Parameters are setup for a future support of delete actions, but currently that isn't supported so the baseType parameter isn't fully functional. If you pass in delete, the function will just exit for now, and in the future calling code will start working when we support Delete as a trigger event for Entity AI Actions...

    Parameters

    Returns Promise<void>

  • Internal

    Handles entity actions (non-AI) for save, delete, or validate operations

    Parameters

    • entity: BaseEntity<unknown>

      The entity being operated on

    • baseType: "save" | "delete" | "validate"

      The type of operation

    • before: boolean

      Whether this is before or after the operation

    • user: UserInfo

      The user performing the operation

    Returns Promise<ActionResult[]>

    Array of action results

  • Loads metadata from local storage if available. Deserializes and reconstructs typed metadata objects.

    Returns Promise<void>

  • Checks if local metadata is obsolete compared to remote metadata. Compares timestamps and row counts to detect changes.

    Parameters

    • Optional type: string

      Optional specific metadata type to check

    Returns boolean

    True if local metadata is out of date

  • Parameters

    • transactionResult: Record<string, any>

    Returns {
        FieldName: string;
        Value: any;
    }[]

  • This method will merge two or more records based on the request provided. The RecordMergeRequest type you pass in specifies the record that will survive the merge, the records to merge into the surviving record, and an optional field map that can update values in the surviving record, if desired. The process followed is:

    1. A transaction is started
    2. The surviving record is loaded and fields are updated from the field map, if provided, and the record is saved. If a FieldMap not provided within the request object, this step is skipped.
    3. For each of the records that will be merged INTO the surviving record, we call the GetEntityDependencies() method and get a list of all other records in the database are linked to the record to be deleted. We then go through each of those dependencies and update the link to point to the SurvivingRecordID and save the record.
    4. The record to be deleted is then deleted.
    5. The transaction is committed if all of the above steps are succesful, otherwise it is rolled back.

    The return value from this method contains detailed information about the execution of the process. In addition, all attempted merges are logged in the RecordMergeLog and RecordMergeDeletionLog tables.

    Parameters

    Returns Promise<RecordMergeResult>

  • Determines whether the database driver requires adjustment for datetimeoffset fields. This method performs an empirical test on first use to detect if the driver (e.g., mssql) incorrectly handles timezone information in datetimeoffset columns.

    Returns Promise<boolean>

    True if datetimeoffset values need timezone adjustment, false otherwise

    Example

    const provider = new SQLServerDataProvider();
    if (await provider.NeedsDatetimeOffsetAdjustment()) {
    console.log('Driver requires datetimeoffset adjustment');
    }

    Remarks

    Some database drivers (notably TypeORM) incorrectly interpret SQL Server's datetimeoffset values as local time instead of respecting the timezone offset. This method detects this behavior by inserting a known UTC time and checking if it's retrieved correctly. The test is performed only once and the result is cached for performance.

  • Post-processes entity metadata to establish relationships between entities and their child objects. Links fields, permissions, relationships, and settings to their parent entities.

    Parameters

    • entities: any[]

      Array of entity metadata

    • fields: any[]

      Array of entity field metadata

    • fieldValues: any[]

      Array of entity field value metadata

    • permissions: any[]

      Array of entity permission metadata

    • relationships: any[]

      Array of entity relationship metadata

    • settings: any[]

      Array of entity settings metadata

    Returns any[]

    Processed array of EntityInfo instances with all relationships established

  • Base class post-processor that all sub-classes should call after they finish their RunView process

    Parameters

    Returns Promise<void>

  • Base class utilty method that should be called after each sub-class handles its internal RunViews() process before returning results This handles the optional conversion of simple objects to entity objects for each requested view depending on if the params requests a result_type === 'entity_object'

    Parameters

    Returns Promise<void>

  • Post-processing hook for RunQueries (batch). Handles telemetry end.

    Parameters

    • results: RunQueryResult[]

      Array of query results

    • params: RunQueryParams[]

      Array of query parameters

    • preResult: {
          allCached: boolean;
          cacheStatusMap?: Map<number, {
              result?: RunQueryResult;
              status: "hit" | "miss" | "disabled" | "expired";
          }>;
          cachedResults?: RunQueryResult[];
          telemetryEventId?: string;
          uncachedParams?: RunQueryParams[];
      }

      The pre-processing result

      • allCached: boolean
      • Optional cacheStatusMap?: Map<number, {
            result?: RunQueryResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>
      • Optional cachedResults?: RunQueryResult[]
      • Optional telemetryEventId?: string
      • Optional uncachedParams?: RunQueryParams[]
    • Optional contextUser: UserInfo

      Optional user context

    Returns Promise<void>

  • Post-processing hook for RunQuery. Handles cache storage and telemetry end.

    Parameters

    • result: RunQueryResult

      The query result

    • params: RunQueryParams

      The query parameters

    • preResult: {
          cacheStatus: "hit" | "miss" | "disabled" | "expired";
          cachedResult?: RunQueryResult;
          fingerprint?: string;
          telemetryEventId?: string;
      }

      The pre-processing result

      • cacheStatus: "hit" | "miss" | "disabled" | "expired"
      • Optional cachedResult?: RunQueryResult
      • Optional fingerprint?: string
      • Optional telemetryEventId?: string
    • Optional contextUser: UserInfo

      Optional user context

    Returns Promise<void>

  • Post-processing hook for RunView. Handles result transformation, cache storage, and telemetry end.

    Parameters

    • result: RunViewResult

      The view result

    • params: RunViewParams

      The view parameters

    • preResult: {
          cacheStatus: "hit" | "miss" | "disabled" | "expired";
          cachedResult?: RunViewResult;
          fingerprint?: string;
          telemetryEventId?: string;
      }

      The pre-processing result

      • cacheStatus: "hit" | "miss" | "disabled" | "expired"
      • Optional cachedResult?: RunViewResult
      • Optional fingerprint?: string
      • Optional telemetryEventId?: string
    • Optional contextUser: UserInfo

      Optional user context

    Returns Promise<void>

  • Post-processing hook for RunViews (batch). Handles result transformation, cache storage, and telemetry end.

    Parameters

    • results: RunViewResult[]

      Array of view results

    • params: RunViewParams[]

      Array of view parameters

    • preResult: {
          allCached: boolean;
          cacheStatusMap?: Map<number, {
              result?: RunViewResult;
              status: "hit" | "miss" | "disabled" | "expired";
          }>;
          cachedResults?: RunViewResult[];
          smartCacheCheckParams?: RunViewWithCacheCheckParams[];
          telemetryEventId?: string;
          uncachedParams?: RunViewParams[];
          useSmartCacheCheck?: boolean;
      }

      The pre-processing result

      • allCached: boolean
      • Optional cacheStatusMap?: Map<number, {
            result?: RunViewResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>
      • Optional cachedResults?: RunViewResult[]
      • Optional smartCacheCheckParams?: RunViewWithCacheCheckParams[]

        When CacheLocal is enabled, contains the cache check params to send to server

      • Optional telemetryEventId?: string
      • Optional uncachedParams?: RunViewParams[]
      • Optional useSmartCacheCheck?: boolean

        When CacheLocal is enabled, indicates we should use smart cache check

    • Optional contextUser: UserInfo

      Optional user context

    Returns Promise<void>

  • Type Parameters

    • T = any

    Parameters

    Returns Promise<void>

    Deprecated

    Use PreRunView instead. This method is kept for backward compatibility.

  • Base class implementation for handling pre-processing of RunViews() each sub-class should call this within their RunViews() method implementation

    Parameters

    Returns Promise<void>

  • Pre-processing hook for RunQueries (batch). Handles telemetry for batch query operations.

    Parameters

    Returns Promise<{
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunQueryResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunQueryResult[];
        telemetryEventId?: string;
        uncachedParams?: RunQueryParams[];
    }>

    Pre-processing result

  • Pre-processing hook for RunQuery. Handles telemetry and cache lookup.

    Parameters

    Returns Promise<{
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunQueryResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }>

    Pre-processing result with cache status and optional cached result

  • Pre-processing hook for RunView. Handles telemetry, validation, entity status check, and cache lookup.

    Parameters

    Returns Promise<{
        cacheStatus: "hit" | "miss" | "disabled" | "expired";
        cachedResult?: RunViewResult;
        fingerprint?: string;
        telemetryEventId?: string;
    }>

    Pre-processing result with cache status and optional cached result

  • Pre-processing hook for RunViews (batch). Handles telemetry, validation, and cache lookup for multiple views.

    Parameters

    Returns Promise<{
        allCached: boolean;
        cacheStatusMap?: Map<number, {
            result?: RunViewResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>;
        cachedResults?: RunViewResult[];
        smartCacheCheckParams?: RunViewWithCacheCheckParams[];
        telemetryEventId?: string;
        uncachedParams?: RunViewParams[];
        useSmartCacheCheck?: boolean;
    }>

    Pre-processing result with cache status for each view

  • Processes entity rows returned from SQL Server to handle:

    1. Timezone conversions for datetime fields
    2. Field-level decryption for encrypted fields

    This method specifically handles the conversion of datetime2 fields (which SQL Server returns without timezone info) to proper UTC dates, preventing JavaScript from incorrectly interpreting them as local time.

    For encrypted fields, this method decrypts values at the data provider level. API-level filtering (AllowDecryptInAPI/SendEncryptedValue) is handled by the GraphQL layer.

    Parameters

    • rows: any[]

      The raw result rows from SQL Server

    • entityInfo: EntityInfo

      The entity metadata to determine field types

    • Optional contextUser: UserInfo

      Optional user context for decryption operations

    Returns Promise<any[]>

    The processed rows with corrected datetime values and decrypted fields

    Security

    Encrypted fields are decrypted here for internal use. The API layer handles response filtering based on AllowDecryptInAPI settings.

  • Refreshes all metadata from the server. Respects the AllowRefresh flag from subclasses.

    Parameters

    Returns Promise<boolean>

    True if refresh was initiated or allowed

  • This method will check to see if the where clause for the view provided has any templating within it, and if it does will replace the templating with the appropriate run-time values. This is done recursively with depth-first traversal so that if there are nested templates, they will be replaced as well. We also maintain a stack to ensure that any possible circular references are caught and an error is thrown if that is the case.

    Parameters

    Returns Promise<string>

  • Runs multiple queries based on the provided parameters. This method orchestrates the full execution flow for batch query operations.

    Parameters

    • params: RunQueryParams[]

      Array of query parameters

    • Optional contextUser: UserInfo

      Optional user context for permissions (required server-side)

    Returns Promise<RunQueryResult[]>

    Array of query results

  • Runs a query based on the provided parameters. This method orchestrates the full execution flow: pre-processing, cache check, internal execution, post-processing, and cache storage.

    Parameters

    • params: RunQueryParams

      The query parameters

    • Optional contextUser: UserInfo

      Optional user context for permissions (required server-side)

    Returns Promise<RunQueryResult>

    The query results

  • Runs a view based on the provided parameters. This method orchestrates the full execution flow: pre-processing, cache check, internal execution, post-processing, and cache storage.

    Type Parameters

    • T = any

    Parameters

    • params: RunViewParams

      The view parameters

    • Optional contextUser: UserInfo

      Optional user context for permissions (required server-side)

    Returns Promise<RunViewResult<T>>

    The view results

  • Runs multiple views based on the provided parameters. This method orchestrates the full execution flow for batch operations.

    Type Parameters

    • T = any

    Parameters

    • params: RunViewParams[]

      Array of view parameters

    • Optional contextUser: UserInfo

      Optional user context for permissions (required server-side)

    Returns Promise<RunViewResult<T>[]>

    Array of view results

  • Transforms the result set from simple objects to entity objects if needed.

    Parameters

    • param: RunViewParams

      The RunViewParams used for the request

    • result: RunViewResult

      The RunViewResult returned from the request

    • Optional contextUser: UserInfo

      The user context for permissions

    Returns Promise<void>

  • Updates the local metadata cache with new data.

    Parameters

    Returns void

  • Private

    Internal centralized method for executing SQL queries with consistent transaction and connection handling. This method ensures proper request object creation and management to avoid concurrency issues, particularly when using transactions where multiple operations may execute in parallel.

    Parameters

    • query: string

      The SQL query to execute

    • Optional parameters: any

      Optional parameters for the query (array for positional, object for named)

    • Optional connectionSource: ConnectionPool | Transaction | Request

      Optional specific connection source (pool, transaction, or request)

    • Optional loggingOptions: {
          contextUser?: UserInfo;
          description?: string;
          ignoreLogging?: boolean;
          isMutation?: boolean;
          simpleSQLFallback?: string;
      }

      Optional logging configuration

      • Optional contextUser?: UserInfo
      • Optional description?: string
      • Optional ignoreLogging?: boolean
      • Optional isMutation?: boolean
      • Optional simpleSQLFallback?: string

    Returns Promise<IResult<any>>

    Promise<sql.IResult> - The raw mssql result object

    Remarks

    • Always creates a new Request object for each query to avoid "EREQINPROG" errors
    • Handles both positional (?) and named (@param) parameter styles
    • Automatically uses active transaction if one exists, otherwise uses connection pool
    • Handles SQL logging in parallel with query execution
    • Provides automatic retry with pool connection if transaction fails

    Throws

    Rethrows any SQL execution errors after logging

  • Internal SQL execution method for instance calls - routes queries based on transaction state

    • Queries without transactions execute directly (allowing parallelism)
    • Queries within transactions go through the instance queue (ensuring serialization)

    Parameters

    • query: string
    • parameters: any
    • context: SQLExecutionContext
    • Optional options: InternalSQLOptions

    Returns Promise<IResult<any>>

  • Internal method to log SQL statement to all active logging sessions. This is called automatically by ExecuteSQL methods.

    Parameters

    • query: string

      The SQL query being executed

    • Optional parameters: any

      Parameters for the query

    • Optional description: string

      Optional description for this operation

    • ignoreLogging: boolean = false

      If true, this statement will not be logged

    • isMutation: boolean = false

      Whether this is a data mutation operation

    • Optional simpleSQLFallback: string

      Optional simple SQL to use for loggers with logRecordChangeMetadata=false

    • Optional contextUser: UserInfo

    Returns Promise<void>

  • Applies pagination to query results based on StartRow and MaxRows parameters

    Parameters

    Returns {
        paginatedResult: any[];
        totalRowCount: number;
    }

    • paginatedResult: any[]
    • totalRowCount: number
  • Recursively escapes quotes in all string properties of an object or array. This method traverses through nested objects and arrays, escaping the specified quote character in all string values to prevent SQL injection and syntax errors.

    Parameters

    • obj: any

      The object, array, or primitive value to process

    • quoteToEscape: string

      The quote character to escape (typically single quote "'")

    Returns any

    A new object/array with all string values having quotes properly escaped. Non-string values are preserved as-is.

    Example

    // Escaping single quotes in a nested object
    const input = {
    name: "John's Company",
    details: {
    description: "It's the best",
    tags: ["Won't fail", "Can't stop"]
    }
    };
    const escaped = this.escapeQuotesInProperties(input, "'");
    // Result: {
    // name: "John''s Company",
    // details: {
    // description: "It''s the best",
    // tags: ["Won''t fail", "Can''t stop"]
    // }
    // }

    Remarks

    This method is essential for preparing data to be embedded in SQL strings. It handles:

    • Nested objects of any depth
    • Arrays (including arrays of objects)
    • Mixed-type objects with strings, numbers, booleans, null values
    • Circular references are NOT handled and will cause stack overflow
  • Executes the query and tracks execution time

    Parameters

    • sql: string
    • Optional contextUser: UserInfo

    Returns Promise<{
        executionTime: number;
        result: any[];
    }>

  • Parameters

    • viewId: number
    • entityBaseView: string
    • whereSQL: string
    • orderBySQL: string
    • user: UserInfo

    Returns Promise<{
        executeViewSQL: string;
        runID: string;
    }>

  • Finds a query by ID or by Name+Category combination. Supports both direct CategoryID lookup and hierarchical CategoryPath path resolution.

    Parameters

    • QueryID: string

      Unique identifier for the query

    • QueryName: string

      Name of the query to find

    • CategoryID: string

      Direct category ID for the query

    • CategoryPath: string

      Hierarchical category path (e.g., "/MJ/AI/Agents/") or simple category name

    • refreshMetadataIfNotFound: boolean = false

      Whether to refresh metadata if query is not found

    Returns Promise<QueryInfo>

    The found QueryInfo or null if not found

  • Generates the stored procedure parameters for a save operation.

    This method handles:

    • Value type conversions (datetimeoffset, uniqueidentifier, etc.)
    • Field-level encryption for fields marked with Encrypt=true
    • Primary key handling for create/update operations

    Parameters

    • entity: BaseEntity<unknown>

      The entity being saved

    • isUpdate: boolean

      Whether this is an update (true) or create (false) operation

    • Optional contextUser: UserInfo

      The user context for encryption operations

    Returns Promise<{
        execParams: string;
        setSQL: string;
        simpleParams: string;
        variablesSQL: string;
    }>

    An object containing the SQL components for the stored procedure call

    Security

    Fields with Encrypt=true are encrypted before being sent to the database. Encryption uses the key specified in EncryptionKeyID.

  • Executes a batched cache status check for multiple queries using their CacheValidationSQL.

    Parameters

    Returns Promise<Map<number, {
        errorMessage?: string;
        maxUpdatedAt?: string;
        rowCount?: number;
        success: boolean;
    }>>

  • Executes a batched cache status check for multiple views in a single SQL call. Uses multiple result sets to return status for each view efficiently.

    Parameters

    Returns Promise<Map<number, {
        errorMessage?: string;
        maxUpdatedAt?: string;
        rowCount?: number;
        success: boolean;
    }>>

  • Compares client cache status with server status to determine if cache is current.

    Parameters

    • clientStatus: {
          maxUpdatedAt: string;
          rowCount: number;
      }
      • maxUpdatedAt: string
      • rowCount: number
    • serverStatus: {
          maxUpdatedAt?: string;
          rowCount?: number;
      }
      • Optional maxUpdatedAt?: string
      • Optional rowCount?: number

    Returns boolean

  • Merges cached and fresh results for RunViews, maintaining original order.

    Parameters

    • preResult: {
          allCached: boolean;
          cacheStatusMap?: Map<number, {
              result?: RunViewResult;
              status: "hit" | "miss" | "disabled" | "expired";
          }>;
          cachedResults?: RunViewResult[];
          smartCacheCheckParams?: RunViewWithCacheCheckParams[];
          telemetryEventId?: string;
          uncachedParams?: RunViewParams[];
          useSmartCacheCheck?: boolean;
      }

      The pre-processing result with cache info

      • allCached: boolean
      • Optional cacheStatusMap?: Map<number, {
            result?: RunViewResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>
      • Optional cachedResults?: RunViewResult[]
      • Optional smartCacheCheckParams?: RunViewWithCacheCheckParams[]

        When CacheLocal is enabled, contains the cache check params to send to server

      • Optional telemetryEventId?: string
      • Optional uncachedParams?: RunViewParams[]
      • Optional useSmartCacheCheck?: boolean

        When CacheLocal is enabled, indicates we should use smart cache check

    • freshResults: RunViewResult[]

      The fresh results from InternalRunViews

    Returns RunViewResult[]

    Combined results in original order

  • Merges cached and fresh results for RunQueries, maintaining original order.

    Parameters

    • preResult: {
          allCached: boolean;
          cacheStatusMap?: Map<number, {
              result?: RunQueryResult;
              status: "hit" | "miss" | "disabled" | "expired";
          }>;
          cachedResults?: RunQueryResult[];
          telemetryEventId?: string;
          uncachedParams?: RunQueryParams[];
      }

      The pre-processing result with cache info

      • allCached: boolean
      • Optional cacheStatusMap?: Map<number, {
            result?: RunQueryResult;
            status: "hit" | "miss" | "disabled" | "expired";
        }>
      • Optional cachedResults?: RunQueryResult[]
      • Optional telemetryEventId?: string
      • Optional uncachedParams?: RunQueryParams[]
    • freshResults: RunQueryResult[]

      The fresh results from InternalRunQueries

    Returns RunQueryResult[]

    Combined results in original order

  • Returns a string that packages the parameter value for the stored procedure call. It will handle quoting the value based on the quoteString provided and will also handle null values by returning 'NULL' as a string. Finally, the prefix is used for unicode fields to add the 'N' prefix if needed.

    Parameters

    • paramValue: any
    • quoteString: string
    • unicodePrefix: string

    Returns string

  • Processes query parameters and applies template substitution if needed

    Parameters

    • query: QueryInfo
    • Optional parameters: Record<string, any>

    Returns {
        appliedParameters: Record<string, any>;
        finalSQL: string;
    }

    • appliedParameters: Record<string, any>
    • finalSQL: string
  • Resolves a hierarchical category path (e.g., "/MJ/AI/Agents/") to a CategoryID. The path is split by "/" and each segment is matched case-insensitively against category names, walking down the hierarchy from root to leaf.

    Parameters

    • categoryPath: string

      The hierarchical category path (e.g., "/MJ/AI/Agents/")

    Returns string

    The CategoryID if the path exists, null otherwise

  • Tests how the database driver handles datetimeoffset fields. This empirical test determines if we need to adjust for incorrect timezone handling.

    Returns Promise<void>

  • Static method to execute a batch of SQL queries using a provided connection source. This allows the batch logic to be reused from external contexts like TransactionGroup. All queries are combined into a single SQL statement and executed together within the same connection/transaction context for optimal performance.

    Parameters

    • connectionSource: ConnectionPool | Transaction | Request

      Either a sql.ConnectionPool, sql.Transaction, or sql.Request to use for execution

    • queries: string[]

      Array of SQL queries to execute

    • Optional parameters: any[][]

      Optional array of parameter arrays, one for each query

    • Optional contextUser: UserInfo

    Returns Promise<any[][]>

    Promise<any[][]> - Array of result arrays, one for each query

  • Static helper method for executing SQL queries on an external connection pool. This method is designed to be used by generated code where a connection pool is passed in from the context. It returns results as arrays for consistency with the expected behavior in generated resolvers.

    Parameters

    • pool: ConnectionPool

      The mssql ConnectionPool to execute the query on

    • query: string

      The SQL query to execute

    • Optional parameters: any

      Optional parameters for the query

    • Optional contextUser: UserInfo

    Returns Promise<any[]>

    Promise<any[]> - Array of results (empty array if no results)

  • Static method to log SQL statements from external sources like transaction groups

    Parameters

    • query: string

      The SQL query being executed

    • Optional parameters: any

      Parameters for the query

    • Optional description: string

      Optional description for this operation

    • isMutation: boolean = false

      Whether this is a data mutation operation

    • Optional simpleSQLFallback: string

      Optional simple SQL to use for loggers with logRecordChangeMetadata=false

    • Optional contextUser: UserInfo

    Returns Promise<void>

  • Static SQL execution method - for static methods like ExecuteSQLWithPool Static methods don't have access to instance queues, so they execute directly Transactions are not supported in static context

    Parameters

    • query: string
    • parameters: any
    • context: SQLExecutionContext
    • Optional options: InternalSQLOptions

    Returns Promise<IResult<any>>