Using transactions

This commit is contained in:
Atridad Lahiji 2024-11-05 00:42:25 -06:00
parent fc8be94ee9
commit d1e2d9bf4f
Signed by: atridad
SSH key fingerprint: SHA256:LGomp8Opq0jz+7kbwNcdfTcuaLRb5Nh0k5AchDDb438

View file

@ -26,26 +26,45 @@ func ProcessMessage(s *discordgo.Session, m *discordgo.MessageCreate) error {
return nil return nil
} }
// Start transaction for user creation/lookup and himbucks entry
tx, err := DBClient.Begin()
if err != nil {
return fmt.Errorf("failed to start transaction: %w", err)
}
defer tx.Rollback()
// Get user from database, create if doesn't exist // Get user from database, create if doesn't exist
var userID int var userID int
err := DBClient.QueryRow("SELECT id FROM users WHERE discord_id = ?", m.Author.ID).Scan(&userID) err = tx.QueryRow("SELECT id FROM users WHERE discord_id = ?", m.Author.ID).Scan(&userID)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
// Store user in database // Store user in database using existing StoreUser function within transaction
err = StoreUser(m.Author.ID, m.Author.Username) result, err := tx.Exec(
"INSERT INTO users (discord_id, username) VALUES (?, ?)",
m.Author.ID, m.Author.Username)
if err != nil { if err != nil {
return fmt.Errorf("failed to store user: %w", err) return fmt.Errorf("failed to store user: %w", err)
} }
// Get the ID of the newly created user id, err := result.LastInsertId()
err = DBClient.QueryRow("SELECT id FROM users WHERE discord_id = ?", m.Author.ID).Scan(&userID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get new user ID: %w", err) return fmt.Errorf("failed to get new user ID: %w", err)
} }
userID = int(id)
// Immediately create corresponding himbucks entry
_, err = tx.Exec(`
INSERT INTO himbucks (user_id, guild_id, balance, message_count)
VALUES (?, ?, 0, 0)`,
userID, m.GuildID)
if err != nil {
return fmt.Errorf("failed to create initial himbucks entry: %w", err)
}
} else if err != nil { } else if err != nil {
return fmt.Errorf("failed to query user: %w", err) return fmt.Errorf("failed to query user: %w", err)
} }
_, err = DBClient.Exec(` // For existing users, ensure himbucks entry exists
_, err = tx.Exec(`
INSERT INTO himbucks (user_id, guild_id, balance, message_count) INSERT INTO himbucks (user_id, guild_id, balance, message_count)
VALUES (?, ?, 0, 0) VALUES (?, ?, 0, 0)
ON CONFLICT (user_id, guild_id) DO NOTHING`, ON CONFLICT (user_id, guild_id) DO NOTHING`,
@ -54,12 +73,7 @@ func ProcessMessage(s *discordgo.Session, m *discordgo.MessageCreate) error {
return fmt.Errorf("failed to create himbucks entry: %w", err) return fmt.Errorf("failed to create himbucks entry: %w", err)
} }
tx, err := DBClient.Begin() // Process the message count and rewards
if err != nil {
return fmt.Errorf("failed to start transaction: %w", err)
}
defer tx.Rollback()
var messageCount int var messageCount int
var lastEarnedAt sql.NullTime var lastEarnedAt sql.NullTime