PyCyphORM 0.1.2__py3-none-any.whl → 0.1.2.dev1__py3-none-any.whl
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.
- PyCyphORM/__init__.py +3 -0
- {src → PyCyphORM}/cli.py +1 -1
- PyCyphORM/lib/__init__.py +2 -0
- PyCyphORM/lib/adapter.py +68 -0
- PyCyphORM/lib/orm.py +175 -0
- {PyCyphORM-0.1.2.dist-info → PyCyphORM-0.1.2.dev1.dist-info}/METADATA +1 -1
- PyCyphORM-0.1.2.dev1.dist-info/RECORD +10 -0
- PyCyphORM-0.1.2.dev1.dist-info/top_level.txt +1 -0
- PyCyphORM-0.1.2.dist-info/RECORD +0 -7
- PyCyphORM-0.1.2.dist-info/top_level.txt +0 -1
- src/__init__.py +0 -3
- {PyCyphORM-0.1.2.dist-info → PyCyphORM-0.1.2.dev1.dist-info}/WHEEL +0 -0
- {PyCyphORM-0.1.2.dist-info → PyCyphORM-0.1.2.dev1.dist-info}/entry_points.txt +0 -0
PyCyphORM/__init__.py
ADDED
{src → PyCyphORM}/cli.py
RENAMED
|
@@ -36,7 +36,7 @@ def cli():
|
|
|
36
36
|
elif args['decrypt']:
|
|
37
37
|
if path.exists(path.abspath(args['decrypt'])):
|
|
38
38
|
|
|
39
|
-
from
|
|
39
|
+
from .lib.adapter import decrypt_cdb, load_config
|
|
40
40
|
|
|
41
41
|
cnf = load_config(".pyorm")
|
|
42
42
|
decrypt_cdb(path.abspath(args['decrypt']), cnf["PASSWORD"], cnf["SALT"])
|
PyCyphORM/lib/adapter.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from cryptography.fernet import Fernet
|
|
2
|
+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
3
|
+
from cryptography.hazmat.primitives import hashes
|
|
4
|
+
from cryptography.hazmat.backends import default_backend
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
import sqlite3
|
|
8
|
+
import gzip
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
from base64 import b16decode, urlsafe_b64encode
|
|
12
|
+
|
|
13
|
+
def load_config(filepath):
|
|
14
|
+
config = None
|
|
15
|
+
with open(filepath, "rb") as f:
|
|
16
|
+
config = json.loads(f.read())
|
|
17
|
+
for key in config:
|
|
18
|
+
if isinstance(config[key], str):
|
|
19
|
+
config[key] = b16decode(config[key])
|
|
20
|
+
return config
|
|
21
|
+
|
|
22
|
+
def key_creation(password, salt):
|
|
23
|
+
kdf=PBKDF2HMAC(algorithm = hashes.SHA256(), salt=salt, iterations=1024, length=32, backend=default_backend())
|
|
24
|
+
key=Fernet(urlsafe_b64encode(kdf.derive(password)))
|
|
25
|
+
return key
|
|
26
|
+
|
|
27
|
+
def encryption(b, password, salt):
|
|
28
|
+
f=key_creation(password, salt)
|
|
29
|
+
safe=f.encrypt(b)
|
|
30
|
+
return safe
|
|
31
|
+
|
|
32
|
+
def decryption(safe, password, salt):
|
|
33
|
+
f=key_creation(password, salt)
|
|
34
|
+
b=f.decrypt(safe)
|
|
35
|
+
return b
|
|
36
|
+
|
|
37
|
+
def open_cdb(filename, password, salt):
|
|
38
|
+
if not os.path.exists(filename):
|
|
39
|
+
con = sqlite3.connect(':memory:')
|
|
40
|
+
return con
|
|
41
|
+
f=gzip.open(filename,'rb')
|
|
42
|
+
safe=f.read()
|
|
43
|
+
f.close()
|
|
44
|
+
content=decryption(safe,password,salt)
|
|
45
|
+
content=content.decode('utf-8')
|
|
46
|
+
con=sqlite3.connect(':memory:')
|
|
47
|
+
con.executescript(content)
|
|
48
|
+
return con
|
|
49
|
+
|
|
50
|
+
def decrypt_cdb(filename, password, salt):
|
|
51
|
+
f=gzip.open(filename,'rb')
|
|
52
|
+
safe=f.read()
|
|
53
|
+
f.close()
|
|
54
|
+
content=decryption(safe,password,salt)
|
|
55
|
+
fp=gzip.open(filename+".decoded.db",'wb')
|
|
56
|
+
fp.write(content)
|
|
57
|
+
fp.close()
|
|
58
|
+
|
|
59
|
+
def save_cdb(con, filename, password, salt):
|
|
60
|
+
fp=gzip.open(filename,'wb')
|
|
61
|
+
b=b''
|
|
62
|
+
for line in con.iterdump():
|
|
63
|
+
b+=bytes('%s\n','utf8') % bytes(line,'utf8')
|
|
64
|
+
b=encryption(b,password, salt)
|
|
65
|
+
fp.write(b)
|
|
66
|
+
fp.close()
|
|
67
|
+
|
|
68
|
+
|
PyCyphORM/lib/orm.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
from .adapter import open_cdb, save_cdb
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
class QueryBuilder:
|
|
5
|
+
|
|
6
|
+
@staticmethod
|
|
7
|
+
def __where__(clause):
|
|
8
|
+
where = []
|
|
9
|
+
for k in clause:
|
|
10
|
+
if clause[k] == None:
|
|
11
|
+
where.append("%s IS NULL" % (k))
|
|
12
|
+
else:
|
|
13
|
+
where.append("%s = \"%s\"" % (k, clause[k]))
|
|
14
|
+
return ",".join(where)
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def __set__(clause):
|
|
18
|
+
st = []
|
|
19
|
+
for k in clause:
|
|
20
|
+
if clause[k] == None:
|
|
21
|
+
st.append("%s = NULL" % (k))
|
|
22
|
+
else:
|
|
23
|
+
st.append("%s = \"%s\"" % (k, clause[k]))
|
|
24
|
+
return ",".join(st)
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def __insert__(table, data):
|
|
28
|
+
if isinstance(data, dict):
|
|
29
|
+
columns = []
|
|
30
|
+
values = []
|
|
31
|
+
for column in data:
|
|
32
|
+
columns.append(column)
|
|
33
|
+
values.append("\"%s\"" % data[column])
|
|
34
|
+
sql = "INSERT INTO %s (%s) VALUES (%s)" % (table, ",".join(columns), ",".join(values))
|
|
35
|
+
else:
|
|
36
|
+
count = 0
|
|
37
|
+
columns = []
|
|
38
|
+
bulk = []
|
|
39
|
+
for row in data:
|
|
40
|
+
values = []
|
|
41
|
+
for column in row:
|
|
42
|
+
if count == 0:
|
|
43
|
+
columns.append(column)
|
|
44
|
+
values.append("\"%s\"" % data[column])
|
|
45
|
+
count += 1
|
|
46
|
+
bulk.append("(%s)" % (",".join(values)))
|
|
47
|
+
sql = "INSERT INTO %s (%s) VALUES %s" % (table, ",".join(columns), ",".join(bulk))
|
|
48
|
+
return sql
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def __create_table__(table, schema):
|
|
52
|
+
definition = []
|
|
53
|
+
for column in schema:
|
|
54
|
+
definition.append("%s %s" % (column, schema[column]))
|
|
55
|
+
sql = "CREATE TABLE %s (%s)" % (table, ",".join(definition))
|
|
56
|
+
return sql
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def __drop_table__(table):
|
|
60
|
+
sql = "DROP TABLE %s" % (table)
|
|
61
|
+
return sql
|
|
62
|
+
|
|
63
|
+
def __update__(self, table, data, where):
|
|
64
|
+
sql = "UPDATE %s SET %s" % (table, self.__set__(data))
|
|
65
|
+
if isinstance(where, dict):
|
|
66
|
+
sql += " WHERE %s" % self.__where__(where)
|
|
67
|
+
return sql
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def __select__(self, table, fields, where=None, orderby=None):
|
|
71
|
+
sql = "SELECT %s FROM %s" % (",".join(fields), table)
|
|
72
|
+
if isinstance(where, dict):
|
|
73
|
+
sql += " WHERE %s" % self.__where__(where)
|
|
74
|
+
if isinstance(orderby, str):
|
|
75
|
+
sql += " ORDER BY %s" % (orderby)
|
|
76
|
+
return sql
|
|
77
|
+
|
|
78
|
+
def __delete__(self, table, where):
|
|
79
|
+
sql = "DELETE FROM %s WHERE %s" % (table, self.__where__(where))
|
|
80
|
+
return sql
|
|
81
|
+
|
|
82
|
+
class Model(QueryBuilder):
|
|
83
|
+
|
|
84
|
+
def __init__(self, conn, table, schema):
|
|
85
|
+
self.conn = conn
|
|
86
|
+
self.table = table
|
|
87
|
+
self.schema = schema
|
|
88
|
+
|
|
89
|
+
def down(self):
|
|
90
|
+
sql = self.__drop_table__(self.table)
|
|
91
|
+
cur = self.conn.cursor()
|
|
92
|
+
cur.execute(sql)
|
|
93
|
+
self.conn.commit()
|
|
94
|
+
return cur.rowcount
|
|
95
|
+
|
|
96
|
+
def up(self):
|
|
97
|
+
sql = self.__create_table__(self.table, self.schema)
|
|
98
|
+
cur = self.conn.cursor()
|
|
99
|
+
cur.execute(sql)
|
|
100
|
+
self.conn.commit()
|
|
101
|
+
return cur.rowcount
|
|
102
|
+
|
|
103
|
+
def insert(self, data):
|
|
104
|
+
sql = self.__insert__(self.table, data)
|
|
105
|
+
cur = self.conn.cursor()
|
|
106
|
+
cur.execute(sql)
|
|
107
|
+
self.conn.commit()
|
|
108
|
+
return cur.lastrowid
|
|
109
|
+
|
|
110
|
+
def update(self, where, data):
|
|
111
|
+
sql = self.__update__(self.table, data, where)
|
|
112
|
+
cur = self.conn.cursor()
|
|
113
|
+
cur.execute(sql)
|
|
114
|
+
self.conn.commit()
|
|
115
|
+
return cur.rowcount
|
|
116
|
+
|
|
117
|
+
def delete(self, where):
|
|
118
|
+
sql = self.__delete__(self.table, where)
|
|
119
|
+
cur = self.conn.cursor()
|
|
120
|
+
cur.execute(sql)
|
|
121
|
+
self.conn.commit()
|
|
122
|
+
return cur.rowcount
|
|
123
|
+
|
|
124
|
+
def find(self, where=None):
|
|
125
|
+
sql = self.__select__(self.table, ["*"], where)
|
|
126
|
+
cur = self.conn.cursor()
|
|
127
|
+
cur.execute(sql)
|
|
128
|
+
rows = cur.fetchall()
|
|
129
|
+
return rows
|
|
130
|
+
|
|
131
|
+
def first(self, where):
|
|
132
|
+
sql = self.__select__(self.table, ["*"], where)
|
|
133
|
+
cur = self.conn.cursor()
|
|
134
|
+
cur.execute(sql)
|
|
135
|
+
row = cur.fetchone()
|
|
136
|
+
return row
|
|
137
|
+
|
|
138
|
+
class ORM:
|
|
139
|
+
|
|
140
|
+
__models__ = {}
|
|
141
|
+
__instance__ = None
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def instance(filename, password, salt, schema):
|
|
145
|
+
if ORM.__instance__ == None:
|
|
146
|
+
ORM.__instance__ = ORM(filename, password, salt, schema)
|
|
147
|
+
return ORM.__instance__
|
|
148
|
+
|
|
149
|
+
def __init__(self, filename, password, salt, schema):
|
|
150
|
+
|
|
151
|
+
self.filename = filename
|
|
152
|
+
self.password = password
|
|
153
|
+
self.salt = salt
|
|
154
|
+
self.__instance__ = self
|
|
155
|
+
|
|
156
|
+
install = False
|
|
157
|
+
if os.path.exists(filename) == False:
|
|
158
|
+
install = True
|
|
159
|
+
|
|
160
|
+
self.conn = open_cdb(self.filename, self.password, self.salt)
|
|
161
|
+
|
|
162
|
+
for table in schema:
|
|
163
|
+
self.__models__[table] = Model(self.conn, table, schema[table])
|
|
164
|
+
if install:
|
|
165
|
+
self.__models__[table].up()
|
|
166
|
+
if install:
|
|
167
|
+
save_cdb(self.conn, self.filename, self.password, self.salt)
|
|
168
|
+
|
|
169
|
+
def model(self, name) -> Model|None:
|
|
170
|
+
if name in self.__models__:
|
|
171
|
+
return self.__models__[name]
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
def save(self):
|
|
175
|
+
save_cdb(self.conn, self.filename, self.password, self.salt)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
PyCyphORM/__init__.py,sha256=7XTdFpAvZBhwIEv-7ebj7Eex64JV_WFyTgRuVOx20Mg,82
|
|
2
|
+
PyCyphORM/cli.py,sha256=At2Q8Fx2erRcV8YjDjLGfTXQaUKJ5Vk8FDw-nLca_uE,1391
|
|
3
|
+
PyCyphORM/lib/__init__.py,sha256=2Br4Dx6sMIJLEHVL3P02LUoCcUnZbgZMlgGLxuglzaU,53
|
|
4
|
+
PyCyphORM/lib/adapter.py,sha256=qLeiraGsm9OSzhie6j6XbGRmCknylBU5J7EsOtBLatU,1836
|
|
5
|
+
PyCyphORM/lib/orm.py,sha256=9KOWv5yQngoN5M3ky_W9KEkMOfGCUXVF6Vl1Xt-9GlA,5212
|
|
6
|
+
PyCyphORM-0.1.2.dev1.dist-info/METADATA,sha256=mFRGmiSRJcN_1HevXyZp4-w_scHlyctZYNLJdSTS0t4,1135
|
|
7
|
+
PyCyphORM-0.1.2.dev1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
8
|
+
PyCyphORM-0.1.2.dev1.dist-info/entry_points.txt,sha256=6R4UorjfxYmbqjbF9d1fgmQybp5Zgy4Bw6PclOdO31Q,38
|
|
9
|
+
PyCyphORM-0.1.2.dev1.dist-info/top_level.txt,sha256=ahpJTN6d1ACvc5oQSlPWSKmmaTqLyo7ctzhwNYoCCbA,10
|
|
10
|
+
PyCyphORM-0.1.2.dev1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyCyphORM
|
PyCyphORM-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
src/__init__.py,sha256=QL_yeVt2TuLjQoDbY8utuRUxvk_B-DGHbBM-tAf91dw,91
|
|
2
|
-
src/cli.py,sha256=z5xOtyWibyx7RkCgOtAAxX_Rd5JATvH-VkNVRyN83S0,1394
|
|
3
|
-
PyCyphORM-0.1.2.dist-info/METADATA,sha256=HPAqg6pGrCd5_P9PK2EYS3KSJDeWzfzBFEH8J7QnSis,1130
|
|
4
|
-
PyCyphORM-0.1.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
5
|
-
PyCyphORM-0.1.2.dist-info/entry_points.txt,sha256=6R4UorjfxYmbqjbF9d1fgmQybp5Zgy4Bw6PclOdO31Q,38
|
|
6
|
-
PyCyphORM-0.1.2.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
|
|
7
|
-
PyCyphORM-0.1.2.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
src
|
src/__init__.py
DELETED
|
File without changes
|
|
File without changes
|