collections-cache 0.1.0__py3-none-any.whl

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.
File without changes
@@ -0,0 +1,106 @@
1
+ import sqlite3
2
+ from multiprocessing import Pool
3
+ from os import cpu_count, path, makedirs, scandir
4
+ from itertools import chain
5
+ from random import choice
6
+ #from threading import Thread as task
7
+ import pickle
8
+
9
+ class Collection_Cache:
10
+ def __init__(self, collection_name):
11
+ self.collection_name = collection_name
12
+ self.cpu_cores = cpu_count()
13
+ self.collection_dir = path.join("./Collections", self.collection_name)
14
+ self.databases_list = []
15
+ self.keys_databases = {}
16
+
17
+ #print(f"Collection '{self.collection_name}' created!")
18
+ #print(f"Number of cpu cores: {self.cpu_cores}")
19
+ self.create_collection()
20
+ self.get_all_databases()
21
+
22
+ def create_collection(self):
23
+ makedirs(self.collection_dir, exist_ok=True)
24
+
25
+ for core in range(self.cpu_cores):
26
+ db_path = path.join(self.collection_dir, f"database_{core}.db")
27
+ self.initialize_databases(db_path)
28
+
29
+ def initialize_databases(self, db_path):
30
+ conn = sqlite3.connect(db_path)
31
+ conn.execute("PRAGMA journal_mode=WAL;")
32
+ conn.execute("""
33
+ CREATE TABLE IF NOT EXISTS data(
34
+ key TEXT,
35
+ value BLOB
36
+ );
37
+ """)
38
+ conn.close()
39
+
40
+ def get_all_databases(self):
41
+ #print("Obtaining all keys...")
42
+ with scandir(self.collection_dir) as contents:
43
+ self.databases_list = [path.join(self.collection_dir, content.name) for content in contents]
44
+
45
+ with Pool(self.cpu_cores) as pool:
46
+ self.keys_databases = dict(chain.from_iterable(pool.map(self.get_all_keys, self.databases_list)))
47
+ #print(self.keys_databases)
48
+
49
+ def get_all_keys(self, database):
50
+ conn = sqlite3.connect(database)
51
+ cursor = conn.cursor()
52
+ cursor.execute("PRAGMA journal_mode=WAL;")
53
+ cursor.execute("SELECT key FROM data;")
54
+ result = cursor.fetchall()
55
+ keys = [(line[0], database) for line in result]
56
+ conn.close()
57
+ return keys
58
+
59
+ def set_key(self, key, value):
60
+ if key not in self.keys_databases:
61
+ database_to_insert = choice(self.databases_list)
62
+ #print(f"Inserting in {database_to_insert}")
63
+ conn = sqlite3.connect(database_to_insert)
64
+ cursor = conn.cursor()
65
+ cursor.execute("PRAGMA journal_mode=WAL;")
66
+ cursor.execute("INSERT INTO data(key, value) VALUES (?, ?);", (key, pickle.dumps(value)))
67
+ conn.commit()
68
+ conn.close()
69
+ self.add_to_keys_database(key, database_to_insert)
70
+
71
+ else:
72
+ #print(f"Updating key '{key}' in {self.keys_databases[key]}...")
73
+ database_to_update = self.keys_databases[key]
74
+ conn = sqlite3.connect(database_to_update)
75
+ cursor = conn.cursor()
76
+ cursor.execute("PRAGMA journal_mode=WAL;")
77
+ cursor.execute("UPDATE data SET value = ? WHERE key = ?;", (pickle.dumps(value), key))
78
+ conn.commit()
79
+ conn.close()
80
+ #print(f"Key '{key}' updated successfully in {database_to_update}")
81
+
82
+ def add_to_keys_database(self, key, database):
83
+ self.keys_databases[key] = database
84
+ #print(self.keys_databases)
85
+
86
+ def get_key(self, key):
87
+ try:
88
+ database_to_search = self.keys_databases[key]
89
+ #print(database_to_search)
90
+
91
+ conn = sqlite3.connect(database_to_search)
92
+ cursor = conn.cursor()
93
+ cursor.execute("PRAGMA journal_mode=WAL;")
94
+ cursor.execute("SELECT value FROM data WHERE key = ?", (key,))
95
+ result = cursor.fetchall()
96
+ conn.close()
97
+ return pickle.loads(result[0][0])
98
+
99
+ except Exception as error:
100
+ return error
101
+
102
+ conn = Collection_Cache("STORE")
103
+ conn.set_key("alunos", ["Luiz", "Marcos", "João"])
104
+
105
+ alunos = conn.get_key("alunos")
106
+ print(alunos)
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.1
2
+ Name: collections-cache
3
+ Version: 0.1.0
4
+ Summary: Collection Cache is a Python package for managing data collections across multiple SQLite databases. It allows efficient storage, retrieval, and updating of key-value pairs, supporting various data types serialized with pickle. The package uses parallel processing for fast access and manipulation of large collections.
5
+ License: MIT
6
+ Author: Luiz-Trindade
7
+ Author-email: luiz.gabriel.m.trindade@gmail.com
8
+ Requires-Python: >=3.12,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Collection Cache
15
+
16
+ `Collection Cache` is a simple and efficient caching solution built using SQLite databases. It allows for storing, updating, and retrieving data using unique keys, supporting complex data types through the use of `pickle`. It is designed to scale across multiple CPU cores by distributing the data across multiple SQLite databases.
17
+
18
+ ## Features
19
+
20
+ - **Multiple SQLite databases**: Distributes data across multiple databases for better scalability.
21
+ - **Key-value store**: Store data as key-value pairs.
22
+ - **Supports complex data types**: Data is serialized using `pickle`, so you can store lists, dictionaries, and other complex Python objects.
23
+ - **Parallel processing**: Uses Python’s `multiprocessing` to handle large collections in parallel across multiple CPU cores.
24
+ - **Efficient data retrieval**: Retrieves stored data based on the key using an efficient search across the collection.
25
+
26
+ ## Installation
27
+
28
+ To install the `Collection Cache` package, use [Poetry](https://python-poetry.org/) for managing dependencies.
29
+
30
+ 1. Clone the repository:
31
+
32
+ ```bash
33
+ git clone https://github.com/Luiz-Trindade/collections_cache.git
34
+ cd collection-cache
35
+ ```
36
+
37
+ 2. Install the package with Poetry:
38
+
39
+ ```bash
40
+ poetry install
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ To use the `Collection Cache` package, you can import the main class `Collection_Cache` and interact with your collection.
46
+
47
+ ### Example:
48
+
49
+ ```python
50
+ from collection_cache import Collection_Cache
51
+
52
+ # Create a new collection
53
+ cache = Collection_Cache("STORE")
54
+
55
+ # Set a key-value pair
56
+ cache.set_key("alunos", ["Luiz", "Marcos", "João"])
57
+
58
+ # Get the value by key
59
+ students = cache.get_key("alunos")
60
+ print(students) # Output: ['Luiz', 'Marcos', 'João']
61
+ ```
62
+
63
+ ### Methods:
64
+
65
+ - **`set_key(key, value)`**: Set a key-value pair in the cache. If the key already exists, it will be updated.
66
+ - **`get_key(key)`**: Retrieve the value associated with a key.
67
+ - **`create_collection()`**: Initializes the collection and sets up databases for key-value storage.
68
+ - **`get_all_keys()`**: Retrieves all keys from the collection.
69
+
70
+ ## Development
71
+
72
+ To contribute or run tests:
73
+
74
+ 1. Install development dependencies:
75
+
76
+ ```bash
77
+ poetry install --dev
78
+ ```
79
+
80
+ 2. Run tests:
81
+
82
+ ```bash
83
+ poetry run pytest
84
+ ```
85
+
86
+ ## License
87
+
88
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
89
+
90
+ ## Acknowledgements
91
+
92
+ - This package was created to demonstrate how to work with SQLite, `pickle`, and Python's `multiprocessing` module.
93
+
94
+
@@ -0,0 +1,5 @@
1
+ collections_cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ collections_cache/collections_cahce.py,sha256=WqobCdFepXcMwoy3ukB5AqImyohfcCxmNbLew8Le0EU,3987
3
+ collections_cache-0.1.0.dist-info/METADATA,sha256=GKY9Xlb1TRwxQfFmwymIyZBSpmc1x9DC6gKDaZPikO4,3199
4
+ collections_cache-0.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
5
+ collections_cache-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any