database-wrapper-sqlite 0.2.17__tar.gz → 0.2.23__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: database_wrapper_sqlite
3
- Version: 0.2.17
3
+ Version: 0.2.23
4
4
  Summary: database_wrapper for PostgreSQL database
5
5
  Author-email: Gints Murans <gm@gm.lv>
6
6
  License: GNU General Public License v3.0 (GPL-3.0)
@@ -32,7 +32,7 @@ Classifier: Topic :: Software Development
32
32
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
33
  Requires-Python: >=3.8
34
34
  Description-Content-Type: text/markdown
35
- Requires-Dist: database_wrapper==0.2.17
35
+ Requires-Dist: database_wrapper==0.2.23
36
36
 
37
37
  # database_wrapper_sqlite
38
38
 
@@ -9,7 +9,8 @@ Part of the database_wrapper package
9
9
  import logging
10
10
 
11
11
  # from .db_wrapper_sqlite import DBWrapperSqlite
12
- from .connector import Sqlite, SqliteConfig
12
+ from .connector import Sqlite, SqliteConfig, SqliteTypedDictCursor
13
+ from .db_wrapper_sqlite import DBWrapperSqlite
13
14
 
14
15
  # Set the logger to a quiet default, can be enabled if needed
15
16
  logger = logging.getLogger("database_wrapper_sqlite")
@@ -18,7 +19,12 @@ if logger.level == logging.NOTSET:
18
19
 
19
20
 
20
21
  __all__ = [
21
- # "DBWrapperSqlite",
22
- "SqliteConfig",
23
- "Sqlite",
22
+ # Wrappers
23
+ DBWrapperSqlite,
24
+ # Connectors
25
+ Sqlite,
26
+ # Connection and Cursor types
27
+ SqliteTypedDictCursor,
28
+ # Helpers
29
+ SqliteConfig,
24
30
  ]
@@ -0,0 +1,114 @@
1
+ import sqlite3
2
+ from typing import Any, NotRequired, TypedDict, cast
3
+
4
+ from database_wrapper import DatabaseBackend
5
+
6
+
7
+ def dict_factory(cursor: sqlite3.Cursor, row: tuple) -> dict[str, Any]:
8
+ fields = [col[0] for col in cursor.description]
9
+ return dict(zip(fields, row, strict=False))
10
+
11
+
12
+ class SqliteConfig(TypedDict):
13
+ database: str
14
+ timeout: NotRequired[float]
15
+ isolation_level: NotRequired[str | None]
16
+ kwargs: NotRequired[dict[str, Any]]
17
+
18
+
19
+ class SqliteTypedDictCursor(sqlite3.Cursor):
20
+ """
21
+ Type hint wrapper only. At runtime, this is just a sqlite3.Cursor
22
+ that happens to produce dicts because of the row_factory.
23
+ """
24
+
25
+ def fetchone(self) -> dict[str, Any] | None:
26
+ return super().fetchone() # type: ignore
27
+
28
+ def fetchall(self) -> list[dict[str, Any]]:
29
+ return super().fetchall() # type: ignore
30
+
31
+ def __iter__(self) -> "SqliteTypedDictCursor":
32
+ return self
33
+
34
+ def __next__(self) -> dict[str, Any]:
35
+ return super().__next__() # type: ignore
36
+
37
+
38
+ class Sqlite(DatabaseBackend):
39
+ """
40
+ SQLite database backend
41
+
42
+ :param config: Configuration for SQLite
43
+ :type config: SqliteConfig
44
+ """
45
+
46
+ config: SqliteConfig
47
+ connection: sqlite3.Connection
48
+ cursor: SqliteTypedDictCursor
49
+
50
+ ##################
51
+ ### Connection ###
52
+ ##################
53
+
54
+ def open(self) -> None:
55
+ self.logger.debug("Connecting to DB")
56
+
57
+ if "kwargs" not in self.config:
58
+ self.config["kwargs"] = {}
59
+
60
+ # Default timeout to 5.0 seconds if not specified
61
+ timeout = self.config.get("timeout", 5.0)
62
+
63
+ # Default isolation_level to None (autocommit mode via library, though SQLite is tricky with this)
64
+ # or leave as default. Let's respect config or default to standard.
65
+ isolation_level = self.config.get("isolation_level", None)
66
+
67
+ self.connection = sqlite3.connect(
68
+ self.config["database"],
69
+ timeout=timeout,
70
+ isolation_level=isolation_level,
71
+ **self.config["kwargs"],
72
+ )
73
+
74
+ # Set row factory to return dicts
75
+ self.connection.row_factory = dict_factory
76
+
77
+ # Create cursor
78
+ self.cursor = cast(SqliteTypedDictCursor, self.connection.cursor())
79
+
80
+ def ping(self) -> bool:
81
+ try:
82
+ self.cursor.execute("SELECT 1")
83
+ self.cursor.fetchone()
84
+ except Exception as e:
85
+ self.logger.debug(f"Error while pinging the database: {e}")
86
+ return False
87
+
88
+ return True
89
+
90
+ ############
91
+ ### Data ###
92
+ ############
93
+
94
+ def last_insert_id(self) -> int:
95
+ assert self.cursor, "Cursor is not initialized"
96
+ return self.cursor.lastrowid or 0
97
+
98
+ def affected_rows(self) -> int:
99
+ assert self.cursor, "Cursor is not initialized"
100
+ return self.cursor.rowcount
101
+
102
+ def commit(self) -> None:
103
+ """Commit DB queries"""
104
+ assert self.connection, "Connection is not initialized"
105
+
106
+ self.logger.debug("Commit DB queries")
107
+ self.connection.commit()
108
+
109
+ def rollback(self) -> None:
110
+ """Rollback DB queries"""
111
+ assert self.connection, "Connection is not initialized"
112
+
113
+ self.logger.debug("Rollback DB queries")
114
+ self.connection.rollback()
@@ -0,0 +1,76 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ from database_wrapper import DBWrapper
5
+
6
+ from .connector import SqliteTypedDictCursor
7
+
8
+
9
+ class DBWrapperSqlite(DBWrapper):
10
+ """Wrapper for SQLite database"""
11
+
12
+ db_cursor: SqliteTypedDictCursor | None
13
+ """ SQLite cursor object """
14
+
15
+ #######################
16
+ ### Class lifecycle ###
17
+ #######################
18
+
19
+ # Meta methods
20
+ # We are overriding the __init__ method for the type hinting
21
+ def __init__(
22
+ self,
23
+ db_cursor: SqliteTypedDictCursor | None = None,
24
+ logger: logging.Logger | None = None,
25
+ ):
26
+ """
27
+ Initializes a new instance of the DBWrapper class.
28
+
29
+ Args:
30
+ db_cursor (SqliteTypedDictCursor): The SQLite database cursor object.
31
+ logger (logging.Logger, optional): The logger object. Defaults to None.
32
+ """
33
+ super().__init__(db_cursor, logger)
34
+
35
+ ###############
36
+ ### Setters ###
37
+ ###############
38
+
39
+ def set_db_cursor(self, db_cursor: SqliteTypedDictCursor | None) -> None:
40
+ """
41
+ Updates the database cursor object.
42
+
43
+ Args:
44
+ db_cursor (SqliteTypedDictCursor): The new database cursor object.
45
+ """
46
+ super().set_db_cursor(db_cursor)
47
+
48
+ ######################
49
+ ### Helper methods ###
50
+ ######################
51
+
52
+ def log_query(
53
+ self,
54
+ cursor: SqliteTypedDictCursor,
55
+ query: Any,
56
+ params: tuple[Any, ...],
57
+ ) -> None:
58
+ """
59
+ Logs the given query and parameters.
60
+
61
+ Args:
62
+ cursor (SqliteTypedDictCursor): The cursor used to execute the query.
63
+ query (Any): The query to log.
64
+ params (tuple[Any, ...]): The parameters to log.
65
+ """
66
+ # sqlite3 does not support mogrify, so we just log query and params
67
+ logging.getLogger().debug(f"Query: {query} with params: {params}")
68
+
69
+ #####################
70
+ ### Query methods ###
71
+ #####################
72
+
73
+ def limit_query(self, offset: int = 0, limit: int = 100) -> str | None:
74
+ if limit == 0:
75
+ return None
76
+ return f"LIMIT {limit} OFFSET {offset}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: database_wrapper_sqlite
3
- Version: 0.2.17
3
+ Version: 0.2.23
4
4
  Summary: database_wrapper for PostgreSQL database
5
5
  Author-email: Gints Murans <gm@gm.lv>
6
6
  License: GNU General Public License v3.0 (GPL-3.0)
@@ -32,7 +32,7 @@ Classifier: Topic :: Software Development
32
32
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
33
  Requires-Python: >=3.8
34
34
  Description-Content-Type: text/markdown
35
- Requires-Dist: database_wrapper==0.2.17
35
+ Requires-Dist: database_wrapper==0.2.23
36
36
 
37
37
  # database_wrapper_sqlite
38
38
 
@@ -2,6 +2,7 @@ README.md
2
2
  pyproject.toml
3
3
  database_wrapper_sqlite/__init__.py
4
4
  database_wrapper_sqlite/connector.py
5
+ database_wrapper_sqlite/db_wrapper_sqlite.py
5
6
  database_wrapper_sqlite/py.typed
6
7
  database_wrapper_sqlite.egg-info/PKG-INFO
7
8
  database_wrapper_sqlite.egg-info/SOURCES.txt
@@ -0,0 +1 @@
1
+ database_wrapper==0.2.23
@@ -4,14 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "database_wrapper_sqlite"
7
- version = "0.2.17"
7
+ version = "0.2.23"
8
8
  description = "database_wrapper for PostgreSQL database"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
11
- license = {text = "GNU General Public License v3.0 (GPL-3.0)"}
12
- authors = [
13
- {name = "Gints Murans", email = "gm@gm.lv"}
14
- ]
11
+ license = { text = "GNU General Public License v3.0 (GPL-3.0)" }
12
+ authors = [{ name = "Gints Murans", email = "gm@gm.lv" }]
15
13
  classifiers = [
16
14
  "Development Status :: 4 - Beta",
17
15
  "Intended Audience :: Developers",
@@ -31,12 +29,10 @@ classifiers = [
31
29
  "Topic :: Database",
32
30
  "Topic :: Database :: Front-Ends",
33
31
  "Topic :: Software Development",
34
- "Topic :: Software Development :: Libraries :: Python Modules"
32
+ "Topic :: Software Development :: Libraries :: Python Modules",
35
33
  ]
36
34
  keywords = ["database", "wrapper", "python", "sqlite"]
37
- dependencies = [
38
- "database_wrapper == 0.2.17",
39
- ]
35
+ dependencies = ["database_wrapper == 0.2.23"]
40
36
 
41
37
  [project.urls]
42
38
  Homepage = "https://github.com/gintsmurans/py_database_wrapper"
@@ -1,63 +0,0 @@
1
- from typing import Any, NotRequired, TypedDict
2
-
3
- from database_wrapper import DatabaseBackend
4
-
5
-
6
- class SqliteConfig(TypedDict):
7
- database: str
8
- kwargs: NotRequired[dict[str, Any]]
9
-
10
-
11
- # TODO: Needs to finish the implementation
12
- class Sqlite(DatabaseBackend):
13
- """
14
- Sqlite database backend
15
-
16
- :param config: Configuration for Sqlite
17
- :type config: MyConfig
18
-
19
- Defaults:
20
- _no defaults_
21
- """
22
-
23
- config: SqliteConfig
24
-
25
- connection: Any
26
- cursor: Any
27
-
28
- def open(self) -> None:
29
- # Free resources
30
- if hasattr(self, "connection") and self.connection:
31
- self.close()
32
-
33
- # Set defaults
34
- if "kwargs" not in self.config or not self.config["kwargs"]:
35
- self.config["kwargs"] = {}
36
-
37
- self.logger.debug("Connecting to DB")
38
-
39
- raise NotImplementedError(
40
- "Sqlite is not yet implemented. See here: https://github.com/gintsmurans/py_database_wrapper/"
41
- )
42
-
43
- def last_insert_id(self) -> int:
44
- assert self.cursor, "Cursor is not initialized"
45
- return self.cursor.lastrowid
46
-
47
- def affected_rows(self) -> int:
48
- assert self.cursor, "Cursor is not initialized"
49
- return self.cursor.rowcount
50
-
51
- def commit(self) -> None:
52
- """Commit DB queries"""
53
- assert self.connection, "Connection is not initialized"
54
-
55
- self.logger.debug("Commit DB queries..")
56
- self.connection.commit()
57
-
58
- def rollback(self) -> None:
59
- """Rollback DB queries"""
60
- assert self.connection, "Connection is not initialized"
61
-
62
- self.logger.debug("Rollback DB queries..")
63
- self.connection.rollback()
@@ -1 +0,0 @@
1
- database_wrapper==0.2.17