arkilian 1.0.0__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.
- arkilian-1.0.0/PKG-INFO +19 -0
- arkilian-1.0.0/arkilian/__init__.py +127 -0
- arkilian-1.0.0/arkilian/binding.py +52 -0
- arkilian-1.0.0/arkilian/py.typed +1 -0
- arkilian-1.0.0/arkilian.egg-info/PKG-INFO +19 -0
- arkilian-1.0.0/arkilian.egg-info/SOURCES.txt +9 -0
- arkilian-1.0.0/arkilian.egg-info/dependency_links.txt +1 -0
- arkilian-1.0.0/arkilian.egg-info/requires.txt +1 -0
- arkilian-1.0.0/arkilian.egg-info/top_level.txt +1 -0
- arkilian-1.0.0/pyproject.toml +35 -0
- arkilian-1.0.0/setup.cfg +4 -0
arkilian-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: arkilian
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Arkilian - SQLite wrapper with automated cloud backup
|
|
5
|
+
Author: CodeDynasty-dev
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/CodeDynasty-dev/birth-of-Arkilian
|
|
8
|
+
Project-URL: Repository, https://github.com/CodeDynasty-dev/birth-of-Arkilian
|
|
9
|
+
Keywords: sqlite,database,backup,s3,c,ffi
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: cffi>=1.15.0
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from .binding import lib, ffi
|
|
2
|
+
|
|
3
|
+
SQLITE_OK = 0
|
|
4
|
+
SQLITE_ROW = 100
|
|
5
|
+
SQLITE_DONE = 101
|
|
6
|
+
SQLITE_ERROR = 1
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Arkilian:
|
|
10
|
+
def __init__(self, db_path="app.sqlite"):
|
|
11
|
+
self._db = ffi.new("arkilian**")
|
|
12
|
+
result = lib.db_init(self._db, db_path.encode())
|
|
13
|
+
if result != 0:
|
|
14
|
+
raise RuntimeError("Failed to initialize database: " + self.last_error)
|
|
15
|
+
if self._db[0] is None:
|
|
16
|
+
raise RuntimeError("Database handle is null")
|
|
17
|
+
|
|
18
|
+
def close(self):
|
|
19
|
+
if self._db and self._db[0]:
|
|
20
|
+
lib.db_close(self._db[0])
|
|
21
|
+
self._db = None
|
|
22
|
+
|
|
23
|
+
def exec(self, sql):
|
|
24
|
+
result = lib.db_exec(self._db[0], sql.encode())
|
|
25
|
+
if result != SQLITE_OK and result != SQLITE_DONE:
|
|
26
|
+
raise RuntimeError(self.last_error)
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
def prepare(self, sql):
|
|
30
|
+
result = lib.db_prepare(self._db[0], sql.encode())
|
|
31
|
+
if result != SQLITE_OK:
|
|
32
|
+
raise RuntimeError(self.last_error)
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def step(self):
|
|
36
|
+
return lib.db_step(self._db[0])
|
|
37
|
+
|
|
38
|
+
def finalize(self):
|
|
39
|
+
result = lib.db_finalize(self._db[0])
|
|
40
|
+
if result != SQLITE_OK:
|
|
41
|
+
raise RuntimeError(self.last_error)
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def reset(self):
|
|
45
|
+
result = lib.db_reset(self._db[0])
|
|
46
|
+
if result != SQLITE_OK:
|
|
47
|
+
raise RuntimeError(self.last_error)
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
def column_count(self):
|
|
51
|
+
return lib.db_column_count(self._db[0])
|
|
52
|
+
|
|
53
|
+
def column_name(self, col):
|
|
54
|
+
return ffi.string(lib.db_column_name(self._db[0], col)).decode()
|
|
55
|
+
|
|
56
|
+
def column_text(self, col):
|
|
57
|
+
ptr = lib.db_column_text(self._db[0], col)
|
|
58
|
+
return ffi.string(ptr).decode() if ptr else None
|
|
59
|
+
|
|
60
|
+
def column_int(self, col):
|
|
61
|
+
return lib.db_column_int(self._db[0], col)
|
|
62
|
+
|
|
63
|
+
def column_double(self, col):
|
|
64
|
+
return lib.db_column_double(self._db[0], col)
|
|
65
|
+
|
|
66
|
+
def bind_text(self, idx, value):
|
|
67
|
+
result = lib.db_bind_text(self._db[0], idx, value.encode())
|
|
68
|
+
if result != SQLITE_OK:
|
|
69
|
+
raise RuntimeError(self.last_error)
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
def bind_int(self, idx, value):
|
|
73
|
+
result = lib.db_bind_int(self._db[0], idx, value)
|
|
74
|
+
if result != SQLITE_OK:
|
|
75
|
+
raise RuntimeError(self.last_error)
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def bind_double(self, idx, value):
|
|
79
|
+
result = lib.db_bind_double(self._db[0], idx, value)
|
|
80
|
+
if result != SQLITE_OK:
|
|
81
|
+
raise RuntimeError(self.last_error)
|
|
82
|
+
return self
|
|
83
|
+
|
|
84
|
+
def run(self, sql, params=None):
|
|
85
|
+
self.prepare(sql)
|
|
86
|
+
if params:
|
|
87
|
+
for i, p in enumerate(params):
|
|
88
|
+
if isinstance(p, str):
|
|
89
|
+
self.bind_text(i + 1, p)
|
|
90
|
+
elif isinstance(p, int):
|
|
91
|
+
self.bind_int(i + 1, p)
|
|
92
|
+
else:
|
|
93
|
+
self.bind_double(i + 1, p)
|
|
94
|
+
self.step()
|
|
95
|
+
self.finalize()
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def all(self, sql, params=None):
|
|
99
|
+
results = []
|
|
100
|
+
self.prepare(sql)
|
|
101
|
+
if params:
|
|
102
|
+
for i, p in enumerate(params):
|
|
103
|
+
if isinstance(p, str):
|
|
104
|
+
self.bind_text(i + 1, p)
|
|
105
|
+
elif isinstance(p, int):
|
|
106
|
+
self.bind_int(i + 1, p)
|
|
107
|
+
else:
|
|
108
|
+
self.bind_double(i + 1, p)
|
|
109
|
+
columns = [self.column_name(i) for i in range(self.column_count())]
|
|
110
|
+
while self.step() == SQLITE_ROW:
|
|
111
|
+
row = {}
|
|
112
|
+
for i, col in enumerate(columns):
|
|
113
|
+
row[col] = self.column_text(i)
|
|
114
|
+
results.append(row)
|
|
115
|
+
self.finalize()
|
|
116
|
+
return results
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def last_error(self):
|
|
120
|
+
return ffi.string(lib.db_errmsg(self._db[0])).decode() if self._db and self._db[0] else ""
|
|
121
|
+
|
|
122
|
+
def __enter__(self):
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
126
|
+
self.close()
|
|
127
|
+
return False
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import cffi
|
|
4
|
+
|
|
5
|
+
ffi = cffi.FFI()
|
|
6
|
+
|
|
7
|
+
ffi.cdef("""
|
|
8
|
+
typedef struct arkilian arkilian;
|
|
9
|
+
|
|
10
|
+
int db_init(arkilian **db, const char *connection_url);
|
|
11
|
+
void db_close(arkilian *db);
|
|
12
|
+
const char* db_errmsg(arkilian *db);
|
|
13
|
+
|
|
14
|
+
int db_exec(arkilian *db, const char *sql);
|
|
15
|
+
int db_prepare(arkilian *db, const char *sql);
|
|
16
|
+
int db_step(arkilian *db);
|
|
17
|
+
int db_finalize(arkilian *db);
|
|
18
|
+
int db_reset(arkilian *db);
|
|
19
|
+
int db_column_count(arkilian *db);
|
|
20
|
+
const char* db_column_name(arkilian *db, int col);
|
|
21
|
+
const char* db_column_text(arkilian *db, int col);
|
|
22
|
+
int db_column_int(arkilian *db, int col);
|
|
23
|
+
double db_column_double(arkilian *db, int col);
|
|
24
|
+
int db_bind_text(arkilian *db, int idx, const char *val);
|
|
25
|
+
int db_bind_int(arkilian *db, int idx, int val);
|
|
26
|
+
int db_bind_double(arkilian *db, int idx, double val);
|
|
27
|
+
""")
|
|
28
|
+
|
|
29
|
+
this_dir = os.path.dirname(os.path.abspath(__file__))
|
|
30
|
+
src_dir = os.path.join(this_dir, "..", "..", "..", "build")
|
|
31
|
+
|
|
32
|
+
lib_name = "libarkilian.dylib" if sys.platform == "darwin" else "libarkilian.so"
|
|
33
|
+
lib_path = os.path.join(src_dir, lib_name)
|
|
34
|
+
|
|
35
|
+
if not os.path.exists(lib_path):
|
|
36
|
+
lib_path = os.path.join(src_dir, "Release", lib_name)
|
|
37
|
+
|
|
38
|
+
if not os.path.exists(lib_path):
|
|
39
|
+
lib_path = os.path.join(src_dir, "Release", "libarkilian.1.0.0.dylib")
|
|
40
|
+
|
|
41
|
+
if not os.path.exists(lib_path):
|
|
42
|
+
lib_path = os.path.join(src_dir, "Release", "libarkilian.1.dylib")
|
|
43
|
+
|
|
44
|
+
if not os.path.exists(lib_path):
|
|
45
|
+
lib_path = os.path.join(src_dir, "Release", "libarkilian.1.0.0.so")
|
|
46
|
+
|
|
47
|
+
if not os.path.exists(lib_path):
|
|
48
|
+
raise RuntimeError(f"Library not found at {lib_path}")
|
|
49
|
+
|
|
50
|
+
lib = ffi.dlopen(lib_path)
|
|
51
|
+
|
|
52
|
+
__all__ = ["ffi", "lib"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# PEP 561 marker file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: arkilian
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Arkilian - SQLite wrapper with automated cloud backup
|
|
5
|
+
Author: CodeDynasty-dev
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/CodeDynasty-dev/birth-of-Arkilian
|
|
8
|
+
Project-URL: Repository, https://github.com/CodeDynasty-dev/birth-of-Arkilian
|
|
9
|
+
Keywords: sqlite,database,backup,s3,c,ffi
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: cffi>=1.15.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cffi>=1.15.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
arkilian
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "cffi>=1.15.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "arkilian"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Arkilian - SQLite wrapper with automated cloud backup"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "CodeDynasty-dev"}]
|
|
13
|
+
keywords = ["sqlite", "database", "backup", "s3", "c", "ffi"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.8",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = ["cffi>=1.15.0"]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/CodeDynasty-dev/birth-of-Arkilian"
|
|
28
|
+
Repository = "https://github.com/CodeDynasty-dev/birth-of-Arkilian"
|
|
29
|
+
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
where = ["."]
|
|
32
|
+
include = ["arkilian*"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.package-data]
|
|
35
|
+
arkilian = ["*.h"]
|
arkilian-1.0.0/setup.cfg
ADDED