File size: 3,795 Bytes
5f685fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import threading
from abc import ABC, abstractmethod

import tinydb
import tinymongo as tm


class AbstractDatabaseDocument(ABC):

    @abstractmethod
    def _save(self, key, data):
        '''Save the data in the database'''
        pass

    @abstractmethod
    def _get(self, key):
        '''Get the data from the database'''
        pass

    @abstractmethod
    def _getId(self):
        '''Get the id of the document'''
        pass

    @abstractmethod
    def __str__(self):
        '''Return the string representation of the document'''
        pass

    @abstractmethod
    def _delete(self):
        '''Delete the document'''
        pass


class TinyMongoClient(tm.TinyMongoClient):
    @property
    def _storage(self):
        return tinydb.storages.JSONStorage


TINY_MONGO_DATABASE = TinyMongoClient("./.database")


class TinyMongoDocument(AbstractDatabaseDocument):
    _lock = threading.Lock()

    def __init__(self, db_name: str, collection_name: str, document_id: str, create=False):
        self.collection = TINY_MONGO_DATABASE[db_name][collection_name]
        self.collection_name = collection_name
        self.document_id = document_id
        if (not self.exists()):
            if create:
                self.collection.insert_one({"_id": document_id})
            else:
                raise Exception(f"The document with id {document_id} in collection {collection_name} of database {db_name} does not exist")

    def exists(self):
        with self._lock:
            return self.collection.find({"_id": self.document_id}).count() == 1

    def _save(self, data):
        with self._lock:
            try:
                update_data = {'$set': {}}
                for key, value in data.items():
                    path_parts = key.split(".")

                    if len(path_parts) > 1:
                        root_key = ".".join(path_parts[:-1])
                        last_key = path_parts[-1]
                        current_value = self._get(root_key)
                        if not isinstance(current_value, dict):
                            current_value = {}
                        current_value[last_key] = value
                        update_data['$set'][root_key] = current_value
                    else:
                        update_data['$set'][key] = value

                self.collection.update_one({'_id': self.document_id}, update_data)
            except Exception as e:
                print(f"Error saving data: {e}")

    def _get(self, key=None):
        with self._lock:
            try:
                document = self.collection.find_one({'_id': self.document_id})
                if not key:
                    del document['_id']
                    return document
                keys = key.split(".")
                value = document[keys[0]]
                for k in keys[1:]:
                    value = value[k]
                return value
            except Exception as e:
                #print(f"Error getting value for key '{key}': {e}")
                return None

    def _delete(self, key):
        with self._lock:
            try:
                document = self.collection.find_one({'_id': self.document_id})
                if key in document:
                    del document[key]
                    self.collection.remove({'_id': self.document_id})
                    self.collection.insert(document)
                else:
                    print(f"Key '{key}' not found in the document")
            except Exception as e:
                print(f"Error deleting key '{key}': {e}")

    def _getId(self):
        return self.document_id

    def __str__(self):
        with self._lock:
            document = self.collection.find_one({'_id': self.document_id})
            return str(document)