forge-sql-orm
Version:
Drizzle ORM integration for Atlassian @forge/sql. Provides a custom driver, schema migration, two levels of caching (local and global via @forge/kvs), optimistic locking, and query analysis.
163 lines • 7.7 kB
TypeScript
import { AnyColumn } from "drizzle-orm";
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
import { PrimaryKeyBuilder } from "drizzle-orm/mysql-core/primary-keys";
import { AnyIndexBuilder } from "drizzle-orm/mysql-core/indexes";
import { CheckBuilder } from "drizzle-orm/mysql-core/checks";
import { ForeignKeyBuilder } from "drizzle-orm/mysql-core/foreign-keys";
import { UniqueConstraintBuilder } from "drizzle-orm/mysql-core/unique-constraint";
import { SelectedFields } from "drizzle-orm/mysql-core/query-builders/select.types";
import { ForgeSqlOperation } from "../core";
import { ColumnDataType } from "drizzle-orm/column-builder";
import { AnyMySqlColumn } from "drizzle-orm/mysql-core/columns/common";
import type { ColumnBaseConfig } from "drizzle-orm/column";
import { TriggerResponse } from "../webtriggers";
/**
* Interface representing table metadata information
*/
export interface MetadataInfo {
/** The name of the table */
tableName: string;
/** Record of column names and their corresponding column definitions */
columns: Record<string, AnyColumn>;
/** Array of index builders */
indexes: AnyIndexBuilder[];
/** Array of check constraint builders */
checks: CheckBuilder[];
/** Array of foreign key builders */
foreignKeys: ForeignKeyBuilder[];
/** Array of primary key builders */
primaryKeys: PrimaryKeyBuilder[];
/** Array of unique constraint builders */
uniqueConstraints: UniqueConstraintBuilder[];
/** Array of all extra builders */
extras: any[];
}
/**
* Parses a date string into a Date object using the specified format
* @param value - The date string to parse or Date
* @param format - The format to use for parsing
* @returns Date object
*/
export declare const parseDateTime: (value: string | Date, format: string) => Date;
/**
* Helper function to validate and format a date-like value using Luxon DateTime.
* @param value - Date object, ISO/RFC2822/SQL/HTTP string, or timestamp (number|string).
* @param format - DateTime format string (Luxon format tokens).
* @param isTimeStamp - Whether to validate timestamp range
* @returns Formatted date string.
* @throws Error if value cannot be parsed as a valid date.
*/
export declare function formatDateTime(value: Date | string | number, format: string, isTimeStamp: boolean): string;
/**
* Gets primary keys from the schema.
* @template T - The type of the table schema
* @param {T} table - The table schema
* @returns {[string, AnyColumn][]} Array of primary key name and column pairs
*/
export declare function getPrimaryKeys<T extends AnyMySqlTable>(table: T): [string, AnyColumn][];
/**
* Extracts table metadata from the schema.
* @param {AnyMySqlTable} table - The table schema
* @returns {MetadataInfo} Object containing table metadata
*/
export declare function getTableMetadata(table: AnyMySqlTable): MetadataInfo;
/**
* Generates SQL statements for dropping tables and/or their sequences.
*
* @param tables - List of table names to generate DROP statements for.
* @param options - Configuration object:
* - sequence: whether to drop associated sequences (default: true)
* - table: whether to drop tables themselves (default: true)
* @returns Array of SQL statements for dropping the specified objects
*/
export declare function generateDropTableStatements(tables: string[], options?: {
sequence: boolean;
table: boolean;
}): string[];
type AliasColumnMap = Record<string, AnyColumn>;
export declare function mapSelectAllFieldsToAlias(selections: any, name: string, uniqName: string, fields: any, aliasMap: AliasColumnMap): any;
export declare function mapSelectFieldsWithAlias<TSelection extends SelectedFields>(fields: TSelection): {
selections: TSelection;
aliasMap: AliasColumnMap;
};
export declare function applyFromDriverTransform<T, TSelection>(rows: T[], selections: TSelection, aliasMap: Record<string, AnyColumn>): T[];
export declare function formatLimitOffset(limitOrOffset: number): number;
export declare function nextVal(sequenceName: string): number;
/**
* Analyzes and prints query performance data from CLUSTER_STATEMENTS_SUMMARY table.
*
* This function queries the CLUSTER_STATEMENTS_SUMMARY table to find queries that were executed
* within the specified time window and prints detailed performance information including:
* - SQL query text
* - Memory usage (average and max in MB)
* - Execution time (average in ms)
* - Number of executions
* - Execution plan
*
* @param forgeSQLORM - The ForgeSQL operation instance for database access
* @param timeDiffMs - Time window in milliseconds to look back for queries (e.g., 1500 for last 1.5 seconds)
* @param timeout - Optional timeout in milliseconds for the query execution (defaults to 3000ms)
*
* @example
* ```typescript
* // Analyze queries from the last 2 seconds
* await printQueriesWithPlan(forgeSQLORM, 2000);
*
* // Analyze queries with custom timeout
* await printQueriesWithPlan(forgeSQLORM, 1000, 3000);
* ```
*
* @throws Does not throw - errors are logged to console.debug instead
*/
export declare function printQueriesWithPlan(forgeSQLORM: ForgeSqlOperation, timeDiffMs: number, timeout?: number): Promise<void>;
export declare function handleErrorsWithPlan(forgeSQLORM: ForgeSqlOperation, timeDiffMs: number, type: "OOM" | "TIMEOUT"): Promise<void>;
/**
* Analyzes and logs slow queries from the last specified number of hours.
*
* This function queries the slow query system table to find queries that were executed
* within the specified time window and logs detailed performance information including:
* - SQL query text
* - Maximum memory usage (in MB)
* - Query execution time (in ms)
* - Execution count
* - Execution plan
*
* @param forgeSQLORM - The ForgeSQL operation instance for database access
* @param hours - Number of hours to look back for slow queries (e.g., 1 for last hour, 24 for last day)
* @param timeout - Optional timeout in milliseconds for the query execution (defaults to 1500ms)
*
* @example
* ```typescript
* // Analyze slow queries from the last hour
* await slowQueryPerHours(forgeSQLORM, 1);
*
* // Analyze slow queries from the last 24 hours with custom timeout
* await slowQueryPerHours(forgeSQLORM, 24, 3000);
*
* // Analyze slow queries from the last 6 hours
* await slowQueryPerHours(forgeSQLORM, 6);
* ```
*
* @throws Does not throw - errors are logged to console.debug instead
*/
export declare function slowQueryPerHours(forgeSQLORM: ForgeSqlOperation, hours: number, timeout?: number): Promise<string[]>;
/**
* Executes a promise with a timeout.
*
* @param promise - The promise to execute
* @param timeoutMs - Timeout in milliseconds
* @returns Promise that resolves with the result or rejects on timeout
* @throws {Error} When the operation times out
*/
export declare function withTimeout<T>(promise: Promise<T>, message: string, timeoutMs: number): Promise<T>;
export declare function withTidbHint<TDataType extends ColumnDataType, TPartial extends Partial<ColumnBaseConfig<TDataType, string>>>(column: AnyMySqlColumn<TPartial>): AnyMySqlColumn<TPartial>;
/**
* Checks if the current environment is production and returns an error response if so.
* This function is used to prevent development-only operations from running in production.
*
* @param functionName - The name of the function being checked (for logging purposes)
* @returns {TriggerResponse<string> | null} Returns error response if in production, null otherwise
*/
export declare function checkProductionEnvironment(functionName: string): TriggerResponse<string> | null;
export {};
//# sourceMappingURL=sqlUtils.d.ts.map