From 1682cc98bb4dc40e8e481f9126c2d00b5361f36f Mon Sep 17 00:00:00 2001
From: Lance Add <1196661499@qq.com>
Date: Wed, 15 Oct 2025 15:50:16 +0800
Subject: [PATCH] feat(gdb): Allow to set table field metadata and allow to
generate table fields registration code when generating dao (#4460)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`gdb`在第一次查询时会拉取一次`table`的`fields meta`信息,为后续orm的字段过滤和时间特性服务,`gen
dao`时已经获得了`table`的所有`fields
meta`,提供一个生成`table`的功能,允许客户自行决定是否生成,是否注入已知表结构缓存到指定`db`实例。
1. 能解决部分兼容`mysql`的二开数据库在获取`fields meta`时无法和`mysql`保持一致的问题。
2.
可以模拟表字段信息而不需要真实的数据库连接,对于已知的表结构,可以直接设置缓存,在无法连接数据库的情况下,仍然可以使用表字段信息,使用gdb构建sql时不需要受限于实际数据库即可使用`gdb.ToSQL()`方法。
4. 提升访问速度
生成的示例目录
生成的示例代码
```golang
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package table
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
)
// RolePermissions defines the fields of table "role_permissions" with their properties.
// This map is used internally by GoFrame ORM to understand table structure.
var RolePermissions = map[string]*gdb.TableField{
"role_id": {
Index: 0,
Name: "role_id",
Type: "bigint unsigned",
Null: false,
Key: "PRI",
Default: nil,
Extra: "",
Comment: "",
},
"permission_id": {
Index: 1,
Name: "permission_id",
Type: "bigint unsigned",
Null: false,
Key: "PRI",
Default: nil,
Extra: "",
Comment: "",
},
"created_at": {
Index: 2,
Name: "created_at",
Type: "timestamp",
Null: false,
Key: "",
Default: "CURRENT_TIMESTAMP",
Extra: "DEFAULT_GENERATED",
Comment: "",
},
"updated_at": {
Index: 3,
Name: "updated_at",
Type: "timestamp",
Null: false,
Key: "",
Default: "CURRENT_TIMESTAMP",
Extra: "DEFAULT_GENERATED on update CURRENT_TIMESTAMP",
Comment: "",
},
"deleted_at": {
Index: 4,
Name: "deleted_at",
Type: "timestamp",
Null: true,
Key: "",
Default: nil,
Extra: "",
Comment: "",
},
}
// SetRolePermissionsTableFields registers the table fields definition to the database instance.
// db: database instance that implements gdb.DB interface.
// schema: optional schema/namespace name, especially for databases that support schemas.
func SetRolePermissionsTableFields(ctx context.Context, db gdb.DB, schema ...string) error {
return db.GetCore().SetTableFields(ctx, "role_permissions", RolePermissions, schema...)
}
```
---
.../cmd/cmd_z_unit_gen_dao_issue_test.go | 4 +
.../internal/cmd/cmd_z_unit_gen_dao_test.go | 3 +
cmd/gf/internal/cmd/gendao.zip | Bin 0 -> 18148 bytes
cmd/gf/internal/cmd/gendao/gendao.go | 11 ++
cmd/gf/internal/cmd/gendao/gendao_table.go | 147 ++++++++++++++++++
cmd/gf/internal/cmd/gendao/gendao_tag.go | 5 +
.../consts/consts_gen_dao_template_table.go | 35 +++++
database/gdb/gdb_core.go | 24 +++
8 files changed, 229 insertions(+)
create mode 100644 cmd/gf/internal/cmd/gendao.zip
create mode 100644 cmd/gf/internal/cmd/gendao/gendao_table.go
create mode 100644 cmd/gf/internal/consts/consts_gen_dao_template_table.go
diff --git a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go
index 1ed9853e5..02d5f5936 100644
--- a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go
+++ b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go
@@ -66,6 +66,7 @@ func Test_Gen_Dao_Issue2572(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: nil,
FieldMapping: nil,
}
@@ -155,6 +156,7 @@ func Test_Gen_Dao_Issue2616(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: nil,
FieldMapping: nil,
}
@@ -266,6 +268,7 @@ func Test_Gen_Dao_Issue2746(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: nil,
FieldMapping: nil,
}
@@ -338,6 +341,7 @@ func Test_Gen_Dao_Issue3459(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: nil,
}
)
diff --git a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go
index bbe18735d..863c1090e 100644
--- a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go
+++ b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go
@@ -69,6 +69,7 @@ func Test_Gen_Dao_Default(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: nil,
FieldMapping: nil,
}
@@ -161,6 +162,7 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: map[gendao.DBFieldTypeName]gendao.CustomAttributeType{
"int": {
Type: "int64",
@@ -263,6 +265,7 @@ func Test_Gen_Dao_FieldMapping(t *testing.T) {
NoJsonTag: false,
NoModelComment: false,
Clear: false,
+ GenTable: false,
TypeMapping: map[gendao.DBFieldTypeName]gendao.CustomAttributeType{
"int": {
Type: "int64",
diff --git a/cmd/gf/internal/cmd/gendao.zip b/cmd/gf/internal/cmd/gendao.zip
new file mode 100644
index 0000000000000000000000000000000000000000..46dace4f024130d5c0223b2c1cf431b5166cf279
GIT binary patch
literal 18148
zcmaI8W00h6m$hBCZQJUyZQC}o%eHOXwr$&Xb-B9GWqp0me9!w#%uGy1TzTf7+`o3N
zz1DH=NJSY?Ff^clUOGReb^hbS|NjOFLc|<9^|6#4G)BBepGQKgKxJz~uv%fc{|db%ol7E;y9?M6!dkCXx4?rx#aoqL^Y<#<`5t10RS)0;)a$N6s2=bW
zaPYi{nCjxlyBewh1;H7`fXh$&t714BRb#xb-s8y+5-0-AU=|)SpMRBTkEesRw8`$v
zI2vMvaw-<=P-avz7dJ{ykw6EAni*(D7&&FIqJtIMC$}O&GUESMbxcL-*jGOZ?v)l
z+Y8!Au$pf06;ADeZU-GRzVAX|L1QT(ZA^G^dW#Ok_AR=MIcbr)$%1g|xK|&H_>nwJ
z<1xHg&C6hwWT;LBPXaOZg#Il^U*8ToLxusKx%1c+dOHI%Q1y}UgBegGg(Rl_yL&lv
z77m<`C6vLU5U|*{9e|d?%1YXr^rNYoX3%56&b8n1UR!m}6bdFZ;8gH-8@SuYWS8M9
z)gksF0W>VQyW22^6GX(3=+(*}fx{Q!H7p_im5e`$#7(wl;m4h;OvCRW(;Bs&nslz<
zB0M>$xPVFyEta9SM4y8LEcHK^ywoeaB)6<+HmqHTA@PGSk&Zf4A+joXEBULdR2A9H|OmNQpMEoYtJ
zb(ayfIezE*hu*hAE9OLuAIbu#x!PMJ<_u&eXAsVfONG0K@uvsD#bC)N
z^Dm>c>usjN+r_(`x7|nq(+M0Gp{9YDwssDp$3FbTy129N(L^?{!DCzC%~YPq3~*?WFRqT3|NY$T(XLp*sgxaiY&YG>HJ
zYhM8WVQ1)L{7+2*6E?K|)x>wi8PshfR_3>OmQTi;(vMQ68&3~uBQyh2EXVrxlr$k<
zwr_}e)UdRC$_4nMPkbEsvNk&F#b%?}dIkwgimUYE#K9w}H25~tId;bY5fj
zYZao~nJQ5#xq4gmz5^3cD>oh&zdN@z?TC_u69R(}0aZ3(XGIxnlup!`It*X3=sKlV
zuUpYOh@J0AYpGH;X_2UNqJ*<#fL*aot)tJDucOzwcO3j=%AMI~?COxCb)~;xIqc{B
zb=5+(2DhvBc#j%KmJ~RlGfT#}hK@?>>F(w+v|EZiM;q(Cei9i%7iiW2wpDN35l<&i
zt5rIseV=Zp;sFcR@0()o9qIHRV#zcT=
zVJ{*BE)9Dx
zl{);4FU(RMgn=dR;yvY@<5WDs^(lHYbAk2VQ!Jz`!oWQNuPm-i+f{=;>*J;UCCUWr_QP
z1`nSM%$DW4jUjh7=|DH#(CN>naU%tJUM4q0JbHtYiHPU?)4B841rrx=eWSf^RKkPD
zM%mZNUj88o_ZfT)OisS&>!_ud1)Y9nUzh=-Ex%-ujUVWOhYbwKV5HC{O!JU&w!p|h
zF;7s}cA0y80jaO{=VaYFA}O`k2nof73))TUZ<(%C@GH`%1R`Xa?@Z_XCXprP-91W
zP}8(f#@3zCIR6xC4wQUzv;1KSV3UA$9$7OU(h<}PUnIWcMmhlso>~R>%(
z;&bRjH_(3gE#GN3tcPF5J)!j+{^yC!A$o|$olbB5r`U*7sWMl<5|S+Og(0B*!>wzf
z9`bijK>CGJZ`%|JpGpJuJ7L3;U@gmC^;A?()kB9zuh=DmFJF9uU+i_X)T?F69JseV
zF-oqD@ZDVns#_>S(oZFnnoVdeDBA2jgu0RX6O$QNKeR484Tu?(>y*t|&0(n2J{t-d
zU<2&1sYpG1sb4#dCFBY!B=^n&?#3|+2(7KE6shEME>z_AO?0KY;b!M#
z`9nOJL(-_#=FMJO`L3cftb?IyJ4_|kcc5y`pb?v&Y7Y|zXw9*l;euNv-k-)3h3O6;S*c5`;BWYWuo9YlrfWk>ZP-;n82AsRP-54tA?i2*0j5
z^iX$u4f_!dOugPnRd(w?u*BpRR{^njA;>h#)q9nVjPlP*0X@;RX>@Wxvhbh*=Z>3?
zbA0kFuWPA4fV9fIIpPwDMOGty%O(q|_6cl<2NDQWtE;$Dkd@Ez_npvM<(2PP
z6G#a&X-DKpdRh@k&fDk*n^B2bjZPm8VW;WLKF~JQ;2AzTGBkSTXwbufH|sEpl|l##
ze}>=dP3es))SafKp{gE(U0YRcO7OiYgZ92__Y8^+B|;g_Hcj{98$EN9Eo3UaUmP^2
z9;UIVN)H?C4*7Dx`eo-+R$uTM`wlz1XE42t#U1l4)#&Mheq{?Eo7lr;G8qU4b6bNq
zQy-Z{d`CD2s;B%CLd7s>$aa7fCgoP{1PS-|RA$s?o+GV_4#@;k&M{WONMkoM@Qs-Y
z;EId3Pz)SeCQGkF@k7bBA7m3jCn2vfYBr**%e-^j4{>N$_14DcGYqp?2TNOVNfqDL
zXp+DZQZ~I?al3tRpgZb76r~!ViRP^K0RbHwi}W-csnEZLIx5#N7id`@B
zAeUb9Q-alaq&p2gcr$G*%ZJX;vNaPda_K(uaudT2v+Fy+BZwzTVBkWxQzK@sIW_3o
zI4~6c;3719uPjA3KR6Pxpp%}n{G)j710rH8NG1?rEb>kK<~DryGxWD+EZg
z^(8+9lTKt~sZl@QP_L4HoF?tU6f9BL7qnfp`wV=Y!}7*!-xxXy8l8N*X01{==9SV*
z8Q`vKglqqa3hK>uU88H&A_v8`!Y8@vj#t3fKpwA2Q4f0B0zC!bVzhsyb?v8e_hd<8
z^qz!PjFr=T>hHtd1SVTNX)#Gz)MA*ZI+=#28mw^tpO4Sfv;bl3U+xdw)yc5eLDG1<
zPzkQJ_EfZlAN@Rm3j$wf*e?UJxai^!8r|djiac9F3{h<91e~S*tAf*F^hfw=@!E77b31Qxj4k$sa?o??54)>iJy_L;FO{@
zVWaCjS-{_lp(2?xU}k0~5cvtl`gFBScrD
zx1Sb={g8xPl<3IvKSR;U5Equ59^?$Q#qGm)LLrIflay}4QnR%R{mh~p{w2IN_Sowj
ztaL8VBj&{t0j-ZZ4-O&%y_zj?jm0%yA;#Vx9YC?-pE{Q*j!v~u)fqhQjw`)7DkjGX
zvJ;9cFRogUIC13l8f
zHkN(#aaFvu5+ZDT)#^Oc-ZXb4uahRJjiQoPxwOM~&MLfuZk@P=TBB-Rs1fVWQ95w{
zO?TJvUgQ?{ZFQS^Nd6zd7NlsS?f%JKzK`85emkv!Pf4)%endOhoUIu{pao6iHHEj
zk~E<5J~4!TMw%NACY7DDpp@)uvbrlMyw`Y5{<07yBAJ@tfv*s$UcD2}6}zbu=f>DY
z;1L=yP^ZP`#P2S7nKC3`O-YWGDaa(cRvtu#?@$q-#7g_(2~2c~WrmVjc!{aRFgN*>
z>ZxJO$VQ@{d@%A>PS>^hrKn4?-!=AGQNI0^I`rnU_n3A*
z3Yq$eI`NK;)}5b9N-SmHq=G&(@-5Wv`nc%ExRr!UR!F@LVh#g{)#tzGLhW2Is``lj
z_{|uo_x(b3*qnNhNchG7Btuc^6RiPl8|UGK6|9y*@!C=O_8up;LNJQY0mL+6W~Stt>!TkkgoRCw$cMmekEgA5#>^q#rZb{P04kF)i2%XB8NFqm?d4mc
zyV}reYhId>Y?pch;R}x3tN>UL9HGHUx~)SN_o5d)r#_&hGHLUyH*hAu>#Xl#$41H6
z)4DebkYyqfVU>$=H|%=^XHziz#B6`MGUWrfq;kkL0&$ZuL10{7`77X
zsoFAHwDW7(c2nc_cEX3sBSfxxcUIaylg3jBu@$o*lqvr5D+rpR(*Ss-5lm;++&nnV|&0q3j!)uyH4?8r~3@T8l!r!etV$&xnMc>peT-K
zk4?ToX!NOxK+{pgYD&hvsz}`Icg#NL!i2^OAS`_iiF>6&zYg1aQs9#y6-4+0^PjBm
za3k;(iwFetPon>K)}NF8H+a+q2Li(Q?^)l##MaEn@n4A_<1cT-{QLZK{x|NJqM~F|
zB#7j@YQX#`6;(aP_cSgdDFwYPB=zQ)tjx}Rq3^;`UDN|O?%S)*EG7><5>#~SeKqfO
zFi!%*FmG$Cq=F`xUYx`!7&qEgwzAbkxz6k&qn5oP8C)kpVXC9i?23k1UC+N}LiJ6&
z1yv}qHZ;-BB0;r)k}vb7QSnZi4i|UU1@;{*9BjeZ5`-VBrNsPWdAR
zUJ`^Z(uCgVx^>R3AmpyVax5SURV%6AFkQ_ae=nCfwx4%h?OexoFIy^iihY^mI5_W~
z{J9xhl6w+E%qw%53^@1DD+oODmp`KWa!Ac+MEIlCx*p%qz4t5vn9s`#3t8<99+-yT
z!-wc}JQ&9i0noyr4hy!9STfC#?@S9;S>Mjm*Jw&7s*M*|HUkqN
zc)EoI6v{n>Zr_XwWnUjCq9M>PurMZ;E32Xud42b=l94MF9$%qf!mqNtPP2+QnsXMt
zW@kqjGkP?t982p;XEG<+PFR(=3KRTJrkNb^&JCxZ4Hl-LB<7M+aSTHt?=T@xQlLW!
zdd2%1|BOvDC8xn=CW^)GKw}|gQdiH~(<}~05xvGzk~Jqs*7-boc;tH>CQVI)^B8|j
zRYVEUV%X0}CBuvy?p957pcyf~pI$)#66`yn&MLgBDfpS-esu=$XV7t3}D0_D5!F(`ffhk8*IE^R-;(`v8
zJT58a=`w!hLbo86KD@bG2lJ#Vn>_V>==P*|Hl?ld~>N-?Q!JRmoKu-G&;9>&`Y
zVhk=!!Cd+~`_S()eZZ*X7Z*D891or{>DqwEyrvJ1P1IZ}N7|Z(!HxV+i}8!8>+Aa)
z{{BZg*b$>G=oG-06?OkN46hm>bB4ehRv|x74kUiJNKrLLo^iW#COZaX})PzBs%JDi`jX@5M2VVGL`6`K&*J65lUfcH$vc
zqAT{ZU$-O@(@<0veP=!~Ma8H0D#V=0+xBIMZ)Pz`3{XsckhSkS_>9bSv<64-t9v%|
z9dzmiW}1(K2RlM3JPL?4FR5f(>PsOJ0Nuhcb%cnL5s0v$pu}(4t8R|xEpl`Shplwg
z#@V(OC=xRYBj38moHrl1tW80^w%&}HZK>Kg_Zi>^h0I2@pHP}6iI;zD$`Dg?W#i@8
zGhaLo2mg84w;fRk_UXYAr(=nLKxwAT}R+hX@mP{~3$*G(-(rK}FP{y5?c6J*-cjw{p+<}RTr1nH{
zao({uwz0Hi%9CThFF!#HZk_dtYKn9Ovczut#~*y%b+rE0u8&jfAp_&3h5=~Zr{#v^o6Yj!F#oguTazL;y$W=_gupqx
zn#Swhn#6+3^=TyqOE2wgME&5hvw7~Duv49;_jF%1N3RNiX~?#$qC?FB)x&v$%Mn0{
zPzln$1OFn9aS*c
z#7~-OC6x1sVbU~xHxTJ{Q@hp$4{UZZ@=2yB7W2X7rC{M-H
zIM*N!kmi7g+w>W+l3QF~;e^yBv}#EqiMTITie8!OV7!N#v@;MX4YnazrWGPnZ*Upx
zqmbGGP5xn`1w
zw4@U*C+-TU9PtI?pf=2BhZvytroz!m<%`aSk5CR^5Tz%T&(xR{C`xY`LsGW;f`?eY
zSBG>x-Daz);Wc{l%wG_Za!aD6f3KQTHz6ECa+q44mGpNtAeu1FhoAQ}W6BG}H0VN}
z-L9OA8VXcy6;40Ys0xM^O%YMm!xv|T68#oJhQZIXLzW>i5>i;s)?<8rL^I$nS$9*n
zb?7=nhgIjHX^8dj_Fu4|qq-&v?H~{vu@hq^r;`;{IY_k@O#}Y1f4$|l
z^mhKq1~&w~`S(XsycCkDl3YmhCXbT-c(p)t(!v&jv5)|BX*-#4<7>1M_KZG5dbY&{
zLCLK)OQN2t*pGTu5x*r)<56g3mPy9La=z9mu$4RXr*TII(S*LTh6&k3-nKH#E-yUB
zF*EYi5!stObMn=j9J6%j0uI8!q6hI#{PsbORhV+wh5}fNK#%WroZWdzgHL3IwIPSA@<)B0XK1Cx)Rb0HXC8bc8bRGb
zu2+SF45vPL1n-X&?A7o`y9f;&iE;u$BbMh(3a^-oUXZbI*$~5PZdr4gK%q=|WddW{IzPIYmuN3>-+veOJ0lb?hr>4Y2c>NrT+t1)<&&!&SB_GwMCd&
zcBQl6=(H<2qg*Hc1{&*@wpnekL+N;04U?fz{`TjY0TA7pnD#I;YIkFTeAqt
zFnBu(_aUN`r9bUYX3Ip76u(Ep6O)fX$S
z41Wt+cx|Y2fb36sLzR>2w49p?37c&$5ZFAGOM>ZegYp_{-b{)_d=e
zz%V(#<}%=j$uPKx{42Tr2r`s6{2(B*=tPk=V^dC3n29h;(1qB53k7xR~oBFSd
z2GMYT)4>05Q>G68GE@KOl7XGW7CX|H?Pp|_f3tF>l+N>vAX72>c86sn5dw^DLjw~E
zxl@X0K=FMb$+wSNG1-)d)fzUtXs!M6Q$Kh?f0RQ&J5$_x$ONFc*gj
zWjZzJpmLGO>HXBy12|7~(q={qfzHV=zEH~~RHw8c6@sN824$`00DBvzNelulFDg;O
z`B`B@c+xt4EfiYU8ezJBA5!14?nqVrOgVv4jKE8OXpym6u+1Zf`P`$>x|jvY9aSKu
z<-l!p%uau!#K=4=o_%v3SW5+S^BM51>h1WzkbuMCKJ-m77PH^R=oF7GRp37GyLT)Y
zqQ_KL+YG--uupYn5{z$IypQMs`)f5^IsLtu#_aB>%~H&);Pk{UM|rrzICRb|K9lFH
z5PxnP2bcoz6tLz*k(N_zw$n@zT(^51N5J0DtRh!&ra1OAua4H-m`>6iX)-fY5CktCm_fI}ZxTGD>z;OGJ+p19~_VTo=PDwc6evD6}f%II7b^ftBNXGR*F2
zc}-McjYzDC$mduaAvU?6c+eu3lq7B2b+P#vCFraL$0M-jni-J3vvQqcP+dBz(qvHd
zqx)upzqCNQx#k^8FW>e@390K-<5M9&l%zot4IZ`z9MAYy*O!om3?ku~EgSWT{P$6ClfsLk}=8dg(!Uyg<^8YZTeKKwcTSBCiz7
zj@dlsqLW{!8CQmsDP?-QA~DOz{xhbFbsUMEB}8)liar34kDUY1i%{Aw3>Ya8!x1&`
z%J8MVJKLZeuP+i(>HiTirP)n}duJbdvcJI%24S~R-y@YYh%C30yzA&{Z_EJ%g!l|1
zDPutU0z5vJ46+{Io^IO!J*y5uGTU`)VV5r59$Wb2QfCr#zhV$7RKU=sf~R6GTZ!9O
z3Oo+QL-A=X+2wH6X=WR}@JM5t<){|O5z>nbH<39-$=a5J0fai(n&fqKoxT=tvIXF7
z@~0TN)N9SPvscjHf&
z0SCrL>ul&&?4Kt3qOkHQ(-ZEvYsO_#SGiW6<_O~HrOg62!qRWVxH+>q_IygcClL$f
zRSn;I8xZH9H?=*GS?#5b8VOycFd%#bDy14g@Ppx%`wJoW-b#%y53-mZD@FS|Q48fupvrw<60N2;FE>_ZFsV7l6}d`c4QFQs3%)Tez{3
zY#D>wirnrdzP;yIilFbJIKWu>8qHYXuI^YG+kzoh6SUyrXSyfDxpb#h*~k6B&-$o~
zxEs`J!sEo)TjFzOH5SFt@lDkvk(~v1gd|q$f|5UYR|8(^O~i$3yemNRHeYz8IcGBG##Lr9pJcu1CC=u)
z)l1R|hp5(4MbTGB6zsk>0AYi4_YLxo_8QMCQQ`hgvHvLSzqR+jCfNg&|Bbac8yVZ0
z{Y!rTk1U&_v1Pv{j^u;UXDmzvuf?jWO~h!e)}OWx*di0REvCXF)ryd@M%}INO197-91@43$g4&lUBHCJy8Gbt@XlALP1YMI+FeFn~w|E7A(
zOR^zQ1@Wso*t#^Mzb+AUY5p|;WQHzR1H3c2;kbaEgbs$pP{kzZd$yIC}XtqURsUb(O1${_|k2+OXR|P(NW!#
zUwvpkM`i^Q86$rH6Ks8kP1$aJXoj=0Zw*j1&>5QdC~SA->oQr6{Ah5$-u}|(BawG}
zVD-rZXvR2AmkV1?`b+UJz-0^y@f_3A)8+)4to@+@trA3GbcE=AL%~wrJZ=OU!2z;$
zvvPUJZ1r)JO|>EVpOs9n_>$;_Rh1c7^xtbgQjZeMa9Bt$@xNqhakV`Ed>9Hv#uHKI
zeg^Leh|I>IhJL`{>V~-YwpmPTu}JX=Vm5Ri`BTGzF^r(!C40A+H}KYZO2o#<5}F?2
z;g0?y3#1220z=KT+sN3bM@H_lp_qS%n`Za+iCV4pS%TkEVl=mD^(BkAW+D5ehVxb(@bg*3EixrJ=8
zq2M?fpGyLi$c{^xmZN3Ge>1Ur+$XLe1E?!V>y6_OY>fy}FuSg85B=Cel#fg0
zpf(OoRP)LP!jdmv3%gQAQLF-!3oavm?qnVbsDFVG{H7Oxb6{FcAG{au88Qv@V(B!A
zHeG(eFV177Hv(APTR;jhTBd2vcDT`qGGUHfhhf~ybUr*$tqq=#(l)HNatw`TS%^Gq
zyI|OZL_4xVL?!L4e}gS^hO#F}3~%PxgFk=QP#yV@T_MHJfkyGd8o2}-HWj~~<
zp~}mJfpH$x8RT{B+jHzl-jGv2aqwW_&gSnm#67G=WB;7ts^;rIB}q|LDhnb!l~C)X
z@=_vR8hr_?zs!XrWS;^-m1I+tSlwIh)SQnifxMo9-Szsr9D~`Ylk1}AG?SNylP>_Ttm>?31p*!fRXsD0k
zyCdEmlFeR@CB9NRR5;6hS)hl{E@~;&mlgqt@?ahFOxZ@n-Ce
zP3^p8B>#=AT>{z%@4+JUV>N_>^JaR@rB#IO_1a*3)2TVM?E
zFbg4Z$KYBnwGnRHazP;@(#p7V1>3=yzxpE=fGrEVYO$cbDVvYnvo?In)te6AF@Gc|
zdW)=s0eMqhX$!rM)%nh_hSL6~H&Uj`-wxO<^SvrhuVD21emvRp<6UAk*B}>eUZTI0
zIn5mTJOFQYH8wpGfXbMYy8_93d&>Delxr4uO$Pjpk8rZ(Mh-u6E&PXhRQWxr+ruvs
zKT6H~jJP7Ix1=&C|9aG09VHb;7
zt)@&sbGVE0W*G<01~)1lk8c~O)wj4e&^E#>sN~?1cpGV>I#0wD_jqtJtL+iZV(40r
zaB^NxCa<G*5bq{V$omDRug?kE~(LkG)J
z0Q1bUxQ5`NcO9aq=@5V)ZNPo4KT_1JD=$0F2myvSgvYZ7G}Y?9M%E&!2bM!wN6hq@
zk(bg48EQAioM)mUi||~Lo8oJP=+pLzt2K$yq86nmoYiOv8p2fV{DFqYtVYYm-w~CX
zTr`;)l#O8G0-F>YMiC6lH3qbg4V6*m5;?KrrT{*K6o%}Kg?~2`t@L3k(gg@Ssw75e
z5%pIK6+fB=*Eq{0uq$Wa(nc`x1Y07($`5w5Buqbgdof3P(klQdcaRx@cRn;lGq&$z
zT4*48ns-_#HQha`&4f*+0s-aw;LBba###4apJHYw&6p4lfE>lQPxx-Y>af31ctrp>l6gUHC7@Il>*g?TGI=gJ&)P&_B!DfqMj
zmJ+6zRu!}tPF!ojupFUSMRzbCIF7l1M6@@yH{;@qyCD&_
z(gt%fkMtjC`O0Aj6g^^@fdb8BnZG0~#^Vc8V#CsqZm=Z;6gFm=I?x}n;9tEEXk~vk
zY8lUFD@d3XI<;6y>9s^$Ro|u3&fR&ZjbE_+M%qv!=`ByqQWQ5#qDB5N36lySUt@-d
zS9z^fM@74bi}fN9h#R|TIQG&VA)2!8mjG$7t(iwvCe|%+o}@si;8}pnWAzs&
z81g!DLgh$CUryx~E8lZ|egH=h!;nJUwbs&-JB}8iA-h>7#PWVNROMWkF5ajnF}PMf
zdJMIokcc1#zVUq7h&RLgAJEZ}q>8*wuz{e#xX3TkGghzqv|9#wAhCsV#2A9Aa<4U&
z*YCm(1DwsV3&r+HZvhyeNU18LCBtyySDXtG?fo6nrwLiv;jqjLeLTiunM&HEvJkLH
zc_UwX(<`1!)sbpQiV
zr3yo~6#NYHB@-S#^ITEQ83HSf*Z`M?I9TB`W+g;t?j2k*VZ1~rk_`$St7TlOG=B$M
zZMj7`HEUceO3)11(Y9nqs@2W!PB?ddZx~)XvQ?BRP9r~~y#|LqGuQo6*7t+1SNhij
z)Z^^MS${gtSQ5(z<7I-*ZUF6KIidn$mUB-5m`HImNNJ{l0)IGn&@niA1Q&8K7+bJp
zWP>~dcEK^e)t}tW#kGVb1s8gV~uCRD00w#^(v90
zK)}Mw5yWHr<#Ks=b{6!21fMGVrNI}Ngo+p6!7}@rOBC@9)a1L$9-AHx2N4N7onjAO
z^@?3LJCN@x_s-v-lN=C7y2;%RS$@^s(&7-3;kRoS>GI-ssbzzb!pb{K1XwSUtB)r!
zFgIF}XksnP3#n7j5Mh)I4x109(qHu!&h!%k06E$2QSfQ-rAM+Z*+E?
zB?5VaffQ%cSJ%wUKWk(H
z_-VmYm!5o>9LQ8)xtVJ?=w4Xy)&iHJ!|vNF7r`>++y-M8DiA8+@sO)1i!SC0mUAuu
z99ylrOMGzlH;<7tJYYaic%z>ioAmXcEukoFOLcJb&&*>bzx!v2ih}rgqVa)Pw$t8f
z4K)@h^yK{q+^oC#fTES%4D4_%+Ys1cwek2Wcm~+J!#&E7ubcx3*fP<71X3ht_G&x_
z&VShPZCx96S%7b%UYONPTXPeaLWt5_;HR3kix+8wQUDgcm58S~RL3uXt-inVJ@-~5
z>P%a#c?uHFONL1_*i&LYWagz`b4S805saImH2{{jPJ8QI?pGJfZF~H&94D0md0{6p
zr5&GoC^gwj!%R;3EQg{r17+SwD8Z7bMVQeO}mo5Q9Mn`7G>9@T#<$N{|O?OtJ?n>kQvzkp|$pf>ja`cI1kdu>{q;tuj%dPd;
z?zUKvhIUth{Tw@Ea*PjkzrFpBq2a3}9SU{8@#(tMd>r{YR_=T_B2P#!oD|6PQO0gx
zM@wVruSp>rF>sxCAW7PODdj_lkA^b-faVUEu~5@W2MnTSQ%$n%m%9iCD1VW#Zu6dj
zj;*`&n=WQiQZE@{G+UyZn(GgESX#MBQE^9sV^tk8E11eyq6$KgdG_8V64fm+4hI8sL!L
zTA_4nzgp`}AA{fQL@Pt+WV~r__={}vNfAZ}@)uXTl$V*raxpH+?Bf{jn&L8Wsis|Z
zb1{S+o(2t)XN1q}^A__ZtX8EzjM;%;9&0I=YzNUHHNo(Hp5~7UIt+sHz&Ejcg;sn#
zz3=@5E{dIkL*sUEQzel8^40R92N8wet7`Ht3;fzE@pN)r<5E~#*(n}V=^1yTNwua?B#^
z<>Qe=(d!Oa<}AOdho_AD`n${G81Ws}P)gej$(}R8Q6v}kPTu~?@sDSlzHE$Eh6V!q
z$C>@xv;9}_+=2rHg!4bZvy-!WbLu=tyuz7Y#(AjZ}mlZ_S+W`+WmKCY0HlG*z4ccE#}YxB<>h(B#y?
zqxx!Hv*G2Tbys6p6`gbQsI5MreVN0J9jC!El%uI$#bjP4Ho#9DW}Fv{vXUcd;=mi)
zcjcNx>q`2pMj{BHSud$>gzg&4Ub{CQ&@$;HQ>W#oIk+`0(%p)G-RFngAIOl%&=auv&b0ms&`zdZ5B?pi
zsTDrsOF9*UXVXhJ?2{5y<3r>1@^Zs?lnjcmVcad9_LZc1{B?I>1+r}4T{$ex+bs%~
z`L2KF@m5b-BsS90zOcf-fJrhnrF+`gP2=V@gI3cxw|n-{L&ezM4Z@*H&S<%XyHglJ
z$ZU~*2Z{R@(-tH$2_w_V@g!tuRmWUd51x|4F3!fP%s#)mQa;5uXOtBrhr81*V#M0XNo
zYsNw3ocvNndl(t&Q*AGAP#HKgo2=?@7chSNLX|{Lc||~;yH~T!IBN1~fF5r*pHPIn
z)v=n4Q&xeK()AX(8Pppev?v+1W47FM1rAG)wieoLW6;)RS2YjOow5S_Ob
zowm4YK_v8jN%;dCdK^_(X0Uu%BejmprVSR3ZE(}ipYvn)0oo^46_mMYam;X(o)d^N
zv?aR2lQ};qQ2h?FfJ;ZPh%4juxHyRv%7#WkFgg7-O4~U|oj7Ep@|DoJ+{MpCfwTSE
zPw0WB;8|@0QFpmU1CsF%eL9R(A82P4OVYe1L_;77j+K^PoyU1S%9&oa-m0qQ_=k60
z^LDQF7Rpb)dmzxIgnx
z`M@iH=%{3P$wv0>4tp#J$dQ7I$I3u7XVJPHid>+Wk-x_B^ekow2rh3@U#quqXgM}-M^SlzJaU%HBa@r+z&qb|S
zOo^6DWek=MN)R&4;?17mX}RHti_Xc`Y{e4cFJhh>K%Y}`uCp85O#o&FRWiWE1+ilT
zy~F+}yna7y>G$cek1TXp3HahSr3Rjqd~0_$1LJ8_3sQ2W-a^_{>4#}KNJRiA&XaVF
z9XLBjK{{}1o}Khet#P+(hLI{;?|mn))@CB9e^rj8Bb2zcGCM&g(_7DPu3N(%qqCFO
zpnj0Yu34D{1Z+JfC!?ZTN+q?O1859WaNH1C_l0Am522LW%MpGdSn2wQti%&~w^E_3
z=2IqupaQqT#tPi5^dDJr==RnxhR!&
z7ITyerzuJc$r=irzmkR0dr>Lm8eCdQ{?Ha}oFCHh8$_8dy`Yq`McyB&%;1He61DwE
zi!>dZ;)OO`DSbJzl(ppzoJB~aZMP@Cti2%n0qo#5--2JSht@5?>(h>e<+j9LQ4Fa0y^!|cn47O0M0
z^R1gGI0(8<7Pk8kE_~EEmVl8SzpQ60B(2FhI%2JLk77iDsLYs53W>!GPL8
zg<3kg5f?g5#XUX=+^VC4A=vVkBUWRp4pyTr^OgaV5WV+VI&AuSxiheL+x;xjMjvf|
zP1w?#`O;J45=+S_wEfF6W!MeILBD$B`&2j5xrCRU74z`6wQtP2o>z{?p{lcrMEp`~
zomglO1>jl8eAw5LcDLgbE-1cht8iYWrcH!@WZ-2KVe~5@GEUXu5L_1E?1XzSxF6Q(
zi1;3g+r->zN10Swu&=~lI$=X7j*|p#3Y@$7pwlGZj+iHgh0JruA82;5bd&K&U#AaZ
z>%84$SQm$eF$m2G^DuM#bJ+G7dIlXXuf{M;_<6D?sGoq$rWVoN>oZm5&eu537L^IE
zPtT`pP;x&3Bw?qqsz&&3j|{h(^yl1)Rk$AdrTJ1t))QV<+kQ*jy~WlN_1X=<(AQd@
zojD>78g##}t5a+PO4m8y#4G?`V8kKpI5CpYlm^CTTO%Al?&zqueDvwu93k3m_G%o@
zqDw58l{~LyWL?K-+HTLF2gafaIjkfcmKrhAY*l8C<2zRTkFpg~ORdX|1@7uSI02QML8M`6
zG`0FSavW%LNVU)-e(59&x@B2#3pSr!f3I
zoVq~Y3DV!n4B2dHjuu~|G5vhZ-idj!e#+rWwUp2d;@$?9VG%ctPlqeq>ExUsZmf5{
z^!uscuc>eZJ^6+Hh*43eJO-*i{vIl
zj?)8W$)~Jv?xvimEB7qnugxN`y)Sz+g^qHF$tz02=Mb!Vr#GHStbDwn@RK*7x1^`Q
zK78DUr$TUdt@gHUfCJX^{;^(>Ibyu1f34R)2J3&fUOazqrLg~p_4@lC0|r*kW_JH#
zX8(utN>Pz>$Pz^2^YRf9i4n2M@zFqgvv4fhbj(kvS^FUVLMaDoaiWq5m-}Ypx55P
zJ^}vbUb+}b>}zP4GM8q?Xz6%A_Tb<;K4ALCmO(m7JTMJ1)b(t@#8%wzDae;nn%gG{`gqQh0z?6hE+1SXAWT0bD(K)1i5?46$H|@I9IuB@t3e#>Rf#WWq
ze@qdGQi<-Kp|RaasDcxFyg}lSUZoxhQ2x`g)m8#J&@siyh7mX
z5{z+#GD?|*$smtYRvNp6Fx7il4CH4DIk-8Mc}MweFjw1DVZpj@%A&hoOT)FN#y}gU
zuX3i<8mnv2r$VS4g;jiwe5)gX-gR@puH+_apI_re_*C6eu}09&N}I3pgZKa2>#qx~
zt=@hAJ3s0D#h)5|E%J&r8@m=%$W~7Nd%*wWvWC-D>mMei=|9#7r7N3B`FB1tGBAKr
zPk=WglL#~JvoBz0VZ3z&u^^{c5OER)#8B8-7|0vbL1$sWz>-E+grN|#i9ZV@e*)PJk;e73YIbO%*i5~4q8=@yqX!bsvZWGH0}ci9*XHiudzqA
z1LOnbH9nwq(J-*2F+m*N4&qixBijJ#vLVl8gVqYcz>>ywKn|)eh*~*>Yyrp%$Rqry
z!K9^zZUM2=H*%Yz)2Pc1}-4H!py+%%L&8-0EuQ)qyPW_
literal 0
HcmV?d00001
diff --git a/cmd/gf/internal/cmd/gendao/gendao.go b/cmd/gf/internal/cmd/gendao/gendao.go
index 684c10bc3..54204755e 100644
--- a/cmd/gf/internal/cmd/gendao/gendao.go
+++ b/cmd/gf/internal/cmd/gendao/gendao.go
@@ -47,8 +47,10 @@ type (
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
+ TablePath string `name:"tablePath" short:"tp" brief:"{CGenDaoBriefTablePath}" d:"table"`
DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
+ TplDaoTablePath string `name:"tplDaoTablePath" short:"t0" brief:"{CGenDaoBriefTplDaoTablePath}"`
TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
@@ -61,6 +63,7 @@ type (
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
+ GenTable bool `name:"genTable" short:"gt" brief:"{CGenDaoBriefGenTable}" orphan:"true"`
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`
@@ -279,6 +282,14 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
NewTableNames: newTableNames,
ShardingTableSet: shardingNewTableSet,
})
+ // Table: table fields.
+ generateTable(ctx, CGenDaoInternalInput{
+ CGenDaoInput: in,
+ DB: db,
+ TableNames: tableNames,
+ NewTableNames: newTableNames,
+ ShardingTableSet: shardingNewTableSet,
+ })
// Do.
generateDo(ctx, CGenDaoInternalInput{
CGenDaoInput: in,
diff --git a/cmd/gf/internal/cmd/gendao/gendao_table.go b/cmd/gf/internal/cmd/gendao/gendao_table.go
new file mode 100644
index 000000000..4af71fc1c
--- /dev/null
+++ b/cmd/gf/internal/cmd/gendao/gendao_table.go
@@ -0,0 +1,147 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package gendao
+
+import (
+ "bytes"
+ "context"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/gogf/gf/v2/database/gdb"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gview"
+ "github.com/gogf/gf/v2/text/gstr"
+ "github.com/gogf/gf/v2/util/gconv"
+
+ "github.com/gogf/gf/cmd/gf/v2/internal/consts"
+ "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
+ "github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
+)
+
+// generateTable generates dao files for given tables.
+func generateTable(ctx context.Context, in CGenDaoInternalInput) {
+ dirPathTable := gfile.Join(in.Path, in.TablePath)
+ if !in.GenTable {
+ if gfile.Exists(dirPathTable) {
+ in.genItems.AppendDirPath(dirPathTable)
+ }
+ return
+ }
+ in.genItems.AppendDirPath(dirPathTable)
+ for i := 0; i < len(in.TableNames); i++ {
+ var (
+ realTableName = in.TableNames[i]
+ newTableName = in.NewTableNames[i]
+ )
+ generateTableSingle(ctx, generateTableSingleInput{
+ CGenDaoInternalInput: in,
+ TableName: realTableName,
+ NewTableName: newTableName,
+ DirPathTable: dirPathTable,
+ })
+ }
+}
+
+// generateTableSingleInput is the input parameter for generateTableSingle.
+type generateTableSingleInput struct {
+ CGenDaoInternalInput
+ // TableName specifies the table name of the table.
+ TableName string
+ // NewTableName specifies the prefix-stripped or custom edited name of the table.
+ NewTableName string
+ DirPathTable string
+}
+
+// generateTableSingle generates dao files for a single table.
+func generateTableSingle(ctx context.Context, in generateTableSingleInput) {
+ // Generating table data preparing.
+ fieldMap, err := in.DB.TableFields(ctx, in.TableName)
+ if err != nil {
+ mlog.Fatalf(`fetching tables fields failed for table "%s": %+v`, in.TableName, err)
+ }
+
+ tableNameSnakeCase := gstr.CaseSnake(in.NewTableName)
+ fileName := gstr.Trim(tableNameSnakeCase, "-_.")
+ if len(fileName) > 5 && fileName[len(fileName)-5:] == "_test" {
+ // Add suffix to avoid the table name which contains "_test",
+ // which would make the go file a testing file.
+ fileName += "_table"
+ }
+ path := filepath.FromSlash(gfile.Join(in.DirPathTable, fileName+".go"))
+ in.genItems.AppendGeneratedFilePath(path)
+ if in.OverwriteDao || !gfile.Exists(path) {
+ var (
+ ctx = context.Background()
+ tplContent = getTemplateFromPathOrDefault(
+ in.TplDaoTablePath, consts.TemplateGenTableContent,
+ )
+ )
+ tplView.ClearAssigns()
+ tplView.Assigns(gview.Params{
+ tplVarGroupName: in.Group,
+ tplVarTableName: in.TableName,
+ tplVarTableNameCamelCase: formatFieldName(in.NewTableName, FieldNameCaseCamel),
+ tplVarPackageName: filepath.Base(in.TablePath),
+ tplVarTableFields: generateTableFields(fieldMap),
+ })
+ indexContent, err := tplView.ParseContent(ctx, tplContent)
+ if err != nil {
+ mlog.Fatalf("parsing template content failed: %v", err)
+ }
+ if err = gfile.PutContents(path, strings.TrimSpace(indexContent)); err != nil {
+ mlog.Fatalf("writing content to '%s' failed: %v", path, err)
+ } else {
+ utils.GoFmt(path)
+ mlog.Print("generated:", gfile.RealPath(path))
+ }
+ }
+}
+
+// generateTableFields generates and returns the field definition content for specified table.
+func generateTableFields(fields map[string]*gdb.TableField) string {
+ var buf bytes.Buffer
+ fieldNames := make([]string, 0, len(fields))
+ for fieldName := range fields {
+ fieldNames = append(fieldNames, fieldName)
+ }
+ sort.Slice(fieldNames, func(i, j int) bool {
+ return fields[fieldNames[i]].Index < fields[fieldNames[j]].Index // asc
+ })
+ for index, fieldName := range fieldNames {
+ field := fields[fieldName]
+ buf.WriteString(" " + strconv.Quote(field.Name) + ": {\n")
+ buf.WriteString(" Index: " + gconv.String(field.Index) + ",\n")
+ buf.WriteString(" Name: " + strconv.Quote(field.Name) + ",\n")
+ buf.WriteString(" Type: " + strconv.Quote(field.Type) + ",\n")
+ buf.WriteString(" Null: " + gconv.String(field.Null) + ",\n")
+ buf.WriteString(" Key: " + strconv.Quote(field.Key) + ",\n")
+ buf.WriteString(" Default: " + generateDefaultValue(field.Default) + ",\n")
+ buf.WriteString(" Extra: " + strconv.Quote(field.Extra) + ",\n")
+ buf.WriteString(" Comment: " + strconv.Quote(field.Comment) + ",\n")
+ buf.WriteString(" },")
+ if index != len(fieldNames)-1 {
+ buf.WriteString("\n")
+ }
+ }
+ return buf.String()
+}
+
+// generateDefaultValue generates and returns the default value definition for specified field.
+func generateDefaultValue(value interface{}) string {
+ if value == nil {
+ return "nil"
+ }
+ switch v := value.(type) {
+ case string:
+ return strconv.Quote(v)
+ default:
+ return gconv.String(v)
+ }
+}
diff --git a/cmd/gf/internal/cmd/gendao/gendao_tag.go b/cmd/gf/internal/cmd/gendao/gendao_tag.go
index 6feeb8081..25bc84258 100644
--- a/cmd/gf/internal/cmd/gendao/gendao_tag.go
+++ b/cmd/gf/internal/cmd/gendao/gendao_tag.go
@@ -60,6 +60,7 @@ CONFIGURATION SUPPORT
CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
+ CGenDaoBriefTablePath = `directory path for storing generated table files under path`
CGenDaoBriefDoPath = `directory path for storing generated do files under path`
CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
@@ -69,6 +70,7 @@ CONFIGURATION SUPPORT
CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
+ CGenDaoBriefGenTable = `generate table files`
CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
CGenDaoBriefFieldMapping = `custom local type mapping for generated struct attributes relevant to specific fields of table`
CGenDaoBriefShardingPattern = `sharding pattern for table name, e.g. "users_?" will be replace tables "users_001,users_002,..." to "users" dao`
@@ -98,6 +100,7 @@ generated json tag case for model struct, cases are as follows:
tplVarTableNameCamelLowerCase = `TplTableNameCamelLowerCase`
tplVarTableSharding = `TplTableSharding`
tplVarTableShardingPrefix = `TplTableShardingPrefix`
+ tplVarTableFields = `TplTableFields`
tplVarPackageImports = `TplPackageImports`
tplVarImportPrefix = `TplImportPrefix`
tplVarStructDefine = `TplStructDefine`
@@ -126,6 +129,7 @@ func init() {
`CGenDaoBriefStdTime`: CGenDaoBriefStdTime,
`CGenDaoBriefWithTime`: CGenDaoBriefWithTime,
`CGenDaoBriefDaoPath`: CGenDaoBriefDaoPath,
+ `CGenDaoBriefTablePath`: CGenDaoBriefTablePath,
`CGenDaoBriefDoPath`: CGenDaoBriefDoPath,
`CGenDaoBriefEntityPath`: CGenDaoBriefEntityPath,
`CGenDaoBriefGJsonSupport`: CGenDaoBriefGJsonSupport,
@@ -137,6 +141,7 @@ func init() {
`CGenDaoBriefNoJsonTag`: CGenDaoBriefNoJsonTag,
`CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
`CGenDaoBriefClear`: CGenDaoBriefClear,
+ `CGenDaoBriefGenTable`: CGenDaoBriefGenTable,
`CGenDaoBriefTypeMapping`: CGenDaoBriefTypeMapping,
`CGenDaoBriefFieldMapping`: CGenDaoBriefFieldMapping,
`CGenDaoBriefShardingPattern`: CGenDaoBriefShardingPattern,
diff --git a/cmd/gf/internal/consts/consts_gen_dao_template_table.go b/cmd/gf/internal/consts/consts_gen_dao_template_table.go
new file mode 100644
index 000000000..a60c92d5d
--- /dev/null
+++ b/cmd/gf/internal/consts/consts_gen_dao_template_table.go
@@ -0,0 +1,35 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package consts
+
+const TemplateGenTableContent = `
+// =================================================================================
+// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
+// =================================================================================
+
+package {{.TplPackageName}}
+
+import (
+ "context"
+
+ "github.com/gogf/gf/v2/database/gdb"
+)
+
+// {{.TplTableNameCamelCase}} defines the fields of table "{{.TplTableName}}" with their properties.
+// This map is used internally by GoFrame ORM to understand table structure.
+var {{.TplTableNameCamelCase}} = map[string]*gdb.TableField{
+{{.TplTableFields}}
+}
+
+// Set{{.TplTableNameCamelCase}}TableFields registers the table fields definition to the database instance.
+// db: database instance that implements gdb.DB interface.
+// schema: optional schema/namespace name, especially for databases that support schemas.
+func Set{{.TplTableNameCamelCase}}TableFields(ctx context.Context, db gdb.DB, schema ...string) error {
+ return db.GetCore().SetTableFields(ctx, "{{.TplTableName}}", {{.TplTableNameCamelCase}}, schema...)
+}
+
+`
diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go
index c335f7f20..d34c58ed3 100644
--- a/database/gdb/gdb_core.go
+++ b/database/gdb/gdb_core.go
@@ -757,6 +757,30 @@ func (c *Core) GetInnerMemCache() *gcache.Cache {
return c.innerMemCache
}
+func (c *Core) SetTableFields(ctx context.Context, table string, fields map[string]*TableField, schema ...string) error {
+ if table == "" {
+ return gerror.NewCode(gcode.CodeInvalidParameter, "table name cannot be empty")
+ }
+ charL, charR := c.db.GetChars()
+ table = gstr.Trim(table, charL+charR)
+ if gstr.Contains(table, " ") {
+ return gerror.NewCode(
+ gcode.CodeInvalidParameter,
+ "function TableFields supports only single table operations",
+ )
+ }
+ var (
+ innerMemCache = c.GetInnerMemCache()
+ // prefix:group@schema#table
+ cacheKey = genTableFieldsCacheKey(
+ c.db.GetGroup(),
+ gutil.GetOrDefaultStr(c.db.GetSchema(), schema...),
+ table,
+ )
+ )
+ return innerMemCache.Set(ctx, cacheKey, fields, gcache.DurationNoExpire)
+}
+
// GetTablesWithCache retrieves and returns the table names of current database with cache.
func (c *Core) GetTablesWithCache() ([]string, error) {
var (