Skip to content

Commit

Permalink
Merge pull request #2 from truethari/alpha
Browse files Browse the repository at this point in the history
Alpha
  • Loading branch information
truethari authored Feb 24, 2022
2 parents 0c9dc6a + fd762bc commit 16c9ec1
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 38 deletions.
50 changes: 42 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
<center><h1>
<h1>
ReallySimpleDB 🧩
</h1>

<img src="assets/images/ReallySimpleDB.png" alt="Icon" height="300"> </img>
<img src="https://raw.githubusercontent.com/truethari/ReallySimpleDB/master/assets/images/ReallySimpleDB.png" alt="Icon" width="465"> </img>

[![PyPI version](https://img.shields.io/pypi/v/ReallySimpleDB.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/ReallySimpleDB/) [![tests](https://github.com/truethari/ReallySimpleDB/actions/workflows/tests.yml/badge.svg?branch=alpha)](https://github.com/truethari/ReallySimpleDB/actions/workflows/tests.yml) [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/09b9e60691484c29b4cac87178b8aaae)](https://www.codacy.com/gh/truethari/ReallySimpleDB/dashboard?utm_source=github.com&utm_medium=referral&utm_content=truethari/ReallySimpleDB&utm_campaign=Badge_Grade) [![PyPI downloads](https://img.shields.io/pypi/dm/reallysimpledb.svg)](https://pypistats.org/packages/reallysimpledb)
[![tests](https://github.com/truethari/ReallySimpleDB/actions/workflows/tests.yml/badge.svg?branch=alpha)](https://github.com/truethari/ReallySimpleDB/actions/workflows/tests.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/befe3049923e4e788f5a1d6d958f6015)](https://www.codacy.com/gh/truethari/ReallySimpleDB/dashboard?utm_source=github.com&utm_medium=referral&utm_content=truethari/ReallySimpleDB&utm_campaign=Badge_Grade) [![PyPI version](https://img.shields.io/pypi/v/ReallySimpleDB.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/ReallySimpleDB/) [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/) [![Downloads](https://pepy.tech/badge/reallysimpledb)](https://pepy.tech/project/reallysimpledb)

## What is This

---

This is a Python application that can be used to manage **sqlite** databases without using any sql command.

</center>

## 🚀 Installation

You can use pip:

```console
pip3 install ReallySimpleDB
~$ pip3 install ReallySimpleDB
```

or

```console
~# python setup.py install
~$ python setup.py install
```

## 📗 Usage
Expand All @@ -52,7 +50,7 @@ or

Here you can not directly call the `create_table` function. Because **sqlite** cannot create table without columns. So you must first define the columns and create a table.

Important: You have to close connection here. If not, code returns error. Because it tries to add column to existing table.
**Important:** You have to close connection here. If not, code returns error. Because it tries to add column to existing table.

```console
>> _dbmanager.close_connection()
Expand Down Expand Up @@ -158,6 +156,34 @@ True

### Filter record/s from a table

If you want to filter **equal values**, add value without any operator.

Examples:

- `{"year":2022}` ✔️
- `{"year":" == 2022"}`

🖇 Comparison operators

| Comparison Operator | Description |
| :-----------------: | :-------------------: |
| != | Not Equal |
| > | Greater Than |
| >= | Greater Than or Equal |
| < | Less Than |
| <= | Less Than or Equal |

Examples:

- `{"marks":"<= 10"}` ✔️
- `{"marks":"== 10"}`
- `{"name":"< ABC"}` ❌ 'Greater Than' and 'Less than' comparisons are not supported with Strings

**Important:** If you are trying to compare strings, please use string between Inch Marks.

- `{"grade":"!= 'A'"}` ✔️
- `{"grade":"!= A"}`

```console
>> _dbmanager.filter_records(table="STUDENTS", values={"year":"2022"})

Expand All @@ -181,3 +207,11 @@ True
- Use a sensible number of commit messages as well

- e.g. Your PR should not have 1000s of commits.

### Run pytest without installing package

If you are adding **new functions** as described above, please add test functions to `tests/test_manager.py`.

```console
~$ python -m pytest -s tests
```
61 changes: 34 additions & 27 deletions ReallySimpleDB/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ def __init__(self) -> None:
self._add_columns_cmd = ""
self.connection = ""

def _not_table(self, table:str):
"""raise OperationalError if the given table not exists"""
raise sqlite3.OperationalError("no such table: {}".format(table))

def clean(self):
"""
cleans add_columns data
Expand Down Expand Up @@ -164,13 +160,14 @@ def delete_table(self, table:str, database:str=""):

return True

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def get_all_column_types(self, table:str, database:str=""):
"""get all the column names with the data types in a table"""
if self.connection == "" and not database:
raise TypeError("get_all_column_types() missing 1 required positional argument: 'database'")
raise TypeError(
"get_all_column_types() missing 1 required positional argument: 'database'")

if database:
self.create_connection(database)
Expand All @@ -187,8 +184,8 @@ def get_all_column_types(self, table:str, database:str=""):

return data_dict

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def get_column_type(self, table:str, column:str, database:str=""):
"""get data type of a column in a table"""
Expand All @@ -197,7 +194,8 @@ def get_column_type(self, table:str, column:str, database:str=""):
# if columns exists in the table and given column in the table
if (not isinstance(all_data, bool)) and (column in all_data):
return all_data[column]
return False

raise sqlite3.OperationalError("no such column: {}".format(column))

def get_columns(self, table:str, database:str=""):
"""get all the column names list in a table"""
Expand Down Expand Up @@ -229,11 +227,10 @@ def get_primary_key(self, table:str, database:str=""):

sql_cmd = "SELECT * FROM pragma_table_info('{}') WHERE pk;".format(table)
fetch = cursor.execute(sql_cmd)

return fetch.fetchall()[0][1]

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def add_record(self, table:str, record, database:str=""):
"""add a new record to a table"""
Expand Down Expand Up @@ -269,7 +266,8 @@ def add_record(self, table:str, record, database:str=""):
if DATA_TYPES[tmp_all_columns[field]] == type(record[field]):
all_columns[field] = record[field]
else:
raise TypeError("The '{}' field requires the '{}' type but got the '{}' type".format(field, DATA_TYPES[tmp_all_columns[field]], type(record[field])))
raise TypeError("The '{}' field requires '{}' but got '{}'"
.format(field, DATA_TYPES[tmp_all_columns[field]], type(record[field])))

# creates the full SQL command
for field in all_columns:
Expand All @@ -286,8 +284,8 @@ def add_record(self, table:str, record, database:str=""):

return True

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def get_record(self, table:str, primary_key, database:str=""):
"""get row data / record from a table using the primary key"""
Expand All @@ -300,7 +298,8 @@ def get_record(self, table:str, primary_key, database:str=""):
if self.is_table(table_name=table, database=database):
cursor = self.connection.cursor()

sql_cmd = "SELECT * FROM {} WHERE {}=?;".format(table, self.get_primary_key(table=table, database=database))
sql_cmd = "SELECT * FROM {} WHERE {}=?;".format(
table, self.get_primary_key(table=table, database=database))
fetch = cursor.execute(sql_cmd, (primary_key,))

# get columns list using get_columns
Expand All @@ -318,8 +317,8 @@ def get_record(self, table:str, primary_key, database:str=""):

return record

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def get_all_records(self, table:str, database:str=""):
"""get all data / records of a table"""
Expand Down Expand Up @@ -350,8 +349,8 @@ def get_all_records(self, table:str, database:str=""):

return records

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def delete_record(self, table:str, primary_key, database:str=""):
"""delete record from a table"""
Expand All @@ -363,14 +362,15 @@ def delete_record(self, table:str, primary_key, database:str=""):

if self.is_table(table_name=table, database=database):
cursor = self.connection.cursor()
sql = "DELETE FROM {} WHERE {}=?".format(table, self.get_primary_key(table=table, database=database))
sql = "DELETE FROM {} WHERE {}=?".format(
table, self.get_primary_key(table=table, database=database))
cursor.execute(sql, (primary_key,))
self.connection.commit()

return True

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def filter_records(self, table:str, values:dict, database:str=""):
"""
Expand All @@ -387,12 +387,19 @@ def filter_records(self, table:str, values:dict, database:str=""):
if self.is_table(table_name=table, database=database):
cursor = self.connection.cursor()

operators = [">", "<", "!", "="]

sql = "SELECT * FROM {} WHERE ".format(table)

for value in values:
try:
# if value is in string type
sql += value + "='" + values[value] + "' AND "
# checks for if value contains any special character
if any(c in operators for c in values[value]):
sql += value + values[value] + " AND "
else:
sql += value + "='" + values[value] + "' AND "

except TypeError:
# if value is in int or float type
sql += value + "=" + str(values[value]) + " AND "
Expand All @@ -416,8 +423,8 @@ def filter_records(self, table:str, values:dict, database:str=""):

return records

# if database not exists
self._not_table(table=table)
# raise OperationalError if the given table not exists
raise sqlite3.OperationalError("no such table: {}".format(table))

def close_connection(self):
"""close the connection with the SQLite database file"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name="ReallySimpleDB",
version="1.0",
version="1.1",
description="A tool for easily manage databases with Python",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
19 changes: 17 additions & 2 deletions tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ def test_delete_table_1():
"""delete table if table exists"""
try:
_dbmanager.delete_table(table="EMPLOYEES")
assert True
except OperationalError:
assert False

def test_delete_table_2():
"""delete table if table not exists"""
try:
_dbmanager.delete_table(table="EMPLOYEES")
assert False
except OperationalError:
assert True

Expand All @@ -95,8 +97,12 @@ def test_get_column_type_1():
assert _dbmanager.get_column_type(table="STUDENTS", column="student_id") == "TEXT"

def test_get_column_type_2():
"""get data type of a column in a table"""
assert _dbmanager.get_column_type(table="STUDENTS", column="address") == False
"""get data type of not exists column in a table"""
try:
_dbmanager.get_column_type(table="STUDENTS", column="address")
assert False
except OperationalError:
assert True

def test_get_columns_1():
"""get all the column names list in a table"""
Expand Down Expand Up @@ -148,6 +154,14 @@ def test_filter_record_2():
"""get filtered record list from a table"""
assert _dbmanager.filter_records(table="STUDENTS", values={"mark":100, "year":"2022"}) == [{'student_id': '1011', 'name': 'DEF', 'mark': 100, 'year': '2022'}]

def test_filter_record_3():
"""get filtered record list from a table: Comparison"""
assert _dbmanager.filter_records(table="STUDENTS", values={"mark":" <= 100"}) == [{'student_id': '1010', 'name': 'ABC', 'mark': 10, 'year': '2022'}, {'student_id': '1011', 'name': 'DEF', 'mark': 100, 'year': '2022'}]

def test_filter_record_4():
"""get filtered record list from a table: Comparison"""
assert _dbmanager.filter_records(table="STUDENTS", values={"mark":" != 100"}) == [{'student_id': '1010', 'name': 'ABC', 'mark': 10, 'year': '2022'}]

def test_delete_record_1():
"""delete record from a table"""
assert _dbmanager.delete_record(table="STUDENTS", primary_key="1010")
Expand All @@ -156,6 +170,7 @@ def test_delete_record_2():
"""delete record from a table when table is not exists"""
try:
_dbmanager.delete_record(table="STUDENTSS", primary_key="1010")
assert False
except OperationalError:
assert True

Expand Down

0 comments on commit 16c9ec1

Please sign in to comment.