SQL Database (db)
The primary, persistent storage. SQLite database is used.
Each module has its own database (and each account has its own). These databases are located at /databases/<ModuleName>/database_<user_id>.db. This path can be obtained using mod.db_path.
Methods
Set-Get System
Data is stored in a key-value format. Only simple data types and structures can be stored: str, int, float, bool, None, list, dict.
Below, the term Any refers to the aforementioned simple data types and structures.
-
async
setSets a value.
Arguments:
variable(str) - Name of the variable (key).value(Any) - Value.
Returns: None
Example:
await mod.db.set('count', 10) -
async
getRetrieves a value. If no record with the specified key exists,
defaultis returned.Arguments:
variable(str) - Name of the variable (key).default(optional) = None - Default value to return ifvariableis not found.
Returns: Any - The value of the variable.
Example:
count = await mod.db.get('count', 0) -
async
getallRetrieves all values.
Arguments:
default(optional) = None - Default value to return if no variables exist in the database.
Returns: List[str, Any] - A dictionary of values where keys are variable names.
Example:
all_values = await mod.db.getall() -
async
remove/deleteDeletes a variable from the database.
Arguments:
variable(str) - Name of the variable to delete.
Returns: None
Example:
await mod.db.remove('count')
SQL
In addition to set-get, you can use the SQL database directly via SQL queries!
-
async
sqlExecutes an SQL query.
Arguments:
sql(str) - SQL query.asdict(optional, bool) = False - Return results as a dictionary (column: value).**params- Values to pass into the SQL query.
dangerAlways use query parameters (
**params) for value substitution!Do not insert data directly using f-strings or
+, as this opens vulnerabilities for SQL injection.✅ Correct:
await mod.db.sql("SELECT * FROM users WHERE age > :age", age=18)❌ Incorrect:
await mod.db.sql(f"SELECT * FROM users WHERE age > {age}") # Vulnerable!!!!Passing parameters via
**paramsautomatically protects against attacks and ensures code safety.Returns: None | Tuple[Tuple[Any]] | Dict[str, Any] - The result of the SQL query.
infoIf the query returns data, the output will be as follows:
- With
asdict=True:[{column: value, ...}, ...] - With
asdict=False:[(value1, value2, ...), ...]
Example:
result = await mod.db.sql("SELECT id, name FROM users WHERE age > :age", asdict=True, age=18)
# Example result: [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
Examples:
The following examples are taken from the MineEvoMiner module (version 2.5) by third-party developer @Kotcananacom.
# When the client is running
async def stats_ready(app: Client, mod: Module):
AutoStopTimer(app, mod)
mod.add_task(miner(app, mod))
if await mod.db.get('mine', False):
await mod.db.set('start_mine', time.time())
await mod.db.sql("CREATE TABLE IF NOT EXISTS mineevo_stats (type_case TEXT, type_bust TEXT, count INTEGER, timee TEXT)")
await initialization_found(app, mod)
# Enable/disable beautiful formatting for found cases
async def beautiful_case_found(app: Client, msg: Message, mod: Module):
beautiful = await mod.db.get('beautiful_found', False)
await mod.db.set('beautiful_found', not beautiful)
if beautiful:
await msg.edit(f"{Emojis.YES_2} {b('Beautiful formatting for found cases disabled')}")
else:
await msg.edit(f"{Emojis.YES} {b('Beautiful formatting for found cases enabled')}")
# Enable/disable mining
async def mine_cmd(app: Client, msg: Message, mod: Module):
mine = await mod.db.get('mine', False)
clicks = await mod.db.get('clicks', 0)
get_mine_bot_value = await get_mine_bot(mod)
await mod.db.set('mine', not mine)
if mine:
await mod.db.set('end_mine', time.time())
start = await mod.db.get('start_mine', 0)
end = await mod.db.get('end_mine', 0)
if end > start:
session_time = end - start
total_time = await mod.db.get('mine_total_time', 0)
total_time += session_time
await mod.db.set('mine_total_time', total_time)
cases = await mod.db.sql("SELECT type_case, SUM(count) FROM mineevo_stats WHERE timee BETWEEN :start_time AND :end_time GROUP BY type_case", start_time=start, end_time=end)
busts = await mod.db.sql("SELECT type_bust, SUM(count) FROM mineevo_stats WHERE timee BETWEEN :start_time AND :end_time GROUP BY type_bust", start_time=start, end_time=end)