1
1
import logging
2
2
import time
3
3
from datetime import date , datetime
4
+ from typing import Any , Dict , List , Optional
4
5
5
6
from _mysql_connector import MySQLInterfaceError
6
7
from mysql .connector .cursor import MySQLCursor
@@ -116,15 +117,16 @@ def __exit__(self, exc_type, exc_val, exc_tb):
116
117
def execute (self , sql , params = None ):
117
118
while True :
118
119
try :
119
- with self .cursor as cursor :
120
- cursor .execute (sql , params )
121
- self .connection .commit ()
122
- return cursor .lastrowid
120
+ cursor = self .cursor
121
+ cursor .execute (sql , params )
122
+ self .connection .commit ()
123
+ return cursor .lastrowid
123
124
except MySQLInterfaceError :
124
125
logger .exception (f"MysqlStore execute error<{ sql } >" )
125
126
del self .connection
126
127
except Exception as e :
127
- raise e
128
+ logger .error (f"Unexpected error during SQL execution: { e } " )
129
+ raise
128
130
129
131
130
132
class ModelMetaClass (type ):
@@ -150,13 +152,16 @@ def __new__(cls, name, bases, attrs):
150
152
151
153
class Model (metaclass = ModelMetaClass ):
152
154
def __init__ (self ):
153
- self ._where_conditions = []
154
- self ._insert_data = {}
155
- self ._update_data = {}
156
- self ._delete_flag = False
155
+ self ._where_conditions : List [str ] = []
156
+ self ._insert_data : Dict [str , Any ] = {}
157
+ self ._update_data : Dict [str , Any ] = {}
158
+ self ._delete_flag : bool = False
159
+ self ._order_by : Optional [str ] = None
160
+ self ._limit : Optional [int ] = None
161
+ self ._offset : Optional [int ] = None
157
162
158
163
@staticmethod
159
- def _format_value (value ) :
164
+ def _format_value (value : Any ) -> str :
160
165
if isinstance (value , str ):
161
166
return f"'{ value } '"
162
167
elif isinstance (value , date ):
@@ -165,7 +170,7 @@ def _format_value(value):
165
170
return f"'{ value .strftime ('%Y-%m-%d %H:%M:%S' )} '"
166
171
return value
167
172
168
- def where (self , ** kwargs ):
173
+ def where (self , ** kwargs ) -> "Model" :
169
174
for key , value in kwargs .items ():
170
175
if isinstance (value , dict ):
171
176
for operator , condition in value .items ():
@@ -180,65 +185,101 @@ def where(self, **kwargs):
180
185
181
186
return self
182
187
183
- def create (self , ** kwargs ):
188
+ def create (self , ** kwargs ) -> "Model" :
184
189
self ._insert_data = kwargs
185
190
return self
186
191
187
- def update (self , ** kwargs ):
192
+ def update (self , ** kwargs ) -> "Model" :
188
193
if not self ._where_conditions :
189
194
raise Exception ("No conditions specified" )
190
195
191
196
self ._update_data = kwargs
192
197
return self
193
198
194
- def delete (self ):
199
+ def delete (self ) -> "Model" :
195
200
if not self ._where_conditions :
196
201
raise Exception ("No conditions specified" )
197
202
198
203
self ._delete_flag = True
199
204
return self
200
205
206
+ def order_by (self , column : str , desc : bool = False ) -> "Model" :
207
+ self ._order_by = f"{ _ (column )} { 'DESC' if desc else 'ASC' } "
208
+ return self
209
+
210
+ def limit (self , limit : int ) -> "Model" :
211
+ self ._limit = limit
212
+ return self
213
+
214
+ def offset (self , offset : int ) -> "Model" :
215
+ self ._offset = offset
216
+ return self
217
+
201
218
@property
202
- def sql (self ):
219
+ def sql (self ) -> str :
203
220
if self ._insert_data :
204
221
keys = "," .join (_ (key ) for key in self ._insert_data .keys ())
205
222
values = "," .join (
206
223
f"{ self ._format_value (value )} " for value in self ._insert_data .values ()
207
224
)
208
- sql = f"INSERT INTO { _ (self .db_table )} ({ keys } ) VALUES ({ values } )"
209
- return sql
225
+ _sql = f"INSERT INTO { _ (self .db_table )} ({ keys } ) VALUES ({ values } )"
226
+ return _sql
210
227
211
228
if self ._where_conditions :
212
229
where_clause = " AND " .join (self ._where_conditions )
213
230
if self ._update_data :
214
231
set_values = ", " .join (
215
232
f"{ _ (key )} = '{ value } '" for key , value in self ._update_data .items ()
216
233
)
217
- return (
234
+ _sql = (
218
235
f"UPDATE { _ (self .db_table )} SET { set_values } WHERE { where_clause } "
219
236
)
237
+ if self ._order_by :
238
+ _sql += f" ORDER BY { self ._order_by } "
239
+ if self ._limit :
240
+ _sql += f" LIMIT { self ._limit } "
241
+ if self ._offset :
242
+ _sql += f" OFFSET { self ._offset } "
243
+ return _sql
220
244
elif self ._delete_flag :
221
- return f"DELETE FROM { _ (self .db_table )} WHERE { where_clause } "
245
+ _sql = f"DELETE FROM { _ (self .db_table )} WHERE { where_clause } "
222
246
else :
223
- return f"SELECT * FROM { _ (self .db_table )} WHERE { where_clause } "
247
+ _sql = f"SELECT * FROM { _ (self .db_table )} WHERE { where_clause } "
224
248
else :
225
- return f"SELECT * FROM { _ (self .db_table )} "
226
-
227
- def execute (self ):
249
+ _sql = f"SELECT * FROM { _ (self .db_table )} "
250
+ if self ._order_by :
251
+ _sql += f" ORDER BY { self ._order_by } "
252
+ if self ._limit :
253
+ _sql += f" LIMIT { self ._limit } "
254
+ if self ._offset :
255
+ _sql += f" OFFSET { self ._offset } "
256
+ return _sql
257
+
258
+ def execute (self ) -> int :
228
259
logger .warning (self .sql )
229
260
return self .connection .execute (self .sql )
230
261
231
- def all (self ):
262
+ def all (self ) -> List [ Dict [ str , Any ]] :
232
263
with self .connection as cursor :
233
264
cursor .execute (self .sql )
234
265
result = cursor .fetchall ()
235
266
return result
236
267
237
- def one (self ):
268
+ def one (self ) -> Optional [ Dict [ str , Any ]] :
238
269
with self .connection as cursor :
239
270
cursor .execute (self .sql )
240
271
result = cursor .fetchone ()
241
272
return result
242
273
274
+ def count (self ) -> int :
275
+ count_sql = f"SELECT COUNT(*) as count FROM { _ (self .db_table )} "
276
+ if self ._where_conditions :
277
+ count_sql += " WHERE " + " AND " .join (self ._where_conditions )
278
+
279
+ with self .connection as cursor :
280
+ cursor .execute (count_sql )
281
+ result = cursor .fetchone ()
282
+ return result ["count" ] if result else 0
283
+
243
284
def __repr__ (self ):
244
285
return f"<{ self .__class__ .__name__ } { self .sql } >"
0 commit comments