From 43f82c2b223ecafa078fa71194137fd4c6b33a25 Mon Sep 17 00:00:00 2001 From: Firepup Sixfifty <firepyp650@gmail.com> Date: Thu, 27 Mar 2025 20:30:47 -0500 Subject: [PATCH] 1.0.6 --- .gitignore | 2 + LICENSE | 21 ++++ package/README.md | 4 +- package/pyproject.toml | 4 +- package/src/fpsql/__init__.py | 214 +++++++++++++++++++++++++++++++++- 5 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 LICENSE diff --git a/.gitignore b/.gitignore index f21c9ec..0c79684 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ venv/** replit*txt .config/** .replit +**/dist/** +**/.env diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1e26c53 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Firepup Sixfifty + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package/README.md b/package/README.md index aaf0e6f..32a56fb 100644 --- a/package/README.md +++ b/package/README.md @@ -1,6 +1,8 @@ # FPSQL An easy to use SQLite package #### Change log: +###### v.1.0.6: +Add AsyncSql, start working on dict actions ###### v.1.0.5: Double check mypy problems and resolve them ###### v.1.0.4: @@ -14,4 +16,4 @@ Actual release ###### v.1.0.0: Initial Release! ###### v.1.0.26: -Mistake release :facepalm: \ No newline at end of file +Mistake release :facepalm: diff --git a/package/pyproject.toml b/package/pyproject.toml index 47840c1..21f91c6 100644 --- a/package/pyproject.toml +++ b/package/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "fpsql" -version = "1.0.5" +version = "1.0.6" authors = ["Firepup650 <firepyp650@gmail.com>"] description = "An easy to use SQLite package" readme = "README.md" @@ -27,4 +27,4 @@ python = "^3.8" [build-system] requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" \ No newline at end of file +build-backend = "poetry.core.masonry.api" diff --git a/package/src/fpsql/__init__.py b/package/src/fpsql/__init__.py index a7e8938..6d95370 100644 --- a/package/src/fpsql/__init__.py +++ b/package/src/fpsql/__init__.py @@ -1,7 +1,8 @@ """Firepup650's SQL Package""" from typing import Any -import sqlite3, ast, pydoc +import sqlite3, aiosqlite, ast, pydoc +from asyncio import run as aRun def alias(Function): @@ -15,8 +16,8 @@ def alias(Function): return decorator -__VERSION__ = "1.0.5" -__NEW__ = "Double check mypy problems and resolve them" +__VERSION__ = "1.0.6" +__NEW__ = "Add AsyncSql, start working on dict actions" __LICENSE__ = "MIT" @@ -111,6 +112,20 @@ class sql: return data[0] return None + def __setitem__(self, name: str, value: object) -> int: + """# Function: sql.__getitem__ + Sets the value of a key + # Inputs: + name: str - The name of the key to set + value: object - The value of the key + + # Returns: + int - `1` if the key was created, `2` if it was updated + + # Raises: + AttributeError - If the table is unset""" + return set(name) + def set(self, name: str, value: object) -> int: """# Function: sql.set Sets the value of a key @@ -125,7 +140,7 @@ class sql: AttributeError - If the table is unset""" if not self.__table: raise AttributeError("Attempted to write to unset table") - if self.get(name): + if self.get(name) != None: self.__con.execute( f"""UPDATE "{self.__table}" SET value = ? WHERE name = ?""", (str(value), name), @@ -190,3 +205,194 @@ class sql: self.__con = None # type: ignore[assignment] self.__db = "" self.__table = "" + + +class asyncSql: + async def addTable(self, tableName: str, mode: int = 0, address: str = "") -> None: + """# Function: sql.addTable + Adds a table to the database + # Inputs: + tableName: str - The name of the table to create + mode: int - Not yet implemented + address: str - Not yet implemented + + # Returns: + None + + # Raises: + None""" + async with aiosqlite.connect(self.__db) as con: + await con.execute( + f"""CREATE TABLE IF NOT EXISTS "{tableName}" + (id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + value TEXT NOT NULL)""" + ) + await con.commit() + self.__table = tableName + + def __init__(self, filename: str): + """# Function: sql.__init__ + Constructs an SQL instance + # Inputs: + filename: str - The name of the database file to connect to + + # Returns: + None + + # Raises: + ValueError - If the filename is `:memory:`, because the memory table doesn't work with how I've setup my async logic + """ + if filename == ":memory:": + raise ValueError("Cannot use `:memory:` table with async code") + if filename.endswith(".db"): + self.__db = filename + else: + self.__db = filename + ".db" + aRun(self.addTable("default")) + + async def setTable(self, tableName: str) -> None: + """# Function: sql.setTable + Sets the currently active table + # Inputs: + tableName: str - The name of the table to use + + # Returns: + None + + # Raises: + None""" + self.__table = tableName + + async def __getitem__(self, name: str) -> Any: + """# Function: sql.__getitem__ + Gets the value of a key + # Inputs: + name: str - The name of the key to retrieve + + # Returns: + Any - If the key exists, return it's value (casted), otherwise, return `None` + + # Raises: + AttributeError - If the table is unset""" + return await get(name) + + async def get(self, name: str) -> Any: + """# Function: sql.get + Gets the value of a key + # Inputs: + name: str - The name of the key to retrieve + + # Returns: + Any - If the key exists, return it's value (casted), otherwise, return `None` + + # Raises: + AttributeError - If the table is unset""" + if not self.__table: + raise AttributeError("Attempted to read from unset table") + async with aiosqlite.connect(self.__db) as con: + cur = await con.execute( + f"""SELECT value FROM "{self.__table}" WHERE name = ?""", (name,) + ) + data = await cur.fetchone() + if data: + try: + return ast.literal_eval(data[0]) + except: + return data[0] + return None + + async def __setitem__(self, name: str, value: object) -> int: + """# Function: sql.__setitem__ + Sets the value of a key + name: str - The name of the key to set + value: object - The value of the key + + # Returns: + int - `1` if the key was created, `2` if it was updated + + # Raises: + AttributeError - If the table is unset""" + return await set() + + async def set(self, name: str, value: object) -> int: + """# Function: sql.set + Sets the value of a key + # Inputs: + name: str - The name of the key to set + value: object - The value of the key + + # Returns: + int - `1` if the key was created, `2` if it was updated + + # Raises: + AttributeError - If the table is unset""" + async with aiosqlite.connect(self.__db) as con: + if not self.__table: + raise AttributeError("Attempted to write to unset table") + if await self.get(name) != None: + await con.execute( + f"""UPDATE "{self.__table}" SET value = ? WHERE name = ?""", + (str(value), name), + ) + await con.commit() + return 2 + else: + await con.execute( + f"""INSERT INTO "{self.__table}" (name, value) VALUES (?, ?)""", + (name, str(value)), + ) + await con.commit() + return 1 + + async def delete(self, name: str) -> None: + """# Function: sql.delete + Deletes a key from the table + # Inputs: + name: str - The name of the key to delete + + # Returns: + None + + # Raises: + AttributeError - If the table is unset""" + async with aiosqlite.connect(self.__db) as con: + if not self.__table: + raise AttributeError("Attempted to delete from unset table") + if await self.get(name): + await con.execute( + f"""DELETE FROM "{self.__table}" WHERE name = ?""", (name,) + ) + await con.commit() + + async def deleteAll(self) -> None: + """# Function: sql.delete_all + Deletes all keys from the table + # Inputs: + None + + # Returns: + None + + # Raises: + AttributeError - If the table is unset""" + async with aiosqlite.connect(self.__db) as con: + if not self.__table: + raise AttributeError("Attempted to delete from unset table") + await con.execute(f"""DELETE FROM "{self.__table}" """) + await con.commit() + + async def close(self) -> None: + """# Function: sql.close + Closes the database connection + # Inputs: + None + + # Returns: + None + + # Raises: + None""" + self.__con = None # type: ignore[assignment] + self.__db = "" + self.__table = ""