pyeasysql 1.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.
- PyEasySQL-1.0/EasySQL/ABC.py +43 -0
- PyEasySQL-1.0/EasySQL/Classes.py +322 -0
- PyEasySQL-1.0/EasySQL/Exceptions.py +31 -0
- PyEasySQL-1.0/EasySQL/Logging.py +18 -0
- PyEasySQL-1.0/EasySQL/Types.py +133 -0
- PyEasySQL-1.0/EasySQL/Where.py +69 -0
- PyEasySQL-1.0/EasySQL/__init__.py +6 -0
- PyEasySQL-1.0/PKG-INFO +76 -0
- PyEasySQL-1.0/PyEasySQL.egg-info/PKG-INFO +76 -0
- PyEasySQL-1.0/PyEasySQL.egg-info/SOURCES.txt +14 -0
- PyEasySQL-1.0/PyEasySQL.egg-info/dependency_links.txt +1 -0
- PyEasySQL-1.0/PyEasySQL.egg-info/requires.txt +1 -0
- PyEasySQL-1.0/PyEasySQL.egg-info/top_level.txt +1 -0
- PyEasySQL-1.0/README.md +61 -0
- PyEasySQL-1.0/setup.cfg +4 -0
- PyEasySQL-1.0/setup.py +26 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Union, TypeVar, List, Set, Tuple
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SQLType(ABC):
|
|
6
|
+
@property
|
|
7
|
+
def name(self):
|
|
8
|
+
raise NotImplementedError
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def default(self):
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
|
|
14
|
+
def parse(self, value) -> str:
|
|
15
|
+
raise NotImplementedError
|
|
16
|
+
|
|
17
|
+
def cast(self, value):
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SQLExecutable(ABC):
|
|
22
|
+
def execute(self, operation, params=()):
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SQLCommand(ABC):
|
|
27
|
+
def get_value(self, *args, **kwargs) -> str:
|
|
28
|
+
raise NotImplementedError
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SQLCommandExecutable(SQLCommand, ABC):
|
|
32
|
+
def execute(self, *args, **kwargs):
|
|
33
|
+
raise NotImplementedError
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Extra Typings
|
|
37
|
+
T = TypeVar('T')
|
|
38
|
+
Collection = Union[List[T], Set[T], Tuple[T]]
|
|
39
|
+
ListOrSingle = Union[T, Collection[T]]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def is_collection(value):
|
|
43
|
+
return isinstance(value, (list, set, tuple))
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
from typing import List, Optional, Union, Any, Dict
|
|
2
|
+
|
|
3
|
+
import mysql.connector
|
|
4
|
+
|
|
5
|
+
from .ABC import ListOrSingle, SQLCommandExecutable, Collection, SQLType
|
|
6
|
+
from .Exceptions import MissingArgumentException, MisMatchException, DatabaseSafetyException
|
|
7
|
+
from .Logging import logger
|
|
8
|
+
from .Where import Where
|
|
9
|
+
|
|
10
|
+
__all__ = ['EasyDatabase', 'EasyTable', 'EasyColumn', 'Select', 'Insert', 'Update', 'Delete']
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EasyColumn:
|
|
14
|
+
def __init__(self, name: str, sql_type: SQLType, default: Any = None, primary: bool = False, not_null: bool = False, auto_increment: bool = False):
|
|
15
|
+
self.name = name
|
|
16
|
+
self.sql_type = sql_type
|
|
17
|
+
self.default = default if default else sql_type.default if not_null else None
|
|
18
|
+
self.primary = primary
|
|
19
|
+
self.auto_increment = auto_increment
|
|
20
|
+
self.not_null = not_null
|
|
21
|
+
|
|
22
|
+
def __hash__(self):
|
|
23
|
+
return hash((self.name,))
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
return f'<EasyColumn "{self.name}" type={self.sql_type}>'
|
|
27
|
+
|
|
28
|
+
def __eq__(self, other):
|
|
29
|
+
if isinstance(other, EasyColumn):
|
|
30
|
+
return self.name == other.name and self.sql_type == other.sql_type
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
def get_sql(self):
|
|
34
|
+
value = f'{self.name} {self.sql_type.name}'
|
|
35
|
+
if self.primary:
|
|
36
|
+
value += ' PRIMARY KEY'
|
|
37
|
+
elif self.not_null:
|
|
38
|
+
value += ' NOT NULL'
|
|
39
|
+
if self.auto_increment:
|
|
40
|
+
value += ' AUTO_INCREMENT'
|
|
41
|
+
if self.default is not None:
|
|
42
|
+
value += f' DEFAULT {self.sql_type.parse(self.default)}'
|
|
43
|
+
return value
|
|
44
|
+
|
|
45
|
+
def parse(self, value):
|
|
46
|
+
return self.sql_type.parse(value)
|
|
47
|
+
|
|
48
|
+
def cast(self, value):
|
|
49
|
+
return self.sql_type.cast(value)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class EasyDatabase:
|
|
53
|
+
def __init__(self, host="127.0.0.1", port=3306, database=None, user="root", password=None):
|
|
54
|
+
if database is None:
|
|
55
|
+
raise MissingArgumentException('Database argument is required.')
|
|
56
|
+
if password is None:
|
|
57
|
+
raise MissingArgumentException('Password is not provided.')
|
|
58
|
+
|
|
59
|
+
self._database = database
|
|
60
|
+
self._password = password
|
|
61
|
+
self._host = host
|
|
62
|
+
self._port = port
|
|
63
|
+
self._user = user
|
|
64
|
+
|
|
65
|
+
self._connection = None
|
|
66
|
+
self._safe = True
|
|
67
|
+
self.prepare()
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def safe(self):
|
|
71
|
+
return self._safe
|
|
72
|
+
|
|
73
|
+
def remove_safety(self, *, confirm: bool):
|
|
74
|
+
self._safe = not confirm
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def connection(self):
|
|
78
|
+
try:
|
|
79
|
+
self._connection.ping()
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.info(f'Connecting to the database called {self._database} due {e}')
|
|
82
|
+
self._connection = mysql.connector.connect(host=self._host, port=self._port, database=self._database, user=self._user, password=self._password)
|
|
83
|
+
return self._connection
|
|
84
|
+
|
|
85
|
+
def prepare(self):
|
|
86
|
+
return self.connection.is_connected()
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def cursor(self):
|
|
90
|
+
self._cursor = self.connection.cursor()
|
|
91
|
+
return self._cursor
|
|
92
|
+
|
|
93
|
+
def execute(self, operation, params=(), auto_commit=True):
|
|
94
|
+
cursor = self.cursor
|
|
95
|
+
|
|
96
|
+
logger.debug(f'SQL command has been requested to be executed:\n\tCommand: "{operation}"\n\tParameters: {params}\n\tCommit: {auto_commit}')
|
|
97
|
+
cursor.execute(operation, params)
|
|
98
|
+
if auto_commit:
|
|
99
|
+
self.commit()
|
|
100
|
+
|
|
101
|
+
return cursor
|
|
102
|
+
|
|
103
|
+
def commit(self):
|
|
104
|
+
return self.connection.commit()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class EasyTable:
|
|
108
|
+
def __init__(self, database: EasyDatabase, name: str, columns: List[EasyColumn]):
|
|
109
|
+
self._database = database
|
|
110
|
+
self._name = name
|
|
111
|
+
self._columns = columns
|
|
112
|
+
|
|
113
|
+
self.create()
|
|
114
|
+
|
|
115
|
+
def assert_columns(self, columns):
|
|
116
|
+
if columns is None or columns == '*':
|
|
117
|
+
return
|
|
118
|
+
for column in columns:
|
|
119
|
+
if column not in self._columns:
|
|
120
|
+
raise MisMatchException(f'Column "{column}" is not implemented in this table.')
|
|
121
|
+
|
|
122
|
+
def manage_values(self, values: Union[Collection[Any], Dict[Union[EasyColumn, str], Any]]) -> Dict[EasyColumn, Any]:
|
|
123
|
+
if isinstance(values, dict):
|
|
124
|
+
columns = [self.get_column(column) for column in values.keys()]
|
|
125
|
+
values = list(values.values())
|
|
126
|
+
else:
|
|
127
|
+
columns = self._columns
|
|
128
|
+
values = list(values)
|
|
129
|
+
|
|
130
|
+
self.assert_columns(columns)
|
|
131
|
+
if len(values) != len(columns):
|
|
132
|
+
raise MisMatchException('Values does not match with columns.')
|
|
133
|
+
|
|
134
|
+
return {columns[i]: values[i] for i in range(len(columns))}
|
|
135
|
+
|
|
136
|
+
def create(self):
|
|
137
|
+
command = f"CREATE TABLE IF NOT EXISTS {self._name} ({', '.join([column.get_sql() for column in self._columns])});"
|
|
138
|
+
self._database.execute(command)
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def columns(self):
|
|
142
|
+
return self._columns
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def name(self):
|
|
146
|
+
return self._name
|
|
147
|
+
|
|
148
|
+
def get_column(self, target) -> Optional[EasyColumn]:
|
|
149
|
+
if target in self._columns:
|
|
150
|
+
return target
|
|
151
|
+
for column in self._columns:
|
|
152
|
+
if column.name == target:
|
|
153
|
+
return column
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
def select(self, columns: ListOrSingle[Union[EasyColumn, str]] = None, where: Where = None):
|
|
157
|
+
if columns is not None:
|
|
158
|
+
if isinstance(columns, str):
|
|
159
|
+
columns = [columns]
|
|
160
|
+
columns = [self.get_column(column) for column in columns]
|
|
161
|
+
|
|
162
|
+
return Select(self._database, columns, self, where).execute()
|
|
163
|
+
|
|
164
|
+
def insert(self, values: Union[Collection[Any], Dict[Union[EasyColumn, str], Any]]):
|
|
165
|
+
return Insert(self._database, self.manage_values(values), self).execute()
|
|
166
|
+
|
|
167
|
+
def update(self, values: Union[Collection[Any], Dict[Union[EasyColumn, str], Any]], where: Where = None):
|
|
168
|
+
return Update(self._database, self.manage_values(values), self, where).execute()
|
|
169
|
+
|
|
170
|
+
def delete(self, where: Where = None):
|
|
171
|
+
return Delete(self._database, self, where).execute()
|
|
172
|
+
|
|
173
|
+
def set(self, values: Union[Collection[Any], Dict[Union[EasyColumn, str], Any]], where: Where = None):
|
|
174
|
+
values = self.manage_values(values)
|
|
175
|
+
selection = self.select(values.keys(), where)
|
|
176
|
+
if selection and len(selection) > 0:
|
|
177
|
+
self.update(values, where)
|
|
178
|
+
else:
|
|
179
|
+
self.insert(values)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class Select(SQLCommandExecutable):
|
|
183
|
+
def __init__(self, database: EasyDatabase, columns: Collection[EasyColumn] = None, table: EasyTable = None, where: Where = None):
|
|
184
|
+
if table and columns:
|
|
185
|
+
table.assert_columns(columns)
|
|
186
|
+
|
|
187
|
+
self._database = database
|
|
188
|
+
self._table = table
|
|
189
|
+
self._columns = columns
|
|
190
|
+
self._where = where
|
|
191
|
+
|
|
192
|
+
def _asserts(self):
|
|
193
|
+
if self._table is None:
|
|
194
|
+
raise MissingArgumentException('Table is missing.')
|
|
195
|
+
self._table.assert_columns(self._columns)
|
|
196
|
+
|
|
197
|
+
def where(self, where: Where):
|
|
198
|
+
self._where = self._where or where
|
|
199
|
+
return self
|
|
200
|
+
|
|
201
|
+
def from_table(self, table: EasyTable):
|
|
202
|
+
self._table = self._table or table
|
|
203
|
+
return self
|
|
204
|
+
|
|
205
|
+
def get_value(self) -> str:
|
|
206
|
+
self._asserts()
|
|
207
|
+
columns = ', '.join([column.name for column in self._columns]) if self._columns else '*'
|
|
208
|
+
return f"SELECT {columns} FROM {self._table.name}" + (f' {self._where.get_value()};' if self._where else ";")
|
|
209
|
+
|
|
210
|
+
def execute(self):
|
|
211
|
+
self._asserts()
|
|
212
|
+
result = self._database.execute(self.get_value(), auto_commit=False).fetchall()
|
|
213
|
+
columns = self._columns if self._columns else self._table.columns
|
|
214
|
+
new_result = []
|
|
215
|
+
for item in result:
|
|
216
|
+
new_result.append(tuple([columns[i].cast(item[i]) for i in range(len(columns))]))
|
|
217
|
+
return new_result
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class Insert(SQLCommandExecutable):
|
|
221
|
+
def __init__(self, database: EasyDatabase, values: Dict[EasyColumn, Any], table: EasyTable = None):
|
|
222
|
+
if table:
|
|
223
|
+
table.assert_columns(values.keys())
|
|
224
|
+
|
|
225
|
+
self._database = database
|
|
226
|
+
self._values = values
|
|
227
|
+
self._table = table
|
|
228
|
+
|
|
229
|
+
def _asserts(self):
|
|
230
|
+
if self._table is None:
|
|
231
|
+
raise MissingArgumentException('Table is missing.')
|
|
232
|
+
self._table.assert_columns(self._values.keys())
|
|
233
|
+
|
|
234
|
+
def into_table(self, table: EasyTable):
|
|
235
|
+
self._table = self._table or table
|
|
236
|
+
return self
|
|
237
|
+
|
|
238
|
+
def get_value(self) -> str:
|
|
239
|
+
self._asserts()
|
|
240
|
+
columns = ', '.join([column.name for column in self._values.keys()])
|
|
241
|
+
values = ', '.join([column.parse(value) for column, value in self._values.items()])
|
|
242
|
+
return f"INSERT INTO {self._table.name} ({columns}) VALUES ({values});"
|
|
243
|
+
|
|
244
|
+
def execute(self):
|
|
245
|
+
self._asserts()
|
|
246
|
+
command = self.get_value()
|
|
247
|
+
return self._database.execute(command).lastrowid
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
# noinspection SqlWithoutWhere
|
|
251
|
+
# The asserts will not allow the missing where
|
|
252
|
+
class Update(SQLCommandExecutable):
|
|
253
|
+
def __init__(self, database: EasyDatabase, values: Dict[EasyColumn, Any], table: EasyTable = None, where: Where = None):
|
|
254
|
+
if table:
|
|
255
|
+
table.assert_columns(values.keys())
|
|
256
|
+
|
|
257
|
+
self._database = database
|
|
258
|
+
self._values = values
|
|
259
|
+
self._table = table
|
|
260
|
+
self._where = where
|
|
261
|
+
|
|
262
|
+
def _asserts(self, safety: bool = True):
|
|
263
|
+
if self._table is None:
|
|
264
|
+
raise MissingArgumentException('Table is missing.')
|
|
265
|
+
self._table.assert_columns(self._values.keys())
|
|
266
|
+
|
|
267
|
+
if self._database.safe and safety:
|
|
268
|
+
if self._where is None:
|
|
269
|
+
raise DatabaseSafetyException('Safety Warning: Update without any condition is prohibited.')
|
|
270
|
+
|
|
271
|
+
def table(self, table: EasyTable):
|
|
272
|
+
self._table = self._table or table
|
|
273
|
+
return self
|
|
274
|
+
|
|
275
|
+
def where(self, where: Where):
|
|
276
|
+
self._where = self._where or where
|
|
277
|
+
return self
|
|
278
|
+
|
|
279
|
+
def get_value(self) -> str:
|
|
280
|
+
self._asserts(safety=False)
|
|
281
|
+
columns = ', '.join([column.name for column in self._values.keys()])
|
|
282
|
+
set_command = ', '.join([f'{column.name} = {column.parse(value)}' for column, value in self._values.items()])
|
|
283
|
+
return f"UPDATE {self._table.name} SET {set_command}" + f' {self._where.get_value()};' if self._where else ";"
|
|
284
|
+
|
|
285
|
+
def execute(self):
|
|
286
|
+
self._asserts()
|
|
287
|
+
command = self.get_value()
|
|
288
|
+
return self._database.execute(command).lastrowid
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# noinspection SqlWithoutWhere
|
|
292
|
+
# The asserts will not allow the missing where
|
|
293
|
+
class Delete(SQLCommandExecutable):
|
|
294
|
+
def __init__(self, database: EasyDatabase, table: EasyTable = None, where: Where = None):
|
|
295
|
+
self._database = database
|
|
296
|
+
self._table = table
|
|
297
|
+
self._where = where
|
|
298
|
+
|
|
299
|
+
def _asserts(self, safety: bool = True):
|
|
300
|
+
if self._table is None:
|
|
301
|
+
raise MissingArgumentException('Table is missing.')
|
|
302
|
+
|
|
303
|
+
if self._database.safe:
|
|
304
|
+
if self._where is None and safety:
|
|
305
|
+
raise DatabaseSafetyException('Safety Warning: Delete without any condition is prohibited.')
|
|
306
|
+
|
|
307
|
+
def where(self, where: Where):
|
|
308
|
+
self._where = self._where or where
|
|
309
|
+
return self
|
|
310
|
+
|
|
311
|
+
def from_table(self, table: EasyTable):
|
|
312
|
+
self._table = self._table or table
|
|
313
|
+
return self
|
|
314
|
+
|
|
315
|
+
def get_value(self) -> str:
|
|
316
|
+
self._asserts(safety=False)
|
|
317
|
+
return f"DELETE FROM {self._table.name}" + f' {self._where.get_value()};' if self._where else ";"
|
|
318
|
+
|
|
319
|
+
def execute(self):
|
|
320
|
+
self._asserts()
|
|
321
|
+
command = self.get_value()
|
|
322
|
+
return self._database.execute(command).lastrowid
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class MissingArgumentException(Exception):
|
|
2
|
+
def __init__(self, message):
|
|
3
|
+
self.message = message
|
|
4
|
+
|
|
5
|
+
def __repr__(self):
|
|
6
|
+
return f'<MissingArgumentException "{self.message}">'
|
|
7
|
+
|
|
8
|
+
def __str__(self):
|
|
9
|
+
return self.message
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MisMatchException(Exception):
|
|
13
|
+
def __init__(self, message):
|
|
14
|
+
self.message = message
|
|
15
|
+
|
|
16
|
+
def __repr__(self):
|
|
17
|
+
return f'<MisMatchException "{self.message}">'
|
|
18
|
+
|
|
19
|
+
def __str__(self):
|
|
20
|
+
return self.message
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DatabaseSafetyException(Exception):
|
|
24
|
+
def __init__(self, message):
|
|
25
|
+
self.message = message
|
|
26
|
+
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
return f'<DatabaseSafetyException "{self.message}">'
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
return self.message
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
logger = logging.getLogger('EasySQL')
|
|
5
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
6
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
7
|
+
handler.setFormatter(formatter)
|
|
8
|
+
logger.addHandler(handler)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def enable_debug():
|
|
12
|
+
logger.setLevel(logging.DEBUG)
|
|
13
|
+
handler.setLevel(logging.DEBUG)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def disable_debug():
|
|
17
|
+
logger.setLevel(logging.INFO)
|
|
18
|
+
handler.setLevel(logging.INFO)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from .ABC import SQLType
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class INTEGER(SQLType):
|
|
5
|
+
@property
|
|
6
|
+
def name(self):
|
|
7
|
+
return 'INT'
|
|
8
|
+
|
|
9
|
+
def parse(self, value):
|
|
10
|
+
return f'{int(value)}'
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def default(self):
|
|
14
|
+
return 0
|
|
15
|
+
|
|
16
|
+
def cast(self, value):
|
|
17
|
+
return int(value)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class STRING(SQLType):
|
|
21
|
+
def __init__(self, size: int = 255):
|
|
22
|
+
self.size = size
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def name(self):
|
|
26
|
+
return f'VARCHAR({self.size})'
|
|
27
|
+
|
|
28
|
+
def parse(self, value):
|
|
29
|
+
return f"'{str(value)}'"
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def default(self):
|
|
33
|
+
return ''
|
|
34
|
+
|
|
35
|
+
def cast(self, value):
|
|
36
|
+
return str(value)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BIT(SQLType):
|
|
40
|
+
def __init__(self, size: int = 1):
|
|
41
|
+
self.size = size
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def name(self):
|
|
45
|
+
return f'BIT({self.size})'
|
|
46
|
+
|
|
47
|
+
def parse(self, value):
|
|
48
|
+
return f'{int(value)}'
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def default(self):
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
def cast(self, value):
|
|
55
|
+
return int(value)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class FLOAT(SQLType):
|
|
59
|
+
@property
|
|
60
|
+
def name(self):
|
|
61
|
+
return 'FLOAT'
|
|
62
|
+
|
|
63
|
+
def parse(self, value):
|
|
64
|
+
return f'{float(value)}'
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def default(self):
|
|
68
|
+
return 0
|
|
69
|
+
|
|
70
|
+
def cast(self, value):
|
|
71
|
+
return float(value)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class DOUBLE(SQLType):
|
|
75
|
+
def __init__(self, size: int = 12, dec: int = 6):
|
|
76
|
+
self.size = size
|
|
77
|
+
self.dec = dec
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def name(self):
|
|
81
|
+
return f'DOUBLE({self.size},{self.dec})'
|
|
82
|
+
|
|
83
|
+
def parse(self, value):
|
|
84
|
+
return f'{float(value)}'
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def default(self):
|
|
88
|
+
return 0
|
|
89
|
+
|
|
90
|
+
def cast(self, value):
|
|
91
|
+
return float(value)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class DECIMAL(SQLType):
|
|
95
|
+
def __init__(self, size: int = 12, dec: int = 6):
|
|
96
|
+
self.size = size
|
|
97
|
+
self.dec = dec
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def name(self):
|
|
101
|
+
return f'DECIMAL({self.size},{self.dec})'
|
|
102
|
+
|
|
103
|
+
def parse(self, value):
|
|
104
|
+
return f'{float(value)}'
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def default(self):
|
|
108
|
+
return 0
|
|
109
|
+
|
|
110
|
+
def cast(self, value):
|
|
111
|
+
return float(value)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class BOOL(SQLType):
|
|
115
|
+
@property
|
|
116
|
+
def name(self):
|
|
117
|
+
return f'BIT(1)'
|
|
118
|
+
|
|
119
|
+
def parse(self, value):
|
|
120
|
+
return f'1' if value else f'0'
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def default(self):
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
def cast(self, value):
|
|
127
|
+
return True if value else False
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
INT = INTEGER
|
|
131
|
+
DEC = DECIMAL
|
|
132
|
+
VARCHAR = STRING
|
|
133
|
+
CHAR = STRING
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from .ABC import SQLCommand
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Where(SQLCommand):
|
|
5
|
+
def __init__(self, sql_string):
|
|
6
|
+
self.value = sql_string
|
|
7
|
+
|
|
8
|
+
def get_value(self) -> str:
|
|
9
|
+
return f'WHERE {self.value}'
|
|
10
|
+
|
|
11
|
+
def AND(self, other: 'Where'):
|
|
12
|
+
return Where(f'({self.value} AND {other.value})')
|
|
13
|
+
|
|
14
|
+
def OR(self, other: 'Where'):
|
|
15
|
+
return Where(f'({self.value} OR {other.value})')
|
|
16
|
+
|
|
17
|
+
def NOT(self):
|
|
18
|
+
return Where(f'NOT {self.value}')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class WhereIsEqual(Where):
|
|
22
|
+
def __init__(self, column, value):
|
|
23
|
+
super().__init__(f'{column.name} = {column.parse(value)}')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class WhereIsNotEqual(Where):
|
|
27
|
+
def __init__(self, column, value):
|
|
28
|
+
super().__init__(f'{column.name} <> {column.parse(value)}')
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class WhereIsGreater(Where):
|
|
32
|
+
def __init__(self, column, value):
|
|
33
|
+
super().__init__(f'{column.name} > {column.parse(value)}')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WhereIsGreaterEqual(Where):
|
|
37
|
+
def __init__(self, column, value):
|
|
38
|
+
super().__init__(f'{column.name} => {column.parse(value)}')
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class WhereIsLesser(Where):
|
|
42
|
+
def __init__(self, column, value):
|
|
43
|
+
super().__init__(f'{column.name} < {column.parse(value)}')
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class WhereIsLesserEqual(Where):
|
|
47
|
+
def __init__(self, column, value):
|
|
48
|
+
super().__init__(f'{column.name} =< {column.parse(value)}')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class WhereIsLike(Where):
|
|
52
|
+
def __init__(self, column, value):
|
|
53
|
+
super().__init__(f'{column.name} LIKE {column.parse(value)}')
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class WhereIsIn(Where):
|
|
57
|
+
def __init__(self, column, values):
|
|
58
|
+
values = (column.parse(value) for value in values)
|
|
59
|
+
super().__init__(f'{column.name} IN {values}')
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class WhereIsBetween(Where):
|
|
63
|
+
def __init__(self, column, a, b):
|
|
64
|
+
values = (column.parse(a), column.parse(b))
|
|
65
|
+
super().__init__(f'{column.name} = {values}')
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
__all__ = ['Where', 'WhereIsEqual', 'WhereIsNotEqual', 'WhereIsGreater', 'WhereIsLesser',
|
|
69
|
+
'WhereIsGreaterEqual', 'WhereIsLesserEqual', 'WhereIsLike', 'WhereIsIn', 'WhereIsBetween']
|
PyEasySQL-1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: PyEasySQL
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: SQL Database management without even a SQL line
|
|
5
|
+
Home-page: https://github.com/ashengaurd/easysql
|
|
6
|
+
Author: Ashenguard
|
|
7
|
+
Author-email: Ashenguard@agmdev.com
|
|
8
|
+
License: MIT License
|
|
9
|
+
Description: # EasySQL
|
|
10
|
+
This library allow you to run SQL Databases without knowing even SQL.
|
|
11
|
+
This library will create SQL queries and execute them as you request and is very simple to use.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## How to install
|
|
15
|
+
To install just use following command
|
|
16
|
+
```shell
|
|
17
|
+
pip install EasySQL
|
|
18
|
+
```
|
|
19
|
+
This library will have dev/beta builds on the github, to install them you can use
|
|
20
|
+
```shell
|
|
21
|
+
pip install --upgrade git+https://github.com/Ashengaurd/EasySQL.git
|
|
22
|
+
```
|
|
23
|
+
***
|
|
24
|
+
By installing this library following libraries and their dependencies will be installed too.
|
|
25
|
+
> mysql-connector: Which is the basic library for connecting to database
|
|
26
|
+
|
|
27
|
+
# Examples
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import EasySQL
|
|
31
|
+
|
|
32
|
+
# Define database which will be needed by any table you create.
|
|
33
|
+
database = EasySQL.EasyDatabase(host='127.0.0.1', port=3306,
|
|
34
|
+
database='DatabaseName',
|
|
35
|
+
user='username', password='PASSWORD')
|
|
36
|
+
|
|
37
|
+
# Define tables and columns
|
|
38
|
+
col1 = EasySQL.EasyColumn('ID', EasySQL.INT(), primary=True, auto_increment=True)
|
|
39
|
+
col2 = EasySQL.EasyColumn('Name', EasySQL.STRING(256), not_null=True, default='Missing')
|
|
40
|
+
col3 = EasySQL.EasyColumn('Premium', EasySQL.BOOL(), not_null=True)
|
|
41
|
+
|
|
42
|
+
table = EasySQL.EasyTable(database, 'Users', [col1, col2, col3])
|
|
43
|
+
|
|
44
|
+
# Insert values with a simple command
|
|
45
|
+
table.insert({'Name': 'Ashenguard', 'Premium': True})
|
|
46
|
+
table.insert({col2: 'Sam', col3: False})
|
|
47
|
+
|
|
48
|
+
# Select data with another simple command
|
|
49
|
+
# It will return a list of tuples which meet conditions
|
|
50
|
+
all = table.select()
|
|
51
|
+
premiums = table.select(['ID', 'Name'], EasySQL.WhereIsEqual(col3, True))
|
|
52
|
+
specific = table.select(['Name'], where=EasySQL.WhereIsLike(col2, "Ash%").AND(EasySQL.WhereIsLesserEqual(col1, 5)))
|
|
53
|
+
|
|
54
|
+
# Delete data with a more simpler command
|
|
55
|
+
table.delete(EasySQL.WhereIsGreater(col1, 5))
|
|
56
|
+
|
|
57
|
+
# Update data with following command
|
|
58
|
+
table.update({'Premium': True}, EasySQL.WhereIsEqual(col1, 3).OR(EasySQL.WhereIsEqual(col2, 'Sam')))
|
|
59
|
+
|
|
60
|
+
# Not sure if you should update or insert? Use set and it will be handled
|
|
61
|
+
table.set({'ID': 5, 'Name': 'Nathaniel', 'Premium': False}, where=EasySQL.WhereIsEqual(col1, 5))
|
|
62
|
+
|
|
63
|
+
# Safety error on delete/update/set without a where statement
|
|
64
|
+
# table.delete() -> raise EasySQL.DatabaseSafetyException
|
|
65
|
+
# Turn the safety off with following command.
|
|
66
|
+
database.remove_safety(confirm=True)
|
|
67
|
+
# Now there will be no error, it will clean the all data that's why we had safety lock
|
|
68
|
+
table.delete()
|
|
69
|
+
```
|
|
70
|
+
Platform: UNKNOWN
|
|
71
|
+
Classifier: Programming Language :: Python :: 3
|
|
72
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
73
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
74
|
+
Classifier: Operating System :: OS Independent
|
|
75
|
+
Requires-Python: >=3.6
|
|
76
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: PyEasySQL
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: SQL Database management without even a SQL line
|
|
5
|
+
Home-page: https://github.com/ashengaurd/easysql
|
|
6
|
+
Author: Ashenguard
|
|
7
|
+
Author-email: Ashenguard@agmdev.com
|
|
8
|
+
License: MIT License
|
|
9
|
+
Description: # EasySQL
|
|
10
|
+
This library allow you to run SQL Databases without knowing even SQL.
|
|
11
|
+
This library will create SQL queries and execute them as you request and is very simple to use.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## How to install
|
|
15
|
+
To install just use following command
|
|
16
|
+
```shell
|
|
17
|
+
pip install EasySQL
|
|
18
|
+
```
|
|
19
|
+
This library will have dev/beta builds on the github, to install them you can use
|
|
20
|
+
```shell
|
|
21
|
+
pip install --upgrade git+https://github.com/Ashengaurd/EasySQL.git
|
|
22
|
+
```
|
|
23
|
+
***
|
|
24
|
+
By installing this library following libraries and their dependencies will be installed too.
|
|
25
|
+
> mysql-connector: Which is the basic library for connecting to database
|
|
26
|
+
|
|
27
|
+
# Examples
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import EasySQL
|
|
31
|
+
|
|
32
|
+
# Define database which will be needed by any table you create.
|
|
33
|
+
database = EasySQL.EasyDatabase(host='127.0.0.1', port=3306,
|
|
34
|
+
database='DatabaseName',
|
|
35
|
+
user='username', password='PASSWORD')
|
|
36
|
+
|
|
37
|
+
# Define tables and columns
|
|
38
|
+
col1 = EasySQL.EasyColumn('ID', EasySQL.INT(), primary=True, auto_increment=True)
|
|
39
|
+
col2 = EasySQL.EasyColumn('Name', EasySQL.STRING(256), not_null=True, default='Missing')
|
|
40
|
+
col3 = EasySQL.EasyColumn('Premium', EasySQL.BOOL(), not_null=True)
|
|
41
|
+
|
|
42
|
+
table = EasySQL.EasyTable(database, 'Users', [col1, col2, col3])
|
|
43
|
+
|
|
44
|
+
# Insert values with a simple command
|
|
45
|
+
table.insert({'Name': 'Ashenguard', 'Premium': True})
|
|
46
|
+
table.insert({col2: 'Sam', col3: False})
|
|
47
|
+
|
|
48
|
+
# Select data with another simple command
|
|
49
|
+
# It will return a list of tuples which meet conditions
|
|
50
|
+
all = table.select()
|
|
51
|
+
premiums = table.select(['ID', 'Name'], EasySQL.WhereIsEqual(col3, True))
|
|
52
|
+
specific = table.select(['Name'], where=EasySQL.WhereIsLike(col2, "Ash%").AND(EasySQL.WhereIsLesserEqual(col1, 5)))
|
|
53
|
+
|
|
54
|
+
# Delete data with a more simpler command
|
|
55
|
+
table.delete(EasySQL.WhereIsGreater(col1, 5))
|
|
56
|
+
|
|
57
|
+
# Update data with following command
|
|
58
|
+
table.update({'Premium': True}, EasySQL.WhereIsEqual(col1, 3).OR(EasySQL.WhereIsEqual(col2, 'Sam')))
|
|
59
|
+
|
|
60
|
+
# Not sure if you should update or insert? Use set and it will be handled
|
|
61
|
+
table.set({'ID': 5, 'Name': 'Nathaniel', 'Premium': False}, where=EasySQL.WhereIsEqual(col1, 5))
|
|
62
|
+
|
|
63
|
+
# Safety error on delete/update/set without a where statement
|
|
64
|
+
# table.delete() -> raise EasySQL.DatabaseSafetyException
|
|
65
|
+
# Turn the safety off with following command.
|
|
66
|
+
database.remove_safety(confirm=True)
|
|
67
|
+
# Now there will be no error, it will clean the all data that's why we had safety lock
|
|
68
|
+
table.delete()
|
|
69
|
+
```
|
|
70
|
+
Platform: UNKNOWN
|
|
71
|
+
Classifier: Programming Language :: Python :: 3
|
|
72
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
73
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
74
|
+
Classifier: Operating System :: OS Independent
|
|
75
|
+
Requires-Python: >=3.6
|
|
76
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
EasySQL/ABC.py
|
|
4
|
+
EasySQL/Classes.py
|
|
5
|
+
EasySQL/Exceptions.py
|
|
6
|
+
EasySQL/Logging.py
|
|
7
|
+
EasySQL/Types.py
|
|
8
|
+
EasySQL/Where.py
|
|
9
|
+
EasySQL/__init__.py
|
|
10
|
+
PyEasySQL.egg-info/PKG-INFO
|
|
11
|
+
PyEasySQL.egg-info/SOURCES.txt
|
|
12
|
+
PyEasySQL.egg-info/dependency_links.txt
|
|
13
|
+
PyEasySQL.egg-info/requires.txt
|
|
14
|
+
PyEasySQL.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mysql-connector
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
EasySQL
|
PyEasySQL-1.0/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# EasySQL
|
|
2
|
+
This library allow you to run SQL Databases without knowing even SQL.
|
|
3
|
+
This library will create SQL queries and execute them as you request and is very simple to use.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## How to install
|
|
7
|
+
To install just use following command
|
|
8
|
+
```shell
|
|
9
|
+
pip install EasySQL
|
|
10
|
+
```
|
|
11
|
+
This library will have dev/beta builds on the github, to install them you can use
|
|
12
|
+
```shell
|
|
13
|
+
pip install --upgrade git+https://github.com/Ashengaurd/EasySQL.git
|
|
14
|
+
```
|
|
15
|
+
***
|
|
16
|
+
By installing this library following libraries and their dependencies will be installed too.
|
|
17
|
+
> mysql-connector: Which is the basic library for connecting to database
|
|
18
|
+
|
|
19
|
+
# Examples
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
import EasySQL
|
|
23
|
+
|
|
24
|
+
# Define database which will be needed by any table you create.
|
|
25
|
+
database = EasySQL.EasyDatabase(host='127.0.0.1', port=3306,
|
|
26
|
+
database='DatabaseName',
|
|
27
|
+
user='username', password='PASSWORD')
|
|
28
|
+
|
|
29
|
+
# Define tables and columns
|
|
30
|
+
col1 = EasySQL.EasyColumn('ID', EasySQL.INT(), primary=True, auto_increment=True)
|
|
31
|
+
col2 = EasySQL.EasyColumn('Name', EasySQL.STRING(256), not_null=True, default='Missing')
|
|
32
|
+
col3 = EasySQL.EasyColumn('Premium', EasySQL.BOOL(), not_null=True)
|
|
33
|
+
|
|
34
|
+
table = EasySQL.EasyTable(database, 'Users', [col1, col2, col3])
|
|
35
|
+
|
|
36
|
+
# Insert values with a simple command
|
|
37
|
+
table.insert({'Name': 'Ashenguard', 'Premium': True})
|
|
38
|
+
table.insert({col2: 'Sam', col3: False})
|
|
39
|
+
|
|
40
|
+
# Select data with another simple command
|
|
41
|
+
# It will return a list of tuples which meet conditions
|
|
42
|
+
all = table.select()
|
|
43
|
+
premiums = table.select(['ID', 'Name'], EasySQL.WhereIsEqual(col3, True))
|
|
44
|
+
specific = table.select(['Name'], where=EasySQL.WhereIsLike(col2, "Ash%").AND(EasySQL.WhereIsLesserEqual(col1, 5)))
|
|
45
|
+
|
|
46
|
+
# Delete data with a more simpler command
|
|
47
|
+
table.delete(EasySQL.WhereIsGreater(col1, 5))
|
|
48
|
+
|
|
49
|
+
# Update data with following command
|
|
50
|
+
table.update({'Premium': True}, EasySQL.WhereIsEqual(col1, 3).OR(EasySQL.WhereIsEqual(col2, 'Sam')))
|
|
51
|
+
|
|
52
|
+
# Not sure if you should update or insert? Use set and it will be handled
|
|
53
|
+
table.set({'ID': 5, 'Name': 'Nathaniel', 'Premium': False}, where=EasySQL.WhereIsEqual(col1, 5))
|
|
54
|
+
|
|
55
|
+
# Safety error on delete/update/set without a where statement
|
|
56
|
+
# table.delete() -> raise EasySQL.DatabaseSafetyException
|
|
57
|
+
# Turn the safety off with following command.
|
|
58
|
+
database.remove_safety(confirm=True)
|
|
59
|
+
# Now there will be no error, it will clean the all data that's why we had safety lock
|
|
60
|
+
table.delete()
|
|
61
|
+
```
|
PyEasySQL-1.0/setup.cfg
ADDED
PyEasySQL-1.0/setup.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setuptools.setup(
|
|
7
|
+
name="PyEasySQL",
|
|
8
|
+
version="1.0",
|
|
9
|
+
license='MIT License',
|
|
10
|
+
author="Ashenguard",
|
|
11
|
+
author_email="Ashenguard@agmdev.com",
|
|
12
|
+
description="SQL Database management without even a SQL line",
|
|
13
|
+
long_description=long_description,
|
|
14
|
+
long_description_content_type="text/markdown",
|
|
15
|
+
url="https://github.com/ashengaurd/easysql",
|
|
16
|
+
packages=setuptools.find_packages(),
|
|
17
|
+
classifiers=[
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Development Status :: 5 - Production/Stable",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
],
|
|
23
|
+
python_requires='>=3.6',
|
|
24
|
+
include_package_data=True,
|
|
25
|
+
install_requires=["mysql-connector"],
|
|
26
|
+
)
|