Module swordie_db.user

This module holds the User class for the SwordieDB package.

Copyright 2020 TEAM SPIRIT. All rights reserved. Use of this source code is governed by a MIT-style license that can be found in the LICENSE file. Refer to database.py or the project wiki on GitHub for usage examples.

Expand source code
"""This module holds the User class for the SwordieDB package.

Copyright 2020 TEAM SPIRIT. All rights reserved.
Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.
Refer to database.py or the project wiki on GitHub for usage examples.
"""
import mysql.connector as con


class User:
    """User object; models SwordieMS users.

    Using instance method SwordieDB::get_user_by_username(username) or the SwordieDB::get_char_by_name(name).user getter
    will create a User object instance with attributes identical to the user with username "username"
    (or IGN "name" for the latter) in the connected Swordie-based database.
    This class contains the appropriate getter and setter methods for said attributes.

    Attributes:
        account_type: Integer, representing the level of authority
        ban_reason: String (256 Char), representing the reason the user is banned
        donation_points: Integer, representing the amount of DP the user has
        maple_points: Integer, representing the amount of Maple Points the user has
        nx_prepaid: Integer, representing the amoung of NX Prepaid the user has
        user_id: Integer, representing the User ID
        vote_points: Integer, representing the amount of VP the user has
    """

    def __init__(self, user_stats, database_config):
        """Emulates how user object is handled server-sided

        Args:
            user_stats: dictionary of user attributes, formatted in SwordieMS style
            database_config: dictionary of protected attributes from a SwordieDB object
        """

        self._user_stats = user_stats
        self._database_config = database_config

        self._id = 0
        self._ban_reason = ""
        self._vote_points = 0
        self._donation_points = 0
        self._maple_points = 0
        self._nx_prepaid = 0
        self._account_type = 0
        self._username = ""
        self._password = ""
        self._pic = ""
        self.init_user_stats()

    def init_user_stats(self):
        """Given a dictionary of stats from Swordie's DB we add them to User object's attributes

        Runs near the end of User::__init__(user_stats, database_config).
        It assigns the user attributes in user_stats to their respective protected attributes belonging to
        the User object instance.
        """
        self._id = self._user_stats["id"]
        self._ban_reason = self._user_stats["banReason"]
        self._vote_points = self._user_stats["votepoints"]
        self._donation_points = self._user_stats["donationpoints"]
        self._maple_points = self._user_stats["maplePoints"]
        self._nx_prepaid = self._user_stats["nxPrepaid"]
        self._account_type = self._user_stats["accounttype"]
        self._username = self._user_stats["name"]
        self._password = self._user_stats["password"]
        self._pic = self._user_stats["pic"]

    @property
    def user_stats(self):
        return self._user_stats

    @property
    def database_config(self):
        return self._database_config

    @property
    def username(self):
        return self._username

    @username.setter
    def username(self, x):
        self._username = x
        self.set_stat_by_column("name", x)

    @property
    def password(self):
        return self._password

    @property
    def pic(self):
        return self._pic

    @pic.setter
    def pic(self, x):
        self._pic = x
        self.set_stat_by_column("pic", x)

    @property
    def user_id(self):
        return self._id

    @property
    def ban_reason(self):
        return self._ban_reason

    @ban_reason.setter
    def ban_reason(self, reason):
        if len(reason) < 255:
            self.set_stat_by_column("banReason", reason)
            self._ban_reason = reason
        else:
            print("Ban Reason was too long.")

    @property
    def vote_points(self):
        return self._vote_points

    @vote_points.setter
    def vote_points(self, amount):
        self.set_stat_by_column("votepoints", amount)
        self._vote_points = amount

    def add_vote_points(self, amount):
        """Adds the specified amount to the current VP count

        Args:
            amount: Int, representing the number of vote points to be added to the current count
        """
        new_vp = int(amount) + self.vote_points
        self.vote_points = new_vp

    @property
    def donation_points(self):
        return self._donation_points

    @donation_points.setter
    def donation_points(self, amount):
        self.set_stat_by_column("donationpoints", amount)
        self._donation_points = amount

    def add_donation_points(self, amount):
        """Adds the specified amount to the current DP count

        Args:
            amount: Int, representing the number of DPs to be added to the current count
        """
        new_dp = int(amount) + self.donation_points
        self.donation_points = new_dp

    @property
    def maple_points(self):
        return self._maple_points

    @maple_points.setter
    def maple_points(self, amount):
        self.set_stat_by_column("maplePoints", amount)
        self._maple_points = amount

    def add_maple_points(self, amount):
        """Adds the specified amount to the current Maple Points pool

        Args:
            amount: Int, representing the number of Maple Points to be added to the current pool
        """
        new_maple_points = int(amount) + self.maple_points
        self.maple_points = new_maple_points

    @property
    def account_type(self):
        return self._account_type

    @account_type.setter
    def account_type(self, acc_type):
        self.set_stat_by_column("accounttype", acc_type)
        self._account_type = acc_type

    def give_admin(self):
        """Sets the user account type to: Admin"""
        self.account_type = 4

    def give_intern(self):
        """Sets the user account type to: Intern"""
        self.account_type = 3

    def give_tester(self):
        """Sets the user account type to: Tester"""
        self.account_type = 5

    def give_player(self):
        """Sets the user account type to: Player"""
        self.account_type = 0

    def is_admin(self):
        """Checks if the user's account type is: Admin (Strictly)

        Checks if the account type ID associated with the user is 4. Both Int and String types are checked.

        Returns:
            Boolean, representing whether user is Admin (True) or not (False)
        """
        return self.account_type == 4 or self.account_type == "4"  # A string check just in case

    def change_password(self, new_pass):
        """WARNING: UNSAFE!

        Primitive password change function. It will break in real Swordie-based sources, as Swordie hashes passwords.
        Note: This is not a safe method to use when changing password as it does not hash the password after changing.

        Args:
            new_pass: string, representing the new plaintext password to be set to the database
        """
        self.set_stat_by_column("password", new_pass)

    def get_acc_type_string(self):
        """Fetches the account type of the user in words

        Fetches the account type (Int) from user attributes. Maps the account type to its meaning in words

        Returns:
            String, representing account type
        """
        if self.account_type == 4:
            return "Admin"
        elif self.account_type == 0:
            return "Player"
        elif self.account_type == 3:
            return "Intern"
        elif self.account_type == 5:
            return "Tester"

    @property
    def nx_prepaid(self):
        return self._nx_prepaid

    @nx_prepaid.setter
    def nx_prepaid(self, amount):
        self.set_stat_by_column("nxPrepaid", amount)
        self._nx_prepaid = amount

    def add_nx_prepaid(self, amount):
        """Adds the specified amount to the current NX pool

        Args:
            amount: Int, representing the amount of NX to be added to the NX pool
        """
        new_nx = int(amount) + self.nx_prepaid
        self.nx_prepaid = new_nx

    def get_stat_by_column(self, column):
        """Fetches user attribute by column name

        Returns:
            Int or String, representing user attribute queried
        Raises:
            Generic error on failure
        """
        try:
            return self.user_stats[str(column)]
        except Exception as e:
            print("[ERROR] Error trying to obtain the given column for table users.", e)

    def set_stat_by_column(self, column, value):
        """Sets a user's attributes by column name in database

        Grabs the database attributes provided through the class constructor.
        Uses these attributes to attempt a database connection.
        Attempts to update the field represented by the provided column in the users table, with the provided value.
        Not recommended to use this alone, as it won't update the user object which this was used from

        Args:
            value: int or string, representing the value to be set in the database
            column: string, representing the column in the database that is to be updated

        Returns:
            A boolean representing whether the operation was successful.

        Raises:
            SQL Error 2003: Can't cannect to DB
            WinError 10060: No response from DB
            List index out of range: Wrong column name
        """
        host = self._database_config["host"]
        user = self._database_config["user"]
        password = self._database_config["password"]
        schema = self._database_config["schema"]
        port = self._database_config["port"]

        try:
            database = con.connect(host=host, user=user, password=password, database=schema, port=port)

            cursor = database.cursor(dictionary=True)
            cursor.execute(f"UPDATE users SET {column} = '{value}' WHERE id = '{self.user_id}'")
            database.commit()
            print(f"Successfully updated {column} value for user id: {self.user_id}.")
            self._user_stats[column] = value  # Update the stats in the dictionary
            database.disconnect()
            return True
        except Exception as e:
            print("[ERROR] Error trying to set stats in database.", e)
            return False

Classes

class User (user_stats, database_config)

User object; models SwordieMS users.

Using instance method SwordieDB::get_user_by_username(username) or the SwordieDB::get_char_by_name(name).user getter will create a User object instance with attributes identical to the user with username "username" (or IGN "name" for the latter) in the connected Swordie-based database. This class contains the appropriate getter and setter methods for said attributes.

Attributes

account_type
Integer, representing the level of authority
ban_reason
String (256 Char), representing the reason the user is banned
donation_points
Integer, representing the amount of DP the user has
maple_points
Integer, representing the amount of Maple Points the user has
nx_prepaid
Integer, representing the amoung of NX Prepaid the user has
user_id
Integer, representing the User ID
vote_points
Integer, representing the amount of VP the user has

Emulates how user object is handled server-sided

Args

user_stats
dictionary of user attributes, formatted in SwordieMS style
database_config
dictionary of protected attributes from a SwordieDB object
Expand source code
class User:
    """User object; models SwordieMS users.

    Using instance method SwordieDB::get_user_by_username(username) or the SwordieDB::get_char_by_name(name).user getter
    will create a User object instance with attributes identical to the user with username "username"
    (or IGN "name" for the latter) in the connected Swordie-based database.
    This class contains the appropriate getter and setter methods for said attributes.

    Attributes:
        account_type: Integer, representing the level of authority
        ban_reason: String (256 Char), representing the reason the user is banned
        donation_points: Integer, representing the amount of DP the user has
        maple_points: Integer, representing the amount of Maple Points the user has
        nx_prepaid: Integer, representing the amoung of NX Prepaid the user has
        user_id: Integer, representing the User ID
        vote_points: Integer, representing the amount of VP the user has
    """

    def __init__(self, user_stats, database_config):
        """Emulates how user object is handled server-sided

        Args:
            user_stats: dictionary of user attributes, formatted in SwordieMS style
            database_config: dictionary of protected attributes from a SwordieDB object
        """

        self._user_stats = user_stats
        self._database_config = database_config

        self._id = 0
        self._ban_reason = ""
        self._vote_points = 0
        self._donation_points = 0
        self._maple_points = 0
        self._nx_prepaid = 0
        self._account_type = 0
        self._username = ""
        self._password = ""
        self._pic = ""
        self.init_user_stats()

    def init_user_stats(self):
        """Given a dictionary of stats from Swordie's DB we add them to User object's attributes

        Runs near the end of User::__init__(user_stats, database_config).
        It assigns the user attributes in user_stats to their respective protected attributes belonging to
        the User object instance.
        """
        self._id = self._user_stats["id"]
        self._ban_reason = self._user_stats["banReason"]
        self._vote_points = self._user_stats["votepoints"]
        self._donation_points = self._user_stats["donationpoints"]
        self._maple_points = self._user_stats["maplePoints"]
        self._nx_prepaid = self._user_stats["nxPrepaid"]
        self._account_type = self._user_stats["accounttype"]
        self._username = self._user_stats["name"]
        self._password = self._user_stats["password"]
        self._pic = self._user_stats["pic"]

    @property
    def user_stats(self):
        return self._user_stats

    @property
    def database_config(self):
        return self._database_config

    @property
    def username(self):
        return self._username

    @username.setter
    def username(self, x):
        self._username = x
        self.set_stat_by_column("name", x)

    @property
    def password(self):
        return self._password

    @property
    def pic(self):
        return self._pic

    @pic.setter
    def pic(self, x):
        self._pic = x
        self.set_stat_by_column("pic", x)

    @property
    def user_id(self):
        return self._id

    @property
    def ban_reason(self):
        return self._ban_reason

    @ban_reason.setter
    def ban_reason(self, reason):
        if len(reason) < 255:
            self.set_stat_by_column("banReason", reason)
            self._ban_reason = reason
        else:
            print("Ban Reason was too long.")

    @property
    def vote_points(self):
        return self._vote_points

    @vote_points.setter
    def vote_points(self, amount):
        self.set_stat_by_column("votepoints", amount)
        self._vote_points = amount

    def add_vote_points(self, amount):
        """Adds the specified amount to the current VP count

        Args:
            amount: Int, representing the number of vote points to be added to the current count
        """
        new_vp = int(amount) + self.vote_points
        self.vote_points = new_vp

    @property
    def donation_points(self):
        return self._donation_points

    @donation_points.setter
    def donation_points(self, amount):
        self.set_stat_by_column("donationpoints", amount)
        self._donation_points = amount

    def add_donation_points(self, amount):
        """Adds the specified amount to the current DP count

        Args:
            amount: Int, representing the number of DPs to be added to the current count
        """
        new_dp = int(amount) + self.donation_points
        self.donation_points = new_dp

    @property
    def maple_points(self):
        return self._maple_points

    @maple_points.setter
    def maple_points(self, amount):
        self.set_stat_by_column("maplePoints", amount)
        self._maple_points = amount

    def add_maple_points(self, amount):
        """Adds the specified amount to the current Maple Points pool

        Args:
            amount: Int, representing the number of Maple Points to be added to the current pool
        """
        new_maple_points = int(amount) + self.maple_points
        self.maple_points = new_maple_points

    @property
    def account_type(self):
        return self._account_type

    @account_type.setter
    def account_type(self, acc_type):
        self.set_stat_by_column("accounttype", acc_type)
        self._account_type = acc_type

    def give_admin(self):
        """Sets the user account type to: Admin"""
        self.account_type = 4

    def give_intern(self):
        """Sets the user account type to: Intern"""
        self.account_type = 3

    def give_tester(self):
        """Sets the user account type to: Tester"""
        self.account_type = 5

    def give_player(self):
        """Sets the user account type to: Player"""
        self.account_type = 0

    def is_admin(self):
        """Checks if the user's account type is: Admin (Strictly)

        Checks if the account type ID associated with the user is 4. Both Int and String types are checked.

        Returns:
            Boolean, representing whether user is Admin (True) or not (False)
        """
        return self.account_type == 4 or self.account_type == "4"  # A string check just in case

    def change_password(self, new_pass):
        """WARNING: UNSAFE!

        Primitive password change function. It will break in real Swordie-based sources, as Swordie hashes passwords.
        Note: This is not a safe method to use when changing password as it does not hash the password after changing.

        Args:
            new_pass: string, representing the new plaintext password to be set to the database
        """
        self.set_stat_by_column("password", new_pass)

    def get_acc_type_string(self):
        """Fetches the account type of the user in words

        Fetches the account type (Int) from user attributes. Maps the account type to its meaning in words

        Returns:
            String, representing account type
        """
        if self.account_type == 4:
            return "Admin"
        elif self.account_type == 0:
            return "Player"
        elif self.account_type == 3:
            return "Intern"
        elif self.account_type == 5:
            return "Tester"

    @property
    def nx_prepaid(self):
        return self._nx_prepaid

    @nx_prepaid.setter
    def nx_prepaid(self, amount):
        self.set_stat_by_column("nxPrepaid", amount)
        self._nx_prepaid = amount

    def add_nx_prepaid(self, amount):
        """Adds the specified amount to the current NX pool

        Args:
            amount: Int, representing the amount of NX to be added to the NX pool
        """
        new_nx = int(amount) + self.nx_prepaid
        self.nx_prepaid = new_nx

    def get_stat_by_column(self, column):
        """Fetches user attribute by column name

        Returns:
            Int or String, representing user attribute queried
        Raises:
            Generic error on failure
        """
        try:
            return self.user_stats[str(column)]
        except Exception as e:
            print("[ERROR] Error trying to obtain the given column for table users.", e)

    def set_stat_by_column(self, column, value):
        """Sets a user's attributes by column name in database

        Grabs the database attributes provided through the class constructor.
        Uses these attributes to attempt a database connection.
        Attempts to update the field represented by the provided column in the users table, with the provided value.
        Not recommended to use this alone, as it won't update the user object which this was used from

        Args:
            value: int or string, representing the value to be set in the database
            column: string, representing the column in the database that is to be updated

        Returns:
            A boolean representing whether the operation was successful.

        Raises:
            SQL Error 2003: Can't cannect to DB
            WinError 10060: No response from DB
            List index out of range: Wrong column name
        """
        host = self._database_config["host"]
        user = self._database_config["user"]
        password = self._database_config["password"]
        schema = self._database_config["schema"]
        port = self._database_config["port"]

        try:
            database = con.connect(host=host, user=user, password=password, database=schema, port=port)

            cursor = database.cursor(dictionary=True)
            cursor.execute(f"UPDATE users SET {column} = '{value}' WHERE id = '{self.user_id}'")
            database.commit()
            print(f"Successfully updated {column} value for user id: {self.user_id}.")
            self._user_stats[column] = value  # Update the stats in the dictionary
            database.disconnect()
            return True
        except Exception as e:
            print("[ERROR] Error trying to set stats in database.", e)
            return False

Instance variables

var account_type
Expand source code
@property
def account_type(self):
    return self._account_type
var ban_reason
Expand source code
@property
def ban_reason(self):
    return self._ban_reason
var database_config
Expand source code
@property
def database_config(self):
    return self._database_config
var donation_points
Expand source code
@property
def donation_points(self):
    return self._donation_points
var maple_points
Expand source code
@property
def maple_points(self):
    return self._maple_points
var nx_prepaid
Expand source code
@property
def nx_prepaid(self):
    return self._nx_prepaid
var password
Expand source code
@property
def password(self):
    return self._password
var pic
Expand source code
@property
def pic(self):
    return self._pic
var user_id
Expand source code
@property
def user_id(self):
    return self._id
var user_stats
Expand source code
@property
def user_stats(self):
    return self._user_stats
var username
Expand source code
@property
def username(self):
    return self._username
var vote_points
Expand source code
@property
def vote_points(self):
    return self._vote_points

Methods

def add_donation_points(self, amount)

Adds the specified amount to the current DP count

Args

amount
Int, representing the number of DPs to be added to the current count
Expand source code
def add_donation_points(self, amount):
    """Adds the specified amount to the current DP count

    Args:
        amount: Int, representing the number of DPs to be added to the current count
    """
    new_dp = int(amount) + self.donation_points
    self.donation_points = new_dp
def add_maple_points(self, amount)

Adds the specified amount to the current Maple Points pool

Args

amount
Int, representing the number of Maple Points to be added to the current pool
Expand source code
def add_maple_points(self, amount):
    """Adds the specified amount to the current Maple Points pool

    Args:
        amount: Int, representing the number of Maple Points to be added to the current pool
    """
    new_maple_points = int(amount) + self.maple_points
    self.maple_points = new_maple_points
def add_nx_prepaid(self, amount)

Adds the specified amount to the current NX pool

Args

amount
Int, representing the amount of NX to be added to the NX pool
Expand source code
def add_nx_prepaid(self, amount):
    """Adds the specified amount to the current NX pool

    Args:
        amount: Int, representing the amount of NX to be added to the NX pool
    """
    new_nx = int(amount) + self.nx_prepaid
    self.nx_prepaid = new_nx
def add_vote_points(self, amount)

Adds the specified amount to the current VP count

Args

amount
Int, representing the number of vote points to be added to the current count
Expand source code
def add_vote_points(self, amount):
    """Adds the specified amount to the current VP count

    Args:
        amount: Int, representing the number of vote points to be added to the current count
    """
    new_vp = int(amount) + self.vote_points
    self.vote_points = new_vp
def change_password(self, new_pass)

WARNING: UNSAFE!

Primitive password change function. It will break in real Swordie-based sources, as Swordie hashes passwords. Note: This is not a safe method to use when changing password as it does not hash the password after changing.

Args

new_pass
string, representing the new plaintext password to be set to the database
Expand source code
def change_password(self, new_pass):
    """WARNING: UNSAFE!

    Primitive password change function. It will break in real Swordie-based sources, as Swordie hashes passwords.
    Note: This is not a safe method to use when changing password as it does not hash the password after changing.

    Args:
        new_pass: string, representing the new plaintext password to be set to the database
    """
    self.set_stat_by_column("password", new_pass)
def get_acc_type_string(self)

Fetches the account type of the user in words

Fetches the account type (Int) from user attributes. Maps the account type to its meaning in words

Returns

String, representing account type

Expand source code
def get_acc_type_string(self):
    """Fetches the account type of the user in words

    Fetches the account type (Int) from user attributes. Maps the account type to its meaning in words

    Returns:
        String, representing account type
    """
    if self.account_type == 4:
        return "Admin"
    elif self.account_type == 0:
        return "Player"
    elif self.account_type == 3:
        return "Intern"
    elif self.account_type == 5:
        return "Tester"
def get_stat_by_column(self, column)

Fetches user attribute by column name

Returns

Int or String, representing user attribute queried

Raises

Generic error on failure

Expand source code
def get_stat_by_column(self, column):
    """Fetches user attribute by column name

    Returns:
        Int or String, representing user attribute queried
    Raises:
        Generic error on failure
    """
    try:
        return self.user_stats[str(column)]
    except Exception as e:
        print("[ERROR] Error trying to obtain the given column for table users.", e)
def give_admin(self)

Sets the user account type to: Admin

Expand source code
def give_admin(self):
    """Sets the user account type to: Admin"""
    self.account_type = 4
def give_intern(self)

Sets the user account type to: Intern

Expand source code
def give_intern(self):
    """Sets the user account type to: Intern"""
    self.account_type = 3
def give_player(self)

Sets the user account type to: Player

Expand source code
def give_player(self):
    """Sets the user account type to: Player"""
    self.account_type = 0
def give_tester(self)

Sets the user account type to: Tester

Expand source code
def give_tester(self):
    """Sets the user account type to: Tester"""
    self.account_type = 5
def init_user_stats(self)

Given a dictionary of stats from Swordie's DB we add them to User object's attributes

Runs near the end of User::init(user_stats, database_config). It assigns the user attributes in user_stats to their respective protected attributes belonging to the User object instance.

Expand source code
def init_user_stats(self):
    """Given a dictionary of stats from Swordie's DB we add them to User object's attributes

    Runs near the end of User::__init__(user_stats, database_config).
    It assigns the user attributes in user_stats to their respective protected attributes belonging to
    the User object instance.
    """
    self._id = self._user_stats["id"]
    self._ban_reason = self._user_stats["banReason"]
    self._vote_points = self._user_stats["votepoints"]
    self._donation_points = self._user_stats["donationpoints"]
    self._maple_points = self._user_stats["maplePoints"]
    self._nx_prepaid = self._user_stats["nxPrepaid"]
    self._account_type = self._user_stats["accounttype"]
    self._username = self._user_stats["name"]
    self._password = self._user_stats["password"]
    self._pic = self._user_stats["pic"]
def is_admin(self)

Checks if the user's account type is: Admin (Strictly)

Checks if the account type ID associated with the user is 4. Both Int and String types are checked.

Returns

Boolean, representing whether user is Admin (True) or not (False)

Expand source code
def is_admin(self):
    """Checks if the user's account type is: Admin (Strictly)

    Checks if the account type ID associated with the user is 4. Both Int and String types are checked.

    Returns:
        Boolean, representing whether user is Admin (True) or not (False)
    """
    return self.account_type == 4 or self.account_type == "4"  # A string check just in case
def set_stat_by_column(self, column, value)

Sets a user's attributes by column name in database

Grabs the database attributes provided through the class constructor. Uses these attributes to attempt a database connection. Attempts to update the field represented by the provided column in the users table, with the provided value. Not recommended to use this alone, as it won't update the user object which this was used from

Args

value
int or string, representing the value to be set in the database
column
string, representing the column in the database that is to be updated

Returns

A boolean representing whether the operation was successful.

Raises

SQL Error 2003
Can't cannect to DB
WinError 10060
No response from DB
List index out of range
Wrong column name
Expand source code
def set_stat_by_column(self, column, value):
    """Sets a user's attributes by column name in database

    Grabs the database attributes provided through the class constructor.
    Uses these attributes to attempt a database connection.
    Attempts to update the field represented by the provided column in the users table, with the provided value.
    Not recommended to use this alone, as it won't update the user object which this was used from

    Args:
        value: int or string, representing the value to be set in the database
        column: string, representing the column in the database that is to be updated

    Returns:
        A boolean representing whether the operation was successful.

    Raises:
        SQL Error 2003: Can't cannect to DB
        WinError 10060: No response from DB
        List index out of range: Wrong column name
    """
    host = self._database_config["host"]
    user = self._database_config["user"]
    password = self._database_config["password"]
    schema = self._database_config["schema"]
    port = self._database_config["port"]

    try:
        database = con.connect(host=host, user=user, password=password, database=schema, port=port)

        cursor = database.cursor(dictionary=True)
        cursor.execute(f"UPDATE users SET {column} = '{value}' WHERE id = '{self.user_id}'")
        database.commit()
        print(f"Successfully updated {column} value for user id: {self.user_id}.")
        self._user_stats[column] = value  # Update the stats in the dictionary
        database.disconnect()
        return True
    except Exception as e:
        print("[ERROR] Error trying to set stats in database.", e)
        return False