mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
Closes #17689 This PR optimizes the audit logs query performance by extracting the count operation into a separate query and replacing the OR-based workspace_builds with conditional joins. ## Query changes * Extracted count query to separate one * Replaced single `workspace_builds` join with OR conditions with separate conditional joins * Added conditional joins * `wb_build` for workspace_build audit logs (which is a direct lookup) * `wb_workspace` for workspace create audit logs (via workspace) Optimized AuditLogsOffset query: https://explain.dalibo.com/plan/4g1hbedg4a564bg8 New CountAuditLogs query: https://explain.dalibo.com/plan/ga2fbcecb9efbce3
98 lines
3.3 KiB
Go
98 lines
3.3 KiB
Go
package database
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/testutil"
|
|
)
|
|
|
|
func TestIsAuthorizedQuery(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
query := `SELECT true;`
|
|
_, err := insertAuthorizedFilter(query, "")
|
|
require.ErrorContains(t, err, "does not contain authorized replace string", "ensure replace string")
|
|
}
|
|
|
|
// TestWorkspaceTableConvert verifies all workspace fields are converted
|
|
// when reducing a `Workspace` to a `WorkspaceTable`.
|
|
// This test is a guard rail to prevent developer oversight mistakes.
|
|
func TestWorkspaceTableConvert(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
staticRandoms := &testutil.Random{
|
|
String: func() string { return "foo" },
|
|
Bool: func() bool { return true },
|
|
Int: func() int64 { return 500 },
|
|
Uint: func() uint64 { return 126 },
|
|
Float: func() float64 { return 3.14 },
|
|
Complex: func() complex128 { return 6.24 },
|
|
Time: func() time.Time {
|
|
return time.Date(2020, 5, 2, 5, 19, 21, 30, time.UTC)
|
|
},
|
|
}
|
|
|
|
// This feels a bit janky, but it works.
|
|
// If you use 'PopulateStruct' to create 2 workspaces, using the same
|
|
// "random" values for each type. Then they should be identical.
|
|
//
|
|
// So if 'workspace.WorkspaceTable()' was missing any fields in its
|
|
// conversion, the comparison would fail.
|
|
|
|
var workspace Workspace
|
|
err := testutil.PopulateStruct(&workspace, staticRandoms)
|
|
require.NoError(t, err)
|
|
|
|
var subset WorkspaceTable
|
|
err = testutil.PopulateStruct(&subset, staticRandoms)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, workspace.WorkspaceTable(), subset,
|
|
"'workspace.WorkspaceTable()' is not missing at least 1 field when converting to 'WorkspaceTable'. "+
|
|
"To resolve this, go to the 'func (w Workspace) WorkspaceTable()' and ensure all fields are converted.")
|
|
}
|
|
|
|
// TestAuditLogsQueryConsistency ensures that GetAuditLogsOffset and CountAuditLogs
|
|
// have identical WHERE clauses to prevent filtering inconsistencies.
|
|
// This test is a guard rail to prevent developer oversight mistakes.
|
|
func TestAuditLogsQueryConsistency(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
getWhereClause := extractWhereClause(getAuditLogsOffset)
|
|
require.NotEmpty(t, getWhereClause, "failed to extract WHERE clause from GetAuditLogsOffset")
|
|
|
|
countWhereClause := extractWhereClause(countAuditLogs)
|
|
require.NotEmpty(t, countWhereClause, "failed to extract WHERE clause from CountAuditLogs")
|
|
|
|
// Compare the WHERE clauses
|
|
if diff := cmp.Diff(getWhereClause, countWhereClause); diff != "" {
|
|
t.Errorf("GetAuditLogsOffset and CountAuditLogs WHERE clauses must be identical to ensure consistent filtering.\nDiff:\n%s", diff)
|
|
}
|
|
}
|
|
|
|
// extractWhereClause extracts the WHERE clause from a SQL query string
|
|
func extractWhereClause(query string) string {
|
|
// Find WHERE and get everything after it
|
|
wherePattern := regexp.MustCompile(`(?is)WHERE\s+(.*)`)
|
|
whereMatches := wherePattern.FindStringSubmatch(query)
|
|
if len(whereMatches) < 2 {
|
|
return ""
|
|
}
|
|
|
|
whereClause := whereMatches[1]
|
|
|
|
// Remove ORDER BY, LIMIT, OFFSET clauses from the end
|
|
whereClause = regexp.MustCompile(`(?is)\s+(ORDER BY|LIMIT|OFFSET).*$`).ReplaceAllString(whereClause, "")
|
|
|
|
// Remove SQL comments
|
|
whereClause = regexp.MustCompile(`(?m)--.*$`).ReplaceAllString(whereClause, "")
|
|
|
|
return strings.TrimSpace(whereClause)
|
|
}
|