From 3f8a0ce8767fad3b6129564132ae97aa282f1379 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 18 Jun 2026 17:22:12 +0800 Subject: [PATCH] feat: CRUD auto-generates validation code from alters.rules - extract_validation_rules() extracts rules from browserfields.alters - data_new_tmpl: adds runtime validation before DB insert - data_update_tmpl: adds runtime validation before DB update - Supports: required, minlength, maxlength, min, max, pattern, email, number - Backend returns Error widget with validation messages on failure --- xls2ddl.egg-info/PKG-INFO | 8 +- xls2ddl.egg-info/entry_points.txt | 1 + xls2ddl/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 145 bytes xls2ddl/__pycache__/json2ddl.cpython-310.pyc | Bin 0 -> 2095 bytes xls2ddl/__pycache__/json2ddl.cpython-312.pyc | Bin 0 -> 3212 bytes .../__pycache__/singletree.cpython-310.pyc | Bin 0 -> 5390 bytes .../__pycache__/singletree.cpython-312.pyc | Bin 0 -> 8358 bytes xls2ddl/__pycache__/tmpls.cpython-310.pyc | Bin 10421 -> 11102 bytes xls2ddl/__pycache__/tmpls.cpython-312.pyc | Bin 0 -> 14016 bytes xls2ddl/__pycache__/xls2crud.cpython-312.pyc | Bin 0 -> 19761 bytes xls2ddl/__pycache__/xls2ddl.cpython-310.pyc | Bin 0 -> 2521 bytes xls2ddl/__pycache__/xls2ui.cpython-310.pyc | Bin 0 -> 1799 bytes xls2ddl/__pycache__/xlsxData.cpython-312.pyc | Bin 0 -> 14549 bytes xls2ddl/tmpls.py | 96 ++++++++++++++++++ xls2ddl/xls2crud.py | 15 +++ 15 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 xls2ddl/__pycache__/__init__.cpython-312.pyc create mode 100644 xls2ddl/__pycache__/json2ddl.cpython-310.pyc create mode 100644 xls2ddl/__pycache__/json2ddl.cpython-312.pyc create mode 100644 xls2ddl/__pycache__/singletree.cpython-310.pyc create mode 100644 xls2ddl/__pycache__/singletree.cpython-312.pyc create mode 100644 xls2ddl/__pycache__/tmpls.cpython-312.pyc create mode 100644 xls2ddl/__pycache__/xls2crud.cpython-312.pyc create mode 100644 xls2ddl/__pycache__/xls2ddl.cpython-310.pyc create mode 100644 xls2ddl/__pycache__/xls2ui.cpython-310.pyc create mode 100644 xls2ddl/__pycache__/xlsxData.cpython-312.pyc diff --git a/xls2ddl.egg-info/PKG-INFO b/xls2ddl.egg-info/PKG-INFO index 7069482..5e9c8ec 100644 --- a/xls2ddl.egg-info/PKG-INFO +++ b/xls2ddl.egg-info/PKG-INFO @@ -1,8 +1,12 @@ -Metadata-Version: 2.4 +Metadata-Version: 2.1 Name: xls2ddl Version: 1.1.3 Summary: a xlsx file to database ddl converter +Home-page: UNKNOWN Author: "yu moqing" Author-email: "yumoqing@gmail.com" License: "MIT" -Requires-Dist: apppublic +Platform: UNKNOWN + +UNKNOWN + diff --git a/xls2ddl.egg-info/entry_points.txt b/xls2ddl.egg-info/entry_points.txt index f00b600..bfbe0c8 100644 --- a/xls2ddl.egg-info/entry_points.txt +++ b/xls2ddl.egg-info/entry_points.txt @@ -3,3 +3,4 @@ json2ddl = xls2ddl.json2ddl:main json2xlsx = xls2ddl.json2xlsx:main xls2ddl = xls2ddl.xls2ddl:main xls2ui = xls2ddl.xls2ui:main + diff --git a/xls2ddl/__pycache__/__init__.cpython-312.pyc b/xls2ddl/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95b72b0e89bc4dea81ef724f5036cffa74d78758 GIT binary patch literal 145 zcmX@j%ge<81eTeSSs?l`h(HIQS%4zb87dhx8U0o=6fpsLpFwJV8R%!^=cejsq!#6- z7AI!v7o`^D7wcE#6dR?aTFF+URgAdLLtf=|R{4!a=UJ82 zen!z6tFs357uXVOLch*i?A%i#_W1e~K@9xRw)XNXI1PHx#yT8`Bv&1N)CFZ(9;A|s zXIyj`OFJqXq+o4iBe0*fEEOW|ru?jFWl%`f7yO->&2L7JIE0B6znAxuoI|`IO{BV? zq`XaZaOb<-yLV$1>*`S|kM74^RftiW>Tt0Y?b`LVH(yj&-mcUo<`}0>0DTqO9cc1z z5DZO7iDq!(V=QhfJOhmp<{Ue}Y)+i9ubdezont&9k5Rr(k#a{{7)>Zf_4LXyXsANIPvWmVCo}lRzbT#&gA4yP*S~GkKV(C)(>4jCZA`#enCU z+NEh)#7u|xj=FrH64;Atk)|t&OmeB>yvwyCmC&w%nbc07EA6JmA?y=~2-^@4p9|Rz zv=7+m0bsPp_S9&=H8s1}xTi4$fw-EQAR5a*kZ8lludi)CDKftOgo}*JIN25)P_qqT zZUC?sz1gTSYz;%RxbeUf|Q$X%xKp$Y#eeNEF^WI>!B!G(Gfkxs2>;fnV1@HBe zBRQs(t5-KPu8b>-LhX!6@5?q7hEMiP!lXo8G+%n!>lG|8aUEP;Xp6@Hl0vhjj$okBKHet` zGx8GXrX0|LoXmNO#3djHH9B)!$WR3QXy!5R*o=JZ0s7hAYavK4P`xThDuij?-qG4=??{f zG&RJCMgN&iq^A5RQTDiPJWt#^Iip#e9jA3 zPmO^jg$@2reg#j>8oN literal 0 HcmV?d00001 diff --git a/xls2ddl/__pycache__/json2ddl.cpython-312.pyc b/xls2ddl/__pycache__/json2ddl.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0267ff80b5b445e001a58010269c5a37cc60d9e GIT binary patch literal 3212 zcmai0U2Gf25#GJKy+4Z7zbW~rrY*-2V_T|YC$b!;tsvP=(AubzxP}N6D#bg|r0+<1 z?-YqNX#6XbUrFiYh>Xrces>q3vr?_^o}BA^~RC6#C%y!EdZ=Ac6AI+2fyT z7|jygot>GTo!g!HcK+`7>j>ItqCfdV1))cL(rBbkJoy_C_mF`MY@tYP#1Xt}E?9ys zMnqhbNfF7DkqCiNv}9X}D4tBRR9lN^9!)IW_C((tq!|0 z(&^Ef)n#`_y6v7w4@Rb9YNpTh8~R65q}TAhk0N`FHt2(fANoGC-w0eEM2M;aGW%BR zAA(T^XK=XvF`r)wW2Vj0M9Q5q7h*8!a&B0TN#8Z;lwnv?u03l3H(+OgznjyZrqP&X z?q+q*rX4p<&1W<_E@s{_!A#UO&!^&vlnM4!E8(~o5|$Yjm^%K}m5GU{8)d!)%UQS( zjk#%>2}?|Cy26OJKa*>lGQG7^OsIbrA5{2@@P8r$m*3T*kV8q#MgQ9jyjthd5tpy< zT2g9ItucoT!4OyLIowjl61TmnPuz|M-B?H4awLwQU3m`F+^&XhvbRCC#vD!tTeAk$h?3?v z$T>M5aD5HAq33W`MyMfw54+q+uf?0(MJXpG_ci#fF(>DQhTn@yPI(&*AlJ)1u5$#@ zzC~&G>HHEIUEI3yXWLV0H)KHgg{bMy(G*jhIopoX4CQym6i5y} z%kF!@@zkcHjv3->5)jj-ZKhn)2nU#IrVM93;a+2MENz%Ehe_#KGsPrtYspGS4W^x6 zh?%o)0(>D}&M`gVBvOtWO~p(mIxb~|C!E8?xal%trRTv<9%4+PVBe%pSY--i$qb|p zlZ|ONGix%5d(ZF;!(asLGKm{u*m3yMP`&MZefV11Hixg7)Ha=HVwjqcMZ;k1Wk~eq z$lc|Pq1lYL6Q}8Mu)}ZJ(IIQ{sI0c-d&-jUfz-1u^%SpeN(U;6|MtzLo5hjRsnYz0 z@?sScvF($SRY8*4D!%r+qsybk%Rf1{H1RnBLA4DLE&tt$pcIs~&cmC+Kv_`Bim&kI z(vONa)|LKJcwIS?@2*IJg7fq7O{uRuaCGH`{E>WSX}EZ3UFa!Jt_ue%s{gLGtQC*m zJO0z-KO5Rm4{^6tFsyd2bq)XF=z7#Uh;98B;SrqOZmSDA)ZcUK$(v7sh z%#d@$PyoK_8a$OC&B!fsXRJ21(k-lBVu*Bur zNJR-0ZWQ-yD1G^p<&Iz>QxZxiO9Q31*8HKRk*Wr3s{y2S8MN|v> zi_wx)y8J*qxGo<2vMK_5$LRqVesSPc;m_Jwko+Yu)MSzR}zu9;-!LRJe_u;zl zA-5?=?taJW++?HnXllXBfIk&lNZ7i(U6!8nCN)+V;&s@Ep5BG$(*Iv+5Pr$K5g(&g zs3zNXxmG9PMXQH0Xf|K2uh_+V^}a$!=AJY|9JRh7*L-)Nwm}e@ls|mD%rH{`#)(w? zF+cO{o-0l?Zl2{p?jdKW9)0}iA9J4{a|$3d>YzT!F=dOM``z z?;raY3EXk+E-WvU@bb-%#((|Bhi|N0{_r~+WH8@Z!E*k_2YpXqOT^TvDelSCRCq5P zwAuhSE5lKvaJ6( z;#%oOc`~yD&ylxEI?Br{7KqNyes6BtO2mfj%sc06&tPwhS-ZO{Zo+araA6(wr)-E< zk-VOyys)6Wa-j!#$6qn;s=O=Vr;>`==G4^h5d9Vxad6pD&jGs3S>`wBMVRu-bPVVq z$1#3{^oK}$i1aOV@DcJqM7}Nb+7>#sg6TMuOQ6N;-f@QtG960nJ qjc7uiYzKO5)Tr?Yep>JR8VU4Z%$ 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 literal 0 HcmV?d00001 diff --git a/xls2ddl/__pycache__/tmpls.cpython-310.pyc b/xls2ddl/__pycache__/tmpls.cpython-310.pyc index eaacf68df2a119e5191a59093a423e8d490ec39a..4bf4668b0bc54e87f7ef49cd944e7b3d818b557e 100644 GIT binary patch delta 640 zcmdlQcrT1EpO=@50SN9cl*_uPHIdIg>>7~IRn5hzRGyiVo?22;S&*t^r4;6rU!kM} z6wNOv$;{6yRCC^JPtwU$d+;rYUK zPxjA+Nh!S8-~Md(l4o-lKH0tP>GJO9yE~pwng48R2UljALRw}{NorA6aekf^mjVy~ zh4S)C6f%o5^NLFn^O93F5Gr&OQZkcEG!=lhsyq6*s4E14mF8g>0x}4pO~F>78m!(* zAsQhX3$hBqRY=V#PF0AGotz*d0`wZEI;t7bU;|?H5(^4a^HMab)zdOlb5hi;6ebJs ziaYBlsOJ{|IqJ6RKxSED5r`ch4-1<7qV&v^_;~eNO|Td9ilZ?lC-*5zPd+CpG`U`$ zt)57`)vK#vRzO0(wiaYRKBtu8b_hf&78qKS*?7bz>oan0ZWVYe&a9=MGC5Dfjx&iR Llf{)Kio+fN{1w;o delta 72 zcmcZ?wl$D1pO=@50SGi|C9_mDCi2;{HUaru8y7clv2Z0ua!h_8D!JL2dm8IzL*d8b ZY`Xdx`MIf+#kK7?<5;3uTv?(x>;a_Z5_kXr diff --git a/xls2ddl/__pycache__/tmpls.cpython-312.pyc b/xls2ddl/__pycache__/tmpls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b46479d98662e3b9484a060be2ccb8c9e03fca9 GIT binary patch literal 14016 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 WW56k+!GEGK>PFj9E9!s@zWX28rF&KY literal 0 HcmV?d00001 diff --git a/xls2ddl/__pycache__/xls2ui.cpython-310.pyc b/xls2ddl/__pycache__/xls2ui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..050c965b809956a0ac07fdb8de467962213e41bd GIT binary patch literal 1799 zcmY)u%WfP+u)F6y`>j-BUX1;G-$4xD&cA&{IyBnu%HtkHOS9M5JRo9p4DG&G&k7cA=H5Z8y4@L75y zEt8mJYEY89pAh-`WAKXq4*;Nf8BSga5N}n~R%y(xLWX?cuJLUs`d_M3TBSdQ>^%z9 zdrO*c9gyy&@onF$YB`Wa-Z=?n=eS7I;&GBc07_(`^1Wxi=k2JYG!L_Q=VN4sp$Id% z<9id|)9#a0eu_56Y&RP>cXzXb$Egf>BHq#)<3`PPfR)fqRvtpHY4apbhj5_41I0)U zM+y&UAGAkljIOkGoTRbT^rJ2n*hX)lgUHzVPKFQSFMLsPH#W}T(SL*R?f(%@kS zFBYJsP7gjm!eeKj0fY%~03bI3K?9IO=O;FS)+lMoeq)c=0r``N71-<=n)PmK`cTu; zN>HJpK zMfPV&PkYah+k7NwnplB_p>p({%p)9*Y9Z)=dO-!N4t<(D2K}oPVi@Pz#QbYBEkZ8vrrL?>cSc)bnuK6_(OKFY zhUx_LizL_nvVsC%5pCBkr_HE<6xyQ%T?u$)iLd~58PW z*r1o+`Y!6AjDf`bN9?0jHwe&f5OmLp4hY0eMDHW|0MQjh7Xaz=;c$3=bd)Ah4==NL znCtXyEcdXD>Q}l>|LUUWdS?S!m8r^)UOU^9FxhEbbxoDMv(Rwjg5aG@V8_?#aQEw> dyoIA9F9ULk3m1f+xp2WIB%q1hhdwp`{SP9b-4Xx* literal 0 HcmV?d00001 diff --git a/xls2ddl/__pycache__/xlsxData.cpython-312.pyc b/xls2ddl/__pycache__/xlsxData.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f81139535d5c604f79eb66d6b9268642c659bb5b GIT binary patch literal 14549 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 int(_rv): + _errors.append(_rm) + break + elif _rt in ('min', 'max'): + if _val: + try: + _n = float(_val) + if _rt == 'min' and _n < float(_rv): _errors.append(_rm); break + if _rt == 'max' and _n > float(_rv): _errors.append(_rm); break + except (ValueError, TypeError): + _errors.append(_rm) + break + elif _rt == 'pattern': + if _val and not _re.match(_rv, _val): + _errors.append(_rm) + break + elif _rt == 'email': + if _val and not _re.match(r'^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$', _val): + _errors.append(_rm) + break + elif _rt == 'number': + if _val: + try: float(_val) + except (ValueError, TypeError): _errors.append(_rm); break +if _errors: + return {"widgettype":"Error","options":{"title":"Validation Failed","cwidth":16,"cheight":9,"timeout":3,"message":"; ".join(_errors)}} +{% endif %} db = DBPools() dbname = get_module_dbname('{{modulename}}') async with db.sqlorContext(dbname) as sor: @@ -309,6 +357,54 @@ ns['{{logined_userorgid}}'] = userorgid if params_kw.get('{{f}}'): ns['{{f}}'] = password_encode(params_kw.get('{{f}}')) {% endfor %} +{% if validation_rules %} +_validation_rules = json.loads(r'''{{validation_rules}}''') +import re as _re +_errors = [] +for _fname, _rules in _validation_rules.items(): +\t_val = params_kw.get(_fname, '') +\tif _val is None: _val = '' +\t_val = str(_val) +\tfor _rule in _rules: +\t\t_rt = _rule.get('type', '') +\t\t_rm = _rule.get('message', _fname) +\t\t_rv = _rule.get('value') +\t\tif _rt == 'required': +\t\t\tif not _val or _val.strip() == '': +\t\t\t\t_errors.append(_rm) +\t\t\t\tbreak +\t\telif _rt == 'minlength': +\t\t\tif _val and len(_val) < int(_rv): +\t\t\t\t_errors.append(_rm) +\t\t\t\tbreak +\t\telif _rt == 'maxlength': +\t\t\tif len(_val) > int(_rv): +\t\t\t\t_errors.append(_rm) +\t\t\t\tbreak +\t\telif _rt in ('min', 'max'): +\t\t\tif _val: +\t\t\t\ttry: +\t\t\t\t\t_n = float(_val) +\t\t\t\t\tif _rt == 'min' and _n < float(_rv): _errors.append(_rm); break +\t\t\t\t\tif _rt == 'max' and _n > float(_rv): _errors.append(_rm); break +\t\t\t\texcept (ValueError, TypeError): +\t\t\t\t\t_errors.append(_rm) +\t\t\t\t\tbreak +\t\telif _rt == 'pattern': +\t\t\tif _val and not _re.match(_rv, _val): +\t\t\t\t_errors.append(_rm) +\t\t\t\tbreak +\t\telif _rt == 'email': +\t\t\tif _val and not _re.match(r'^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$', _val): +\t\t\t\t_errors.append(_rm) +\t\t\t\tbreak +\t\telif _rt == 'number': +\t\t\tif _val: +\t\t\t\ttry: float(_val) +\t\t\t\texcept (ValueError, TypeError): _errors.append(_rm); break +if _errors: +\treturn {"widgettype":"Error","options":{"title":"Validation Failed","cwidth":16,"cheight":9,"timeout":3,"message":"; ".join(_errors)}} +{% endif %} db = DBPools() dbname = get_module_dbname('{{modulename}}') diff --git a/xls2ddl/xls2crud.py b/xls2ddl/xls2crud.py index fcc0819..37bd184 100644 --- a/xls2ddl/xls2crud.py +++ b/xls2ddl/xls2crud.py @@ -263,9 +263,23 @@ def build_data_browser(pat: str, desc: dict): with codecs.open(os.path.join(pat, f'index.ui'), 'w', "utf-8") as f: f.write(filter_backslash(s)) +def extract_validation_rules(desc) -> str: + """Extract validation rules from field alters. Returns JSON string or empty.""" + rules = {} + alters = desc.get('browserfields', {}).get('alters', {}) + if not alters: + return '' + for fname, alter in alters.items(): + if 'rules' in alter and alter['rules']: + rules[fname] = alter['rules'] + if not rules: + return '' + return json.dumps(rules, ensure_ascii=False) + def build_data_new(pat: str, desc: dict): e = MyTemplateEngine([]) desc = desc.copy() + desc['validation_rules'] = extract_validation_rules(desc) s = e.renders(data_new_tmpl, desc) with codecs.open(os.path.join(pat, f'add_{desc.tblname}.dspy'), 'w', "utf-8") as f: f.write(filter_backslash(s)) @@ -273,6 +287,7 @@ def build_data_new(pat: str, desc: dict): def build_data_update(pat: str, desc: dict): e = MyTemplateEngine([]) desc = desc.copy() + desc['validation_rules'] = extract_validation_rules(desc) s = e.renders(data_update_tmpl, desc) with codecs.open(os.path.join(pat, f'update_{desc.tblname}.dspy'), 'w', "utf-8") as f: f.write(filter_backslash(s))