Skip to content

Commit 5834c74

Browse files
feat: sql compare (#76)
1 parent 4177f62 commit 5834c74

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

docs/jest-otel/syntax/db-pg.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ So, a complete assertion can look like:
3030
expectTrace(traceloop.serviceByName('orders-service'))
3131
.toQueryPostgreSQL()
3232
.withDatabaseName('postgres')
33+
.withOperationAndTable('INSERT', 'orders')
3334
.withStatement(
3435
/INSERT INTO orders \(id, price_in_cents\) VALUES \('[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}', [0-9]+\)/,
3536
{ compareType: COMPARE_TYPE.REGEX },

packages/expect-opentelemetry/src/matchers/service/to-query-postgresql.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('postgresql query', () => {
2424
expectTrace(traceloop.serviceByName('orders-service'))
2525
.toQueryPostgreSQL()
2626
.withDatabaseName('postgres', { compareType: COMPARE_TYPE.EQUALS })
27+
.withOperationAndTable('INSERT', 'orders')
2728
.withStatement(
2829
/INSERT INTO orders \(id, price_in_cents\) VALUES \('[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}', [0-9]+\)/,
2930
{ compareType: COMPARE_TYPE.REGEX },

packages/expect-opentelemetry/src/matchers/utils/filters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const filterByAttributeKey = (
77
attName: string,
88
) =>
99
spans.filter((span) => {
10-
span.attributes?.find((attribute) => {
10+
return span.attributes?.find((attribute) => {
1111
return attribute.key === attName;
1212
});
1313
});

packages/expect-opentelemetry/src/resources/postgresql-query.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class PostgreSQLQuery {
1111
private readonly serviceName: string,
1212
) {}
1313

14-
withDatabaseName(name: string | RegExp, options: CompareOptions) {
14+
withDatabaseName(name: string | RegExp, options?: CompareOptions) {
1515
const filteredSpans = filterByAttributeStringValue(
1616
this.spans,
1717
SemanticAttributes.DB_NAME,
@@ -28,7 +28,7 @@ export class PostgreSQLQuery {
2828
return new PostgreSQLQuery(filteredSpans, this.serviceName);
2929
}
3030

31-
withStatement(statement: string | RegExp, options: CompareOptions) {
31+
withStatement(statement: string | RegExp, options?: CompareOptions) {
3232
const filteredSpans = filterByAttributeStringValue(
3333
this.spans,
3434
SemanticAttributes.DB_STATEMENT,
@@ -44,4 +44,28 @@ export class PostgreSQLQuery {
4444

4545
return new PostgreSQLQuery(filteredSpans, this.serviceName);
4646
}
47+
48+
withOperationAndTable(operation: string, table: string) {
49+
const regex = new RegExp(`${operation}.*${table}`, 'i'); // case insensitive
50+
51+
const filteredSpans = this.spans.filter((span) => {
52+
const statement = span.attributes?.find(
53+
(attribute) => attribute.key === SemanticAttributes.DB_STATEMENT,
54+
)?.value?.stringValue;
55+
56+
if (!statement) {
57+
return false;
58+
}
59+
60+
return regex.test(statement);
61+
});
62+
63+
if (filteredSpans.length === 0) {
64+
throw new Error(
65+
`No query by ${this.serviceName} to postgresql with operation ${operation} and table ${table} was found`,
66+
);
67+
}
68+
69+
return new PostgreSQLQuery(filteredSpans, this.serviceName);
70+
}
4771
}

0 commit comments

Comments
 (0)