From 3b7deaa10773db867573a26c2bd86ccb15393210 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Tue, 25 Feb 2025 22:11:59 +0100 Subject: [PATCH] Update workspaces to query builder --- server/internal/db/workspaces.go | 289 +++++++++++++++++-------------- 1 file changed, 161 insertions(+), 128 deletions(-) diff --git a/server/internal/db/workspaces.go b/server/internal/db/workspaces.go index 1d7fcc8..06bff0c 100644 --- a/server/internal/db/workspaces.go +++ b/server/internal/db/workspaces.go @@ -25,51 +25,53 @@ func (db *database) CreateWorkspace(workspace *models.Workspace) error { return fmt.Errorf("failed to encrypt token: %w", err) } - result, err := db.Exec(` - INSERT INTO workspaces ( - user_id, name, theme, auto_save, show_hidden_files, - git_enabled, git_url, git_user, git_token, - git_auto_commit, git_commit_msg_template, - git_commit_name, git_commit_email - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - workspace.UserID, workspace.Name, workspace.Theme, workspace.AutoSave, workspace.ShowHiddenFiles, - workspace.GitEnabled, workspace.GitURL, workspace.GitUser, encryptedToken, - workspace.GitAutoCommit, workspace.GitCommitMsgTemplate, workspace.GitCommitName, workspace.GitCommitEmail, - ) + query := NewQuery(db.dbType). + Insert("workspaces", + "user_id", "name", "theme", "auto_save", "show_hidden_files", + "git_enabled", "git_url", "git_user", "git_token", + "git_auto_commit", "git_commit_msg_template", + "git_commit_name", "git_commit_email"). + Values(13). + AddArgs( + workspace.UserID, workspace.Name, workspace.Theme, workspace.AutoSave, workspace.ShowHiddenFiles, + workspace.GitEnabled, workspace.GitURL, workspace.GitUser, encryptedToken, + workspace.GitAutoCommit, workspace.GitCommitMsgTemplate, workspace.GitCommitName, workspace.GitCommitEmail). + Returning("id", "created_at") + + err = db.QueryRow(query.String(), query.Args()...). + Scan(&workspace.ID, &workspace.CreatedAt) if err != nil { return fmt.Errorf("failed to insert workspace: %w", err) } - id, err := result.LastInsertId() - if err != nil { - return fmt.Errorf("failed to get workspace ID: %w", err) - } - workspace.ID = int(id) - return nil } // GetWorkspaceByID retrieves a workspace by its ID func (db *database) GetWorkspaceByID(id int) (*models.Workspace, error) { + query := NewQuery(db.dbType). + Select( + "id", "user_id", "name", "created_at", + "theme", "auto_save", "show_hidden_files", + "git_enabled", "git_url", "git_user", "git_token", + "git_auto_commit", "git_commit_msg_template", + "git_commit_name", "git_commit_email", + "last_opened_file_path"). + From("workspaces"). + Where("id = ").Placeholder(id) + workspace := &models.Workspace{} var encryptedToken string - err := db.QueryRow(` - SELECT - id, user_id, name, created_at, - theme, auto_save, show_hidden_files, - git_enabled, git_url, git_user, git_token, - git_auto_commit, git_commit_msg_template, - git_commit_name, git_commit_email - FROM workspaces - WHERE id = ?`, - id, - ).Scan( + var lastOpenedFile sql.NullString + + err := db.QueryRow(query.String(), query.Args()...).Scan( &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, &workspace.Theme, &workspace.AutoSave, &workspace.ShowHiddenFiles, &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &encryptedToken, &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, &workspace.GitCommitName, &workspace.GitCommitEmail, + &lastOpenedFile, ) if err == sql.ErrNoRows { @@ -79,6 +81,10 @@ func (db *database) GetWorkspaceByID(id int) (*models.Workspace, error) { return nil, fmt.Errorf("failed to fetch workspace: %w", err) } + if lastOpenedFile.Valid { + workspace.LastOpenedFilePath = lastOpenedFile.String + } + // Decrypt token workspace.GitToken, err = db.decryptToken(encryptedToken) if err != nil { @@ -90,25 +96,29 @@ func (db *database) GetWorkspaceByID(id int) (*models.Workspace, error) { // GetWorkspaceByName retrieves a workspace by its name and user ID func (db *database) GetWorkspaceByName(userID int, workspaceName string) (*models.Workspace, error) { + query := NewQuery(db.dbType). + Select( + "id", "user_id", "name", "created_at", + "theme", "auto_save", "show_hidden_files", + "git_enabled", "git_url", "git_user", "git_token", + "git_auto_commit", "git_commit_msg_template", + "git_commit_name", "git_commit_email", + "last_opened_file_path"). + From("workspaces"). + Where("user_id = ").Placeholder(userID). + And("name = ").Placeholder(workspaceName) + workspace := &models.Workspace{} var encryptedToken string + var lastOpenedFile sql.NullString - err := db.QueryRow(` - SELECT - id, user_id, name, created_at, - theme, auto_save, show_hidden_files, - git_enabled, git_url, git_user, git_token, - git_auto_commit, git_commit_msg_template, - git_commit_name, git_commit_email - FROM workspaces - WHERE user_id = ? AND name = ?`, - userID, workspaceName, - ).Scan( + err := db.QueryRow(query.String(), query.Args()...).Scan( &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, &workspace.Theme, &workspace.AutoSave, &workspace.ShowHiddenFiles, &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &encryptedToken, &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, &workspace.GitCommitName, &workspace.GitCommitEmail, + &lastOpenedFile, ) if err == sql.ErrNoRows { @@ -118,6 +128,10 @@ func (db *database) GetWorkspaceByName(userID int, workspaceName string) (*model return nil, fmt.Errorf("failed to fetch workspace: %w", err) } + if lastOpenedFile.Valid { + workspace.LastOpenedFilePath = lastOpenedFile.String + } + // Decrypt token workspace.GitToken, err = db.decryptToken(encryptedToken) if err != nil { @@ -135,37 +149,24 @@ func (db *database) UpdateWorkspace(workspace *models.Workspace) error { return fmt.Errorf("failed to encrypt token: %w", err) } - _, err = db.Exec(` - UPDATE workspaces - SET - name = ?, - theme = ?, - auto_save = ?, - show_hidden_files = ?, - git_enabled = ?, - git_url = ?, - git_user = ?, - git_token = ?, - git_auto_commit = ?, - git_commit_msg_template = ?, - git_commit_name = ?, - git_commit_email = ? - WHERE id = ? AND user_id = ?`, - workspace.Name, - workspace.Theme, - workspace.AutoSave, - workspace.ShowHiddenFiles, - workspace.GitEnabled, - workspace.GitURL, - workspace.GitUser, - encryptedToken, - workspace.GitAutoCommit, - workspace.GitCommitMsgTemplate, - workspace.GitCommitName, - workspace.GitCommitEmail, - workspace.ID, - workspace.UserID, - ) + query := NewQuery(db.dbType). + Update("workspaces"). + Set("name").Placeholder(workspace.Name). + Set("theme").Placeholder(workspace.Theme). + Set("auto_save").Placeholder(workspace.AutoSave). + Set("show_hidden_files").Placeholder(workspace.ShowHiddenFiles). + Set("git_enabled").Placeholder(workspace.GitEnabled). + Set("git_url").Placeholder(workspace.GitURL). + Set("git_user").Placeholder(workspace.GitUser). + Set("git_token").Placeholder(encryptedToken). + Set("git_auto_commit").Placeholder(workspace.GitAutoCommit). + Set("git_commit_msg_template").Placeholder(workspace.GitCommitMsgTemplate). + Set("git_commit_name").Placeholder(workspace.GitCommitName). + Set("git_commit_email").Placeholder(workspace.GitCommitEmail). + Where("id = ").Placeholder(workspace.ID). + And("user_id = ").Placeholder(workspace.UserID) + + _, err = db.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to update workspace: %w", err) } @@ -175,17 +176,18 @@ func (db *database) UpdateWorkspace(workspace *models.Workspace) error { // GetWorkspacesByUserID retrieves all workspaces for a user func (db *database) GetWorkspacesByUserID(userID int) ([]*models.Workspace, error) { - rows, err := db.Query(` - SELECT - id, user_id, name, created_at, - theme, auto_save, show_hidden_files, - git_enabled, git_url, git_user, git_token, - git_auto_commit, git_commit_msg_template, - git_commit_name, git_commit_email - FROM workspaces - WHERE user_id = ?`, - userID, - ) + query := NewQuery(db.dbType). + Select( + "id", "user_id", "name", "created_at", + "theme", "auto_save", "show_hidden_files", + "git_enabled", "git_url", "git_user", "git_token", + "git_auto_commit", "git_commit_msg_template", + "git_commit_name", "git_commit_email", + "last_opened_file_path"). + From("workspaces"). + Where("user_id = ").Placeholder(userID) + + rows, err := db.Query(query.String(), query.Args()...) if err != nil { return nil, fmt.Errorf("failed to query workspaces: %w", err) } @@ -195,17 +197,23 @@ func (db *database) GetWorkspacesByUserID(userID int) ([]*models.Workspace, erro for rows.Next() { workspace := &models.Workspace{} var encryptedToken string + var lastOpenedFile sql.NullString err := rows.Scan( &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, &workspace.Theme, &workspace.AutoSave, &workspace.ShowHiddenFiles, &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &encryptedToken, &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, &workspace.GitCommitName, &workspace.GitCommitEmail, + &lastOpenedFile, ) if err != nil { return nil, fmt.Errorf("failed to scan workspace row: %w", err) } + if lastOpenedFile.Valid { + workspace.LastOpenedFilePath = lastOpenedFile.String + } + // Decrypt token workspace.GitToken, err = db.decryptToken(encryptedToken) if err != nil { @@ -224,34 +232,28 @@ func (db *database) GetWorkspacesByUserID(userID int) ([]*models.Workspace, erro // UpdateWorkspaceSettings updates only the settings portion of a workspace func (db *database) UpdateWorkspaceSettings(workspace *models.Workspace) error { - _, err := db.Exec(` - UPDATE workspaces - SET - theme = ?, - auto_save = ?, - show_hidden_files = ?, - git_enabled = ?, - git_url = ?, - git_user = ?, - git_token = ?, - git_auto_commit = ?, - git_commit_msg_template = ?, - git_commit_name = ?, - git_commit_email = ? - WHERE id = ?`, - workspace.Theme, - workspace.AutoSave, - workspace.ShowHiddenFiles, - workspace.GitEnabled, - workspace.GitURL, - workspace.GitUser, - workspace.GitToken, - workspace.GitAutoCommit, - workspace.GitCommitMsgTemplate, - workspace.GitCommitName, - workspace.GitCommitEmail, - workspace.ID, - ) + // Encrypt token before storing + encryptedToken, err := db.encryptToken(workspace.GitToken) + if err != nil { + return fmt.Errorf("failed to encrypt token: %w", err) + } + + query := NewQuery(db.dbType). + Update("workspaces"). + Set("theme").Placeholder(workspace.Theme). + Set("auto_save").Placeholder(workspace.AutoSave). + Set("show_hidden_files").Placeholder(workspace.ShowHiddenFiles). + Set("git_enabled").Placeholder(workspace.GitEnabled). + Set("git_url").Placeholder(workspace.GitURL). + Set("git_user").Placeholder(workspace.GitUser). + Set("git_token").Placeholder(encryptedToken). + Set("git_auto_commit").Placeholder(workspace.GitAutoCommit). + Set("git_commit_msg_template").Placeholder(workspace.GitCommitMsgTemplate). + Set("git_commit_name").Placeholder(workspace.GitCommitName). + Set("git_commit_email").Placeholder(workspace.GitCommitEmail). + Where("id = ").Placeholder(workspace.ID) + + _, err = db.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to update workspace settings: %w", err) } @@ -263,7 +265,12 @@ func (db *database) UpdateWorkspaceSettings(workspace *models.Workspace) error { func (db *database) DeleteWorkspace(id int) error { log := getLogger().WithGroup("workspaces") - _, err := db.Exec("DELETE FROM workspaces WHERE id = ?", id) + query := NewQuery(db.dbType). + Delete(). + From("workspaces"). + Where("id = ").Placeholder(id) + + _, err := db.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to delete workspace: %w", err) } @@ -275,7 +282,13 @@ func (db *database) DeleteWorkspace(id int) error { // DeleteWorkspaceTx removes a workspace record from the database within a transaction func (db *database) DeleteWorkspaceTx(tx *sql.Tx, id int) error { log := getLogger().WithGroup("workspaces") - result, err := tx.Exec("DELETE FROM workspaces WHERE id = ?", id) + + query := NewQuery(db.dbType). + Delete(). + From("workspaces"). + Where("id = ").Placeholder(id) + + result, err := tx.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to delete workspace in transaction: %w", err) } @@ -285,15 +298,18 @@ func (db *database) DeleteWorkspaceTx(tx *sql.Tx, id int) error { return fmt.Errorf("failed to get rows affected in transaction: %w", err) } - log.Debug("workspace deleted", - "workspace_id", id) + log.Debug("workspace deleted", "workspace_id", id) return nil } // UpdateLastWorkspaceTx sets the last workspace for a user in a transaction func (db *database) UpdateLastWorkspaceTx(tx *sql.Tx, userID, workspaceID int) error { - result, err := tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", - workspaceID, userID) + query := NewQuery(db.dbType). + Update("users"). + Set("last_workspace_id").Placeholder(workspaceID). + Where("id = ").Placeholder(userID) + + result, err := tx.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to update last workspace in transaction: %w", err) } @@ -308,8 +324,12 @@ func (db *database) UpdateLastWorkspaceTx(tx *sql.Tx, userID, workspaceID int) e // UpdateLastOpenedFile updates the last opened file path for a workspace func (db *database) UpdateLastOpenedFile(workspaceID int, filePath string) error { - _, err := db.Exec("UPDATE workspaces SET last_opened_file_path = ? WHERE id = ?", - filePath, workspaceID) + query := NewQuery(db.dbType). + Update("workspaces"). + Set("last_opened_file_path").Placeholder(filePath). + Where("id = ").Placeholder(workspaceID) + + _, err := db.Exec(query.String(), query.Args()...) if err != nil { return fmt.Errorf("failed to update last opened file: %w", err) } @@ -319,9 +339,13 @@ func (db *database) UpdateLastOpenedFile(workspaceID int, filePath string) error // GetLastOpenedFile retrieves the last opened file path for a workspace func (db *database) GetLastOpenedFile(workspaceID int) (string, error) { + query := NewQuery(db.dbType). + Select("last_opened_file_path"). + From("workspaces"). + Where("id = ").Placeholder(workspaceID) + var filePath sql.NullString - err := db.QueryRow("SELECT last_opened_file_path FROM workspaces WHERE id = ?", - workspaceID).Scan(&filePath) + err := db.QueryRow(query.String(), query.Args()...).Scan(&filePath) if err == sql.ErrNoRows { return "", fmt.Errorf("workspace not found") @@ -339,15 +363,17 @@ func (db *database) GetLastOpenedFile(workspaceID int) (string, error) { // GetAllWorkspaces retrieves all workspaces in the database func (db *database) GetAllWorkspaces() ([]*models.Workspace, error) { - rows, err := db.Query(` - SELECT - id, user_id, name, created_at, - theme, auto_save, show_hidden_files, - git_enabled, git_url, git_user, git_token, - git_auto_commit, git_commit_msg_template, - git_commit_name, git_commit_email - FROM workspaces`, - ) + query := NewQuery(db.dbType). + Select( + "id", "user_id", "name", "created_at", + "theme", "auto_save", "show_hidden_files", + "git_enabled", "git_url", "git_user", "git_token", + "git_auto_commit", "git_commit_msg_template", + "git_commit_name", "git_commit_email", + "last_opened_file_path"). + From("workspaces") + + rows, err := db.Query(query.String(), query.Args()...) if err != nil { return nil, fmt.Errorf("failed to query workspaces: %w", err) } @@ -357,17 +383,24 @@ func (db *database) GetAllWorkspaces() ([]*models.Workspace, error) { for rows.Next() { workspace := &models.Workspace{} var encryptedToken string + var lastOpenedFile sql.NullString + err := rows.Scan( &workspace.ID, &workspace.UserID, &workspace.Name, &workspace.CreatedAt, &workspace.Theme, &workspace.AutoSave, &workspace.ShowHiddenFiles, &workspace.GitEnabled, &workspace.GitURL, &workspace.GitUser, &encryptedToken, &workspace.GitAutoCommit, &workspace.GitCommitMsgTemplate, &workspace.GitCommitName, &workspace.GitCommitEmail, + &lastOpenedFile, ) if err != nil { return nil, fmt.Errorf("failed to scan workspace row: %w", err) } + if lastOpenedFile.Valid { + workspace.LastOpenedFilePath = lastOpenedFile.String + } + // Decrypt token workspace.GitToken, err = db.decryptToken(encryptedToken) if err != nil {