From d193000aece9ca7751c64f0042f74d3a2cac8b2a Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Fri, 24 Nov 2023 22:45:44 +0100 Subject: [PATCH] Add controller to database --- ...417afca55278e269f12203f4fc83096944810.json | Bin 0 -> 728 bytes ...f1ff46abbb21dfc3eb3f4f38b251f99d10abd.json | Bin 0 -> 797 bytes ...83d24f993442ea05e17910f587a4c92d4e7f5.json | Bin 0 -> 295 bytes ...b94e91e7851a53ebae17a26b19300b83d7dac.json | Bin 0 -> 277 bytes ...b5abbab1b0c8eec7cf11597267de780299d0d.json | Bin 0 -> 468 bytes ...ebc2015558f66dbcd00cb4ce559d80f2bd023.json | Bin 0 -> 683 bytes ...8fdab37cc699720e5484c30697b5566b8d513.json | Bin 0 -> 670 bytes ...73396e85db762d482607e4662e788c5542fea.json | Bin 0 -> 783 bytes ...31665a416687772b95d159e5d3e98cde3511c.json | Bin 0 -> 787 bytes ...07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json | Bin 0 -> 268 bytes ...ad8c0bacd8d9e73e375dc35e759bdb82369a1.json | Bin 0 -> 718 bytes ...120ecf4e5542011b781d8023bdb422580d97a.json | Bin 0 -> 731 bytes ...5b7b4da78ab8acec79c7e7ea51ce5c9414bcb.json | Bin 0 -> 445 bytes ...11691dae057a431fffc27417e4f5504dcfb30.json | Bin 0 -> 257 bytes ...febe44c1250f25989034a3f9e4e8bcb39dece.json | Bin 0 -> 259 bytes ...e86d095af0af9545252cf06f30827e9ca502a.json | Bin 0 -> 846 bytes ...3086dd6e4e204e9e063535b19db666476fe88.json | Bin 0 -> 900 bytes ...97c41c9f71f6a4a3f44221f5ec012c99ebf54.json | Bin 0 -> 796 bytes ...d962b1da35b5b2b663f759f6af106650951b8.json | Bin 0 -> 467 bytes ...2697741fb210ea8bfc3d61f1508106c0b076e.json | Bin 0 -> 684 bytes ...d36ed21da18ceed5b71e51a1e749bab466422.json | Bin 0 -> 481 bytes Makefile | 5 +- emgauwa-controller/src/main.rs | 21 ++- emgauwa-core/src/main.rs | 4 +- emgauwa-lib/src/db/controllers.rs | 122 +++++++++++++++ emgauwa-lib/src/db/mod.rs | 15 +- emgauwa-lib/src/db/schedules.rs | 34 ++-- emgauwa-lib/src/db/tag.rs | 10 ++ emgauwa-lib/src/db/types/controller_uid.rs | 62 ++++++++ emgauwa-lib/src/db/types/emgauwa_uid.rs | 146 ----------------- emgauwa-lib/src/db/types/mod.rs | 7 +- emgauwa-lib/src/db/types/schedule_uid.rs | 147 ++++++++++++++++++ emgauwa-lib/src/handlers/v1/schedules.rs | 24 +-- migrations/20231120000000_init.up.sql | 9 +- 34 files changed, 411 insertions(+), 195 deletions(-) create mode 100644 .sqlx/query-08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810.json create mode 100644 .sqlx/query-1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd.json create mode 100644 .sqlx/query-1d658709678f72291d835ef2a4183d24f993442ea05e17910f587a4c92d4e7f5.json create mode 100644 .sqlx/query-1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac.json create mode 100644 .sqlx/query-3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d.json create mode 100644 .sqlx/query-457e9d4808332255ed7354a28e6ebc2015558f66dbcd00cb4ce559d80f2bd023.json create mode 100644 .sqlx/query-66a141b71041a7827f1932e6e288fdab37cc699720e5484c30697b5566b8d513.json create mode 100644 .sqlx/query-7519da166e2e0b6de4c02559fc173396e85db762d482607e4662e788c5542fea.json create mode 100644 .sqlx/query-7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c.json create mode 100644 .sqlx/query-87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json create mode 100644 .sqlx/query-96f34b8654265ea5ab5210ab5dcad8c0bacd8d9e73e375dc35e759bdb82369a1.json create mode 100644 .sqlx/query-a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a.json create mode 100644 .sqlx/query-a6dc153657cb3fefb5ba5b763dc5b7b4da78ab8acec79c7e7ea51ce5c9414bcb.json create mode 100644 .sqlx/query-a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30.json create mode 100644 .sqlx/query-a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece.json create mode 100644 .sqlx/query-acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a.json create mode 100644 .sqlx/query-b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88.json create mode 100644 .sqlx/query-c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54.json create mode 100644 .sqlx/query-db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8.json create mode 100644 .sqlx/query-e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e.json create mode 100644 .sqlx/query-ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422.json create mode 100644 emgauwa-lib/src/db/controllers.rs create mode 100644 emgauwa-lib/src/db/types/controller_uid.rs delete mode 100644 emgauwa-lib/src/db/types/emgauwa_uid.rs create mode 100644 emgauwa-lib/src/db/types/schedule_uid.rs diff --git a/.sqlx/query-08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810.json b/.sqlx/query-08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810.json new file mode 100644 index 0000000000000000000000000000000000000000..b29819bd5882d448fac7fb50c95ed6cb4dbc8729 GIT binary patch literal 728 zcmbtSL2JVx6u$RYh^Kb+powXdUCIt+6iUX@c9$`NG1@q+=@N4&rT=}J)WM*Gv3U^v z-h1Eo{GR6#0I)1_O%EL21Gsr!OT*#R!5H_YVezzmw>VdK+@#kv8@>7~Z&{c*|fW_m#0g(C1z)g}PIU z7Rt@jk55q5axeSsVw&zN;Ld}p-Fr4z(YA84Loti+90y1+QIIGkG!!BtD8Y!}ITegX cQ815rFiQju0u%}&SRA5cmJkwS1V@+AC*z2(NB{r; literal 0 HcmV?d00001 diff --git a/.sqlx/query-1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd.json b/.sqlx/query-1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd.json new file mode 100644 index 0000000000000000000000000000000000000000..5be1688e89bdf4fccb72b2aecd37d3b2ed744a13 GIT binary patch literal 797 zcmb7?T}#6-6o&8jD?%>Ci>2*qCx|eqC``mT*oDZ*rwe4sOjB`;{dbeJ-3M$idlBe+ z&UwzuIcL)Y05USyc*)@{fbVZ(={UR&@^{VcI*R4Ee3*hO@HlyW0n}(`jZ)lJVD?l_ zN>ED%?!bLh#dt-nB!RZ^6wjeX)k|G@;Ufy54a8vASh83iG+$yYlNu{u(hpXe54!b= z&!rY7n0nSO&tMzec3Dl!kPkbucXt|%x+0%^gdQnFE+NMb2avt%p3;GcBjp!=Q>1g8Sc}97h=E! g5+chnAtXUe(3F!@WFjp{GC*QDWT=k`gS~C<4>&@&T&l1ANbGPZh=^WgCwV70OefC|@gC;fl`4lDu`$JYE`jQdv6T1FuNH^|tNC@~+ zy8d;;?7i%LKHMKLSvVQwG$0{Vuj{rc#ky&2!C!wkE~3_yx2SPayyR literal 0 HcmV?d00001 diff --git a/.sqlx/query-1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac.json b/.sqlx/query-1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac.json new file mode 100644 index 0000000000000000000000000000000000000000..e3769c96e43b4de2434cc4ebbdf9ca17799ce97d GIT binary patch literal 277 zcmXYqF;BxV5QX>rij(IKb=@=$5<*BsVqk!_h@q;`**=IRH!XHDpsN3!yO!~N@7;Ij z3P1(-IpBfR9jMLQOB_kf1piEwe+9n3K0R(bD88pKB`UD#wjdX94-YdqQI5w@B*4dW zx9%VY2{%ii;&XIjKeLs+{+Oo2P#Em?@`%w1GwVjmLT@vs>-gP|49s%ZzH)wLl@wq2lK88q6vc1f+K#?~6Sb4a?u#mec{%;(OU&;<0V Gx>SEpRZ6Y^ literal 0 HcmV?d00001 diff --git a/.sqlx/query-3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d.json b/.sqlx/query-3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d.json new file mode 100644 index 0000000000000000000000000000000000000000..4b85000268d4b52d888003f289dac6d48415dae3 GIT binary patch literal 468 zcmZutOH0Hs5We?UggJ_bz8`{kkcz^JSQk8qEJ-un2D0herr@&de>X`RK`@7qeDghK z<{S_Lob41nAlwjmd))|)aBbnQ8OM_Y>rH*XC0FF3d3h$9?kDp8SU0tOl3Q}O&^b=+ zD44Z58@VxP2RR?qWPlF`khS27K2dNdx0sO(BNvKFBMEH}%K?2l;!db;u-!ZtAP=@VQXoNJq0Fjia5$XF((Oy*5DPxN9$-vrs{1VN=5{LR>D1fdk`9wHL0TbCt31Ov<5`MG!?I%;WsI_jg>8x07HtGd zTA^!nGqfnMvem+)whrMSvN8RtwoZ5t0@@csF{Wx2+P&slnpWwW8`nbo9K(mZ%^H@v zE*n45W8Gyb-WPY#HAH$pj^zFndK{aa`3QY$8gULeBpg6~r=|z$5qbgN-8twrw7OCD z@0}#4=tqNx)qD(AyymStZwIYELtGM`>(8ol!Z>*MOT=|=3>U^L%ZqIH*pfmar8Ld0l%Qo?3l!V+0u3SmUP-n{dS>Ga(DUZ)74@P5Icn%9mV{n(id*&3 zsEkfDdfeB&0X`jo=7AgfASIpLVn)(*Qq@cwNob>|2M>o9cB(ELyTnU9&;-xJlV?ql zmXE#jc+Hx4ks&XvA9cfTadrt8Cg-iA3v^+lQlI$f?r#@6Yb>HTT8hu9~lj zid)v1iw@A)Gx(D5MtxUnnRNN*PHA v&q$aMmgP}ak|K_PLX_vFWIWDPRX?FHmY^NTL6-w5Q;HM@F4e?lW4<*qS8rHAKrh+?zXTJs?olUM`cNlhT1okfu&pIJ|(uCH+p2`47UuJH+aX1#=OdyTaLNp~xzJ7xc#%lJ~l)pMcD zim!gT!+ekZ=a<~4TFc-5!|>mGD%w)xuEzR1h?{qFU5Jmh^=k~=VNFPNQqo%b8;K{; zP}xFE{m)O|gnNTITGMvz&!a4|38xt$fFZ33hn%IjC?*Zd%JFzYpelG>63p`oleC1K R5DaBiv7*Rv0~C!8qaR9Gxhntw literal 0 HcmV?d00001 diff --git a/.sqlx/query-7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c.json b/.sqlx/query-7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c.json new file mode 100644 index 0000000000000000000000000000000000000000..c9041612822aac535347d355dd5cf63db86447e0 GIT binary patch literal 787 zcma)4-%GmJb#%83HVaOpAA%714fhReu3&V1K#A&zd#T1?D-Ja=yrYx z(0DqHV)Qf{PtiwHq*9bcBIydvx^dsCC4!^t1HG@J*T*Q1I^@0*XzOlTYaHsd5=>j( zDXYqCTIS8Vs1@*L0JKk-q@7N1L)Vz1lob~R%@t*!=WRbMw;M=Au`KoE<3jo_-Y36p zRohb6W2@Ypk|vgmFd>%Vv6oKo)?H>-JX zOYw$Q>Nk>5=`+|R;aIFPsQ_YX_e;b@ljoG>`hxagOPbeUyZ#fjebsC9a7OD)-z#7a x07)qyxsZ*4X1i_Gn9w%N19(N!dr5qfOkQDd6dq3Ah$A16- literal 0 HcmV?d00001 diff --git a/.sqlx/query-87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json b/.sqlx/query-87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json new file mode 100644 index 0000000000000000000000000000000000000000..63d4cfd0b89139c9471922e880c974556311ecdf GIT binary patch literal 268 zcmXZVv2Md46ouj4Pl1>_fJuy9De6+H4ymfTkupS)b%C3hijdZZp^EbEg{14pxj&bR z5Nh=h;Dq#%(9e&xi%1^||0JA#3qGs0+9>kUzrT^M6ijsIFhn?#?W^h)nazkcc^sT2 zEAn(dwm6%~=@PxF}{--uJu`z&kkj$_QgZ=>t~HYD#s`x4yk z^UKZY2=kbQwo*&cH3uyl&IH4H*^0*Kj-h1|xV8Y?wl$!z3t>5v=Fn;|0y_;0Q!ift!rACi2r>_+Asyj3?7nVJo=tF~a3=Db+CM`tq%-(#ZjtT>emyw(OZ_6a9nDAAiubhEi)^4aYj8utsrW1!4G`Pg z4-uEGl$1%cLAS6il?t5eKR=zXzO5cEs4C39;&4l*EDD3E9|k}J$^w5f);G^7kMc32 cIgfY@GXi9$K@z|$h#6;*Pr{f^@ZdD~0lxmN7ytkO literal 0 HcmV?d00001 diff --git a/.sqlx/query-a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a.json b/.sqlx/query-a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a.json new file mode 100644 index 0000000000000000000000000000000000000000..f6c5009b534f6a10a01ad93b1009d45e3b5faa60 GIT binary patch literal 731 zcmbtSv2MaJ6x{g=%M(-#u}L85f;ylI38iX)E>(r>*e0%wLmg*8h<~r`kgAm!sy2fa z-@AABaxdor0Fcq0CI=4h0bDF zlWYu{vf`{&++9ZC(o8B*y&^mK(p6J~CLyePtbh1NRy!)U8s4 zD!A&wL)d%yC+?;z( z&bc{{gpgY8EF4Ha2>JQ3tQ^TZ5C3-5oC26Fv*(R)uoo}+`rQ|;SgclAF5cFQmH6o_ zx~jH2&sg8y$BgYNEgpkv%+>Za%d;EJxW$rmXJ{Zk4fdK^Y%1krojDE%!rF8P+cNMK z0C8!A=5+%03wjT-rfzg)!La7u4>c_5PDeJgMeWDi(4Ui+ULVfyfhv#C@V_`}yyp;t zpUkU$=@^Itx4&?0XACIg<6hGhU|Jd;(}_kt eRIDMLftmplrgKawB}gKq1m|%SD^zmSkNyG8LwQ;N literal 0 HcmV?d00001 diff --git a/.sqlx/query-a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30.json b/.sqlx/query-a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30.json new file mode 100644 index 0000000000000000000000000000000000000000..bd4f9f704b9c1f5e75ba047d127e0bc4549c1306 GIT binary patch literal 257 zcmXZVy=ucS6o%p5S8>qX!HO-*E`%&q>5vfW7CM9w^m9}j6t}gkp@iIfkCLvBzVqr* z05E4xlRhJR1orm29T#K|nST<_zZsv@R=q2D?)N*0c0iW`M)-J9y@E74Si|Oi;V{~H zG`V!40yXScNaraM9F93k^sQ(5Y{5C}eMZ`kpTk1HZ=>t~c1j^=6LRoyq?ensLC1lF y>DH`VXT7W1#t7eOCyZ>+m#yTy>A2Ha3aRUgd++T^)?8xkg(z!hy{Sr8T#G+9R7C0k literal 0 HcmV?d00001 diff --git a/.sqlx/query-a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece.json b/.sqlx/query-a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece.json new file mode 100644 index 0000000000000000000000000000000000000000..b203d50a3630be5e7bf7ed06f3a1c1ddf6c0d506 GIT binary patch literal 259 zcmX}lKWoD<5QpL2pW@J*!GEMCDugUm=#WtA7CM9wq|>=JD0U;;LkaorJ*B1Vqu;%{ zW&pywQ*X~C9zndl?z)M@BJpLW_?_^{?997?ZT+$b9Qr8^Ay6FQzbLvbJ7{Q*)9747-dF9 literal 0 HcmV?d00001 diff --git a/.sqlx/query-acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a.json b/.sqlx/query-acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a.json new file mode 100644 index 0000000000000000000000000000000000000000..a85a6446b01cdf20f5772269751b39e4a6d4c906 GIT binary patch literal 846 zcmb7CU2DQH6n*zsggoi!Lsr|`?qy7nQIL++x|cB|O_LdjiEGm_5&!#=emDgMS4yGh zo_o&8&D{?GfJMHNctha>fQ#2T*AzMy{;FxYvtXPoW@!fEBzplwNnI)-Xjy?_%?k(E zRtJ<+;N6O-T51PiqWL!+fw!mma<%}&M+bE82&A)YnI>`a4DMQ+f>xyDxwYRLTVqU= zs5i1Qz@?o!R zPIX!OzHc(*GwG>N`7O$g!->dWYWD;^lg{XmzD4?E{+Gj#uQ|lG&ZWK8%j(`W^{Gd%o+tgrUHYLU%$Vf_>y-I5-S` E0nbIuKL7v# literal 0 HcmV?d00001 diff --git a/.sqlx/query-b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88.json b/.sqlx/query-b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88.json new file mode 100644 index 0000000000000000000000000000000000000000..24b6a1344b8e12b826c4f74fdb6a004790e20adf GIT binary patch literal 900 zcmb7CU2DQH6n*zsgglN>T2rGA#+ajH4yUXNdl;i6O=>%0;@Wgf#Q(nZQwtMZ9}4%} zd(S=h=Ina_Kt=;eHXPmnxO|-@n#1b?{>pi}D?xAOJ*+?$#+>DXTUX%GU%Y@&Nu4So zc$$IxWt#@m`P}ot^I|#&pScWmqGX`S8Z5f8)$j!g1GjCvWumty&-XgbmLaI>?kaJN zXJMMqLiFBi!AZpch9j;loGA}^7tQBDcq9OSXCR(wJ&e(>L=@18^9@R>t}*8 z7lKexc%-pJL`24$ss9No5$0c#!Cbm>Wmr17`sCp@zDtO4!vLAbmDmc literal 0 HcmV?d00001 diff --git a/.sqlx/query-c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54.json b/.sqlx/query-c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54.json new file mode 100644 index 0000000000000000000000000000000000000000..9d225d6659c235ef3162bdf32f0ad6e41982a56a GIT binary patch literal 796 zcmb7?T}#6-6o&8jD?%>Ci>AvyDu^(tC``mT*oDYQ(!>R_WTvS&#{RoW+U^4!)LsPo zo^zh_a?aWH0DuKuYO?0=2Ee!1sdOA(2l=bwb{oZfn%~dC6?mAvJOgI5vqmXyOR#v% zXE~4sxCM80QNc@QB@M8hhj^ocR*;6D!kqfUhzV*Lp@e-ww!`?=2K=gN5j z#oT61P*+M3s=|%5Cn1O`dE50rKeY+}MmSuNauv>l^%FE03W`uF7)!?@84F4|OEAht f3?r6_5fVd!Nnc=`rbrBY5Tz{3I28kbS^M5ErJTKG literal 0 HcmV?d00001 diff --git a/.sqlx/query-db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8.json b/.sqlx/query-db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8.json new file mode 100644 index 0000000000000000000000000000000000000000..f31d95b29c414b84f8010a3cd632f23106a97f89 GIT binary patch literal 467 zcmZutO-sWt7{2#cg!d>O`mv^sAReTmFcIs(gUCphWDR8LY*TQI{dbeJ5d?Dx#xe@*nGs__n{!A>nhT!jTT{gRB_*HZcoYwePG0vcO%sfSI(W zO#6?BdrPWE5mUosc6WDBK}W~VFUQ%cmW&jF$UGOK;xw&lOa;jbPH@gLPK%P2EN2)O UvMPzhRAwp0WlGA7)sS409{@XWW&i*H literal 0 HcmV?d00001 diff --git a/.sqlx/query-e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e.json b/.sqlx/query-e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e.json new file mode 100644 index 0000000000000000000000000000000000000000..e54e4a6d57525665b624da7938dc2ca3166e54a7 GIT binary patch literal 684 zcma)(TT8=05QX3KE0%o}AF@evsUU(9QK*Qu;Dbon%fu{flbB7wQu^QB-DI(aiVY!< zGjqN<%W|#e+|%Womec2yA`@X_si!eq@=AC4gwKEJu;f)$LwKl@L6VOy}ML$*wXSbTMG@Xz&RmKw9AmfAkZ3}Bz zmyM0|Soi4+PsP3O8b{iG?8zqGX*BUB(|m-!RSi3b>?RyQep5#W>JfSc-~Bo07CPAo zeL8sj7yT%>Tg}JVid)*5`}WY;Gx#OprTnaVBM{d+EfLp)Qj{rsL4UB4Dh+<>KR@GK z^L0F2QC-=4!931W$}->#W*kUd<^YL#^CU{=SvDgji%1AGXC;qCN=lN1ISEr9vM@^l H2m9a$wUDC^ literal 0 HcmV?d00001 diff --git a/.sqlx/query-ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422.json b/.sqlx/query-ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422.json new file mode 100644 index 0000000000000000000000000000000000000000..1967a26f3542406ea6db26d84841f21bcaa2ebb9 GIT binary patch literal 481 zcmZut&uhXk6u$dcgq(Ej(9{_1E@Ou>3evG!y^J9*=2Z(db!~)+_`fen&0w$`9^`x9 zkN4hnL(cksD}u z)Lc%ut##G<(Xd9b hm6{4vF;l=6J47{;bA~ep4Cg$NAh{4cj_K$&`T=i6bj<(& literal 0 HcmV?d00001 diff --git a/Makefile b/Makefile index 9ef63f8..c5184dd 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ build: cargo build -sqlx: build +sqlx: + rm ./emgauwa-dev.sqlite cargo sqlx database create cargo sqlx migrate run - cargo sqlx prepare + cargo sqlx prepare --workspace build-rpi: cross build --target arm-unknown-linux-gnueabihf diff --git a/emgauwa-controller/src/main.rs b/emgauwa-controller/src/main.rs index 020b544..ca61306 100644 --- a/emgauwa-controller/src/main.rs +++ b/emgauwa-controller/src/main.rs @@ -2,8 +2,10 @@ use std::str; use futures::{future, pin_mut, StreamExt}; use futures::channel::mpsc; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::io::AsyncReadExt; use tokio_tungstenite::{connect_async, tungstenite::protocol::Message}; +use tokio_tungstenite::tungstenite::Error; +use emgauwa_lib::db; mod settings; @@ -11,6 +13,8 @@ mod settings; async fn main() { let settings = settings::init(); + let _pool = db::init(&settings.database).await; + let url = format!( "ws://{}:{}/api/v1/ws/controllers", settings.core.host, @@ -21,17 +25,11 @@ async fn main() { tokio::spawn(read_stdin(stdin_tx)); let (ws_stream, _) = connect_async(url).await.expect("Failed to connect"); - println!("WebSocket handshake has been successfully completed"); let (write, read) = ws_stream.split(); let stdin_to_ws = stdin_rx.map(Ok).forward(write); - let ws_to_stdout = { - read.for_each(|message| async { - let data = message.unwrap().into_text().unwrap(); - println!("{}", data); - }) - }; + let ws_to_stdout = read.for_each(handle_message); pin_mut!(stdin_to_ws, ws_to_stdout); future::select(stdin_to_ws, ws_to_stdout).await; @@ -50,4 +48,11 @@ async fn read_stdin(tx: mpsc::UnboundedSender) { buf.truncate(n); tx.unbounded_send(Message::text(str::from_utf8(&buf).unwrap())).unwrap(); } +} + +pub async fn handle_message(message_result: Result) { + match message_result { + Ok(message) => println!("{}", message.into_text().unwrap()), + Err(err) => println!("Error: {}", err) + } } \ No newline at end of file diff --git a/emgauwa-core/src/main.rs b/emgauwa-core/src/main.rs index 4efb3e8..bfd365b 100644 --- a/emgauwa-core/src/main.rs +++ b/emgauwa-core/src/main.rs @@ -14,13 +14,13 @@ async fn main() -> std::io::Result<()> { let settings = settings::init(); let log_level: LevelFilter = LevelFilter::from_str(&settings.logging.level) - .unwrap_or_else(|_| panic!("Error parsing log level.")); + .expect("Error parsing log level."); trace!("Log level set to {:?}", log_level); SimpleLogger::new() .with_level(log_level) .init() - .unwrap_or_else(|_| panic!("Error initializing logger.")); + .expect("Error initializing logger."); let pool = emgauwa_lib::db::init(&settings.database).await; diff --git a/emgauwa-lib/src/db/controllers.rs b/emgauwa-lib/src/db/controllers.rs new file mode 100644 index 0000000..b427c63 --- /dev/null +++ b/emgauwa-lib/src/db/controllers.rs @@ -0,0 +1,122 @@ +use serde_derive::{Deserialize, Serialize}; +use std::ops::DerefMut; + +use sqlx::pool::PoolConnection; +use sqlx::Sqlite; + +use crate::db::errors::DatabaseError; +use crate::db::model_utils::Period; +use crate::db::tag::Tag; +use crate::db::types::ControllerUid; + +#[derive(Debug, Serialize, Clone)] +pub struct Controller { + pub id: i64, + pub uid: ControllerUid, + pub name: String, + pub relay_count: i64, + pub active: bool, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] +pub struct Periods(pub Vec); + +impl Controller { + pub async fn get_all( + conn: &mut PoolConnection, + ) -> Result, DatabaseError> { + Ok(sqlx::query_as!(Controller, "SELECT * FROM controllers") + .fetch_all(conn.deref_mut()) + .await?) + } + + pub async fn get( + conn: &mut PoolConnection, + id: i64, + ) -> Result { + sqlx::query_as!( + Controller, + "SELECT * FROM controllers WHERE id = ?", + id + ) + .fetch_optional(conn.deref_mut()) + .await + .map(|s| s.ok_or(DatabaseError::NotFound))? + } + + pub async fn get_by_uid( + conn: &mut PoolConnection, + filter_uid: &ControllerUid, + ) -> Result { + sqlx::query_as!( + Controller, + "SELECT * FROM controllers WHERE uid = ?", + filter_uid + ) + .fetch_optional(conn.deref_mut()) + .await + .map(|s| s.ok_or(DatabaseError::NotFound))? + } + + pub async fn get_by_tag( + conn: &mut PoolConnection, + tag: &Tag, + ) -> Result, DatabaseError> { + Ok(sqlx::query_as!(Controller, "SELECT schedule.* FROM controllers AS schedule INNER JOIN junction_tag ON junction_tag.schedule_id = schedule.id WHERE junction_tag.tag_id = ?", tag.id) + .fetch_all(conn.deref_mut()) + .await?) + } + + pub async fn delete_by_uid( + conn: &mut PoolConnection, + filter_uid: ControllerUid, + ) -> Result<(), DatabaseError> { + sqlx::query!("DELETE FROM controllers WHERE uid = ?", filter_uid) + .execute(conn.deref_mut()) + .await + .map(|res| match res.rows_affected() { + 0 => Err(DatabaseError::DeleteError), + _ => Ok(()), + })? + } + + pub async fn create( + conn: &mut PoolConnection, + new_uid: &ControllerUid, + new_name: &str, + new_relay_count: i64, + new_active: bool + ) -> Result { + sqlx::query_as!( + Controller, + "INSERT INTO controllers (uid, name, relay_count, active) VALUES (?, ?, ?, ?) RETURNING *", + new_uid, + new_name, + new_relay_count, + new_active, + ) + .fetch_optional(conn.deref_mut()) + .await? + .ok_or(DatabaseError::InsertGetError) + } + + pub async fn update( + &self, + conn: &mut PoolConnection, + new_name: &str, + new_relay_count: i64, + new_active: bool + ) -> Result { + sqlx::query!( + "UPDATE controllers SET name = ?, relay_count = ?, active = ? WHERE id = ?", + new_name, + new_relay_count, + new_active, + self.id, + ) + .execute(conn.deref_mut()) + .await?; + + Controller::get_by_uid(conn, &self.uid).await + } +} diff --git a/emgauwa-lib/src/db/mod.rs b/emgauwa-lib/src/db/mod.rs index a870673..0b31050 100644 --- a/emgauwa-lib/src/db/mod.rs +++ b/emgauwa-lib/src/db/mod.rs @@ -6,17 +6,18 @@ use std::str::FromStr; use crate::db::errors::DatabaseError; use crate::db::model_utils::Period; -use crate::db::types::EmgauwaUid; +use crate::db::types::ScheduleUid; // export for easier/flatter access pub use crate::db::schedules::{Periods, Schedule}; -pub(crate) mod errors; +pub mod errors; mod model_utils; mod models; -pub(crate) mod schedules; -pub(crate) mod tag; +pub mod schedules; +pub mod tag; pub mod types; +pub mod controllers; static MIGRATOR: Migrator = sqlx::migrate!("../migrations"); // defaults to "./migrations" @@ -27,7 +28,7 @@ pub async fn run_migrations(pool: &Pool) { async fn init_schedule( pool: &Pool, - uid: &EmgauwaUid, + uid: &ScheduleUid, name: &str, periods: Periods, ) -> Result<(), DatabaseError> { @@ -68,13 +69,13 @@ pub async fn init(db: &str) -> Pool { run_migrations(&pool).await; - init_schedule(&pool, &EmgauwaUid::Off, "Off", Periods(vec![])) + init_schedule(&pool, &ScheduleUid::Off, "Off", Periods(vec![])) .await .expect("Error initializing schedule Off"); init_schedule( &pool, - &EmgauwaUid::On, + &ScheduleUid::On, "On", Periods(vec![Period::new_on()]), ) diff --git a/emgauwa-lib/src/db/schedules.rs b/emgauwa-lib/src/db/schedules.rs index afe136e..b353969 100644 --- a/emgauwa-lib/src/db/schedules.rs +++ b/emgauwa-lib/src/db/schedules.rs @@ -8,14 +8,14 @@ use sqlx::Sqlite; use crate::db::errors::DatabaseError; use crate::db::model_utils::Period; use crate::db::tag::Tag; -use crate::db::types::EmgauwaUid; +use crate::db::types::ScheduleUid; #[derive(Debug, Serialize, Clone)] pub struct Schedule { #[serde(skip)] pub id: i64, #[serde(rename(serialize = "id"))] - pub uid: EmgauwaUid, + pub uid: ScheduleUid, pub name: String, pub periods: Periods, } @@ -32,9 +32,23 @@ impl Schedule { .await?) } + pub async fn get( + conn: &mut PoolConnection, + id: &i64, + ) -> Result { + sqlx::query_as!( + Schedule, + "SELECT * FROM schedules WHERE id = ?", + id + ) + .fetch_optional(conn.deref_mut()) + .await + .map(|s| s.ok_or(DatabaseError::NotFound))? + } + pub async fn get_by_uid( conn: &mut PoolConnection, - filter_uid: &EmgauwaUid, + filter_uid: &ScheduleUid, ) -> Result { sqlx::query_as!( Schedule, @@ -57,12 +71,12 @@ impl Schedule { pub async fn delete_by_uid( conn: &mut PoolConnection, - filter_uid: EmgauwaUid, + filter_uid: ScheduleUid, ) -> Result<(), DatabaseError> { let filter_uid = match filter_uid { - EmgauwaUid::Off => Err(DatabaseError::Protected), - EmgauwaUid::On => Err(DatabaseError::Protected), - EmgauwaUid::Any(_) => Ok(filter_uid), + ScheduleUid::Off => Err(DatabaseError::Protected), + ScheduleUid::On => Err(DatabaseError::Protected), + ScheduleUid::Any(_) => Ok(filter_uid), }?; sqlx::query!("DELETE FROM schedules WHERE uid = ?", filter_uid) @@ -79,7 +93,7 @@ impl Schedule { new_name: &str, new_periods: &Periods, ) -> Result { - let uid = EmgauwaUid::default(); + let uid = ScheduleUid::default(); sqlx::query_as!( Schedule, "INSERT INTO schedules (uid, name, periods) VALUES (?, ?, ?) RETURNING *", @@ -100,8 +114,8 @@ impl Schedule { ) -> Result { // overwrite periods on protected schedules let new_periods = match self.uid { - EmgauwaUid::Off | EmgauwaUid::On => self.periods.borrow(), - EmgauwaUid::Any(_) => new_periods, + ScheduleUid::Off | ScheduleUid::On => self.periods.borrow(), + ScheduleUid::Any(_) => new_periods, }; sqlx::query!( diff --git a/emgauwa-lib/src/db/tag.rs b/emgauwa-lib/src/db/tag.rs index 82819f0..5eb192b 100644 --- a/emgauwa-lib/src/db/tag.rs +++ b/emgauwa-lib/src/db/tag.rs @@ -37,6 +37,16 @@ impl Tag { } pub async fn get( + conn: &mut PoolConnection, + id: i64, + ) -> Result { + sqlx::query_as!(Tag, "SELECT * FROM tags WHERE id = ?", id) + .fetch_optional(conn.deref_mut()) + .await + .map(|t| t.ok_or(DatabaseError::NotFound))? + } + + pub async fn get_by_tag( conn: &mut PoolConnection, target_tag: &str, ) -> Result { diff --git a/emgauwa-lib/src/db/types/controller_uid.rs b/emgauwa-lib/src/db/types/controller_uid.rs new file mode 100644 index 0000000..63817f1 --- /dev/null +++ b/emgauwa-lib/src/db/types/controller_uid.rs @@ -0,0 +1,62 @@ +use serde::{Serialize, Serializer}; +use sqlx::{Decode, Encode, Sqlite, Type}; +use sqlx::database::HasArguments; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef}; +use uuid::Uuid; + +#[derive(Clone, Debug)] +pub struct ControllerUid(Uuid); + +impl Serialize for ControllerUid { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + String::from(self).serialize(serializer) + } +} + +impl From<&ControllerUid> for String { + fn from(uid: &ControllerUid) -> String { + uid.0.as_hyphenated().to_string() + } +} + +impl Type for ControllerUid { + fn type_info() -> SqliteTypeInfo { + <&[u8] as Type>::type_info() + } + + fn compatible(ty: &SqliteTypeInfo) -> bool { + <&[u8] as Type>::compatible(ty) + } +} + +impl<'q> Encode<'q, Sqlite> for ControllerUid { + //noinspection DuplicatedCode + fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { + let uuid_val = self.0.as_bytes().to_vec(); + <&Vec as Encode>::encode(&uuid_val, buf) + } +} + +impl<'r> Decode<'r, Sqlite> for ControllerUid { + //noinspection DuplicatedCode + fn decode(value: SqliteValueRef<'r>) -> Result { + Ok(Self::from(<&[u8] as Decode>::decode(value)?)) + } +} + +impl From<&[u8]> for ControllerUid { + fn from(value: &[u8]) -> Self { + Self(Uuid::from_slice(&value).unwrap()) + } +} + +impl From> for ControllerUid { + fn from(value: Vec) -> Self { + Self::from(value.as_slice()) + } +} diff --git a/emgauwa-lib/src/db/types/emgauwa_uid.rs b/emgauwa-lib/src/db/types/emgauwa_uid.rs deleted file mode 100644 index 6287ad4..0000000 --- a/emgauwa-lib/src/db/types/emgauwa_uid.rs +++ /dev/null @@ -1,146 +0,0 @@ -use std::convert::TryFrom; -use std::fmt::{Debug, Formatter}; -use std::str::FromStr; - -use serde::{Serialize, Serializer}; -use sqlx::database::HasArguments; -use sqlx::encode::IsNull; -use sqlx::error::BoxDynError; -use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef}; -use sqlx::{Decode, Encode, Sqlite, Type}; -use uuid::Uuid; - -#[derive(Clone)] -pub enum EmgauwaUid { - Off, - On, - Any(Uuid), -} - -impl EmgauwaUid { - const OFF_STR: &'static str = "off"; - const ON_STR: &'static str = "on"; - const OFF_U8: u8 = 0; - const ON_U8: u8 = 1; - const OFF_U128: u128 = 0; - const ON_U128: u128 = 1; -} - -impl Default for EmgauwaUid { - fn default() -> Self { - EmgauwaUid::Any(Uuid::new_v4()) - } -} - -impl Debug for EmgauwaUid { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - EmgauwaUid::Off => EmgauwaUid::OFF_STR.fmt(f), - EmgauwaUid::On => EmgauwaUid::ON_STR.fmt(f), - EmgauwaUid::Any(value) => value.fmt(f), - } - } -} - -impl Type for EmgauwaUid { - fn type_info() -> SqliteTypeInfo { - <&[u8] as Type>::type_info() - } - - fn compatible(ty: &SqliteTypeInfo) -> bool { - <&[u8] as Type>::compatible(ty) - } -} - -impl<'q> Encode<'q, Sqlite> for EmgauwaUid { - //noinspection DuplicatedCode - fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { - <&Vec as Encode>::encode(&Vec::from(self), buf) - } -} - -impl<'r> Decode<'r, Sqlite> for EmgauwaUid { - fn decode(value: SqliteValueRef<'r>) -> Result { - Ok(EmgauwaUid::from(<&[u8] as Decode>::decode(value)?)) - } -} - -impl Serialize for EmgauwaUid { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - String::from(self).serialize(serializer) - } -} - -impl From for EmgauwaUid { - fn from(uid: Uuid) -> EmgauwaUid { - match uid.as_u128() { - EmgauwaUid::OFF_U128 => EmgauwaUid::Off, - EmgauwaUid::ON_U128 => EmgauwaUid::On, - _ => EmgauwaUid::Any(uid), - } - } -} - -impl TryFrom<&str> for EmgauwaUid { - type Error = uuid::Error; - - fn try_from(value: &str) -> Result { - match value { - EmgauwaUid::OFF_STR => Ok(EmgauwaUid::Off), - EmgauwaUid::ON_STR => Ok(EmgauwaUid::On), - any => match Uuid::from_str(any) { - Ok(uuid) => Ok(EmgauwaUid::Any(uuid)), - Err(err) => Err(err), - }, - } - } -} - -impl From<&EmgauwaUid> for Uuid { - fn from(emgauwa_uid: &EmgauwaUid) -> Uuid { - match emgauwa_uid { - EmgauwaUid::Off => Uuid::from_u128(EmgauwaUid::OFF_U128), - EmgauwaUid::On => Uuid::from_u128(EmgauwaUid::ON_U128), - EmgauwaUid::Any(value) => *value, - } - } -} - -impl From<&EmgauwaUid> for String { - fn from(emgauwa_uid: &EmgauwaUid) -> String { - match emgauwa_uid { - EmgauwaUid::Off => String::from(EmgauwaUid::OFF_STR), - EmgauwaUid::On => String::from(EmgauwaUid::ON_STR), - EmgauwaUid::Any(value) => value.as_hyphenated().to_string(), - } - } -} - -impl From<&EmgauwaUid> for Vec { - fn from(emgauwa_uid: &EmgauwaUid) -> Vec { - match emgauwa_uid { - EmgauwaUid::Off => vec![EmgauwaUid::OFF_U8], - EmgauwaUid::On => vec![EmgauwaUid::ON_U8], - EmgauwaUid::Any(value) => value.as_bytes().to_vec(), - } - } -} - -impl From<&[u8]> for EmgauwaUid { - fn from(value: &[u8]) -> Self { - match value { - [EmgauwaUid::OFF_U8] => EmgauwaUid::Off, - [EmgauwaUid::ON_U8] => EmgauwaUid::On, - value_bytes => EmgauwaUid::Any(Uuid::from_slice(value_bytes).unwrap()), - } - } -} - -impl From> for EmgauwaUid { - fn from(value: Vec) -> Self { - EmgauwaUid::from(value.as_slice()) - } -} diff --git a/emgauwa-lib/src/db/types/mod.rs b/emgauwa-lib/src/db/types/mod.rs index 04e5e86..9974977 100644 --- a/emgauwa-lib/src/db/types/mod.rs +++ b/emgauwa-lib/src/db/types/mod.rs @@ -1,2 +1,5 @@ -pub mod emgauwa_uid; -pub use emgauwa_uid::EmgauwaUid; +mod schedule_uid; +mod controller_uid; + +pub use schedule_uid::ScheduleUid; +pub use controller_uid::ControllerUid; \ No newline at end of file diff --git a/emgauwa-lib/src/db/types/schedule_uid.rs b/emgauwa-lib/src/db/types/schedule_uid.rs new file mode 100644 index 0000000..69d9339 --- /dev/null +++ b/emgauwa-lib/src/db/types/schedule_uid.rs @@ -0,0 +1,147 @@ +use std::convert::TryFrom; +use std::fmt::{Debug, Formatter}; +use std::str::FromStr; + +use serde::{Serialize, Serializer}; +use sqlx::database::HasArguments; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef}; +use sqlx::{Decode, Encode, Sqlite, Type}; +use uuid::Uuid; + +#[derive(Clone)] +pub enum ScheduleUid { + Off, + On, + Any(Uuid), +} + +impl ScheduleUid { + const OFF_STR: &'static str = "off"; + const ON_STR: &'static str = "on"; + const OFF_U8: u8 = 0; + const ON_U8: u8 = 1; + const OFF_U128: u128 = 0; + const ON_U128: u128 = 1; +} + +impl Default for ScheduleUid { + fn default() -> Self { + Self::Any(Uuid::new_v4()) + } +} + +impl Debug for ScheduleUid { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Off => Self::OFF_STR.fmt(f), + Self::On => Self::ON_STR.fmt(f), + Self::Any(value) => value.fmt(f), + } + } +} + +impl Type for ScheduleUid { + fn type_info() -> SqliteTypeInfo { + <&[u8] as Type>::type_info() + } + + fn compatible(ty: &SqliteTypeInfo) -> bool { + <&[u8] as Type>::compatible(ty) + } +} + +impl<'q> Encode<'q, Sqlite> for ScheduleUid { + //noinspection DuplicatedCode + fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { + <&Vec as Encode>::encode(&Vec::from(self), buf) + } +} + +impl<'r> Decode<'r, Sqlite> for ScheduleUid { + //noinspection DuplicatedCode + fn decode(value: SqliteValueRef<'r>) -> Result { + Ok(Self::from(<&[u8] as Decode>::decode(value)?)) + } +} + +impl Serialize for ScheduleUid { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + String::from(self).serialize(serializer) + } +} + +impl From for ScheduleUid { + fn from(uid: Uuid) -> Self { + match uid.as_u128() { + Self::OFF_U128 => Self::Off, + Self::ON_U128 => Self::On, + _ => Self::Any(uid), + } + } +} + +impl TryFrom<&str> for ScheduleUid { + type Error = uuid::Error; + + fn try_from(value: &str) -> Result { + match value { + Self::OFF_STR => Ok(Self::Off), + Self::ON_STR => Ok(Self::On), + any => match Uuid::from_str(any) { + Ok(uuid) => Ok(Self::Any(uuid)), + Err(err) => Err(err), + }, + } + } +} + +impl From<&ScheduleUid> for Uuid { + fn from(uid: &ScheduleUid) -> Uuid { + match uid { + ScheduleUid::Off => Uuid::from_u128(ScheduleUid::OFF_U128), + ScheduleUid::On => Uuid::from_u128(ScheduleUid::ON_U128), + ScheduleUid::Any(value) => *value, + } + } +} + +impl From<&ScheduleUid> for String { + fn from(uid: &ScheduleUid) -> String { + match uid { + ScheduleUid::Off => String::from(ScheduleUid::OFF_STR), + ScheduleUid::On => String::from(ScheduleUid::ON_STR), + ScheduleUid::Any(value) => value.as_hyphenated().to_string(), + } + } +} + +impl From<&ScheduleUid> for Vec { + fn from(uid: &ScheduleUid) -> Vec { + match uid { + ScheduleUid::Off => vec![ScheduleUid::OFF_U8], + ScheduleUid::On => vec![ScheduleUid::ON_U8], + ScheduleUid::Any(value) => value.as_bytes().to_vec(), + } + } +} + +impl From<&[u8]> for ScheduleUid { + fn from(value: &[u8]) -> Self { + match value { + [Self::OFF_U8] => Self::Off, + [Self::ON_U8] => Self::On, + value_bytes => Self::Any(Uuid::from_slice(value_bytes).unwrap()), + } + } +} + +impl From> for ScheduleUid { + fn from(value: Vec) -> Self { + Self::from(value.as_slice()) + } +} diff --git a/emgauwa-lib/src/handlers/v1/schedules.rs b/emgauwa-lib/src/handlers/v1/schedules.rs index 5c62a59..841e6e4 100644 --- a/emgauwa-lib/src/handlers/v1/schedules.rs +++ b/emgauwa-lib/src/handlers/v1/schedules.rs @@ -6,7 +6,7 @@ use sqlx::{Pool, Sqlite}; use crate::db::errors::DatabaseError; use crate::db::{Periods, Schedule}; use crate::db::tag::Tag; -use crate::db::types::EmgauwaUid; +use crate::db::types::ScheduleUid; use crate::handlers::errors::ApiError; use crate::return_models::ReturnSchedule; use crate::utils::vec_has_error; @@ -41,7 +41,7 @@ pub async fn tagged( let mut pool_conn = pool.acquire().await?; let (tag,) = path.into_inner(); - let tag_db = Tag::get(&mut pool_conn, &tag).await?; + let tag_db = Tag::get_by_tag(&mut pool_conn, &tag).await?; let schedules = Schedule::get_by_tag(&mut pool_conn, &tag_db).await?; @@ -61,9 +61,9 @@ pub async fn show( let mut pool_conn = pool.acquire().await?; let (schedule_uid,) = path.into_inner(); - let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; + let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; - let schedule = Schedule::get_by_uid(&mut pool_conn, &emgauwa_uid).await?; + let schedule = Schedule::get_by_uid(&mut pool_conn, &uid).await?; let mut return_schedule = ReturnSchedule::from(schedule); return_schedule.load_tags(&mut pool_conn); @@ -148,9 +148,9 @@ pub async fn update( let mut pool_conn = pool.acquire().await?; let (schedule_uid,) = path.into_inner(); - let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; + let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; - let schedule = Schedule::get_by_uid(&mut pool_conn, &emgauwa_uid).await?; + let schedule = Schedule::get_by_uid(&mut pool_conn, &uid).await?; let schedule = schedule .update(&mut pool_conn, data.name.as_str(), &data.periods) @@ -173,13 +173,13 @@ pub async fn delete( let mut pool_conn = pool.acquire().await?; let (schedule_uid,) = path.into_inner(); - let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; + let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?; - match emgauwa_uid { - EmgauwaUid::Off => Err(ApiError::ProtectedSchedule), - EmgauwaUid::On => Err(ApiError::ProtectedSchedule), - EmgauwaUid::Any(_) => { - Schedule::delete_by_uid(&mut pool_conn, emgauwa_uid).await?; + match uid { + ScheduleUid::Off => Err(ApiError::ProtectedSchedule), + ScheduleUid::On => Err(ApiError::ProtectedSchedule), + ScheduleUid::Any(_) => { + Schedule::delete_by_uid(&mut pool_conn, uid).await?; Ok(HttpResponse::Ok().json("schedule got deleted")) } } diff --git a/migrations/20231120000000_init.up.sql b/migrations/20231120000000_init.up.sql index e963801..108c5a6 100644 --- a/migrations/20231120000000_init.up.sql +++ b/migrations/20231120000000_init.up.sql @@ -6,18 +6,15 @@ CREATE TABLE controllers AUTOINCREMENT NOT NULL, uid - VARCHAR(36) + BLOB NOT NULL UNIQUE, name VARCHAR(128) NOT NULL, - ip - VARCHAR(16), - port - INTEGER, relay_count - INTEGER, + INTEGER + NOT NULL, active BOOLEAN NOT NULL