Compare commits

...

18 Commits
0.0.4 ... main

Author SHA1 Message Date
Andros Fenollosa
d278077471 Add delete function 2022-12-14 09:48:24 +01:00
Andros Fenollosa
ea8807cd36 Update TODO 2022-12-13 20:23:26 +01:00
Andros Fenollosa
42fa9c9cf7 Finish update function 2022-12-13 20:19:34 +01:00
Andros Fenollosa
872ecbe4e1 Update TODO 2022-12-05 15:16:54 +01:00
Andros Fenollosa
ebf9b5bcb6 Update returns 2022-12-05 15:15:45 +01:00
Andros Fenollosa
3d09cb6ebf Update updates 2022-12-05 14:52:09 +01:00
Andros Fenollosa
7f00126742 Add test update 2022-12-05 14:02:22 +01:00
Andros Fenollosa
26f8caa3d2 Update test update 2022-11-30 12:57:16 +01:00
Andros Fenollosa
8c21bd09b4 Fix table add 2022-11-30 11:05:31 +01:00
Andros Fenollosa
52afdbd08f Update add with table 2022-11-30 09:52:21 +01:00
Andros Fenollosa
cd3f1eec65 Add todo 2022-11-28 16:58:19 +01:00
Andros Fenollosa
6af275506e Update load test 2022-11-28 16:55:39 +01:00
Andros Fenollosa
677704cdf9 Add test save 2022-11-28 16:50:21 +01:00
Andros Fenollosa
ba5778e21d Add add 2022-11-28 16:10:49 +01:00
Andros Fenollosa
a396a264e7 Update test start 2022-11-21 16:37:43 +01:00
Andros Fenollosa
95c6d1a7fa Add test start 2022-11-20 22:15:20 +01:00
Andros Fenollosa
dbc4f1156d
Update README.md 2022-11-13 17:05:21 +01:00
Andros Fenollosa
8339419c46 Update docs 2022-11-13 16:04:24 +01:00
12 changed files with 894 additions and 61 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
dist/
build/
fiable_db.egg-info/
/fiabledb.json

100
README.md
View File

@ -19,6 +19,8 @@
## Install
Python version: >=3.8
```python
pip3 install --user fiable_db
```
@ -51,7 +53,7 @@ Only one:
```python
fiable_db.add({"name": "Miguel", "age": 41, "height": 189})
# {"id": 1, "rev": 1, "data": {"name": "Miguel", "age": 41, "height": 189}}
# {"id": 1, "rev": 1, "table": "default", "data": {"name": "Miguel", "age": 41, "height": 189}}
```
Various:
@ -65,9 +67,9 @@ fiable_db.add(
]
)
# [
# {"id": 2, "rev": 1, "data": {{"name": "Noelia", "age": 34, "height": 165}},
# {"id": 3, "rev": 1, "data": {{"name": "Juan", "age": 41, "height": 187}},
# {"id": 4, "rev": 1, "data": {{"name": "Valentina", "age": 12, "height": 142}},
# {"id": 2, "rev": 1, "table": "default", "data": {"name": "Noelia", "age": 34, "height": 165}},
# {"id": 3, "rev": 1, "table": "default", "data": {"name": "Juan", "age": 41, "height": 187}},
# {"id": 4, "rev": 1, "table": "default", "data": {"name": "Valentina", "age": 12, "height": 142}},
# ]
```
@ -77,28 +79,28 @@ Update a key:
```python
fiable_db.update(4, {"age": 21})
# {"id": 4, "rev": 2, "data": {{"name": "Valentina", "age": 21, "height": 172}}
# {"id": 4, "rev": 2, "table": "default", "data": {"name": "Valentina", "age": 21, "height": 172}}
```
If the key does not exist, it will be added:
```python
fiable_db.update(4, {"is_active": True})
# {"id": 4, "rev": 3, "data": {{"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
# {"id": 4, "rev": 3, "table": "default", "data": {"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
```
To delete a key you only have to give it a value `None`.
```python
fiable_db.update(4, {"height": None})
# {"id": 4, "rev": 4, "data": {{"name": "Valentina", "age": 21, "is_active": True}}
# {"id": 4, "rev": 4, "table": "default", "data": {"name": "Valentina", "age": 21, "is_active": True}}
```
To overwrite the dictionary, use the `force=True`:
```python
fiable_db.update(4, {"name": "Javier", "email": "foo@example.com"}, force=True)
# {"id": 4, "rev": 5, "data": {{"name": "Javier", "email": "foo@example.com"}}
# {"id": 4, "rev": 5, "table": "default", "data": {"name": "Javier", "email": "foo@example.com"}}
```
### Step 4: Delete
@ -107,14 +109,7 @@ You can be specific by using the `id`.
```python
fiable_db.delete(id=4)
# {"id": 4, "rev": 6, "data": None}
```
And you can delete by performing a search for their values:
```python
fiable_db.delete(data={"name": "Javier"})
# {"id": 4, "rev": 6, "data": None}
# {"id": 4, "rev": 6, "table": "default", "data": {}}
```
### Step 5: Find one
@ -123,21 +118,21 @@ Search by id.
```python
fiable_db.find_one(id=2)
# {"id": 2, "rev": 1, "data": {{"name": "Noelia", "age": 34, "height": 165}}
# {"id": 2, "rev": 1, "table": "default", "data": {"name": "Noelia", "age": 34, "height": 165}}
```
Search by value. It will give you the first match.
```python
fiable_db.find_one(data={"name": "Noelia"})
# {"id": 2, "rev": 1, "data": {{"name": "Noelia", "age": 34, "height": 165}}
# {"id": 2, "rev": 1, "table": "default", "data": {"name": "Noelia", "age": 34, "height": 165}}
```
Search by several values.
```python
fiable_db.find_one(data={"name": "Noelia", "age": 34})
# {"id": 2, "rev": 1, "data": {{"name": "Noelia", "age": 34, "height": 165}}
# {"id": 2, "rev": 1, "table": "default", "data": {"name": "Noelia", "age": 34, "height": 165}}
```
If there are no results it will return a None.
@ -153,8 +148,8 @@ fiable_db.find_one(data={"name": "Noelia", "is_active": False})
```python
fiable_db.find_all(data={"age": 41})
# [
# {"id": 1, "rev": 1, "data": {{"name": "Miguel", "age": 41, "height": 189}},
# {"id": 3, "rev": 1, "data": {{"name": "Juan", "age": 41, "height": 187}},
# {"id": 1, "rev": 1, "table": "default", "data": {"name": "Miguel", "age": 41, "height": 189}},
# {"id": 3, "rev": 1, "table": "default", "data": {"name": "Juan", "age": 41, "height": 187}},
# ]
```
@ -173,17 +168,17 @@ Example: Previous version to be deleted.
```python
fiable_db.find_one(id=4, rev=3)
# {"id": 4, "rev": 3, "data": {{"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
# {"id": 4, "rev": 3, "table": "default", "data": {"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
```
For convenience, you can use negative numbers. `-1` will be the previous state, `-2` is 2 states back, etc.
```python
fiable_db.find_one(id=4, rev=-1)
# {"id": 4, "rev": 3, "data": {{"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
# {"id": 4, "rev": 3, "table": "default", "data": {"name": "Valentina", "age": 21, "height": 172, "is_active": True}}
fiable_db.find_one(id=4, rev=-2)
# {"id": 4, "rev": 2, "data": {{"name": "Valentina", "age": 21, "height": 172}}
# {"id": 4, "rev": 2, "table": "default", "data": {"name": "Valentina", "age": 21, "height": 172}}
```
### Step 8: Working with tables or collections.
@ -192,15 +187,66 @@ You can create as many tables as you want. The default table is called `default`
```python
fiable_db.add({"name": "Luciano", "age": 54, "height": 165}, table="users")
# {"id": 1, "rev": 1, "data": {"name": "Luciano", "age": 54, "height": 165}}
# {"id": 1, "rev": 1, "table": "users", "data": {"name": "Luciano", "age": 54, "height": 165}}
fiable_db.find_one(id=1, table="users") # "users" table
# {"id": 1, "rev": 1, "data": {"name": "Luciano", "age": 54, "height": 165}}
# {"id": 1, "rev": 1, "table": "users", "data": {"name": "Luciano", "age": 54, "height": 165}}
fiable_db.find_one(id=1) # Default table
# {"id": 1, "rev": 1, "data": {"name": "Miguel", "age": 41, "height": 189}}
# {"id": 1, "rev": 1, "table": "default", "data": {"name": "Miguel", "age": 41, "height": 189}}
```
You can use the `table` parameter with any function.
```python
fiable_db.update(1, {"age", 10}, table="users")
# {"id": 1, "rev": 2, "table": "users", "data": {"name": "Luciano", "age": 10, "height": 165}}
fiable_db.delete(1, table="users")
# {"id": 1, "rev": 3, "table": "users", "data": {"name": "Luciano", "age": 10, "height": 165}}
fiable_db.find_all(id=1, table="users")
```
### Step 9: Save changes
Save the database to a file.
```python
fiable_db.save()
```
### Other help functions
#### Get all data
Get all data from the database.
```python
fiable_db.get_database()
```
### Load file
Load a file into the database.
```python
fiable_db.load(filename)
```
### Save file
Save a file into the database.
```python
fiable_db.save(filename)
```
## Implementations in other languages
- [Clojure](https://github.com/Toni-zgz/db_inmutable).
- [Haskell](https://github.com/FabianVegaA/SafeDB).
---
Thanks to the power of 🐍 Python 🐍

View File

@ -1,43 +1,142 @@
from typing import Dict, Tuple, Union, Sequence, TypedDict
from functools import reduce
import json
from os import path
from copy import deepcopy
# Variables
FILE = "fiabledb.json"
data = {}
database = []
# Type aliases
def start(filename: str = "") -> str:
class TypeData(TypedDict):
id: int
rev: int
data: dict
Type_Data_List = Tuple[TypeData]
Type_Add_Data = Union[Dict, Sequence[Dict]]
Type_Add_Return = Union[Tuple[int, int, Dict], Tuple[Tuple[int, int, Dict]], None]
Type_Update_Return = Union[Tuple[Tuple[int, int, Dict]], None]
Type_Delete_Return = Union[Tuple[Tuple[int, int, Dict]], None]
Type_Find_One_Return = TypeData
Type_Find_All_Return = Tuple[Type_Find_One_Return]
# Functions
def get_next_id(table: str = "default") -> int:
"""Get the next id for the table"""
global database
# Get the last id for the table
def get_id(current_id, row: TypeData) -> int:
if current_id == None and table == row["table"]:
return row["id"]
else:
return current_id
last_id = reduce(get_id, database[::-1], None)
# Return the next id, or 1 if there is no last id
return last_id + 1 if last_id else 1
def start(file_name: str = "") -> str:
"""Start the database
Args:
file (str, optional): The file to use. Defaults to FILE.
Returns:
str: The file used
"""
file_name = filename if filename else FILE
print("Function not implemented yet")
return file_name
global FILE
global database
my_file_name = file_name if file_name != "" else FILE
if path.exists(my_file_name):
# Load the database
load(my_file_name)
else:
# Create the database
database = []
save(my_file_name)
return my_file_name
def save(filename: str = "", data: list[str, list[int, int, dict]] = {}) -> bool:
def save(file_name: str = "") -> bool:
"""Save the database
Args:
filename (str, optional): The file to save to. Defaults to "".
file_name (str, optional): The file to save to. Defaults to "".
data (list[str, list[int, int, dict]], optional): The data to save. Defaults to {}.
Returns:
bool: True if the data was saved, False otherwise
"""
print("Function not implemented yet")
global FILE
global database
my_file_name = file_name if file_name != "" else FILE
with open(my_file_name, "w") as f:
json.dump(database, f)
return True
def load(filename: str = "") -> list[str, list[int, int, dict]]:
def load(file_name: Union[str, None] = None) -> bool:
"""Load the database
Args:
filename (str, optional): The file to load from. Defaults to "".
file_name (str, optional): The file to load from. Defaults to "".
Returns:
list[str, list[int, int, dict]]: The data loaded
Bool - The data loaded
"""
print("Function not implemented yet")
global database
my_file_name = file_name if file_name else FILE
is_exists = path.exists(my_file_name)
if is_exists:
with open(my_file_name, "r") as f:
text = f.read()
if text != "":
database = json.loads(text)
else:
database = []
else:
raise FileNotFoundError("File not found")
return is_exists
def add(
new_data: dict | list, table: str = ""
) -> dict[int, int, dict] | list[dict[int, int, dict]]:
def get_database() -> Type_Data_List:
"""Get the data
Returns:
list[dict[int, int, dict]]: The data
"""
global database
return database
def get_pos_by_id(id: int, table: str = "") -> int:
"""Get the position of the data by id
Args:
id (int): The id of the data
table (str, optional): The table to search in. Defaults to "".
Returns:
int: The position of the data
"""
global database
def get_key(
current_key: Union[TypeData, None], key_and_row: TypeData
) -> Union[int, None]:
"""Function to get the key of the data"""
if (
current_key is None
and key_and_row[1]["id"] == id
and key_and_row[1]["table"] == table
):
return key_and_row[0]
return current_key
return reduce(get_key, list(enumerate(database))[::-1], None)
def add(new_data: Type_Add_Data, table: str = "default") -> Type_Add_Return:
"""Add data to the database
Args:
new_data (dict|list): The data to add
@ -45,30 +144,50 @@ def add(
Returns:
dict[int, int, dict]|list[dict[int, int, dict]]: The data added
"""
global database
if isinstance(new_data, dict):
return _add(new_data, table)
new_row = {"id": get_next_id(table), "rev": 1, "table": table, "data": new_data}
database.append(new_row)
return new_row
elif isinstance(new_data, list):
return [_add(entry, table) for entry in new_data]
for row in new_data:
new_row = {"id": get_next_id(table), "rev": 1, "table": table, "data": row}
database.append(new_row)
else:
raise TypeError("new_data must be a dict or list")
print("Function not implemented yet")
def update(
new_data: dict | list, table: str = "", force: bool = False
) -> dict[int, int, dict]:
id: int, new_data: dict, table: str = "default", force: bool = False
) -> Type_Update_Return:
"""Update data in the database
Args:
new_data (dict|list): The data to update
id (int): The id of the data to update.
new_data (dict): The data to update
table (str, optional): The table to update. Defaults to "".
force (bool, optional): Force the update. Defaults to False.
Returns:
dict[int, int, dict]: The data updated
dict[int, int, dict] or None: The data updated
"""
print("Function not implemented yet")
global database
# Get the key to update
key = get_pos_by_id(id, table)
if key is not None:
row = deepcopy(database[key])
my_new_data = deepcopy(new_data)
if force:
row["data"] = my_new_data
else:
row["data"].update(my_new_data)
new_rev = row["rev"] + 1
new_data_to_row = row["data"]
new_row = {"id": id, "rev": new_rev, "table": table, "data": new_data_to_row}
database.append(new_row)
return new_row
return None
def delete(id: int, data: dict, table: str = "") -> dict[int, int, dict]:
def delete(id: int, table: str = "default") -> Type_Delete_Return:
"""Delete data from the database
Args:
id (int): The id of the data to delete
@ -77,12 +196,12 @@ def delete(id: int, data: dict, table: str = "") -> dict[int, int, dict]:
Returns:
dict[int, int, dict]: The data deleted
"""
print("Function not implemented yet")
return update(id=id, new_data={}, table=table, force=True)
def find_one(
id: int = 0, data: dict = {}, table: str = "", rev: int = 0
) -> dict[int, int, dict]:
) -> Type_Find_One_Return:
"""Find one data in the database
Args:
id (int, optional): The id of the data to find. Defaults to 0.
@ -95,7 +214,7 @@ def find_one(
print("Function not implemented yet")
def find_all(data: dict = {}, table: str = "") -> list[dict[int, int, dict]]:
def find_all(data: dict = {}, table: str = "") -> Type_Find_All_Return:
"""Find all data in the database
Args:
data (dict, optional): Filter the data to find. Defaults to {}.

0
test/__init__.py Normal file
View File

29
test/example.json Normal file
View File

@ -0,0 +1,29 @@
[
{
"id": 2,
"rev": 1,
"data": {
"name": "Noelia",
"age": 34,
"height": 165
}
},
{
"id": 3,
"rev": 1,
"data": {
"name": "Juan",
"age": 41,
"height": 187
}
},
{
"id": 4,
"rev": 1,
"data": {
"name": "Valentina",
"age": 12,
"height": 142
}
}
]

100
test/test_add.py Normal file
View File

@ -0,0 +1,100 @@
from fiable_db import add, get_database
def test_add_one():
"""Add one item to the database."""
add({"name": "John", "age": 42})
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}}
]
def test_add_two():
"""Add two items to the database."""
add({"name": "John", "age": 12})
add({"name": "Jane", "age": 34})
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
]
def test_add_list():
"""Add a list of items to the database."""
add(
[
{"name": "John", "age": 12},
{"name": "Jane", "age": 34},
]
)
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
]
def test_add_list_with_one():
"""Add a list with one item to the database."""
add([{"name": "John", "age": 42}])
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 6, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
]
def test_add_empty():
"""Add an empty list to the database."""
add([])
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 6, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
]
def test_add_in_table_foo():
"""Add an item to the database in the table foo."""
add({"name": "John", "age": 42}, table="foo")
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 6, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 1, "rev": 1, "table": "foo", "data": {"name": "John", "age": 42}},
]
add({"name": "Simone", "age": 33}, table="foo")
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 6, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 1, "rev": 1, "table": "foo", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "foo", "data": {"name": "Simone", "age": 33}},
]
add({"name": "Jose", "age": 25})
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 3, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 4, "rev": 1, "table": "default", "data": {"name": "John", "age": 12}},
{"id": 5, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 34}},
{"id": 6, "rev": 1, "table": "default", "data": {"name": "John", "age": 42}},
{"id": 1, "rev": 1, "table": "foo", "data": {"name": "John", "age": 42}},
{"id": 2, "rev": 1, "table": "foo", "data": {"name": "Simone", "age": 33}},
{"id": 7, "rev": 1, "table": "default", "data": {"name": "Jose", "age": 25}},
]

126
test/test_delete.py Normal file
View File

@ -0,0 +1,126 @@
from fiable_db import start, add, delete, get_database
def test_delete_simple():
"""Test delete in the default table."""
start()
add(
[
{"name": "Noelia", "age": 34, "height": 165},
{"name": "Juan", "age": 41, "height": 187},
{"name": "Valentina", "age": 12, "height": 142},
]
)
delete(1)
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{"id": 1, "rev": 2, "table": "default", "data": {}},
]
def test_delete_multiple():
"""Test delete two rows"""
start()
add(
[
{"name": "Noelia", "age": 34, "height": 165},
{"name": "Juan", "age": 41, "height": 187},
{"name": "Valentina", "age": 12, "height": 142},
]
)
delete(2)
delete(3)
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{"id": 2, "rev": 2, "table": "default", "data": {}},
{"id": 3, "rev": 2, "table": "default", "data": {}},
]
def test_delete_with_table():
"""Test delete two rows"""
start()
add(
[
{"name": "Noelia", "age": 34, "height": 165},
{"name": "Juan", "age": 41, "height": 187},
{"name": "Valentina", "age": 12, "height": 142},
],
table="people",
)
add(
[
{"name": "Mortadelo", "age": 22, "height": 184},
{"name": "Filemon", "age": 25, "height": 185},
],
)
delete(2, table="people")
delete(1)
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "people",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "people",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "people",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Mortadelo", "age": 22, "height": 184},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Filemon", "age": 25, "height": 185},
},
{"id": 2, "rev": 2, "table": "people", "data": {}},
{"id": 1, "rev": 2, "table": "default", "data": {}},
]

View File

@ -1,7 +0,0 @@
# content of test_sample.py
def inc(x):
return x + 1
def test_answer():
assert inc(3) == 5

View File

@ -0,0 +1,45 @@
import os
from fiable_db import start, add, save, get_database, load
filename = "fiabledb.json"
def delete_file():
"""Delete the database file."""
if os.path.exists(filename):
os.remove(filename)
def test_empty():
"""Test that save() works when the database is empty."""
delete_file()
start()
save()
load()
assert get_database() == []
def test_one():
"""Test that save() works when the database has one entry."""
delete_file()
start()
add({"name": "John", "age": 30})
save()
load()
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 30}}
]
def test_two():
"""Test that save() works when the database has two entries."""
delete_file()
start()
add({"name": "John", "age": 30})
add({"name": "Jane", "age": 28})
save()
load()
assert get_database() == [
{"id": 1, "rev": 1, "table": "default", "data": {"name": "John", "age": 30}},
{"id": 2, "rev": 1, "table": "default", "data": {"name": "Jane", "age": 28}},
]

48
test/test_start.py Normal file
View File

@ -0,0 +1,48 @@
import os
import shutil
from fiable_db import start, get_database
def test_create_new_file():
"""Create a new file with a different name"""
filename = "test.json"
start(filename)
assert os.path.isfile(filename), "The file does not exist"
# Remove the file
os.remove(filename)
def test_create_default_file():
"""Create a new file with the default name"""
filename = "fiabledb.json"
start()
assert os.path.isfile(filename), "The file does not exist"
# Remove the file
os.remove(filename)
def test_read_file_default():
"""Read the default file"""
input_file = "test/example.json"
output_file = "fiabledb.json"
shutil.copy(input_file, output_file)
start()
data = get_database()
assert data == [
{"id": 2, "rev": 1, "data": {"name": "Noelia", "age": 34, "height": 165}},
{"id": 3, "rev": 1, "data": {"name": "Juan", "age": 41, "height": 187}},
{"id": 4, "rev": 1, "data": {"name": "Valentina", "age": 12, "height": 142}},
], "The data is not the same: " + str(data)
os.remove(output_file)
def test_read_file_custom_name():
"""Read a file with a custom name"""
filename = "test/example.json"
start(filename)
data = get_database()
assert data == [
{"id": 2, "rev": 1, "data": {"name": "Noelia", "age": 34, "height": 165}},
{"id": 3, "rev": 1, "data": {"name": "Juan", "age": 41, "height": 187}},
{"id": 4, "rev": 1, "data": {"name": "Valentina", "age": 12, "height": 142}},
], "The data is not the same: " + str(data)

320
test/test_update.py Normal file
View File

@ -0,0 +1,320 @@
from fiable_db import start, add, update, get_database
def test_update_simple():
"""Test update in the default table."""
start()
add(
[
{"name": "Noelia", "age": 34, "height": 165},
{"name": "Juan", "age": 41, "height": 187},
{"name": "Valentina", "age": 12, "height": 142},
]
)
update(2, {"age": 99})
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{
"id": 2,
"rev": 2,
"table": "default",
"data": {"name": "Juan", "age": 99, "height": 187},
},
]
update(2, {"name": "Cristo"})
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{
"id": 2,
"rev": 2,
"table": "default",
"data": {"name": "Juan", "age": 99, "height": 187},
},
{
"id": 2,
"rev": 3,
"table": "default",
"data": {"name": "Cristo", "age": 99, "height": 187},
},
]
update(1, {"height": 150})
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{
"id": 2,
"rev": 2,
"table": "default",
"data": {"name": "Juan", "age": 99, "height": 187},
},
{
"id": 2,
"rev": 3,
"table": "default",
"data": {"name": "Cristo", "age": 99, "height": 187},
},
{
"id": 1,
"rev": 2,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 150},
},
]
def test_update_table():
"""Test update in a table."""
add({"name": "Antony", "age": 77, "height": 188}, table="users")
update(1, {"age": 99}, table="users")
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 165},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Juan", "age": 41, "height": 187},
},
{
"id": 3,
"rev": 1,
"table": "default",
"data": {"name": "Valentina", "age": 12, "height": 142},
},
{
"id": 2,
"rev": 2,
"table": "default",
"data": {"name": "Juan", "age": 99, "height": 187},
},
{
"id": 2,
"rev": 3,
"table": "default",
"data": {"name": "Cristo", "age": 99, "height": 187},
},
{
"id": 1,
"rev": 2,
"table": "default",
"data": {"name": "Noelia", "age": 34, "height": 150},
},
{
"id": 1,
"rev": 1,
"table": "users",
"data": {"name": "Antony", "age": 77, "height": 188},
},
{
"id": 1,
"rev": 2,
"table": "users",
"data": {"name": "Antony", "age": 99, "height": 188},
},
]
def test_update_table_not_exists():
"""Test update in a table that not exists."""
start()
add({"name": "Antony", "age": 77, "height": 188}, table="users")
update(1, {"name": "David"}, table="boo")
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "users",
"data": {"name": "Antony", "age": 77, "height": 188},
}
]
def test_update_id_not_exists():
"""Test update with an id that not exists."""
start()
add({"name": "Antony", "age": 77, "height": 188}, table="users")
update(2, {"name": "David"}, table="users")
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "users",
"data": {"name": "Antony", "age": 77, "height": 188},
}
]
def test_update_multiple_values_default():
"""Test update multiple values in the default table."""
start()
add({"name": "Antony", "age": 77, "height": 188})
add({"name": "Dolores", "age": 32})
update(1, {"name": "David", "age": 9})
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Antony", "age": 77, "height": 188},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Dolores", "age": 32},
},
{
"id": 1,
"rev": 2,
"table": "default",
"data": {"name": "David", "age": 9, "height": 188},
},
]
def test_update_multiple_values_table():
"""Test update multiple values in a table."""
start()
add({"name": "Antony", "age": 77, "height": 188}, table="users")
add({"name": "Dolores", "age": 32}, table="users")
update(1, {"name": "David", "age": 9}, table="users")
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "users",
"data": {"name": "Antony", "age": 77, "height": 188},
},
{
"id": 2,
"rev": 1,
"table": "users",
"data": {"name": "Dolores", "age": 32},
},
{
"id": 1,
"rev": 2,
"table": "users",
"data": {"name": "David", "age": 9, "height": 188},
},
]
def test_update_with_keys_not_exists():
"""Test update with keys that not exists."""
start()
add({"name": "Antony", "age": 77, "height": 188})
add({"name": "Dolores", "age": 32})
update(1, {"is_active": True, "eyes": "blue"})
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {
"name": "Antony",
"age": 77,
"height": 188,
},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Dolores", "age": 32},
},
{
"id": 1,
"rev": 2,
"table": "default",
"data": {
"name": "Antony",
"age": 77,
"height": 188,
"is_active": True,
"eyes": "blue",
},
},
]
def test_update_with_force():
"""Test update with force."""
start()
add({"name": "Antony", "age": 77, "height": 188})
add({"name": "Dolores", "age": 32})
update(1, {"name": "David", "age": 9}, force=True)
assert get_database() == [
{
"id": 1,
"rev": 1,
"table": "default",
"data": {"name": "Antony", "age": 77, "height": 188},
},
{
"id": 2,
"rev": 1,
"table": "default",
"data": {"name": "Dolores", "age": 32},
},
{
"id": 1,
"rev": 2,
"table": "default",
"data": {"name": "David", "age": 9},
},
]

6
todo.org Normal file
View File

@ -0,0 +1,6 @@
* Tasks
** TODO Test Find one
** TODO Function Find one
** TODO Test Find All
** TODO Function Find All