cloudoll 2.4.0__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.
- cloudoll/__init__.py +1 -0
- cloudoll/__main__.py +4 -0
- cloudoll/cli.py +76 -0
- cloudoll/error/__init__.py +0 -0
- cloudoll/error/errors.py +48 -0
- cloudoll/logging/__init__.py +188 -0
- cloudoll/mail/__init__.py +0 -0
- cloudoll/mail/smtp.py +197 -0
- cloudoll/orm/__init__.py +252 -0
- cloudoll/orm/base.py +80 -0
- cloudoll/orm/err.py +2 -0
- cloudoll/orm/field.py +522 -0
- cloudoll/orm/model.py +806 -0
- cloudoll/orm/mysql.py +84 -0
- cloudoll/orm/parse.py +139 -0
- cloudoll/orm/postgres.py +70 -0
- cloudoll/robot/__init__.py +0 -0
- cloudoll/robot/dingtalk.py +209 -0
- cloudoll/robot/feishu.py +102 -0
- cloudoll/robot/slack.py +115 -0
- cloudoll/utils/__init__.py +0 -0
- cloudoll/utils/cli_main.py +72 -0
- cloudoll/utils/cli_mian.py +74 -0
- cloudoll/utils/common.py +57 -0
- cloudoll/utils/m2d.py +311 -0
- cloudoll/utils/patch_loop.py +222 -0
- cloudoll/utils/snowflake.py +86 -0
- cloudoll/utils/watch.py +194 -0
- cloudoll/web/__init__.py +53 -0
- cloudoll/web/core.py +557 -0
- cloudoll/web/exception.py +63 -0
- cloudoll/web/html.py +93 -0
- cloudoll/web/http.py +79 -0
- cloudoll/web/jwt.py +40 -0
- cloudoll/web/requests.py +161 -0
- cloudoll/web/settings.py +22 -0
- cloudoll-2.4.0.dist-info/METADATA +414 -0
- cloudoll-2.4.0.dist-info/RECORD +42 -0
- cloudoll-2.4.0.dist-info/WHEEL +6 -0
- cloudoll-2.4.0.dist-info/entry_points.txt +2 -0
- cloudoll-2.4.0.dist-info/licenses/LICENSE +21 -0
- cloudoll-2.4.0.dist-info/top_level.txt +1 -0
cloudoll/orm/field.py
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
class objdict(dict):
|
|
2
|
+
def __getattr__(self, attr):
|
|
3
|
+
try:
|
|
4
|
+
return self[attr]
|
|
5
|
+
except KeyError:
|
|
6
|
+
raise AttributeError(attr)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
OP = objdict(
|
|
10
|
+
AND="AND",
|
|
11
|
+
OR="OR",
|
|
12
|
+
ADD="+",
|
|
13
|
+
SUB="-",
|
|
14
|
+
MUL="*",
|
|
15
|
+
DIV="/",
|
|
16
|
+
BIN_AND="&",
|
|
17
|
+
BIN_OR="|",
|
|
18
|
+
XOR="#",
|
|
19
|
+
MOD="%",
|
|
20
|
+
EQ="=",
|
|
21
|
+
LT="<",
|
|
22
|
+
LTE="<=",
|
|
23
|
+
GT=">",
|
|
24
|
+
GTE=">=",
|
|
25
|
+
NE="!=",
|
|
26
|
+
IN="IN",
|
|
27
|
+
NOT_IN="NOT IN",
|
|
28
|
+
IS="IS",
|
|
29
|
+
DESC="DESC",
|
|
30
|
+
ASC="ASC",
|
|
31
|
+
AVG="AVG",
|
|
32
|
+
AS="AS",
|
|
33
|
+
SUM="SUM",
|
|
34
|
+
MAX="MAX",
|
|
35
|
+
MIN="MIN",
|
|
36
|
+
IS_TODAY="IS_TODAY",
|
|
37
|
+
IS_THIS_WEEK="THIS_WEEK",
|
|
38
|
+
IS_THIS_MONTH="THIS_MONTH",
|
|
39
|
+
IS_THIS_YEAR="THIS_YEAR",
|
|
40
|
+
LASTED_HOURS="LASTED_HOURS",
|
|
41
|
+
LASTED_MINUTES="LASTED_MINUTES",
|
|
42
|
+
LASTED_SECONDS="LASTED_SECONDS",
|
|
43
|
+
LASTED_YEARS="LASTED_YEARS",
|
|
44
|
+
LASTED_MONTHS="LASTED_MONTHS",
|
|
45
|
+
LASTED_DAYS="LASTED_DAYS",
|
|
46
|
+
BEFORE_YEARS="BEFORE_YEARS",
|
|
47
|
+
BEFORE_MONTHS="BEFORE_MONTHS",
|
|
48
|
+
BEFORE_DAYS="BEFORE_DAYS",
|
|
49
|
+
BEFORE_HOURS="BEFORE_HOURS",
|
|
50
|
+
BEFORE_MINUTES="BEFORE_MINUTES",
|
|
51
|
+
BEFORE_SECONDS="BEFORE_SECONDS",
|
|
52
|
+
DATE_FORMAT="DATE_FORMAT",
|
|
53
|
+
JSON_CONTAINS_OBJECT="JSON_CONTAINS_OBJECT",
|
|
54
|
+
JSON_CONTAINS_ARRAY="JSON_CONTAINS_ARRAY",
|
|
55
|
+
COUNT="COUNT",
|
|
56
|
+
COUNT_WHEN="COUNT_WHEN",
|
|
57
|
+
SUM_WHEN="SUM_WHEN",
|
|
58
|
+
MAX_WHEN="MAX_WHEN",
|
|
59
|
+
MIN_WHEN="MIN_WHEN",
|
|
60
|
+
AVG_WHEN="AVG_WHEN",
|
|
61
|
+
IS_NOT="IS NOT",
|
|
62
|
+
IS_NOT_NULL="IS NOT NULL",
|
|
63
|
+
IS_NULL="IS NULL",
|
|
64
|
+
LIKE="LIKE",
|
|
65
|
+
NOT_LIKE="NOT LIKE",
|
|
66
|
+
ILIKE="ILIKE",
|
|
67
|
+
BETWEEN="BETWEEN",
|
|
68
|
+
CONTAINS="CONTAINS",
|
|
69
|
+
NOT_BETWEEN="NOT BETWEEN",
|
|
70
|
+
REGEXP="REGEXP",
|
|
71
|
+
IREGEXP="IREGEXP",
|
|
72
|
+
GROUP_CONCAT="GROUP_CONCAT",
|
|
73
|
+
DISTINCT="DISTINCT",
|
|
74
|
+
CONCAT="||",
|
|
75
|
+
BITWISE_NEGATION="~",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FieldBase(object):
|
|
80
|
+
def _op(op, inverse=False):
|
|
81
|
+
def inner(self, rhs):
|
|
82
|
+
if inverse:
|
|
83
|
+
return Expression(rhs, op, self)
|
|
84
|
+
return Expression(self, op, rhs)
|
|
85
|
+
|
|
86
|
+
return inner
|
|
87
|
+
|
|
88
|
+
def __eq__(self, rhs):
|
|
89
|
+
return Expression(self, OP.EQ, rhs)
|
|
90
|
+
|
|
91
|
+
def __ne__(self, rhs):
|
|
92
|
+
return Expression(self, OP.NE, rhs)
|
|
93
|
+
|
|
94
|
+
__lt__ = _op(OP.LT) # <
|
|
95
|
+
__le__ = _op(OP.LTE) # <=
|
|
96
|
+
__gt__ = _op(OP.GT) # >
|
|
97
|
+
__ge__ = _op(OP.GTE) # >=
|
|
98
|
+
__and__ = _op(OP.AND) # and
|
|
99
|
+
__or__ = _op(OP.OR) # or
|
|
100
|
+
|
|
101
|
+
# 运算
|
|
102
|
+
__add__ = _op(OP.ADD) # +
|
|
103
|
+
__radd__ = _op(OP.ADD, True) # +=
|
|
104
|
+
__sub__ = _op(OP.SUB) # -
|
|
105
|
+
__rsub__ = _op(OP.SUB, True) # -=
|
|
106
|
+
__mul__ = _op(OP.MUL) # *
|
|
107
|
+
__rmul__ = _op(OP.MUL, True) # *=
|
|
108
|
+
__div__ = _op(OP.DIV) # /
|
|
109
|
+
__rdiv__ = _op(OP.DIV, True) # /=
|
|
110
|
+
|
|
111
|
+
In = _op(OP.IN) # in
|
|
112
|
+
not_in = _op(OP.NOT_IN) # not in
|
|
113
|
+
like = _op(OP.LIKE) # like
|
|
114
|
+
ilike = _op(OP.ILIKE) # ilike for pg
|
|
115
|
+
not_like = _op(OP.NOT_LIKE) # not like
|
|
116
|
+
|
|
117
|
+
def group_concat(self, *arg):
|
|
118
|
+
return Function(self, OP.GROUP_CONCAT, arg)
|
|
119
|
+
|
|
120
|
+
def distinct(self, *arg):
|
|
121
|
+
return Function(self, OP.DISTINCT, arg)
|
|
122
|
+
|
|
123
|
+
def desc(self):
|
|
124
|
+
return Expression(self, OP.DESC, None)
|
|
125
|
+
|
|
126
|
+
def asc(self):
|
|
127
|
+
return Expression(self, OP.ASC, None)
|
|
128
|
+
|
|
129
|
+
def count(self):
|
|
130
|
+
return Function(self, OP.COUNT)
|
|
131
|
+
|
|
132
|
+
def count_when(self, *arg):
|
|
133
|
+
"""
|
|
134
|
+
input: count_when(A.field > 10 ,1 , 0) \n
|
|
135
|
+
output: count(case when A.field > 10 then 1 else 0 end)
|
|
136
|
+
"""
|
|
137
|
+
return Function(self, OP.COUNT_WHEN, arg)
|
|
138
|
+
|
|
139
|
+
def max(self):
|
|
140
|
+
return Function(self, OP.MAX)
|
|
141
|
+
|
|
142
|
+
def max_when(self, *arg):
|
|
143
|
+
"""
|
|
144
|
+
input: max_when(A.field > 10 ,A.field) \n
|
|
145
|
+
output: max(case when A.field > 10 then A.field end)
|
|
146
|
+
"""
|
|
147
|
+
return Function(self, OP.MAX_WHEN, arg)
|
|
148
|
+
|
|
149
|
+
def min(self):
|
|
150
|
+
return Function(self, OP.MIN)
|
|
151
|
+
|
|
152
|
+
def min_when(self, *arg):
|
|
153
|
+
"""
|
|
154
|
+
input: min_when(A.field > 10 ,A.field) \n
|
|
155
|
+
output: min(case when A.field > 10 then A.field end)
|
|
156
|
+
"""
|
|
157
|
+
return Function(self, OP.MIN_WHEN, arg)
|
|
158
|
+
|
|
159
|
+
def sum(self):
|
|
160
|
+
return Function(self, OP.SUM)
|
|
161
|
+
|
|
162
|
+
def sum_when(self, *arg):
|
|
163
|
+
"""
|
|
164
|
+
input: sum_when(A.field > 10 ,1 , 0)\n
|
|
165
|
+
output: sum(case when A.field > 10 then 1 else 0 end)
|
|
166
|
+
"""
|
|
167
|
+
return Function(self, OP.SUM_WHEN, arg)
|
|
168
|
+
|
|
169
|
+
def avg(self):
|
|
170
|
+
return Function(self, OP.AVG)
|
|
171
|
+
|
|
172
|
+
def avg_when(self, *arg):
|
|
173
|
+
"""
|
|
174
|
+
input: avg_when(A.field > 10 , A.field)\n
|
|
175
|
+
output: avg(case when A.field > 10 then A.field end)
|
|
176
|
+
"""
|
|
177
|
+
return Function(self, OP.AVG_WHEN, arg)
|
|
178
|
+
|
|
179
|
+
def date_format(self, args):
|
|
180
|
+
return Function(self, OP.DATE_FORMAT, args)
|
|
181
|
+
|
|
182
|
+
def is_today(self):
|
|
183
|
+
return Function(self, OP.IS_TODAY)
|
|
184
|
+
|
|
185
|
+
def is_this_week(self):
|
|
186
|
+
return Function(self, OP.IS_THIS_WEEK)
|
|
187
|
+
|
|
188
|
+
def is_this_month(self):
|
|
189
|
+
return Function(self, OP.IS_THIS_MONTH)
|
|
190
|
+
|
|
191
|
+
def is_this_year(self):
|
|
192
|
+
return Function(self, OP.IS_THIS_YEAR)
|
|
193
|
+
|
|
194
|
+
def lasted_hours(self, args):
|
|
195
|
+
return Function(self, OP.LASTED_HOURS, args)
|
|
196
|
+
|
|
197
|
+
def lasted_minutes(self, args):
|
|
198
|
+
return Function(self, OP.LASTED_MINUTES, args)
|
|
199
|
+
|
|
200
|
+
def lasted_seconds(self, args):
|
|
201
|
+
return Function(self, OP.LASTED_SECONDS, args)
|
|
202
|
+
|
|
203
|
+
def lasted_years(self, args):
|
|
204
|
+
return Function(self, OP.LASTED_YEARS, args)
|
|
205
|
+
|
|
206
|
+
def lasted_months(self, args):
|
|
207
|
+
return Function(self, OP.LASTED_MONTHS, args)
|
|
208
|
+
|
|
209
|
+
def lasted_days(self, args):
|
|
210
|
+
return Function(self, OP.LASTED_DAYS, args)
|
|
211
|
+
|
|
212
|
+
def before_months(self, args):
|
|
213
|
+
return Function(self, OP.BEFORE_MONTHS, args)
|
|
214
|
+
|
|
215
|
+
def before_years(self, args):
|
|
216
|
+
return Function(self, OP.BEFORE_YEARS, args)
|
|
217
|
+
|
|
218
|
+
def before_days(self, args):
|
|
219
|
+
return Function(self, OP.BEFORE_DAYS, args)
|
|
220
|
+
|
|
221
|
+
def before_hours(self, args):
|
|
222
|
+
return Function(self, OP.BEFORE_HOURS, args)
|
|
223
|
+
|
|
224
|
+
def before_minutes(self, args):
|
|
225
|
+
return Function(self, OP.BEFORE_MINUTES, args)
|
|
226
|
+
|
|
227
|
+
def before_seconds(self, args):
|
|
228
|
+
return Function(self, OP.BEFORE_SECOBDS, args)
|
|
229
|
+
|
|
230
|
+
def json_contains_object(self, key, value):
|
|
231
|
+
return Function(self, OP.JSON_CONTAINS_OBJECT, (key, value))
|
|
232
|
+
|
|
233
|
+
def json_contains_array(self, args):
|
|
234
|
+
return Function(self, OP.JSON_CONTAINS_ARRAY, args)
|
|
235
|
+
|
|
236
|
+
def contains(self, args):
|
|
237
|
+
return Function(self, OP.CONTAINS, args)
|
|
238
|
+
# return AO(f"contains({self.full_name},?)", args)
|
|
239
|
+
|
|
240
|
+
def As(self, args):
|
|
241
|
+
return Expression(self, OP.AS, args)
|
|
242
|
+
|
|
243
|
+
def is_null(self):
|
|
244
|
+
return Expression(self, OP.IS_NULL, None)
|
|
245
|
+
|
|
246
|
+
def not_null(self):
|
|
247
|
+
return Expression(self, OP.IS_NOT_NULL, None)
|
|
248
|
+
|
|
249
|
+
def between(self, h1, h2):
|
|
250
|
+
return Expression(self, OP.BETWEEN, ExpList(h1, OP.AND, h2))
|
|
251
|
+
|
|
252
|
+
def not_between(self, h1, h2):
|
|
253
|
+
return Expression(self, OP.NOT_BETWEEN, ExpList(h1, OP.AND, h2))
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class ExpList(FieldBase):
|
|
257
|
+
def __init__(self, lpt, op, rpt):
|
|
258
|
+
self.lpt = lpt
|
|
259
|
+
self.op = op
|
|
260
|
+
self.rpt = rpt
|
|
261
|
+
|
|
262
|
+
def sql(self):
|
|
263
|
+
lpt = self.lpt
|
|
264
|
+
rpt = self.rpt
|
|
265
|
+
|
|
266
|
+
p = []
|
|
267
|
+
q = []
|
|
268
|
+
if isinstance(lpt, Exception):
|
|
269
|
+
_q, _p = lpt.sql()
|
|
270
|
+
q = q + _q
|
|
271
|
+
p = p + _p
|
|
272
|
+
else:
|
|
273
|
+
q.append("?")
|
|
274
|
+
p.append(lpt)
|
|
275
|
+
q.append(f" {self.op} ")
|
|
276
|
+
if isinstance(rpt, Exception):
|
|
277
|
+
_q, _p = lpt.sql()
|
|
278
|
+
q = q + _q
|
|
279
|
+
p = p + _p
|
|
280
|
+
else:
|
|
281
|
+
q.append("?")
|
|
282
|
+
p.append(lpt)
|
|
283
|
+
|
|
284
|
+
return "".join(q), p
|
|
285
|
+
# return f"{lpt.sql() if isinstance(lpt,Expression) else lpt} {self.op} {rpt.sql() if isinstance(rpt,Expression) else rpt}"
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def deconstruct(args):
|
|
289
|
+
f = args[0] if len(args) > 0 else None
|
|
290
|
+
v1 = args[1] if len(args) > 1 else 1
|
|
291
|
+
v2 = args[2] if len(args) > 2 and args[2] is not None else 'NULL'
|
|
292
|
+
c = None
|
|
293
|
+
v = None
|
|
294
|
+
if isinstance(f, FieldBase):
|
|
295
|
+
c = f"{f.lhs.full_name} {f.op} ?"
|
|
296
|
+
v = f.rhs
|
|
297
|
+
if isinstance(v1, FieldBase):
|
|
298
|
+
v1 = v1.name
|
|
299
|
+
return c, v, v1, v2
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
class Function(FieldBase):
|
|
303
|
+
def __init__(self, col, op, rpt=None):
|
|
304
|
+
self.col = col
|
|
305
|
+
self.op = op
|
|
306
|
+
self.rpt = rpt
|
|
307
|
+
|
|
308
|
+
def sql(self):
|
|
309
|
+
op = self.op
|
|
310
|
+
col_name = self.col.full_name
|
|
311
|
+
is_field = isinstance(self.rpt, Field)
|
|
312
|
+
# todo:
|
|
313
|
+
if op == OP.DATE_FORMAT:
|
|
314
|
+
return f"{op}({col_name},?)", [self.rpt]
|
|
315
|
+
elif op == OP.IS_TODAY:
|
|
316
|
+
return f"DATE({col_name}) = CURDATE()", None
|
|
317
|
+
elif op == OP.IS_THIS_WEEK:
|
|
318
|
+
return f"WEEK({col_name}, 1) = WEEK(CURDATE(), 1)", None
|
|
319
|
+
elif op == OP.IS_THIS_MONTH:
|
|
320
|
+
return f"MONTH({col_name}) = MONTH(CURDATE())", None
|
|
321
|
+
elif op == OP.IS_THIS_YEAR:
|
|
322
|
+
return f"YEAR({col_name}) = YEAR(CURDATE())", None
|
|
323
|
+
|
|
324
|
+
elif op == OP.LASTED_SECONDS:
|
|
325
|
+
return f"{col_name} >= NOW() - INTERVAL {self.rpt} SECOND", None
|
|
326
|
+
elif op == OP.LASTED_MINUTES:
|
|
327
|
+
return f"{col_name} >= NOW() - INTERVAL {self.rpt} MINUTE", None
|
|
328
|
+
elif op == OP.LASTED_HOURS:
|
|
329
|
+
return f"{col_name} >= NOW() - INTERVAL {self.rpt} HOUR", None
|
|
330
|
+
elif op == OP.LASTED_YEARS:
|
|
331
|
+
return f"{col_name} >= NOW() - INTERVAL {self.rpt} YEAR", None
|
|
332
|
+
elif op == OP.LASTED_MONTHS:
|
|
333
|
+
return f"{col_name} >= NOW() - INTERVAL {self.rpt} MONTH", None
|
|
334
|
+
elif op == OP.LASTED_DAYS:
|
|
335
|
+
return f"DATE({col_name}) >= CURDATE() - INTERVAL {self.rpt} DAY", None
|
|
336
|
+
|
|
337
|
+
elif op == OP.BEFORE_YEARS:
|
|
338
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} YEAR", None
|
|
339
|
+
elif op == OP.BEFORE_MONTHS:
|
|
340
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} MONTH", None
|
|
341
|
+
elif op == OP.BEFORE_DAYS:
|
|
342
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} DAY", None
|
|
343
|
+
elif op == OP.BEFORE_HOURS:
|
|
344
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} HOUR", None
|
|
345
|
+
elif op == OP.BEFORE_MINUTES:
|
|
346
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} MINUTE", None
|
|
347
|
+
elif op == OP.BEFORE_SECONDS:
|
|
348
|
+
return f"{col_name} < NOW() - INTERVAL {self.rpt} SECOND", None
|
|
349
|
+
elif op == OP.CONTAINS:
|
|
350
|
+
return f"{col_name} LIKE CONCAT('%%',?,'%%')", [self.rpt]
|
|
351
|
+
# return f"CONTAINS({col_name},?)", [self.rpt]
|
|
352
|
+
elif op == OP.JSON_CONTAINS_OBJECT:
|
|
353
|
+
_k, _v = self.rpt
|
|
354
|
+
key = _k.full_name if isinstance(_k, Field) else f"'{_k}'"
|
|
355
|
+
return f"json_contains({col_name},json_object({key},?))", [_v]
|
|
356
|
+
elif op == OP.JSON_CONTAINS_ARRAY:
|
|
357
|
+
if is_field:
|
|
358
|
+
return f"json_contains({col_name},json_array({self.rpt.full_name}))", None
|
|
359
|
+
return f"json_contains({col_name},json_array(?))", [self.rpt]
|
|
360
|
+
elif op == OP.COUNT:
|
|
361
|
+
return f"COUNT({col_name})", None
|
|
362
|
+
elif op == OP.COUNT_WHEN:
|
|
363
|
+
c, v, v1, v2 = deconstruct(self.rpt)
|
|
364
|
+
return f"COUNT(CASE WHEN {c} THEN {v1} ELSE {v2} END)", [v]
|
|
365
|
+
elif op == OP.SUM:
|
|
366
|
+
return f"SUM({col_name})", None
|
|
367
|
+
elif op == OP.SUM_WHEN:
|
|
368
|
+
c, v, v1, v2 = deconstruct(self.rpt)
|
|
369
|
+
return f"SUM(CASE WHEN {c} THEN {v1} ELSE {v2} END)", [v]
|
|
370
|
+
elif op == OP.AVG:
|
|
371
|
+
return f"AVG({col_name})", None
|
|
372
|
+
elif op == OP.AVG_WHEN:
|
|
373
|
+
c, v, v1, v2 = deconstruct(self.rpt)
|
|
374
|
+
return f"AVG(CASE WHEN {c} THEN {v1} ELSE {v2} END)", [v]
|
|
375
|
+
elif op == OP.MAX:
|
|
376
|
+
return f"MAX({col_name})", None
|
|
377
|
+
elif op == OP.MAX_WHEN:
|
|
378
|
+
c, v, v1, v2 = deconstruct(self.rpt)
|
|
379
|
+
return f"MAX(CASE WHEN {c} THEN {v1} ELSE {v2} END)", [v]
|
|
380
|
+
elif op == OP.MIN:
|
|
381
|
+
return f"MIN({col_name})", None
|
|
382
|
+
elif op == OP.MIN_WHEN:
|
|
383
|
+
c, v, v1, v2 = deconstruct(self.rpt)
|
|
384
|
+
return f"MIN(CASE WHEN {c} THEN {v1} ELSE {v2} END)", [v]
|
|
385
|
+
elif op == OP.GROUP_CONCAT:
|
|
386
|
+
arg = self.rpt
|
|
387
|
+
extra = None
|
|
388
|
+
if len(arg) == 0:
|
|
389
|
+
extra = col_name
|
|
390
|
+
elif len(arg) == 1 and isinstance(arg[0], FieldBase):
|
|
391
|
+
extra = f"{arg[0].op} {arg[0].col.name}"
|
|
392
|
+
else:
|
|
393
|
+
# todo : DISTINCT name ORDER BY name ASC SEPARATOR '; '
|
|
394
|
+
extra = col_name
|
|
395
|
+
|
|
396
|
+
return f"GROUP_CONCAT({extra})", None
|
|
397
|
+
elif op == OP.DISTINCT:
|
|
398
|
+
return f"DISTINCT {col_name}", None
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class Expression(FieldBase):
|
|
402
|
+
def __init__(self, lhs, op, rhs):
|
|
403
|
+
self.lhs = lhs
|
|
404
|
+
self.op = op
|
|
405
|
+
self.rhs = rhs
|
|
406
|
+
# self.__value = ""
|
|
407
|
+
# if op in "+-*/|&~" and lhs._value:
|
|
408
|
+
# cal = f"{lhs._value}{op}"
|
|
409
|
+
# if isinstance(rhs, FieldBase):
|
|
410
|
+
# self.__value = str(eval(f"{cal}{rhs._value}"))
|
|
411
|
+
# else:
|
|
412
|
+
# self.__value = str(eval(f"{cal}{rhs}"))
|
|
413
|
+
|
|
414
|
+
def sql(self):
|
|
415
|
+
l = self.lhs
|
|
416
|
+
r = self.rhs
|
|
417
|
+
is_fun = isinstance(l, Function)
|
|
418
|
+
p = []
|
|
419
|
+
q = []
|
|
420
|
+
if not is_fun:
|
|
421
|
+
q.append("(")
|
|
422
|
+
if isinstance(l, Field):
|
|
423
|
+
q.append(l.full_name)
|
|
424
|
+
elif isinstance(l, Expression):
|
|
425
|
+
_q, _p = l.sql()
|
|
426
|
+
q.append(_q)
|
|
427
|
+
p = p + _p
|
|
428
|
+
elif is_fun:
|
|
429
|
+
_q, _p = l.sql()
|
|
430
|
+
q.append(_q)
|
|
431
|
+
if _p:
|
|
432
|
+
p = p + _p
|
|
433
|
+
|
|
434
|
+
q.append(f" {self.op} ")
|
|
435
|
+
|
|
436
|
+
if isinstance(r, Field):
|
|
437
|
+
if r._value is not None:
|
|
438
|
+
q.append("?")
|
|
439
|
+
p.append(r._value)
|
|
440
|
+
else:
|
|
441
|
+
q.append(r.full_name)
|
|
442
|
+
elif isinstance(r, FieldBase):
|
|
443
|
+
_q, _p = r.sql()
|
|
444
|
+
q.append(_q)
|
|
445
|
+
if _p:
|
|
446
|
+
p = p + _p
|
|
447
|
+
elif self.op == OP.AS:
|
|
448
|
+
q.append(r)
|
|
449
|
+
elif r is not None:
|
|
450
|
+
q.append("?")
|
|
451
|
+
p.append(r)
|
|
452
|
+
if not is_fun:
|
|
453
|
+
q.append(")")
|
|
454
|
+
q = [str(num) for num in q]
|
|
455
|
+
return "".join(q), p
|
|
456
|
+
|
|
457
|
+
# def __str__(self):
|
|
458
|
+
# return self.__value
|
|
459
|
+
# cal = f"{self.lhs._value}{self.op}"
|
|
460
|
+
# if isinstance(self.rhs, FieldBase):
|
|
461
|
+
# return str(eval(f"{cal}{self.rhs._value}"))
|
|
462
|
+
# return str(eval(f"{cal}{self.rhs}"))
|
|
463
|
+
|
|
464
|
+
def __repr__(self):
|
|
465
|
+
cal = f"{self.lhs.value}{self.op}"
|
|
466
|
+
if isinstance(self.rhs, FieldBase):
|
|
467
|
+
return str(eval(f"{cal}{self.rhs.value}"))
|
|
468
|
+
return str(eval(f"{cal}{self.rhs}"))
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class Field(FieldBase):
|
|
472
|
+
def __init__(
|
|
473
|
+
self,
|
|
474
|
+
name, # 列名
|
|
475
|
+
column_type, # 类型
|
|
476
|
+
default=None, # 默认值
|
|
477
|
+
primary_key=False, # 主键
|
|
478
|
+
charset=None, # 编码
|
|
479
|
+
max_length=None, # 长度
|
|
480
|
+
scale_length=None, # 精度
|
|
481
|
+
auto_increment=False, # 自增
|
|
482
|
+
NOT_NULL=False, # 非空
|
|
483
|
+
created_generated=False, # 创建时for datetime
|
|
484
|
+
update_generated=False, # 更新时for datetime
|
|
485
|
+
unsigned=False, # 无符号,没有负数
|
|
486
|
+
comment=None, # 备注
|
|
487
|
+
**kwargs,
|
|
488
|
+
):
|
|
489
|
+
super().__init__()
|
|
490
|
+
self.full_name = None
|
|
491
|
+
self._value = None
|
|
492
|
+
self.name = name
|
|
493
|
+
self.column_type = column_type
|
|
494
|
+
self.primary_key = primary_key
|
|
495
|
+
self.charset = charset
|
|
496
|
+
self.default = default
|
|
497
|
+
self.max_length = max_length
|
|
498
|
+
self.scale_length = scale_length
|
|
499
|
+
self.auto_increment = auto_increment
|
|
500
|
+
self.NOT_NULL = NOT_NULL
|
|
501
|
+
self.created_generated = created_generated
|
|
502
|
+
self.update_generated = update_generated
|
|
503
|
+
self.comment = comment
|
|
504
|
+
self.unsigned = unsigned
|
|
505
|
+
|
|
506
|
+
def __str__(self):
|
|
507
|
+
return str(self._value)
|
|
508
|
+
# "<%s, %s:%s>" % (self.__class__.__name__, self.column_type, self.name)
|
|
509
|
+
# return self.name
|
|
510
|
+
|
|
511
|
+
def __repr__(self):
|
|
512
|
+
return str(self._value)
|
|
513
|
+
|
|
514
|
+
# def __getattr__(self, item):
|
|
515
|
+
# return self[item]
|
|
516
|
+
@property
|
|
517
|
+
def value(self):
|
|
518
|
+
return self._value
|
|
519
|
+
|
|
520
|
+
@value.setter
|
|
521
|
+
def value(self, value):
|
|
522
|
+
self._value = value
|