diff --git a/lib/player/db/postgres.go b/lib/player/db/postgres.go index 94cf5a9efd519..b06da70f13afd 100644 --- a/lib/player/db/postgres.go +++ b/lib/player/db/postgres.go @@ -98,7 +98,18 @@ func (p *PostgresTranslator) TranslateEvent(evt events.AuditEvent) *events.Sessi const lineBreak = "\r\n" func (p *PostgresTranslator) generateCommandPrint(metadata events.DatabaseMetadata, command string) string { - return lineBreak + fmt.Sprintf("%s=> %s", metadata.DatabaseName, command) + lineBreak + lead := metadata.DatabaseName + "=> " + leadSpacing := strings.Repeat(" ", len(lead)) + + var sb strings.Builder + commandLines := strings.Split(command, "\n") + sb.WriteString(lead + strings.TrimSpace(commandLines[0]) + lineBreak) + + for i := 1; i < len(commandLines); i++ { + sb.WriteString(leadSpacing + strings.TrimSpace(commandLines[i]) + lineBreak) + } + + return lineBreak + sb.String() } func (p *PostgresTranslator) generatePreparedStatementPrint(metadata events.Metadata, databaseMetadata events.DatabaseMetadata, portalName string) *events.SessionPrint { diff --git a/lib/player/db/postgres_test.go b/lib/player/db/postgres_test.go index f174d3d277d53..cbd6accb7f530 100644 --- a/lib/player/db/postgres_test.go +++ b/lib/player/db/postgres_test.go @@ -344,6 +344,67 @@ func TestPostgresRecording(t *testing.T) { nil, }, }, + "queries with line spacing": { + events: []events.AuditEvent{ + &events.DatabaseSessionQuery{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + DatabaseQuery: "SELECT \n1;", + }, + &events.DatabaseSessionCommandResult{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + Status: events.Status{Success: true}, + AffectedRecords: 1, + }, + &events.DatabaseSessionQuery{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + DatabaseQuery: "SELECT *\nfrom events\nlimit 1;", + }, + &events.DatabaseSessionCommandResult{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + Status: events.Status{Success: true}, + AffectedRecords: 1, + }, + &events.DatabaseSessionQuery{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + DatabaseQuery: "SELECT *\r\nfrom events\r\nlimit 1;", + }, + &events.DatabaseSessionCommandResult{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + Status: events.Status{Success: true}, + AffectedRecords: 1, + }, + &events.DatabaseSessionQuery{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + DatabaseQuery: "SELECT *\r\nfrom events\r\nlimit 1;", + }, + &events.DatabaseSessionCommandResult{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + Status: events.Status{Success: true}, + AffectedRecords: 1, + }, + &events.DatabaseSessionQuery{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + DatabaseQuery: "SELECT *\t\r\n from events\t\r\n limit 1;", + }, + &events.DatabaseSessionCommandResult{ + DatabaseMetadata: events.DatabaseMetadata{DatabaseName: "test"}, + Status: events.Status{Success: true}, + AffectedRecords: 1, + }, + }, + expectedPrints: [][]byte{ + []byte("\r\ntest=> SELECT\r\n 1;\r\n"), + []byte("SUCCESS\r\n(1 row affected)\r\n"), + []byte("\r\ntest=> SELECT *\r\n from events\r\n limit 1;\r\n"), + []byte("SUCCESS\r\n(1 row affected)\r\n"), + []byte("\r\ntest=> SELECT *\r\n from events\r\n limit 1;\r\n"), + []byte("SUCCESS\r\n(1 row affected)\r\n"), + []byte("\r\ntest=> SELECT *\r\n from events\r\n limit 1;\r\n"), + []byte("SUCCESS\r\n(1 row affected)\r\n"), + []byte("\r\ntest=> SELECT *\r\n from events\r\n limit 1;\r\n"), + []byte("SUCCESS\r\n(1 row affected)\r\n"), + }, + }, } { t.Run(name, func(t *testing.T) { translator := NewPostgresTranslator()