GoldyBot.database

1from . import database
2from . import member
3
4Database = database.Database
5""""""
6
7Member = member.Member
8""""""
class Database:
 11class Database():
 12    """Goldy Bot's class to interface with a Mongo Database."""
 13    def __init__(self, database_token_url:str):
 14        self.database_token_url = database_token_url
 15        self.loop = asyncio.get_event_loop()
 16
 17        config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON))
 18
 19        try:
 20            if not database_token_url.lower() in ["none", "null"]: 
 21                # Initializing MongoDB database
 22                self.client:pymongo.MongoClient = motor.motor_asyncio.AsyncIOMotorClient(self.database_token_url, serverSelectionTimeoutMS=2000)
 23                self.loop.run_until_complete(self.client.server_info())
 24                self.database = self.client[config.read("database_name")]
 25
 26                # Cache database class.
 27                GoldyBot.cache.main_cache_dict["database"] = self
 28
 29                GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] [CONNECTED]")
 30            
 31            else:
 32                GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] [DATABASE DISABLED]")
 33                GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Database is disabled because '{database_token_url}' was entered.")
 34
 35        except Exception:
 36            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Couldn't connect to Database! Check the database URL you entered.")
 37            GoldyBot.Goldy().stop("Couldn't connect to Database! Check the database URL you entered.")
 38
 39    async def insert(self, collection:str, data) -> bool:
 40        """Tells database to insert the data provided into a collection."""
 41        await self.database[collection].insert_one(data)
 42        GoldyBot.logging.log(f"[{MODULE_NAME}] Inserted '{data}' into '{collection}.'")
 43        return True
 44
 45    async def edit(self, collection:str, query, data:dict) -> bool:
 46        """Tells database to find and edit a document with the data provided in a collection."""
 47        await self.database[collection].update_one(query, {"$set": data})
 48        GoldyBot.logging.log(f"[{MODULE_NAME}] Edited '{query}' into '{data}.'")
 49        return True
 50
 51    async def remove(self, collection:str, data) -> bool:
 52        """Tells database to find and delete a copy of this data from the collection."""
 53        await self.database[collection].delete_one(data)
 54        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Deleted '{data}' from '{collection}.'")
 55        return True
 56
 57    async def find(self, collection:str, query, key:str, max_to_find=50) -> List[dict]:
 58        """Searches for documents with the query."""
 59        try:
 60            document_list = []
 61            cursor = self.database[collection].find(query).sort(key)
 62
 63            for document in await cursor.to_list(max_to_find):
 64                document_list.append(document)
 65
 66            return document_list
 67        except KeyError as e:
 68            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
 69            return None
 70
 71    async def find_all(self, collection:str, max_to_find=100) -> List[dict] | None:
 72        """Finds and returns all documents in a collection. This took me a day to make! 😞"""
 73        try:
 74            document_list = []
 75            cursor = self.database[collection].find().sort('_id')
 76
 77            for document in await cursor.to_list(max_to_find):
 78                document_list.append(document)
 79
 80            return document_list
 81        except KeyError as e:
 82            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
 83            return None
 84
 85    async def get_collection(self, collection):
 86        """Returns cursor of the following collection."""
 87        return self.database[collection]
 88
 89    async def list_collection_names(self) -> List[str]:
 90        """Returns list of all collection names."""
 91        return await self.database.list_collection_names()
 92
 93    async def find_one(self, collection:str, query:dict) -> (dict | None):
 94        """Tells database to search for and return specific data from a collection."""
 95        data = await self.database[collection].find_one(query)
 96
 97        if not data == None:
 98            GoldyBot.logging.log(f"[{MODULE_NAME}] Found '{query}' in '{collection}.'")
 99            return data
100        else:
101            GoldyBot.logging.log(f"[{MODULE_NAME}] '{query}' was not found in '{collection}.'")
102            return None
103        
104    async def create_collection(self, collection_name:str, data):
105        await self.database[collection_name].insert_one(data)
106        GoldyBot.logging.log(f"[{MODULE_NAME}] Database collection '{collection_name}' created.")
107
108    async def delete_collection(self, collection_name:str):
109        await self.database[collection_name].drop()
110        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Database collection '{collection_name}' dropped.")
111
112    def new_instance(self, database_name:str):
113        """Starts a new database instance the efficient way. 👍"""
114        class NewDatabase(Database):
115            def __init__(self, database_self:Database):
116                self.database = database_self.client[database_name]
117
118        return NewDatabase(self)

Goldy Bot's class to interface with a Mongo Database.

Database(database_token_url: str)
13    def __init__(self, database_token_url:str):
14        self.database_token_url = database_token_url
15        self.loop = asyncio.get_event_loop()
16
17        config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON))
18
19        try:
20            if not database_token_url.lower() in ["none", "null"]: 
21                # Initializing MongoDB database
22                self.client:pymongo.MongoClient = motor.motor_asyncio.AsyncIOMotorClient(self.database_token_url, serverSelectionTimeoutMS=2000)
23                self.loop.run_until_complete(self.client.server_info())
24                self.database = self.client[config.read("database_name")]
25
26                # Cache database class.
27                GoldyBot.cache.main_cache_dict["database"] = self
28
29                GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] [CONNECTED]")
30            
31            else:
32                GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] [DATABASE DISABLED]")
33                GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Database is disabled because '{database_token_url}' was entered.")
34
35        except Exception:
36            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Couldn't connect to Database! Check the database URL you entered.")
37            GoldyBot.Goldy().stop("Couldn't connect to Database! Check the database URL you entered.")
async def insert(self, collection: str, data) -> bool:
39    async def insert(self, collection:str, data) -> bool:
40        """Tells database to insert the data provided into a collection."""
41        await self.database[collection].insert_one(data)
42        GoldyBot.logging.log(f"[{MODULE_NAME}] Inserted '{data}' into '{collection}.'")
43        return True

Tells database to insert the data provided into a collection.

async def edit(self, collection: str, query, data: dict) -> bool:
45    async def edit(self, collection:str, query, data:dict) -> bool:
46        """Tells database to find and edit a document with the data provided in a collection."""
47        await self.database[collection].update_one(query, {"$set": data})
48        GoldyBot.logging.log(f"[{MODULE_NAME}] Edited '{query}' into '{data}.'")
49        return True

Tells database to find and edit a document with the data provided in a collection.

async def remove(self, collection: str, data) -> bool:
51    async def remove(self, collection:str, data) -> bool:
52        """Tells database to find and delete a copy of this data from the collection."""
53        await self.database[collection].delete_one(data)
54        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Deleted '{data}' from '{collection}.'")
55        return True

Tells database to find and delete a copy of this data from the collection.

async def find(self, collection: str, query, key: str, max_to_find=50) -> List[dict]:
57    async def find(self, collection:str, query, key:str, max_to_find=50) -> List[dict]:
58        """Searches for documents with the query."""
59        try:
60            document_list = []
61            cursor = self.database[collection].find(query).sort(key)
62
63            for document in await cursor.to_list(max_to_find):
64                document_list.append(document)
65
66            return document_list
67        except KeyError as e:
68            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
69            return None

Searches for documents with the query.

async def find_all(self, collection: str, max_to_find=100) -> Optional[List[dict]]:
71    async def find_all(self, collection:str, max_to_find=100) -> List[dict] | None:
72        """Finds and returns all documents in a collection. This took me a day to make! 😞"""
73        try:
74            document_list = []
75            cursor = self.database[collection].find().sort('_id')
76
77            for document in await cursor.to_list(max_to_find):
78                document_list.append(document)
79
80            return document_list
81        except KeyError as e:
82            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
83            return None

Finds and returns all documents in a collection. This took me a day to make! 😞

async def get_collection(self, collection):
85    async def get_collection(self, collection):
86        """Returns cursor of the following collection."""
87        return self.database[collection]

Returns cursor of the following collection.

async def list_collection_names(self) -> List[str]:
89    async def list_collection_names(self) -> List[str]:
90        """Returns list of all collection names."""
91        return await self.database.list_collection_names()

Returns list of all collection names.

async def find_one(self, collection: str, query: dict) -> dict | None:
 93    async def find_one(self, collection:str, query:dict) -> (dict | None):
 94        """Tells database to search for and return specific data from a collection."""
 95        data = await self.database[collection].find_one(query)
 96
 97        if not data == None:
 98            GoldyBot.logging.log(f"[{MODULE_NAME}] Found '{query}' in '{collection}.'")
 99            return data
100        else:
101            GoldyBot.logging.log(f"[{MODULE_NAME}] '{query}' was not found in '{collection}.'")
102            return None

Tells database to search for and return specific data from a collection.

async def create_collection(self, collection_name: str, data):
104    async def create_collection(self, collection_name:str, data):
105        await self.database[collection_name].insert_one(data)
106        GoldyBot.logging.log(f"[{MODULE_NAME}] Database collection '{collection_name}' created.")
async def delete_collection(self, collection_name: str):
108    async def delete_collection(self, collection_name:str):
109        await self.database[collection_name].drop()
110        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Database collection '{collection_name}' dropped.")
def new_instance(self, database_name: str):
112    def new_instance(self, database_name:str):
113        """Starts a new database instance the efficient way. 👍"""
114        class NewDatabase(Database):
115            def __init__(self, database_self:Database):
116                self.database = database_self.client[database_name]
117
118        return NewDatabase(self)

Starts a new database instance the efficient way. 👍

class Member(GoldyBot.database.member.money.Money):
 8class Member(Money):
 9    """Creates member database interface with ctx to allow for easy grabbing of member data."""
10    def __init__(self, ctx, member) -> None:
11        self.ctx = ctx
12        self.actual_member:GoldyBot.member.Member = member
13
14        self.database = GoldyBot.cache.database()
15
16        super().__init__(member)
17
18    async def get_member_data(self):
19        """Returns member's database collection."""
20        # Generate document if member doesn't exists in database.
21        await self.setup()
22
23        # Return member data.
24        return await self.database.find_one("global", {"_id":int(self.actual_member.member_id)})
25
26    async def edit_member_data(self, new_data:dict) -> bool:
27        """Updates member's database collection."""
28        # Generate document if member doesn't exists in database.
29        await self.setup()
30
31        # Update member data.
32        return await self.actual_member.database.edit("global", {"_id":int(self.actual_member.member_id)}, new_data)
33
34
35    async def setup(self):
36        """Makes sure this member is setup in global and guild collection."""
37
38        # Global setup if member does not exist in global collection.
39        if await self.database.find_one("global", {"_id":int(self.actual_member.member_id)}) == None:
40            await self.database.insert("global", data={
41                "_id":int(self.actual_member.member_id),
42
43                f"{self.actual_member.member_id}" : {}
44            })
45
46        # Guild setup if member does not exist in guild collection.
47        if await self.database.find_one(GoldyBot.cache.FindGuilds().find_object_by_id(self.ctx.guild.id).database_collection_name, {"_id":int(self.actual_member.member_id)}) == None:
48            await self.database.insert(GoldyBot.cache.FindGuilds().find_object_by_id(self.ctx.guild.id).database_collection_name, data={
49                "_id":int(self.actual_member.member_id),
50
51                f"{self.actual_member.member_id}" : {}
52            })

Creates member database interface with ctx to allow for easy grabbing of member data.

Member(ctx, member)
10    def __init__(self, ctx, member) -> None:
11        self.ctx = ctx
12        self.actual_member:GoldyBot.member.Member = member
13
14        self.database = GoldyBot.cache.database()
15
16        super().__init__(member)
async def get_member_data(self):
18    async def get_member_data(self):
19        """Returns member's database collection."""
20        # Generate document if member doesn't exists in database.
21        await self.setup()
22
23        # Return member data.
24        return await self.database.find_one("global", {"_id":int(self.actual_member.member_id)})

Returns member's database collection.

async def edit_member_data(self, new_data: dict) -> bool:
26    async def edit_member_data(self, new_data:dict) -> bool:
27        """Updates member's database collection."""
28        # Generate document if member doesn't exists in database.
29        await self.setup()
30
31        # Update member data.
32        return await self.actual_member.database.edit("global", {"_id":int(self.actual_member.member_id)}, new_data)

Updates member's database collection.

async def setup(self):
35    async def setup(self):
36        """Makes sure this member is setup in global and guild collection."""
37
38        # Global setup if member does not exist in global collection.
39        if await self.database.find_one("global", {"_id":int(self.actual_member.member_id)}) == None:
40            await self.database.insert("global", data={
41                "_id":int(self.actual_member.member_id),
42
43                f"{self.actual_member.member_id}" : {}
44            })
45
46        # Guild setup if member does not exist in guild collection.
47        if await self.database.find_one(GoldyBot.cache.FindGuilds().find_object_by_id(self.ctx.guild.id).database_collection_name, {"_id":int(self.actual_member.member_id)}) == None:
48            await self.database.insert(GoldyBot.cache.FindGuilds().find_object_by_id(self.ctx.guild.id).database_collection_name, data={
49                "_id":int(self.actual_member.member_id),
50
51                f"{self.actual_member.member_id}" : {}
52            })

Makes sure this member is setup in global and guild collection.