HIMBOT RETURNS
This commit is contained in:
29
lib/db.go
29
lib/db.go
@ -17,35 +17,16 @@ var DBClient *sql.DB
|
||||
var DBConnector *libsql.Connector
|
||||
|
||||
func InitDB() error {
|
||||
dbUrl := os.Getenv("DATABASE_URL")
|
||||
dbToken := os.Getenv("DATABASE_AUTH_TOKEN")
|
||||
|
||||
if dbUrl == "" || dbToken == "" {
|
||||
return fmt.Errorf("database configuration missing")
|
||||
}
|
||||
|
||||
// Determine DB path based on /data directory existence
|
||||
dbPath := "himbot.db" // default to local
|
||||
if _, err := os.Stat("/data"); !os.IsNotExist(err) {
|
||||
dbPath = "/data/himbot.db"
|
||||
}
|
||||
dbName := "file:./himbot.db"
|
||||
|
||||
connector, connectorError := libsql.NewEmbeddedReplicaConnector(
|
||||
dbPath,
|
||||
dbUrl,
|
||||
libsql.WithAuthToken(dbToken),
|
||||
)
|
||||
|
||||
if connectorError != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to open db %s: %s", dbUrl, connectorError)
|
||||
db, err := sql.Open("libsql", dbName)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to open db %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// finalDBUrl := fmt.Sprintf("%s?authToken=%s", dbUrl, dbToken)
|
||||
|
||||
client := sql.OpenDB(connector)
|
||||
|
||||
DBClient = client
|
||||
DBConnector = connector
|
||||
DBClient = db
|
||||
|
||||
return runMigrations()
|
||||
}
|
||||
|
142
lib/himbucks.go
142
lib/himbucks.go
@ -85,98 +85,88 @@ func GetBalance(discordID, guildID string) (int, error) {
|
||||
}
|
||||
|
||||
func SendBalance(fromDiscordID, toDiscordID, guildID string, amount int) error {
|
||||
// Start database transaction
|
||||
tx, err := DBClient.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
// Start database transaction
|
||||
tx, err := DBClient.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// Get sender's user ID
|
||||
var fromUserID string
|
||||
err = tx.QueryRow(`
|
||||
SELECT id
|
||||
FROM users
|
||||
// Get sender's user ID
|
||||
var fromUserID string
|
||||
err = tx.QueryRow(`
|
||||
SELECT id
|
||||
FROM users
|
||||
WHERE discord_id = ?`, fromDiscordID).Scan(&fromUserID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sender not found: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("sender not found: %w", err)
|
||||
}
|
||||
|
||||
// Get recipient's user ID
|
||||
var toUserID string
|
||||
err = tx.QueryRow(`
|
||||
SELECT id
|
||||
FROM users
|
||||
// Get recipient's user ID
|
||||
var toUserID string
|
||||
err = tx.QueryRow(`
|
||||
SELECT id
|
||||
FROM users
|
||||
WHERE discord_id = ?`, toDiscordID).Scan(&toUserID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("recipient not found: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("recipient not found: %w", err)
|
||||
}
|
||||
|
||||
// Check if sender has sufficient balance
|
||||
var senderBalance int
|
||||
err = tx.QueryRow(`
|
||||
SELECT currency_balance
|
||||
FROM guild_profiles
|
||||
// Check if sender has sufficient balance
|
||||
var senderBalance int
|
||||
err = tx.QueryRow(`
|
||||
SELECT currency_balance
|
||||
FROM guild_profiles
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
fromUserID, guildID).Scan(&senderBalance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get sender balance: %w", err)
|
||||
}
|
||||
fromUserID, guildID).Scan(&senderBalance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get sender balance: %w", err)
|
||||
}
|
||||
|
||||
if senderBalance < amount {
|
||||
return fmt.Errorf("insufficient balance: have %d, trying to send %d", senderBalance, amount)
|
||||
}
|
||||
if senderBalance < amount {
|
||||
return fmt.Errorf("insufficient balance: have %d, trying to send %d", senderBalance, amount)
|
||||
}
|
||||
|
||||
// Deduct from sender
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance - ?
|
||||
// Deduct from sender
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance - ?
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
amount, fromUserID, guildID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to deduct from sender: %w", err)
|
||||
}
|
||||
amount, fromUserID, guildID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to deduct from sender: %w", err)
|
||||
}
|
||||
|
||||
// Add to recipient
|
||||
result, err := tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance + ?
|
||||
// Add to recipient
|
||||
result, err := tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance + ?
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
amount, toUserID, guildID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add to recipient: %w", err)
|
||||
}
|
||||
amount, toUserID, guildID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add to recipient: %w", err)
|
||||
}
|
||||
|
||||
// Check if recipient exists in guild_profiles
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check rows affected: %w", err)
|
||||
}
|
||||
// Check if recipient exists in guild_profiles
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check rows affected: %w", err)
|
||||
}
|
||||
|
||||
// If recipient doesn't have a profile in this guild, create one
|
||||
if rowsAffected == 0 {
|
||||
_, err = tx.Exec(`
|
||||
// If recipient doesn't have a profile in this guild, create one
|
||||
if rowsAffected == 0 {
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO guild_profiles (user_id, guild_id, currency_balance, message_count)
|
||||
VALUES (?, ?, ?, 0)`,
|
||||
toUserID, guildID, amount)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create recipient profile: %w", err)
|
||||
}
|
||||
}
|
||||
toUserID, guildID, amount)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create recipient profile: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
if err = tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SyncBalance() error {
|
||||
_, syncError := DBConnector.Sync()
|
||||
if syncError != nil {
|
||||
fmt.Println("Error syncing database:", syncError)
|
||||
return syncError
|
||||
// Commit transaction
|
||||
if err = tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
Reference in New Issue
Block a user