feat: Add bank and wallet balance commands with improved transfer validation

- Added /bank and /wallet commands to check user balances
- Enhanced transfer validation to check for valid number input
- Included debug token logging in main function (to be removed in production)
- Added account creation logic for new users in balance commands
- Improved error handling for invalid transfer amounts
This commit is contained in:
2026-06-03 11:56:09 +00:00
parent 4b07ca86b9
commit b315069b1c
4 changed files with 168 additions and 84 deletions
+6 -3
View File
@@ -27,7 +27,11 @@ async def bank_data(user: discord.Member | discord.User) -> Dict[str, int]:
if balance is None:
await create_account(user)
return await bank_data(user)
return balance
# Ensure we return a dictionary with WALLET and BANK keys
return {
"WALLET": balance.get("WALLET", 0),
"BANK": balance.get("BANK", 0)
}
async def record_transaction(
@@ -88,5 +92,4 @@ async def update_daily_timestamp(user: discord.User | discord.Member, timestamp:
Updates the DAILY_TIMESTAMP field for the user in the economy table.
Stores the timestamp as a float (UNIX time).
"""
db.execute_query("UPDATE economy SET DAILY = %s WHERE ID = %s",(timestamp.timestamp(), user.id),
)
db.execute_query("UPDATE economy SET DAILY = %s WHERE ID = %s",(timestamp.timestamp(), user.id))
+55 -54
View File
@@ -263,54 +263,55 @@ class DatabaseManager:
)
return [col.strip() for col in match.group(1).split(",") if col.strip()]
def execute_query(self, query, params=None, retries=3, delay=1):
connection = None
cursor = None
for attempt in range(retries):
try:
connection = self.get_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
cursor.execute(query, params or ())
connection.commit()
logger.info(f"Executed query: {query} with params: {params}")
return cursor.rowcount
except mysql.connector.Error as err:
logger.warning(f"Attempt {attempt + 1} failed: {err}")
time.sleep(delay * (2**attempt))
finally:
if cursor:
cursor.close()
if connection:
connection.close()
def execute_query(self, query, params=None, retries=3, delay=1):
connection = None
cursor = None
for attempt in range(retries):
try:
connection = self.get_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
cursor.execute(query, params or ())
connection.commit()
logger.info(f"Executed query: {query} with params: {params}")
# Return the actual cursor results instead of closing it
return cursor.fetchall() if cursor.with_rows else cursor.rowcount
except mysql.connector.Error as err:
logger.warning(f"Attempt {attempt + 1} failed: {err}")
time.sleep(delay * (2**attempt))
finally:
if cursor:
cursor.close()
if connection:
connection.close()
logger.error(f"All {retries} attempts failed for query: {query}")
return None
logger.error(f"All {retries} attempts failed for query: {query}")
return None
def insert(self, query: str, params: tuple, overwrite: bool = True) -> None:
"""
Inserts data into the database using the given query and parameters.
Args:
query (str): The SQL query to execute.
params (tuple): The parameters to pass into the query.
overwrite (bool, optional): Whether to perform an upsert operation. Defaults to True.
Raises:
ValueError: If no parameters are provided.
"""
if not params:
raise ValueError("Params must be provided for the insert operation.")
if overwrite:
columns = self._parse_insert_columns(query)
update_set = ", ".join(f"{col} = VALUES({col})" for col in columns)
query = f"{query} ON DUPLICATE KEY UPDATE {update_set}"
rowcount = self.execute_query(query, params)
if rowcount is None:
logger.error(f"Insert failed with query: {query}.")
else:
logger.info(f"Insert completed with query: {query}.")
def insert(self, query: str, params: tuple, overwrite: bool = True) -> None:
"""
Inserts data into the database using the given query and parameters.
Args:
query (str): The SQL query to execute.
params (tuple): The parameters to pass into the query.
overwrite (bool, optional): Whether to perform an upsert operation. Defaults to True.
Raises:
ValueError: If no parameters are provided.
"""
if not params:
raise ValueError("Params must be provided for the insert operation.")
if overwrite:
columns = self._parse_insert_columns(query)
update_set = ", ".join(f"{col} = VALUES({col})" for col in columns)
query = f"{query} ON DUPLICATE KEY UPDATE {update_set}"
rowcount = self.execute_query(query, params)
if rowcount is None:
logger.error(f"Insert failed with query: {query}.")
else:
logger.info(f"Insert completed with query: {query}.")
def bulk_insert(self, query, params=None):
if not params:
@@ -345,13 +346,13 @@ class DatabaseManager:
if connection:
connection.close()
def delete(self, table_name: str, condition: dict) -> None:
"""Deletes a record from the specified table based on the condition provided."""
table_name = self._sanitize_identifier(table_name)
condition_column, condition_value = next(iter(condition.items()))
condition_column = self._sanitize_identifier(condition_column)
query = f"DELETE FROM {table_name} WHERE {condition_column} = %s"
self.execute_query(query, (condition_value,))
def delete(self, table_name: str, condition: dict) -> None:
"""Deletes a record from the specified table based on the condition provided."""
table_name = self._sanitize_identifier(table_name)
condition_column, condition_value = next(iter(condition.items()))
condition_column = self._sanitize_identifier(condition_column)
query = f"DELETE FROM {table_name} WHERE {condition_column} = %s"
self.execute_query(query, (condition_value,))
def fetch_one(self, query, params=None):
connection = None