fuckreplitdb 1.6.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+
2
+ Copyright (c) 2018 The Python Packaging Authority
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
21
+
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: fuckreplitdb
3
+ Version: 1.6.9
4
+ Summary: For the devs who wrote apps a bit too big with Replit DB.
5
+ Author-email: theroyalwhale <admin@dyntech.cc>
6
+ License-Expression: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+
15
+ # General Information and Usage
16
+
17
+ ## Overview
18
+
19
+ The `FuckReplitDB` class is designed to function as a simple drop-in replacement for Replit DB (or any other key-value store), similar to how you might use a dictionary, but with persistent file-backed storage. It stores data in a JSON-like structure on disk and offers both basic key-value operations and the ability to handle nested dictionaries, making it ideal for use cases where you need to persist data in a file but want a simple API for access and modification.
20
+
21
+ ### **Key Features**
22
+
23
+ - **Drop-in Replacement**: The class is designed to work like a Python dictionary, so you can directly replace a dictionary in your code with an instance of `FuckReplitDB` without changing much of the underlying logic. It supports all the basic dictionary operations like `get`, `set`, `delete`, and checking for key existence.
24
+
25
+ - **Persistent Storage**: The data is stored on disk in a file using the `orjson` format, allowing you to persist data between application runs. This makes it a lightweight alternative to more complex databases for simple applications.
26
+
27
+ - **Nested Data**: With support for nested dictionaries, the class allows you to easily represent and manipulate complex hierarchical data structures, making it useful for storing configuration settings, user data, or any other type of structured data.
28
+
29
+ - **Thread-Safe**: The class uses `threading.Lock` to ensure thread-safe operations, so it can be used in multi-threaded environments without the risk of data corruption.
30
+
31
+ - **Simple API**: The class exposes an intuitive dictionary-like API, making it easy to use and understand.
32
+
33
+ ---
34
+
35
+ ## Drop-in Replacement
36
+
37
+ One of the core design principles behind `FuckReplitDB` is that it should be as simple to use as a Python dictionary. Here's a quick comparison of using `FuckReplitDB` versus a regular dictionary:
38
+
39
+ ### **Using Python Dictionary:**
40
+
41
+ ```python
42
+ # Using a regular dictionary
43
+ my_dict = {}
44
+
45
+ # Setting a value
46
+ my_dict['name'] = 'Alice'
47
+
48
+ # Getting a value
49
+ print(my_dict.get('name')) # Output: Alice
50
+
51
+ # Deleting a key
52
+ del my_dict['name']
53
+ ```
54
+
55
+ ### **Using `FuckReplitDB`:**
56
+
57
+ ```python
58
+ # Using FuckReplitDB for persistent storage
59
+ db = FuckReplitDB('data.json')
60
+
61
+ # Setting a value
62
+ db.set('name', 'Alice')
63
+
64
+ # Getting a value
65
+ print(db.get('name')) # Output: Alice
66
+
67
+ # Deleting a key
68
+ del db['name']
69
+ ```
70
+
71
+ As you can see, the usage of `FuckReplitDB` is nearly identical to using a regular dictionary. The key difference is that `FuckReplitDB` persists its data to a file, and operations are thread-safe.
72
+
73
+ ---
74
+
75
+ ## Advanced Usage
76
+
77
+ ### **Working with Nested Data**
78
+
79
+ `FuckReplitDB` supports nested dictionaries using the `NestedDict` class, which allows you to work with hierarchical data structures. For example:
80
+
81
+ ```python
82
+ # Using nested dictionaries
83
+ db['user'] = {'name': 'Bob', 'details': {'age': 30, 'city': 'New York'}}
84
+
85
+ # Accessing nested data
86
+ print(db['user']['name']) # Output: Bob
87
+ print(db['user']['details']['age']) # Output: 30
88
+
89
+ # Modifying nested data
90
+ db['user']['details']['city'] = 'San Francisco'
91
+
92
+ # Deleting nested data
93
+ del db['user']['details']['city']
94
+ ```
95
+
96
+ This feature allows you to manipulate data that is structured in multiple levels, like a user profile with personal information and settings.
97
+
98
+ ---
99
+
100
+ ## Basic Operations
101
+
102
+ ### **Setting a Key-Value Pair**
103
+
104
+ You can set values using `db.set(key, value)` or using dictionary-style syntax:
105
+
106
+ ```python
107
+ db.set('age', 25) # Setting with set()
108
+ db['name'] = 'Alice' # Setting with dictionary-style assignment
109
+ ```
110
+
111
+ ### **Getting a Value**
112
+
113
+ You can retrieve a value using the `get()` method or the dictionary-style `[]` operator:
114
+
115
+ ```python
116
+ print(db.get('age')) # Using get()
117
+ print(db['name']) # Using dictionary-style access
118
+ ```
119
+
120
+ ### **Checking for Existence**
121
+
122
+ Check if a key exists with the `in` operator, just like a regular dictionary:
123
+
124
+ ```python
125
+ if 'age' in db:
126
+ print('Age is set')
127
+ ```
128
+
129
+ ### **Deleting a Key**
130
+
131
+ Use `del` to remove a key from the database:
132
+
133
+ ```python
134
+ del db['age']
135
+ ```
136
+
137
+ ### **Iterating over Keys**
138
+
139
+ You can iterate over the keys in the database using `db.keys()` or by directly iterating over the object:
140
+
141
+ ```python
142
+ for key in db:
143
+ print(key)
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Thread Safety
149
+
150
+ `FuckReplitDB` ensures that multiple threads accessing the database simultaneously do not cause data corruption or race conditions. The database uses a lock (`threading.Lock`) around all file operations to make sure that only one thread can read or write to the file at a time.
151
+
152
+ For example, if you have multiple threads accessing and modifying the database:
153
+
154
+ ```python
155
+ import threading
156
+
157
+ def set_data():
158
+ db.set('name', 'Alice')
159
+
160
+ threads = []
161
+ for _ in range(10):
162
+ t = threading.Thread(target=set_data)
163
+ threads.append(t)
164
+ t.start()
165
+
166
+ for t in threads:
167
+ t.join()
168
+ ```
169
+
170
+ This is thread-safe because each file operation is locked, preventing concurrent writes or reads that could cause data inconsistency.
171
+
172
+ ---
173
+
174
+ ## Conclusion
175
+
176
+ The `FuckReplitDB` class is an easy-to-use, lightweight, and thread-safe key-value store that can be used as a simple drop-in replacement for Python's built-in dictionary when you need persistent storage. It supports all basic dictionary operations, works with nested data structures, and handles concurrency without any extra complexity on your part. I made this because I wrote an app with Replit DB that got a bit too big for a complete rewrite (oops) so that's where the name came from.
177
+
@@ -0,0 +1,164 @@
1
+
2
+ # General Information and Usage
3
+
4
+ ## Overview
5
+
6
+ The `FuckReplitDB` class is designed to function as a simple drop-in replacement for Replit DB (or any other key-value store), similar to how you might use a dictionary, but with persistent file-backed storage. It stores data in a JSON-like structure on disk and offers both basic key-value operations and the ability to handle nested dictionaries, making it ideal for use cases where you need to persist data in a file but want a simple API for access and modification.
7
+
8
+ ### **Key Features**
9
+
10
+ - **Drop-in Replacement**: The class is designed to work like a Python dictionary, so you can directly replace a dictionary in your code with an instance of `FuckReplitDB` without changing much of the underlying logic. It supports all the basic dictionary operations like `get`, `set`, `delete`, and checking for key existence.
11
+
12
+ - **Persistent Storage**: The data is stored on disk in a file using the `orjson` format, allowing you to persist data between application runs. This makes it a lightweight alternative to more complex databases for simple applications.
13
+
14
+ - **Nested Data**: With support for nested dictionaries, the class allows you to easily represent and manipulate complex hierarchical data structures, making it useful for storing configuration settings, user data, or any other type of structured data.
15
+
16
+ - **Thread-Safe**: The class uses `threading.Lock` to ensure thread-safe operations, so it can be used in multi-threaded environments without the risk of data corruption.
17
+
18
+ - **Simple API**: The class exposes an intuitive dictionary-like API, making it easy to use and understand.
19
+
20
+ ---
21
+
22
+ ## Drop-in Replacement
23
+
24
+ One of the core design principles behind `FuckReplitDB` is that it should be as simple to use as a Python dictionary. Here's a quick comparison of using `FuckReplitDB` versus a regular dictionary:
25
+
26
+ ### **Using Python Dictionary:**
27
+
28
+ ```python
29
+ # Using a regular dictionary
30
+ my_dict = {}
31
+
32
+ # Setting a value
33
+ my_dict['name'] = 'Alice'
34
+
35
+ # Getting a value
36
+ print(my_dict.get('name')) # Output: Alice
37
+
38
+ # Deleting a key
39
+ del my_dict['name']
40
+ ```
41
+
42
+ ### **Using `FuckReplitDB`:**
43
+
44
+ ```python
45
+ # Using FuckReplitDB for persistent storage
46
+ db = FuckReplitDB('data.json')
47
+
48
+ # Setting a value
49
+ db.set('name', 'Alice')
50
+
51
+ # Getting a value
52
+ print(db.get('name')) # Output: Alice
53
+
54
+ # Deleting a key
55
+ del db['name']
56
+ ```
57
+
58
+ As you can see, the usage of `FuckReplitDB` is nearly identical to using a regular dictionary. The key difference is that `FuckReplitDB` persists its data to a file, and operations are thread-safe.
59
+
60
+ ---
61
+
62
+ ## Advanced Usage
63
+
64
+ ### **Working with Nested Data**
65
+
66
+ `FuckReplitDB` supports nested dictionaries using the `NestedDict` class, which allows you to work with hierarchical data structures. For example:
67
+
68
+ ```python
69
+ # Using nested dictionaries
70
+ db['user'] = {'name': 'Bob', 'details': {'age': 30, 'city': 'New York'}}
71
+
72
+ # Accessing nested data
73
+ print(db['user']['name']) # Output: Bob
74
+ print(db['user']['details']['age']) # Output: 30
75
+
76
+ # Modifying nested data
77
+ db['user']['details']['city'] = 'San Francisco'
78
+
79
+ # Deleting nested data
80
+ del db['user']['details']['city']
81
+ ```
82
+
83
+ This feature allows you to manipulate data that is structured in multiple levels, like a user profile with personal information and settings.
84
+
85
+ ---
86
+
87
+ ## Basic Operations
88
+
89
+ ### **Setting a Key-Value Pair**
90
+
91
+ You can set values using `db.set(key, value)` or using dictionary-style syntax:
92
+
93
+ ```python
94
+ db.set('age', 25) # Setting with set()
95
+ db['name'] = 'Alice' # Setting with dictionary-style assignment
96
+ ```
97
+
98
+ ### **Getting a Value**
99
+
100
+ You can retrieve a value using the `get()` method or the dictionary-style `[]` operator:
101
+
102
+ ```python
103
+ print(db.get('age')) # Using get()
104
+ print(db['name']) # Using dictionary-style access
105
+ ```
106
+
107
+ ### **Checking for Existence**
108
+
109
+ Check if a key exists with the `in` operator, just like a regular dictionary:
110
+
111
+ ```python
112
+ if 'age' in db:
113
+ print('Age is set')
114
+ ```
115
+
116
+ ### **Deleting a Key**
117
+
118
+ Use `del` to remove a key from the database:
119
+
120
+ ```python
121
+ del db['age']
122
+ ```
123
+
124
+ ### **Iterating over Keys**
125
+
126
+ You can iterate over the keys in the database using `db.keys()` or by directly iterating over the object:
127
+
128
+ ```python
129
+ for key in db:
130
+ print(key)
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Thread Safety
136
+
137
+ `FuckReplitDB` ensures that multiple threads accessing the database simultaneously do not cause data corruption or race conditions. The database uses a lock (`threading.Lock`) around all file operations to make sure that only one thread can read or write to the file at a time.
138
+
139
+ For example, if you have multiple threads accessing and modifying the database:
140
+
141
+ ```python
142
+ import threading
143
+
144
+ def set_data():
145
+ db.set('name', 'Alice')
146
+
147
+ threads = []
148
+ for _ in range(10):
149
+ t = threading.Thread(target=set_data)
150
+ threads.append(t)
151
+ t.start()
152
+
153
+ for t in threads:
154
+ t.join()
155
+ ```
156
+
157
+ This is thread-safe because each file operation is locked, preventing concurrent writes or reads that could cause data inconsistency.
158
+
159
+ ---
160
+
161
+ ## Conclusion
162
+
163
+ The `FuckReplitDB` class is an easy-to-use, lightweight, and thread-safe key-value store that can be used as a simple drop-in replacement for Python's built-in dictionary when you need persistent storage. It supports all basic dictionary operations, works with nested data structures, and handles concurrency without any extra complexity on your part. I made this because I wrote an app with Replit DB that got a bit too big for a complete rewrite (oops) so that's where the name came from.
164
+
@@ -0,0 +1,20 @@
1
+
2
+ [build-system]
3
+ requires = ["setuptools >= 77.0.3"]
4
+ build-backend = "setuptools.build_meta"
5
+
6
+ [project]
7
+ name = "fuckreplitdb"
8
+ version = "1.6.9"
9
+ authors = [
10
+ { name="theroyalwhale", email="admin@dyntech.cc" },
11
+ ]
12
+ description = "For the devs who wrote apps a bit too big with Replit DB."
13
+ readme = "README.md"
14
+ requires-python = ">=3.8"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ license = "MIT"
20
+ license-files = ["LICEN[CS]E*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,204 @@
1
+
2
+
3
+ import orjson
4
+ import os
5
+ import threading
6
+ from typing import Dict, Any, Iterator
7
+
8
+ class NestedDict:
9
+ def __init__(self, parent, key_path):
10
+ self.parent = parent
11
+ self.key_path = key_path
12
+
13
+ def __getitem__(self, key):
14
+ new_path = self.key_path + [key]
15
+
16
+ with self.parent.lock:
17
+ try:
18
+ with open(self.parent.filename, 'rb') as f:
19
+ data = orjson.loads(f.read())
20
+
21
+ current = data
22
+ for k in self.key_path:
23
+ current = current[k]
24
+
25
+ value = current[key]
26
+ if isinstance(value, dict):
27
+ return NestedDict(self.parent, new_path)
28
+ return value
29
+ except (KeyError, ValueError, FileNotFoundError):
30
+ raise KeyError(key)
31
+
32
+ def __setitem__(self, key, value):
33
+ new_path = self.key_path + [key]
34
+
35
+ with self.parent.lock:
36
+ try:
37
+ with open(self.parent.filename, 'rb') as f:
38
+ data = orjson.loads(f.read())
39
+ except (ValueError, FileNotFoundError):
40
+ data = {}
41
+
42
+ current = data
43
+ for k in self.key_path:
44
+ if k not in current:
45
+ current[k] = {}
46
+ current = current[k]
47
+
48
+ current[key] = value
49
+
50
+ with open(self.parent.filename, 'wb') as f:
51
+ f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2))
52
+
53
+ def __contains__(self, key):
54
+ with self.parent.lock:
55
+ try:
56
+ with open(self.parent.filename, 'rb') as f:
57
+ data = orjson.loads(f.read())
58
+
59
+ current = data
60
+ for k in self.key_path:
61
+ current = current[k]
62
+
63
+ return key in current
64
+ except (KeyError, ValueError, FileNotFoundError):
65
+ return False
66
+
67
+ def __delitem__(self, key):
68
+ with self.parent.lock:
69
+ try:
70
+ with open(self.parent.filename, 'rb') as f:
71
+ data = orjson.loads(f.read())
72
+
73
+ current = data
74
+ for k in self.key_path:
75
+ current = current[k]
76
+
77
+ if key in current:
78
+ del current[key]
79
+
80
+ with open(self.parent.filename, 'wb') as f:
81
+ f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2))
82
+ else:
83
+ raise KeyError(key)
84
+ except (KeyError, ValueError, FileNotFoundError):
85
+ raise KeyError(key)
86
+
87
+ class FuckReplitDB:
88
+ def __init__(self, filename):
89
+ self.filename = filename
90
+ self.lock = threading.Lock()
91
+
92
+ if not os.path.exists(filename):
93
+ with open(filename, 'wb') as f:
94
+ f.write(orjson.dumps({}))
95
+
96
+ def get(self, key, default=None):
97
+ with self.lock:
98
+ try:
99
+ with open(self.filename, 'rb') as f:
100
+ data = orjson.loads(f.read())
101
+ return data.get(key, default)
102
+ except (ValueError, FileNotFoundError):
103
+ return default
104
+
105
+ def set(self, key, value):
106
+ with self.lock:
107
+ try:
108
+ with open(self.filename, 'rb') as f:
109
+ data = orjson.loads(f.read())
110
+ except (ValueError, FileNotFoundError):
111
+ data = {}
112
+
113
+ data[key] = value
114
+
115
+ with open(self.filename, 'wb') as f:
116
+ f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2))
117
+
118
+ def delete(self, key):
119
+ with self.lock:
120
+ try:
121
+ with open(self.filename, 'rb') as f:
122
+ data = orjson.loads(f.read())
123
+
124
+ if key in data:
125
+ del data[key]
126
+
127
+ with open(self.filename, 'wb') as f:
128
+ f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2))
129
+ except (ValueError, FileNotFoundError):
130
+ pass
131
+
132
+ def items(self):
133
+ with self.lock:
134
+ try:
135
+ with open(self.filename, 'rb') as f:
136
+ data = orjson.loads(f.read())
137
+ return data.items()
138
+ except (ValueError, FileNotFoundError):
139
+ return {}
140
+
141
+ def keys(self):
142
+ with self.lock:
143
+ try:
144
+ with open(self.filename, 'rb') as f:
145
+ data = orjson.loads(f.read())
146
+ return data.keys()
147
+ except (ValueError, FileNotFoundError):
148
+ return []
149
+
150
+ def __contains__(self, key):
151
+ with self.lock:
152
+ try:
153
+ with open(self.filename, 'rb') as f:
154
+ data = orjson.loads(f.read())
155
+ return key in data
156
+ except (ValueError, FileNotFoundError):
157
+ return False
158
+
159
+ def __getitem__(self, key):
160
+ with self.lock:
161
+ try:
162
+ with open(self.filename, 'rb') as f:
163
+ data = orjson.loads(f.read())
164
+
165
+ value = data[key]
166
+ if isinstance(value, dict):
167
+ return NestedDict(self, [key])
168
+ return value
169
+ except (KeyError, ValueError, FileNotFoundError):
170
+ raise KeyError(key)
171
+
172
+ def __setitem__(self, key, value):
173
+ self.set(key, value)
174
+
175
+ def __delitem__(self, key):
176
+ with self.lock:
177
+ try:
178
+ with open(self.filename, 'rb') as f:
179
+ data = orjson.loads(f.read())
180
+
181
+ if key in data:
182
+ del data[key]
183
+
184
+ with open(self.filename, 'wb') as f:
185
+ f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2))
186
+ else:
187
+ raise KeyError(key)
188
+ except (ValueError, FileNotFoundError):
189
+ raise KeyError(key)
190
+
191
+ def __iter__(self) -> Iterator:
192
+ with self.lock:
193
+ try:
194
+ with open(self.filename, 'rb') as f:
195
+ data = orjson.loads(f.read())
196
+ return iter(data)
197
+ except (ValueError, FileNotFoundError):
198
+ return iter([])
199
+
200
+
201
+
202
+
203
+
204
+
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: fuckreplitdb
3
+ Version: 1.6.9
4
+ Summary: For the devs who wrote apps a bit too big with Replit DB.
5
+ Author-email: theroyalwhale <admin@dyntech.cc>
6
+ License-Expression: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+
15
+ # General Information and Usage
16
+
17
+ ## Overview
18
+
19
+ The `FuckReplitDB` class is designed to function as a simple drop-in replacement for Replit DB (or any other key-value store), similar to how you might use a dictionary, but with persistent file-backed storage. It stores data in a JSON-like structure on disk and offers both basic key-value operations and the ability to handle nested dictionaries, making it ideal for use cases where you need to persist data in a file but want a simple API for access and modification.
20
+
21
+ ### **Key Features**
22
+
23
+ - **Drop-in Replacement**: The class is designed to work like a Python dictionary, so you can directly replace a dictionary in your code with an instance of `FuckReplitDB` without changing much of the underlying logic. It supports all the basic dictionary operations like `get`, `set`, `delete`, and checking for key existence.
24
+
25
+ - **Persistent Storage**: The data is stored on disk in a file using the `orjson` format, allowing you to persist data between application runs. This makes it a lightweight alternative to more complex databases for simple applications.
26
+
27
+ - **Nested Data**: With support for nested dictionaries, the class allows you to easily represent and manipulate complex hierarchical data structures, making it useful for storing configuration settings, user data, or any other type of structured data.
28
+
29
+ - **Thread-Safe**: The class uses `threading.Lock` to ensure thread-safe operations, so it can be used in multi-threaded environments without the risk of data corruption.
30
+
31
+ - **Simple API**: The class exposes an intuitive dictionary-like API, making it easy to use and understand.
32
+
33
+ ---
34
+
35
+ ## Drop-in Replacement
36
+
37
+ One of the core design principles behind `FuckReplitDB` is that it should be as simple to use as a Python dictionary. Here's a quick comparison of using `FuckReplitDB` versus a regular dictionary:
38
+
39
+ ### **Using Python Dictionary:**
40
+
41
+ ```python
42
+ # Using a regular dictionary
43
+ my_dict = {}
44
+
45
+ # Setting a value
46
+ my_dict['name'] = 'Alice'
47
+
48
+ # Getting a value
49
+ print(my_dict.get('name')) # Output: Alice
50
+
51
+ # Deleting a key
52
+ del my_dict['name']
53
+ ```
54
+
55
+ ### **Using `FuckReplitDB`:**
56
+
57
+ ```python
58
+ # Using FuckReplitDB for persistent storage
59
+ db = FuckReplitDB('data.json')
60
+
61
+ # Setting a value
62
+ db.set('name', 'Alice')
63
+
64
+ # Getting a value
65
+ print(db.get('name')) # Output: Alice
66
+
67
+ # Deleting a key
68
+ del db['name']
69
+ ```
70
+
71
+ As you can see, the usage of `FuckReplitDB` is nearly identical to using a regular dictionary. The key difference is that `FuckReplitDB` persists its data to a file, and operations are thread-safe.
72
+
73
+ ---
74
+
75
+ ## Advanced Usage
76
+
77
+ ### **Working with Nested Data**
78
+
79
+ `FuckReplitDB` supports nested dictionaries using the `NestedDict` class, which allows you to work with hierarchical data structures. For example:
80
+
81
+ ```python
82
+ # Using nested dictionaries
83
+ db['user'] = {'name': 'Bob', 'details': {'age': 30, 'city': 'New York'}}
84
+
85
+ # Accessing nested data
86
+ print(db['user']['name']) # Output: Bob
87
+ print(db['user']['details']['age']) # Output: 30
88
+
89
+ # Modifying nested data
90
+ db['user']['details']['city'] = 'San Francisco'
91
+
92
+ # Deleting nested data
93
+ del db['user']['details']['city']
94
+ ```
95
+
96
+ This feature allows you to manipulate data that is structured in multiple levels, like a user profile with personal information and settings.
97
+
98
+ ---
99
+
100
+ ## Basic Operations
101
+
102
+ ### **Setting a Key-Value Pair**
103
+
104
+ You can set values using `db.set(key, value)` or using dictionary-style syntax:
105
+
106
+ ```python
107
+ db.set('age', 25) # Setting with set()
108
+ db['name'] = 'Alice' # Setting with dictionary-style assignment
109
+ ```
110
+
111
+ ### **Getting a Value**
112
+
113
+ You can retrieve a value using the `get()` method or the dictionary-style `[]` operator:
114
+
115
+ ```python
116
+ print(db.get('age')) # Using get()
117
+ print(db['name']) # Using dictionary-style access
118
+ ```
119
+
120
+ ### **Checking for Existence**
121
+
122
+ Check if a key exists with the `in` operator, just like a regular dictionary:
123
+
124
+ ```python
125
+ if 'age' in db:
126
+ print('Age is set')
127
+ ```
128
+
129
+ ### **Deleting a Key**
130
+
131
+ Use `del` to remove a key from the database:
132
+
133
+ ```python
134
+ del db['age']
135
+ ```
136
+
137
+ ### **Iterating over Keys**
138
+
139
+ You can iterate over the keys in the database using `db.keys()` or by directly iterating over the object:
140
+
141
+ ```python
142
+ for key in db:
143
+ print(key)
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Thread Safety
149
+
150
+ `FuckReplitDB` ensures that multiple threads accessing the database simultaneously do not cause data corruption or race conditions. The database uses a lock (`threading.Lock`) around all file operations to make sure that only one thread can read or write to the file at a time.
151
+
152
+ For example, if you have multiple threads accessing and modifying the database:
153
+
154
+ ```python
155
+ import threading
156
+
157
+ def set_data():
158
+ db.set('name', 'Alice')
159
+
160
+ threads = []
161
+ for _ in range(10):
162
+ t = threading.Thread(target=set_data)
163
+ threads.append(t)
164
+ t.start()
165
+
166
+ for t in threads:
167
+ t.join()
168
+ ```
169
+
170
+ This is thread-safe because each file operation is locked, preventing concurrent writes or reads that could cause data inconsistency.
171
+
172
+ ---
173
+
174
+ ## Conclusion
175
+
176
+ The `FuckReplitDB` class is an easy-to-use, lightweight, and thread-safe key-value store that can be used as a simple drop-in replacement for Python's built-in dictionary when you need persistent storage. It supports all basic dictionary operations, works with nested data structures, and handles concurrency without any extra complexity on your part. I made this because I wrote an app with Replit DB that got a bit too big for a complete rewrite (oops) so that's where the name came from.
177
+
@@ -0,0 +1,8 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/fuckreplitdb/__init__.py
5
+ src/fuckreplitdb.egg-info/PKG-INFO
6
+ src/fuckreplitdb.egg-info/SOURCES.txt
7
+ src/fuckreplitdb.egg-info/dependency_links.txt
8
+ src/fuckreplitdb.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ fuckreplitdb