Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.5.1 release #17

Merged
merged 5 commits into from May 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions README.md
Expand Up @@ -15,7 +15,7 @@
$ pip install elara
```

* Latest - `v0.5.0`
* Latest - `v0.5.1`

Go through the [release notes](#releases) for details on upgrades as breaking changes might happen between version upgrades while Elara is in beta.

Expand Down Expand Up @@ -193,6 +193,8 @@ Elara can also be used as a fast in-memory cache.

The LRU eviction searches for, and deletes, expired keys lazily after every function call.

Note - In `exe_cache`, the `path` parameter is a required argument in case you need to commit your cache contents into the database.

* `set(key, value, max_age=None)` - The `set()` function takes another argument, `max_age`, that is set to `None` by default ie. the key-value pair will follow the default `max_age` set in `cache_param` OR they stay never get evicted if `cache_param` is not defined. The `max_age` param in `set()` allows for more granular control over cache item expiry. `max_age` should be an integer greater than 0. `max_age = "i"` indicates the item will not be removed from memory (overrides default `max_age` or `max_age` defined in `cache_param`)

Similarly, `lnew(key, max_age=None)`, `hnew(key, max_age=None)` (read the API reference) and `getset(key, value, max_age=None)`, all accept the optional `max_age` argument.
Expand Down Expand Up @@ -332,6 +334,8 @@ print(cache.get("obj").num)
* `slen(key)` - returns the length of the string value if the key exists; returns `-1` otherwise.
* `append(key, data)` - Append the data (String) to an existing string value; returns `False` if it fails.

[Go back to the table of contents](#contents)

<span id="lists"></span>
### Lists :

Expand Down Expand Up @@ -369,7 +373,8 @@ print(db.get('newlist'))

```

=> The following methods do not have complete test coverage yet :
[Go back to the table of contents](#contents)

<span id="dict"></span>
### Hashtable/Dictionary :

Expand Down Expand Up @@ -484,11 +489,10 @@ $ python -m unittest -v
## Release notes

* Latest - `v0.5.x`
- `v0.5.0` - No breaking changes

`v0.5.x` comes with an internal re-architecture that allows for much better caching and granular control on item expiry.
- `v0.5.1` - No breaking changes
- `v0.5.0`

* Previous - `v0.4.0`
`v0.5.x` comes with an internal re-architecture that allows for much better caching and granular control on item expiry. No breaking changes from `v0.4.x`.

`v0.4.x` moves away from the json-based (`dump`, `load`) storage approach used in earlier versions, instead storing it as bytes and has support for checksums and database file version flags for added security.

Expand All @@ -500,6 +504,8 @@ To safeguard data, its better to **export all existing data** from any existing

View Elara's [release history](https://github.com/saurabh0719/elara/releases/).

[Go back to the table of contents](#contents)

<hr>

<span id="contrib"></span>
Expand Down
11 changes: 6 additions & 5 deletions README.rst
Expand Up @@ -189,6 +189,8 @@ Elara can also be used as a fast in-memory cache.

The LRU eviction searches for, and deletes, expired keys lazily after every function call.

Note - In ``exe_cache``, the ``path`` parameter is a required argument in case you need to commit your cache contents into the database.

- ``set(key, value, max_age=None)`` - The ``set()`` function takes another argument, ``max_age``, that is set to ``None`` by default ie. the key-value pair will follow the default ``max_age`` set in ``cache_param`` OR they stay never get evicted if ``cache_param`` is not defined. The ``max_age`` param in ``set()`` allows for more granular control over cache item expiry.
``max_age`` should be an integer greater than 0. ``max_age = "i"`` indicates the item will not be removed from memory (overrides default ``max_age`` or ``max_age`` defined in ``cache_param``)

Expand Down Expand Up @@ -380,8 +382,7 @@ Lists :
print(db.get('newlist'))
# [3, 4, 6, 7, 8, 9]

| => The following methods do not have complete test coverage yet :
|


Hashtable/Dictionary :
~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -517,11 +518,11 @@ Releases notes

- Latest - ``v0.5.x``

- ``v0.5.0`` - No breaking changes
- ``v0.5.1`` - No breaking changes
- ``v0.5.0``

``v0.5.x`` comes with an internal re-architecture that allows for much better caching and granular control on item expiry.

- Previous - ``v0.4.0``
No breaking changes from ``v0.4.x``

``v0.4.x`` moves away from the json-based (``dump``, ``load``) storage approach used in earlier versions,
instead storing it as bytes and has support for checksums and database file version flags for added security.
Expand Down
13 changes: 7 additions & 6 deletions elara/elara.py
Expand Up @@ -8,6 +8,7 @@
from .elarautil import Util
from .lru import LRU, Cache_obj
from .status import Status
from .exceptions import InvalidCacheParams


def is_pos(val):
Expand Down Expand Up @@ -57,24 +58,24 @@ def __init__(self, path, commitdb, key_path=None, cache_param=None):
self.lru = LRU(cache_param["max_size"])
self.max_age = cache_param["max_age"]
else:
raise Exception
raise InvalidCacheParams("max_age, max_size")
elif "max_age" in cache_param:
if is_pos(cache_param["max_age"]):
self.max_age = cache_param["max_age"]
self.lru = LRU()
else:
raise Exception
raise InvalidCacheParams("max_age")
elif "max_size" in cache_param:
if is_pos(cache_param["max_size"]):
self.lru = LRU(cache_param["max_size"])
self.max_age = None
else:
raise Exception
raise InvalidCacheParams("max_size")
if "cull_freq" in cache_param:
if is_pos(cache_param["cull_freq"]) and cache_param["cull_freq"] <= 100:
self.cull_freq = cache_param["cull_freq"]
else:
raise Exception
raise InvalidCacheParams("cull_freq")
else:
self.cull_freq = 20

Expand Down Expand Up @@ -135,7 +136,7 @@ def set(self, key, value, max_age=None):
if is_pos(max_age):
cache_obj = Cache_obj(key, max_age)
else:
raise Exception
raise InvalidCacheParams("max_age")

# this is for when a key is being overwritten by set
if self.exists(key):
Expand Down Expand Up @@ -165,7 +166,7 @@ def get(self, key):
return None

def rem(self, key):
if self.lru.rem_key(key) == False:
if self.lru.rem_key(key) == Status.NOTFOUND:
raise Exception
del self.db[key]
self._autocommit()
Expand Down
10 changes: 8 additions & 2 deletions elara/exceptions.py
Expand Up @@ -12,7 +12,6 @@
class FileAccessError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

def __str__(self):
return f"Error -> {self.message}"
Expand All @@ -21,7 +20,14 @@ def __str__(self):
class FileKeyError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

def __str__(self):
return f"Error -> {self.message}"


class InvalidCacheParams(Exception):
def __init__(self, message):
self.message = "Invalid Cache parameters provided - " + message

def __str__(self):
return f"Error -> {self.message}"
Expand Down
3 changes: 2 additions & 1 deletion elara/hashtables.py
Expand Up @@ -7,6 +7,7 @@

from .lru import Cache_obj
from .status import Status
from .exceptions import InvalidCacheParams


def is_pos(val):
Expand All @@ -24,7 +25,7 @@ def hnew(self, key, max_age=None):
if is_pos(max_age):
cache_obj = Cache_obj(key, max_age)
else:
raise Exception
raise InvalidCacheParams("max_age")

if self.lru.push(cache_obj) == Status.FULL:
self.cull(self.cull_freq) # Automatic cull
Expand Down
3 changes: 2 additions & 1 deletion elara/lists.py
Expand Up @@ -8,6 +8,7 @@

from .lru import Cache_obj
from .status import Status
from .exceptions import InvalidCacheParams


def is_pos(val):
Expand All @@ -25,7 +26,7 @@ def lnew(self, key, max_age=None):
if is_pos(max_age):
cache_obj = Cache_obj(key, max_age)
else:
raise Exception
raise InvalidCacheParams("max_age")

if self.lru.push(cache_obj) == Status.FULL:
self.cull(self.cull_freq) # Automatic cull
Expand Down
1 change: 0 additions & 1 deletion elara/status.py
Expand Up @@ -12,4 +12,3 @@ class Status(Enum):
EXPIRED = -1
FULL = -2
NOTFOUND = -3

2 changes: 1 addition & 1 deletion settings.json
@@ -1,5 +1,5 @@
{
"branch": "v0.4.0-develop",
"branch": "v0.5.1-develop",
"message": "Add files via upload",
"log": 1
}
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -6,7 +6,7 @@
setup(
name="elara",
packages=["elara"],
version="0.5.0",
version="0.5.1",
license="three-clause BSD",
description="Elara DB is an easy to use, lightweight NoSQL database written for python that can also be used as a fast in-memory cache for JSON-serializable data. Includes various methods and features to manipulate data structures in-memory, protect database files and export data.",
long_description=long_description,
Expand All @@ -21,8 +21,8 @@
"key-value database",
"nosql",
"nosql database",
"in-memory cache"
"cache",
"in-memory cache",
"file cache",
],
project_urls={
Expand Down
7 changes: 6 additions & 1 deletion test/test_1.py
Expand Up @@ -2,7 +2,6 @@

import unittest
import elara
import os


class RunTests(unittest.TestCase):
Expand All @@ -20,6 +19,12 @@ def test_set(self):
self.db.set("key", "test")
self.assertEqual(self.db.get("key"), "test")

self.db.clear()
self.db.set("key", "test", 50)
self.assertEqual(len(self.db.lru.cache), 1)
with self.assertRaises(Exception):
self.db.set("key", "test", -1)

def test_rem(self):
self.db.clear()
self.db.set("key", "test")
Expand Down
4 changes: 4 additions & 0 deletions test/test_2.py
Expand Up @@ -25,6 +25,10 @@ def test_getset(self):
self.assertEqual(self.db.getset("key", 1), "newvalue")
self.assertEqual(self.db.get("key"), 1)

self.assertEqual(self.db.getset("keynotfound", 1), False)
with self.assertRaises(Exception):
self.db.getset("key", 5, -1)

def test_mget(self):
self.db.set("key", "value")
self.db.set("key1", 3)
Expand Down
4 changes: 4 additions & 0 deletions test/test_3.py
Expand Up @@ -9,6 +9,10 @@ def setUp(self):
self.db = elara.exe("test.db", False)
self.db.lnew("newlist")

def test_lnew(self):
with self.assertRaises(Exception):
self.db.lnew("key", -1)

def test_lpush(self):
self.assertEqual(len(self.db.get("newlist")), 0)
self.db.lpush("newlist", 3)
Expand Down
4 changes: 4 additions & 0 deletions test/test_4.py
Expand Up @@ -10,6 +10,10 @@ def setUp(self):
self.db = elara.exe("test.db", False)
self.db.hnew("newmap")

def test_hnew(self):
with self.assertRaises(Exception):
self.db.hnew("key", -1)

def test_hadd(self):
self.assertEqual(len(self.db.get("newmap")), 0)
self.db.hadd("newmap", "one", 1)
Expand Down
5 changes: 5 additions & 0 deletions test/test_cache.py
Expand Up @@ -10,6 +10,11 @@ def setUp(self):
cache_param = {"max_age": 2, "max_size": 2}
self.db = elara.exe_cache("test.db", cache_param)

def test_exe_cache(self):
cache_param = {"max_age": -1, "max_size": 2}
with self.assertRaises(Exception):
new_db = elara.exe_cache("new.db", cache_param)

def test_age(self):
self.db.set("key1", 1)
self.assertEqual(self.db.get("key1"), 1)
Expand Down