Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/connectors/__tests__/sqlserver.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ describe('SQL Server Connector Integration Tests', () => {
expect(result.rows[0].value).toBe(1);
expect(result.messages).toBeDefined();
expect(result.messages!.length).toBeGreaterThan(0);
expect(result.messages).toContain('hello from sql server');
expect(result.messages!.some(msg => msg.text === 'hello from sql server')).toBe(true);
});

it('should capture SET STATISTICS TIME output in messages', async () => {
Expand All @@ -598,7 +598,7 @@ describe('SQL Server Connector Integration Tests', () => {
expect(result.messages!.length).toBeGreaterThan(0);
// STATISTICS TIME emits messages containing "CPU time" and "elapsed time"
const hasTimingMessage = result.messages!.some(
msg => msg.includes('CPU time') || msg.includes('elapsed time')
msg => msg.text.includes('CPU time') || msg.text.includes('elapsed time')
);
expect(hasTimingMessage).toBe(true);
});
Expand Down
19 changes: 18 additions & 1 deletion src/connectors/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,28 @@ export type ConnectorType = "postgres" | "mysql" | "mariadb" | "sqlite" | "sqlse
* Database Connector Interface
* This defines the contract that all database connectors must implement.
*/
/**
* An informational (non-error) message emitted by the database during query
* execution, e.g. SQL Server STATISTICS TIME/IO and PRINT output, or
* PostgreSQL NOTICE/WARNING. Modeled to be cross-database: only `text` is
* guaranteed, the rest are populated when the driver exposes them.
*/
export interface DatabaseMessage {
/** Human-readable message text */
text: string;
/** Severity indicator where available; interpret per database (PostgreSQL: level name like NOTICE/WARNING; SQL Server: numeric severity class as a string) */
severity?: string;
/** Database-specific message code (PostgreSQL: SQLSTATE; SQL Server: message number) */
code?: string | number;
/** 1-based line number within the SQL batch that produced the message, when reported */
line?: number;
}

export interface SQLResult {
rows: any[];
rowCount: number;
/** Informational messages from the database (e.g. SQL Server STATISTICS TIME/IO, PRINT output) */
messages?: string[];
messages?: DatabaseMessage[];
}

export interface TableColumn {
Expand Down
18 changes: 14 additions & 4 deletions src/connectors/sqlserver/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ConnectorRegistry,
DSNParser,
SQLResult,
DatabaseMessage,
TableColumn,
TableIndex,
StoredProcedure,
Expand Down Expand Up @@ -610,10 +611,19 @@ export class SQLServerConnector implements Connector {

// Create request and collect informational messages (e.g. SET STATISTICS TIME/IO, PRINT)
const request = this.connection.request();
const messages: string[] = [];
request.on('info', (info: { message: string }) => {
messages.push(info.message);
});
const messages: DatabaseMessage[] = [];
request.on(
'info',
(info: { message: string; number?: number; class?: number; lineNumber?: number }) => {
messages.push({
text: info.message,
// SQL Server reports severity as a numeric class; info messages are < 10.
severity: info.class !== undefined ? String(info.class) : undefined,
code: info.number,
line: info.lineNumber,
});
}
);

if (parameters && parameters.length > 0) {
// SQL Server uses @p1, @p2, etc. for parameters
Expand Down
Loading