From 73092a55f9d4c5354b409eddd9558910a80116cf Mon Sep 17 00:00:00 2001 From: Filipriec Date: Tue, 1 Sep 2026 11:07:22 +0200 Subject: [PATCH] history and a single alias reference --- common/proto/table_definition.proto | 44 ++++- common/src/proto/descriptor.bin | Bin 227570 -> 230833 bytes common/src/proto/komp_ac.table_definition.rs | 177 ++++++++++++++++++- server | 2 +- 4 files changed, 218 insertions(+), 5 deletions(-) diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index bba0b921..b3f6d94e 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -58,6 +58,9 @@ service TableDefinition { // Returns the stored rename history for column aliases in one profile. rpc GetColumnAliasRenameHistory(GetColumnAliasRenameHistoryRequest) returns (GetColumnAliasRenameHistoryResponse); + // Returns the unified append-only history for column and option aliases. + rpc GetAliasChangeHistory(GetAliasChangeHistoryRequest) returns (GetAliasChangeHistoryResponse); + // Atomically replaces the aliases and presentation order of a table's columns. // Physical column names and identities remain unchanged. rpc SetColumnPresentation(SetColumnPresentationRequest) returns (SetColumnPresentationResponse); @@ -485,6 +488,43 @@ message GetColumnAliasRenameHistoryResponse { repeated ColumnAliasRenameHistoryEntry entries = 2; } +enum AliasChangeKind { + ALIAS_CHANGE_KIND_UNSPECIFIED = 0; + ALIAS_CHANGE_KIND_COLUMN = 1; + ALIAS_CHANGE_KIND_OPTION = 2; +} + +message GetAliasChangeHistoryRequest { + string profile_name = 1; + optional int64 table_definition_id = 2; + optional int64 column_id = 3; + AliasChangeKind alias_kind = 4; + optional string option_value = 5; + uint32 limit = 6; +} + +message AliasChangeHistoryEntry { + int64 id = 1; + string change_set_id = 2; + AliasChangeKind alias_kind = 3; + string profile_name = 4; + int64 table_definition_id = 5; + string table_name = 6; + optional int64 column_id = 7; + string column_name = 8; + optional string option_value = 9; + optional string old_alias = 10; + optional string new_alias = 11; + optional string changed_by_user_id = 12; + optional string changed_by_user_name = 13; + string changed_at = 14; +} + +message GetAliasChangeHistoryResponse { + string profile_name = 1; + repeated AliasChangeHistoryEntry entries = 2; +} + // Describes a table with its columns and associated scripts. message TableDetail { string name = 1; @@ -530,8 +570,8 @@ message ColumnBehavior { // This is not an authorization boundary; data APIs still expose the column. bool hidden_from_forms = 6; - // User-selected labels for stable option values. Empty means clients display - // the canonical value. Writes may submit either value or alias. + // Current public aliases for stable option values. Identity aliases equal the + // canonical value. Once renamed, public writes must use the current alias. repeated OptionValueAlias option_value_aliases = 7; } diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index d5dd41f1e9af0fb61610d6ed3adf706bf08e7126..f6f8374b6680d6d6eabd50bbc1d4d96fe9a9cbf6 100644 GIT binary patch delta 15676 zcmai*dz@9pmG4j0u6_FSKHWfX8oFt^p?N=)Mg$#6L<2}fjVOpFV`eTAX%jw!paSOl znVTF@P!v=I%w~L!L2?}&f(gb}oQR1a4l3~xi3lP_!3hvw2nGXszpEa7Ff*Ue{ja~f zYW-@}s#T9&XZI%`SN~#BhwC3xL+{bQ{h)2wJ!(d6%^!5qcy{ZY(KDt`ojvvkQ)hlZ zo3TcH|FpC@sl0sFjJa3NoHBh{eblT5M&s3_f_rq%w1rBg)0T zc~Exs!>ZvQ%4)6WQ8=m6R+K-}{z=uWtL99fHFL_fQ)kR=t&g#*9Iq!8-P23tp{Um; z@r>zLPM=esr$Y542V=S>wae}-)V7SNN|Gt<{*CFFR8KixwfE{csVh72lb@>|BYP*+ zmrMUzr_64hBc0OH@}#1Bcv0(|bEf@Gm!#LBOATeUzwOepADh0}=%1@P6))>GrM}dZ zBy*;IZ$|5snNzQ9weD9=s!!?|-Fl4#ugX?6lREmcG1py8i6llzr6ZEszcsNvskTP(q?)f7NteVG;ufr?&Z+Mp zbthH&C!^>5e@5IE+rCbgoV3{9u`yke&QpSRxf5gRk}m)4u{hfM4wW>0by9R)t45^f zB^9kR=Ug+rbvDTp4J@8K%%*!%&W*O4)~ee&_P#3VSbk>nCGC|ojsDg-qc55=cKqlG zXOGJ+dtKL#Y)tBpe>mm5b0(ZMW$Xpty7>GFomBcimR@k-p>9gm|y5_p{RO?-r|FJN8d6Vi>{gtA&xtr7gowVJmlZrG}xi7MxZB`el z32mQmR#TGF#fi!1bX6LS(%)+s-#n>x&fIHe&TgLbgVyG`GpAoMy>(ji)T^#)ojGmD zteG>eYyN?AqWOwh*EGA-ZJs)FTC6J&=YPPYV=5W2-Mq zmMiN*bsCM%roF0`4z0#&bh}kGR-@aks<9e9_OfJ^GwP5= z+rL+rmKee4{CthC)d`#P)4qYQIe+MwBuTW%rRKuiB*ov6$zgM0VMtO;jLGR-8coy< zVj>U=6#`LlVr7>=$W5&8X600BCg;Abl9K2#t)j_=7OSU3?_%9-Z2^^xCEL{3)d^F5w|I!&)JoSDgx=Jyb;*A*99U3xMRxcPYTw8! zv`rj&mgiy7`3*^x#y-{^2=goY4@eF=a|U2W)@{2wG;&6}xu!QWigt_;lNM&A-MqQR zd`4qaveTJES7&Fxsdk-kb-TL}23Px0&^nSTjKa&#z@*W&*@ZjQt0S*%Z_m))we9U0 z%&$%R`SuLv*A5(%9CPuZ=8xLGyOZ_w#2>Xc7-R9HN}Ig+8)NaKp3TY6T!Z=4%u`vs zOWpT()ufEp`Br5(8n6GfyBMS2s zS?m#o`D(zR*IOwHo#%-!nF zGZvSdt)wf9Rk5eHsYGJ2Y91C4iN$KfsmYCb5-m#e_o>{!w{>_&>8R6vs?eD1k_bj* zm|5A@{GPf@wX6(L;3;A&Lli*7R;q^X$(qO-QTj;R&-bXcYUm?nBNEFzqAELB4zfiefWsBce+s!XjVbHQ=OUIYG+qyR zM`|8Zday6l#-bYx8E-*97$8cIDbh#c45IXyB7drIDNalIHkJF0Qq1AVkT#}G6$aW? zVhPL>iiJfCA!I?9B_MU5P$ac4MfM3rR*QqNwE3jcu5S>gU@(=wJ?Z;alFHaV89EnB z=hiEIiWip7fv$5DGUV%3aZo5lYP}kKQb3f}tKlQO7tm8mf6W(0D1kvKLg^`WVzGZH zM(QawAhgRY1y389JTD0tiyO~mm+n(rhCZWM4qdOAndTYAdgu|GXA}$Ke`tc6PxG5q zZcE!m`&qn7n^l4H7*ctO>+?!CStE$xfG#*7lFzHk`cR7G^QyZ{Wih4jKb1bw7qY4e zHU_k%O#=dA`k!j>37G1*luPq3s@!XCq+@C2MHTlJ*;sZE^ODlT#ZZVsuq7Y^@{$^M zvad_wR;6tt)RnOWIW=2TMcu8cpY187(C?I%30V?haUZts3)t4iC&Ns!8~ssRI& z4`q&4r1>{g?yc;!57Y;xH&j9P2xBTFK--meg90H5x*-Em+^*P;Bnv<~vR$zsIa3PX z45M9PrveyEC46s&(WVsBH^XR`DkMNVlRn~@5Yr1RAI1{ ztdt<^R~&O>tRW;pw~2vB?pGXid?}LqW&M}b) zXeqlWfSrHa7cs1 zx_wyEV5O|0iHzmv*;${eRi}R*y3Rwo{<-3GCcOcX_*`*3^GK_o%WVFdRe+9V{SK+q zM;$9G$jBZGTV7(*`PK%AJT z{aFG;VxAsxO0q~+_F|g9RpQKGm=`yCU)E70W|h~y&ecT5n; zMcVI}Md|cn?N=BGQ!toHR2OT%!cdCoV(nL$Qcx!oYz@Es=p+ zED2bYR9l`^9Z|QpEZ2U*@Q~)0Yfgl&`8+nuH3#M!oef9c71{Gg)PmBA@{m+uvqJk* za#2@cvqEz|lw(y@n!iWq{#CnE6)&yk9?ct#Ox-HUk$bgYKp;8?x&;KJ?!DSCARwyu zYQKO~Y3@wSecG>QRW?aLmn5Jq_3Igk?R}c{%r#4n+#m9*$|eQqRtyl+`*p#sY9OZf zhy1D%dO*u&TVixT1^{*g0Mdg8LVkfrJ)mpc>;k-Zaet-$nwu>!r4MO$gc5RSw`V~rKcqP`oxxaCr}>9t+|3Eh}AaYujo$hL;+&*inx5WHGy8w{;$!q zhrAwgquNIHbzR|J2|%f&c_p~cnlLEav$JFU&qKDC9g}&rU01pdu-eY6?Yg#0a-lV0 z;C5yo#(GlA&T=bqJld%%f}b*fcIvcqa;waRYMDQ~vsrn)xU^eq_ln3vYi~?M+bI#o%<+zzCw@dxK9^)^3<3P;@W|%v7pBf zIS_)wLxc{5=?T)&12R1&o*kr>53@T9#Ph>21U!_d+RsW5lMiK9o<-Xo)BHi5dnBu= z)ML|wn)iqc5b79lRzIZmvFwUUJ)!21PHK}uNnW0dSD$5@D)k8?K4ULWIwlqFF^znt zi(SeOXy!B7T-GRWNsXgf-$bt+arAggaqp-uc5Sy52aifxonT#I%3dGof5|F}dT@Gu zM749Rpq;NbMA_J)K5zI9k*V|oZsy()G4{?m9-w$bM3+Z;OPXAe{idkDK72vc-U&C0 z7evL5?S|sYf{5JvKi-g0y(Jr3rGI?ZEs-fVAW3;kR9)9@C?j!8RNuS&0Hs?ZcDYNu z61+J3xJrNLti{JG$y&BJs_xuwD684xsCGd4fmlXta)0lYWM9i}tJdEge#h~hu{&DS zJ|fEPX%Qnb#v9Vq(yV(2eb$Jjktwt{AoFi&R9TLK%)q4*g*Dn+(%ltp%R1Sv}K7aWAWkEL~ z?=O!C4-mXxd>QKvY4O2qZ6`f$%!B1PG8=L6!Kga*z2bpXj5>EKKS1fhh%=c@Gs){! z*{L;p$f#A3-&s2994f1#VrrL65RFw)XLn2lQCJmmthF!b9c9c{Xa8EGw~SvM`8|<` z@-*TmOjcbGo7E9JyX?}P()^kz_h{sHX|7?-nuzo8MZ~I;IJ7qVWvVYOtql(GkTF{u z`BMvs$=WFGVZ}kj*G9c$pVy`)&HpmWJ?6!0sQJr?wMF*g8WCR?X?JM>kwT!`PeFRU zE-Jdqvl`t;T3HwMJHfU>F|DkNT86SzaKuXUZBcH0_HUi_gxa>K(42go22yF@$w)Ue z49SLF8FkHi)#~0YJa8ukijjOW@+VOc$tNW>zlCJyH2>=;_e^$mtv;{x>&PE%JB#Gg zNLnu-A^|!<5W%N|Ac)}8A}HPMEF-fa@+U!v?t-qnAl=;%u>i>kfwpp;I|+7$k=hWk zR?B)>o93U5a+|Y>UG&(}vr)laht-O28zbGzN4-(?z=VLgY`15Q3mPDS`;T5c!iLh~Nv6KPh&R)?SR<=?Nj}7U;SK z+R{q*MgU^^V$`|Tj#jCQbnB%s(h#OJStD2yKo0wI75j7))g? z-5M3#NK4bHK{76NY5vV9_s8tBE>hacO7h4TLG^dIQ>0KP^E_cZS%O z>SSEriu^l2ge@4F73H@ibz~Y*itSsnIJ#z`U6Fseth3_+hGu14c18Z>l2TjQzg*Ty zR=*wTrji$y7dJTA$~O0Q~rr#xGV>{`ZT{M%KcZitU-?}?THF<|7lFUjN0B1dI)DgCkP_A zHzX2>;NB4WdWr4(k-w3K2npy$7{t~0BY$xN+RB66;$DK0dOxyP(waWz_eHr6+^!Hy z;P*wbop`bR9b$i^-Mysy{QcBS^lOq*_L{-Y@Oncua#QS+myAU{SL(@g^SaR?wp06`Z(kh&j-0D|=T zCm56@;|`XU z>wm{J1U?3bd8&$w6X4vxg#g;Vk4Z zcp-D-kX`!ag_&Zc4ux|9h}0o>P7o<79}cTLL)CduK*|DZ%Eria}suT4XmKN95@ z8h3tapyrWq#AuMg`aIGl_ZkNx3%k_fZ5Zj|+KWz{?7V-fyV#X z*`SLkfkCN=(t@&55v2vj|MJ|ROGTs>7=C(oUR9;$CgZO+8*~*?V34Xp>ZY=kT-)7b z_z+DN04k$&lNsc8lLlR#nw!hxRgEba#)}V5Kz7uUv*jZbxU2j$qfK`%k4^42KW)2H z^;YAL7TsmqE;9a<4Iv9US&+Jmj6WZMs4g;o4s@5fwb*F)g8@X}7Ms(3=U{Smu_?N1 zU(nX>GuUW_?*|}K%Z&Rq5L;-u(Jl@UVFH7a>;cOSZ|$xf7M&8@)tz9dZH@iC zbfc^~cZI}+90n;_gzgI2L@7?)W&E%3AWC-`cejO8)cuKZzrPCM1!!9>31j;c)5HEA zD~Rn+jQc$nq;h8b*$zSq3?m|oP9~Y?IwXruX8iiqD2vXD@?grM1G*Os3Nc+_n*0|T zFt#gXH2K1dW?6OaHrWeJ`odEHOz$oarYtgdOU}4fWs$jC(*Fs$Lu`~)<^hvk*h8TGqhzIZr)Be^c5*L0@ihL%a821z(s@nUP||sg7*4i^Wb>m&H#U4T`}qoeQntUB?oQj1 z1w3{`2O{yP@joztNIYt|%aPA;nuOM6BYW!!7|K?;uH3e4mFrA}+jJ?Fs)kEn=QLUR zc(%T`o;ae(Zj_IQVFNLI+!TVL^&@(=P|Fl`nr=nlG4nd22IDe1o!xxp+}U%Q z`2y8`ba=UM(0)qDhlG-nctjX*sU7jK<>|15P)vWGHjVBO57M8f4QKeVq*9MG|67xL zK6}5fKBLrwiofL-bGyX#kW_lsX!nK-5hTzpaUgY{4dDe5eOAIND_jp5?TyC2IzyO( zE*C&s>JMEYrW*~1F1tGRkW<$tz=yVN|xEx314R4$y;3JjF8}yI6wQYz?slQQsP3*;9J_ zJL4}-AWT8$7-&oVks8GGcU;%mpZ%ND{A(t+-Kd6dHjkb&>q^NuK2pt|7@*HAHDmai z@vlS8;^*(fRt?bz=o$g3`}?qrfi&{_uvIsUf3Jrn8^RO}rsCi0VacWx)7NFmo-9#s zma*OzHXVpT09_t~Ftl&Z#GoAyfcJ525!e}3sj%^l(V(o2G}GejPuXQ10rKlnOb*Dt$W^pfZ z_ATS@tRQSb7ZuQ!`a3HS+qYyvm7w&JpzI1kfd~rdf&vnhT_GqSO1nZ(z$onm6P00B z3gO*Z%V0fZL@yha-61LKnTyEi-f8|llY2kAW3Zl3>P^M>3_mrBcfBPj zdqPkkItIFqfz;h&d^&=N?vbE4QwsN%O(iB^FqN3>Et^VA_WF2g(cuv!_aKG1{h?3KMadEh|q`O{0E9< zIREvL-1sQG;z0NS1|MY6`Y7Z*rI>yc^1g4HKWK7COv$}(_oeDV1Vc z=n@~K?x!K~L1aG-W87EzeJJETgemAE3ffYi_h7_{^iW9rz7o;HA)*krpz95Y?coqn zkY*2uMY6BZXW>W<5f{+S8IX{E7D5W5^qCK7$-vgwpQ-ywO#c#c0>TS0cp)+UOPDp3 zV)_@C658}j^M5tD8)6sIe$@PH2x&hF>Cup+5UOCoy;H$dJ{qzVMD}RN(tgtOW5FW` zThPT6w52{tK}?T@B<&|5{UU@E!W49!0af~4*q@PLY`+LG?I-l5Ke!tRThL_zNV8vt zLlS5!b4ZdOocc)&=f&BbLs>omEa%1Ttx5>z#eO-a6w7(BUyl2y`T22fkq=>iYR-=f z_R~kxUqZMb_8TFDD(L(HskuOf6kIS-H?FORcPC+iZX z63OLdQ;FpA*e4^Um@XH`T5xP&nqLv;?vJyNPu2r#2U2rI%oYE45FIFv-5qB`hU<$) z0Epfl;sjFl?l80@ zIQQ>aj}iLpS_$Zbaa<>-w%CX_E930C5&E0|3!rRe><+V1Mn0^JIdbxiIiH~Ovu&)a zWrG8-TNM}WH<&^g9*-DWnu7jxhtC(M3(8@&f2Yr{2Ptif`Nm?id@2D;U!KY?I8FcN>y`-6 zQ+$_bf4a60FnB8V-znG!1nH@mbMX(o02MZ5=Z(}?pDx7`;SI+Ni0d2TqWj9g)<9r` z3_9Q6Iv428#_TU6^&YDrGiYP%KN1iFiNr=p8u`Y;K0slkDEv%55|Af6*wWVR>-_hk z?S)LFEyqj9RN4~rX;6@m$+Sf#qI}>X3Jlas*__k$S>Le4j_^`!+=n9e0Rk_@bv@e! zWKO*l^Ap8&UVtWFiA~Rj>DlNrbwiep(vxj>`Xg?9uLv+<)wd zd-X|P2)*G3WOuglOugw0>AqZn>^?q0=5OfX zjcC{`emAb_p4_dHf(#$Ju9}ntY_NU8|SO|@S`$Rp{2cXbpIAv{FJNCugSj=u0BCS8jZW^QiX^ito68nQVpB!f; zsr^A*Y&`xELLbO}_v^@y0M|fA+J=wSZR%Wv?CtUqK22 zpm`)7Hr#&gHAq5rEE_RSj~T(=B>u73AB8})j>Y~?5Jc%%+|^wmg6JH(dG$Emwt8GN He)#_bxjnMM delta 12890 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 Zr8P+(|2HHMJ8OQ|F, } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetAliasChangeHistoryRequest { + #[prost(string, tag = "1")] + pub profile_name: ::prost::alloc::string::String, + #[prost(int64, optional, tag = "2")] + pub table_definition_id: ::core::option::Option, + #[prost(int64, optional, tag = "3")] + pub column_id: ::core::option::Option, + #[prost(enumeration = "AliasChangeKind", tag = "4")] + pub alias_kind: i32, + #[prost(string, optional, tag = "5")] + pub option_value: ::core::option::Option<::prost::alloc::string::String>, + #[prost(uint32, tag = "6")] + pub limit: u32, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AliasChangeHistoryEntry { + #[prost(int64, tag = "1")] + pub id: i64, + #[prost(string, tag = "2")] + pub change_set_id: ::prost::alloc::string::String, + #[prost(enumeration = "AliasChangeKind", tag = "3")] + pub alias_kind: i32, + #[prost(string, tag = "4")] + pub profile_name: ::prost::alloc::string::String, + #[prost(int64, tag = "5")] + pub table_definition_id: i64, + #[prost(string, tag = "6")] + pub table_name: ::prost::alloc::string::String, + #[prost(int64, optional, tag = "7")] + pub column_id: ::core::option::Option, + #[prost(string, tag = "8")] + pub column_name: ::prost::alloc::string::String, + #[prost(string, optional, tag = "9")] + pub option_value: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag = "10")] + pub old_alias: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag = "11")] + pub new_alias: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag = "12")] + pub changed_by_user_id: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag = "13")] + pub changed_by_user_name: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, tag = "14")] + pub changed_at: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetAliasChangeHistoryResponse { + #[prost(string, tag = "1")] + pub profile_name: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub entries: ::prost::alloc::vec::Vec, +} /// Describes a table with its columns and associated scripts. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -545,8 +601,8 @@ pub struct ColumnBehavior { /// This is not an authorization boundary; data APIs still expose the column. #[prost(bool, tag = "6")] pub hidden_from_forms: bool, - /// User-selected labels for stable option values. Empty means clients display - /// the canonical value. Writes may submit either value or alias. + /// Current public aliases for stable option values. Identity aliases equal the + /// canonical value. Once renamed, public writes must use the current alias. #[prost(message, repeated, tag = "7")] pub option_value_aliases: ::prost::alloc::vec::Vec, } @@ -900,6 +956,36 @@ impl BooleanLedgerOperator { } } } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AliasChangeKind { + Unspecified = 0, + Column = 1, + Option = 2, +} +impl AliasChangeKind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ALIAS_CHANGE_KIND_UNSPECIFIED", + Self::Column => "ALIAS_CHANGE_KIND_COLUMN", + Self::Option => "ALIAS_CHANGE_KIND_OPTION", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ALIAS_CHANGE_KIND_UNSPECIFIED" => Some(Self::Unspecified), + "ALIAS_CHANGE_KIND_COLUMN" => Some(Self::Column), + "ALIAS_CHANGE_KIND_OPTION" => Some(Self::Option), + _ => None, + } + } +} /// How a column type is spelled in ColumnDefinition.field_type. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] @@ -1403,6 +1489,36 @@ pub mod table_definition_client { ); self.inner.unary(req, path, codec).await } + /// Returns the unified append-only history for column and option aliases. + pub async fn get_alias_change_history( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.table_definition.TableDefinition/GetAliasChangeHistory", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.table_definition.TableDefinition", + "GetAliasChangeHistory", + ), + ); + self.inner.unary(req, path, codec).await + } /// Atomically replaces the aliases and presentation order of a table's columns. /// Physical column names and identities remain unchanged. pub async fn set_column_presentation( @@ -1651,6 +1767,14 @@ pub mod table_definition_server { tonic::Response, tonic::Status, >; + /// Returns the unified append-only history for column and option aliases. + async fn get_alias_change_history( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; /// Atomically replaces the aliases and presentation order of a table's columns. /// Physical column names and identities remain unchanged. async fn set_column_presentation( @@ -2353,6 +2477,55 @@ pub mod table_definition_server { }; Box::pin(fut) } + "/komp_ac.table_definition.TableDefinition/GetAliasChangeHistory" => { + #[allow(non_camel_case_types)] + struct GetAliasChangeHistorySvc(pub Arc); + impl< + T: TableDefinition, + > tonic::server::UnaryService + for GetAliasChangeHistorySvc { + type Response = super::GetAliasChangeHistoryResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_alias_change_history( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetAliasChangeHistorySvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/komp_ac.table_definition.TableDefinition/SetColumnPresentation" => { #[allow(non_camel_case_types)] struct SetColumnPresentationSvc(pub Arc); diff --git a/server b/server index 7bb3706e..1804c1dd 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 7bb3706ec6e670e1e7d6495d2f699d50a9bc41e3 +Subproject commit 1804c1dd19206ff3ac21f7a849807fb117dd0ad7