Update users to query builder

This commit is contained in:
2025-02-25 21:37:06 +01:00
parent 802f192dc0
commit 9da51aeb5e

View File

@@ -17,26 +17,18 @@ func (db *database) CreateUser(user *models.User) (*models.User, error) {
} }
defer tx.Rollback() defer tx.Rollback()
result, err := tx.Exec(` query := NewQuery(db.dbType).
INSERT INTO users (email, display_name, password_hash, role) Insert("users", "email", "display_name", "password_hash", "role").
VALUES (?, ?, ?, ?)`, Values(4).
user.Email, user.DisplayName, user.PasswordHash, user.Role) AddArgs(user.Email, user.DisplayName, user.PasswordHash, user.Role).
Returning("id", "created_at")
err = tx.QueryRow(query.String(), query.Args()...).
Scan(&user.ID, &user.CreatedAt)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to insert user: %w", err) return nil, fmt.Errorf("failed to insert user: %w", err)
} }
userID, err := result.LastInsertId()
if err != nil {
return nil, fmt.Errorf("failed to get last insert ID: %w", err)
}
user.ID = int(userID)
// Retrieve the created_at timestamp
err = tx.QueryRow("SELECT created_at FROM users WHERE id = ?", user.ID).Scan(&user.CreatedAt)
if err != nil {
return nil, fmt.Errorf("failed to get created timestamp: %w", err)
}
// Create default workspace with default settings // Create default workspace with default settings
defaultWorkspace := &models.Workspace{ defaultWorkspace := &models.Workspace{
UserID: user.ID, UserID: user.ID,
@@ -51,7 +43,13 @@ func (db *database) CreateUser(user *models.User) (*models.User, error) {
} }
// Update user's last workspace ID // Update user's last workspace ID
_, err = tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", defaultWorkspace.ID, user.ID) query = NewQuery(db.dbType).
Update("users").
Set("last_workspace_id").
Placeholder(defaultWorkspace.ID).
Where("id = ").
Placeholder(user.ID)
_, err = tx.Exec(query.String(), query.Args()...)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to update last workspace ID: %w", err) return nil, fmt.Errorf("failed to update last workspace ID: %w", err)
} }
@@ -70,44 +68,43 @@ func (db *database) CreateUser(user *models.User) (*models.User, error) {
// Helper function to create a workspace in a transaction // Helper function to create a workspace in a transaction
func (db *database) createWorkspaceTx(tx *sql.Tx, workspace *models.Workspace) error { func (db *database) createWorkspaceTx(tx *sql.Tx, workspace *models.Workspace) error {
log := getLogger().WithGroup("users") log := getLogger().WithGroup("users")
result, err := tx.Exec(`
INSERT INTO workspaces ( insertQuery := NewQuery(db.dbType).
user_id, name, Insert("workspaces",
theme, auto_save, show_hidden_files, "user_id", "name",
git_enabled, git_url, git_user, git_token, "theme", "auto_save", "show_hidden_files",
git_auto_commit, git_commit_msg_template, "git_enabled", "git_url", "git_user", "git_token",
git_commit_name, git_commit_email "git_auto_commit", "git_commit_msg_template",
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "git_commit_name", "git_commit_email").
workspace.UserID, workspace.Name, Values(13).
workspace.Theme, workspace.AutoSave, workspace.ShowHiddenFiles, AddArgs(
workspace.GitEnabled, workspace.GitURL, workspace.GitUser, workspace.GitToken, workspace.UserID, workspace.Name,
workspace.GitAutoCommit, workspace.GitCommitMsgTemplate, workspace.Theme, workspace.AutoSave, workspace.ShowHiddenFiles,
workspace.GitCommitName, workspace.GitCommitEmail, workspace.GitEnabled, workspace.GitURL, workspace.GitUser, workspace.GitToken,
) workspace.GitAutoCommit, workspace.GitCommitMsgTemplate,
workspace.GitCommitName, workspace.GitCommitEmail).
Returning("id")
err := tx.QueryRow(insertQuery.String(), insertQuery.Args()...).Scan(&workspace.ID)
if err != nil { if err != nil {
return fmt.Errorf("failed to insert workspace: %w", err) 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)
log.Debug("created user workspace", log.Debug("created user workspace",
"workspace_id", workspace.ID, "workspace_id", workspace.ID,
"user_id", workspace.UserID) "user_id", workspace.UserID)
return nil return nil
} }
// GetUserByID retrieves a user by its ID
func (db *database) GetUserByID(id int) (*models.User, error) { func (db *database) GetUserByID(id int) (*models.User, error) {
query := NewQuery(db.dbType).
Select("id", "email", "display_name", "password_hash", "role", "created_at", "last_workspace_id").
From("users").
Where("id = ").Placeholder(id)
user := &models.User{} user := &models.User{}
err := db.QueryRow(` err := db.QueryRow(query.String(), query.Args()...).
SELECT
id, email, display_name, password_hash, role, created_at,
last_workspace_id
FROM users
WHERE id = ?`, id).
Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash, Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash,
&user.Role, &user.CreatedAt, &user.LastWorkspaceID) &user.Role, &user.CreatedAt, &user.LastWorkspaceID)
@@ -120,14 +117,15 @@ func (db *database) GetUserByID(id int) (*models.User, error) {
return user, nil return user, nil
} }
// GetUserByEmail retrieves a user by its email
func (db *database) GetUserByEmail(email string) (*models.User, error) { func (db *database) GetUserByEmail(email string) (*models.User, error) {
query := NewQuery(db.dbType).
Select("id", "email", "display_name", "password_hash", "role", "created_at", "last_workspace_id").
From("users").
Where("email = ").Placeholder(email)
user := &models.User{} user := &models.User{}
err := db.QueryRow(` err := db.QueryRow(query.String(), query.Args()...).
SELECT
id, email, display_name, password_hash, role, created_at,
last_workspace_id
FROM users
WHERE email = ?`, email).
Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash, Scan(&user.ID, &user.Email, &user.DisplayName, &user.PasswordHash,
&user.Role, &user.CreatedAt, &user.LastWorkspaceID) &user.Role, &user.CreatedAt, &user.LastWorkspaceID)
@@ -141,14 +139,18 @@ func (db *database) GetUserByEmail(email string) (*models.User, error) {
return user, nil return user, nil
} }
// UpdateUser updates an existing user record in the database
func (db *database) UpdateUser(user *models.User) error { func (db *database) UpdateUser(user *models.User) error {
result, err := db.Exec(` query := NewQuery(db.dbType).
UPDATE users Update("users").
SET email = ?, display_name = ?, password_hash = ?, role = ?, last_workspace_id = ? Set("email").Placeholder(user.Email).
WHERE id = ?`, Set("display_name").Placeholder(user.DisplayName).
user.Email, user.DisplayName, user.PasswordHash, user.Role, Set("password_hash").Placeholder(user.PasswordHash).
user.LastWorkspaceID, user.ID) Set("role").Placeholder(user.Role).
Set("last_workspace_id").Placeholder(user.LastWorkspaceID).
Where("id = ").Placeholder(user.ID)
result, err := db.Exec(query.String(), query.Args()...)
if err != nil { if err != nil {
return fmt.Errorf("failed to update user: %w", err) return fmt.Errorf("failed to update user: %w", err)
} }
@@ -165,13 +167,14 @@ func (db *database) UpdateUser(user *models.User) error {
return nil return nil
} }
// GetAllUsers retrieves all users from the database
func (db *database) GetAllUsers() ([]*models.User, error) { func (db *database) GetAllUsers() ([]*models.User, error) {
rows, err := db.Query(` query := NewQuery(db.dbType).
SELECT Select("id", "email", "display_name", "role", "created_at", "last_workspace_id").
id, email, display_name, role, created_at, From("users").
last_workspace_id OrderBy("id ASC")
FROM users
ORDER BY id ASC`) rows, err := db.Query(query.String(), query.Args()...)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to query users: %w", err) return nil, fmt.Errorf("failed to query users: %w", err)
} }
@@ -200,15 +203,26 @@ func (db *database) UpdateLastWorkspace(userID int, workspaceName string) error
} }
defer tx.Rollback() defer tx.Rollback()
// Find workspace ID from name
workspaceQuery := NewQuery(db.dbType).
Select("id").
From("workspaces").
Where("user_id = ").Placeholder(userID).
And("name = ").Placeholder(workspaceName)
var workspaceID int var workspaceID int
err = tx.QueryRow("SELECT id FROM workspaces WHERE user_id = ? AND name = ?", err = tx.QueryRow(workspaceQuery.String(), workspaceQuery.Args()...).Scan(&workspaceID)
userID, workspaceName).Scan(&workspaceID)
if err != nil { if err != nil {
return fmt.Errorf("failed to find workspace: %w", err) return fmt.Errorf("failed to find workspace: %w", err)
} }
_, err = tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", // Update user's last workspace
workspaceID, userID) updateQuery := NewQuery(db.dbType).
Update("users").
Set("last_workspace_id").Placeholder(workspaceID).
Where("id = ").Placeholder(userID)
_, err = tx.Exec(updateQuery.String(), updateQuery.Args()...)
if err != nil { if err != nil {
return fmt.Errorf("failed to update last workspace: %w", err) return fmt.Errorf("failed to update last workspace: %w", err)
} }
@@ -221,6 +235,7 @@ func (db *database) UpdateLastWorkspace(userID int, workspaceName string) error
return nil return nil
} }
// DeleteUser deletes a user and all their workspaces
func (db *database) DeleteUser(id int) error { func (db *database) DeleteUser(id int) error {
log := getLogger().WithGroup("users") log := getLogger().WithGroup("users")
log.Debug("deleting user", "user_id", id) log.Debug("deleting user", "user_id", id)
@@ -233,13 +248,24 @@ func (db *database) DeleteUser(id int) error {
// Delete all user's workspaces first // Delete all user's workspaces first
log.Debug("deleting user workspaces", "user_id", id) log.Debug("deleting user workspaces", "user_id", id)
_, err = tx.Exec("DELETE FROM workspaces WHERE user_id = ?", id)
deleteWorkspacesQuery := NewQuery(db.dbType).
Delete().
From("workspaces").
Where("user_id = ").Placeholder(id)
_, err = tx.Exec(deleteWorkspacesQuery.String(), deleteWorkspacesQuery.Args()...)
if err != nil { if err != nil {
return fmt.Errorf("failed to delete workspaces: %w", err) return fmt.Errorf("failed to delete workspaces: %w", err)
} }
// Delete the user // Delete the user
_, err = tx.Exec("DELETE FROM users WHERE id = ?", id) deleteUserQuery := NewQuery(db.dbType).
Delete().
From("users").
Where("id = ").Placeholder(id)
_, err = tx.Exec(deleteUserQuery.String(), deleteUserQuery.Args()...)
if err != nil { if err != nil {
return fmt.Errorf("failed to delete user: %w", err) return fmt.Errorf("failed to delete user: %w", err)
} }
@@ -253,15 +279,16 @@ func (db *database) DeleteUser(id int) error {
return nil return nil
} }
// GetLastWorkspaceName retrieves the name of the last workspace accessed by a user
func (db *database) GetLastWorkspaceName(userID int) (string, error) { func (db *database) GetLastWorkspaceName(userID int) (string, error) {
query := NewQuery(db.dbType).
Select("w.name").
From("workspaces w").
Join(InnerJoin, "users u", "u.last_workspace_id = w.id").
Where("u.id = ").Placeholder(userID)
var workspaceName string var workspaceName string
err := db.QueryRow(` err := db.QueryRow(query.String(), query.Args()...).Scan(&workspaceName)
SELECT
w.name
FROM workspaces w
JOIN users u ON u.last_workspace_id = w.id
WHERE u.id = ?`, userID).
Scan(&workspaceName)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return "", fmt.Errorf("no last workspace found") return "", fmt.Errorf("no last workspace found")
@@ -275,8 +302,13 @@ func (db *database) GetLastWorkspaceName(userID int) (string, error) {
// CountAdminUsers returns the number of admin users in the system // CountAdminUsers returns the number of admin users in the system
func (db *database) CountAdminUsers() (int, error) { func (db *database) CountAdminUsers() (int, error) {
query := NewQuery(db.dbType).
Select("COUNT(*)").
From("users").
Where("role = ").Placeholder(models.RoleAdmin)
var count int var count int
err := db.QueryRow("SELECT COUNT(*) FROM users WHERE role = 'admin'").Scan(&count) err := db.QueryRow(query.String(), query.Args()...).Scan(&count)
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to count admin users: %w", err) return 0, fmt.Errorf("failed to count admin users: %w", err)
} }