Skip to content

Commit cc9a6dc

Browse files
committed
feat(e2e): using postgres connection pooling
1 parent c3f8197 commit cc9a6dc

File tree

8 files changed

+98
-59
lines changed

8 files changed

+98
-59
lines changed

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,22 @@
22

33
A diff viewer that gives you sharable diff view links but does not store your data. (This takes inspiration from typescript playground how it stores your code in url itself) but the for very large data we will be doing end to end encryption just like `excalidraw` so you can still have sharable links without worrying if you should store your enterprise data or not.
44

5+
# Data Privacy and security
6+
57
## :bangbang: No data sent to server
68

7-
You can take a look at the source code itself. All your data is kept as hash fragment in URL which never makes its way to server. Totally avoiding man in middle and XSS attacks to steal your data or any data breach. The data always stays in your URL and browser and never makes its way on the wire. Thats the main motive behind developing this tool. More about reasoning, why and how can be found in [Motivation](#motivation) section below.
9+
- You can take a look at the source code itself.
10+
- All your data is kept as hash fragment in URL which never makes its way to server. Totally avoiding man in middle and XSS attacks to steal your data or any data breach.
11+
- The data always stays in your URL and browser and never makes its way on the wire. Thats the main motive behind developing this tool.
12+
- More about reasoning, why and how can be found in [Motivation](#motivation) section below.
13+
14+
## End to End Encryption
15+
16+
- If the calculated diff data is larger 10000 characters then your data is first encrypted on browser and the encrypted data is stored on server.
17+
- The key to decrypt the data is added as hash fragment in the url, also each diff view is encrypted with different key
18+
- Every diff view is assigned cryptographically strong unique identifier making it impossible to guess diff view identifiers for hackers
19+
- The data is always decrypted in browser cause the hash fragement is never sent to server by browsers, so server has no way to decrypt the data
20+
- even if someone gets hold of your data using man in middle attack they cannot decrypt it as decryption key is available only in browser.
821

922
# Formats currently supported
1023

@@ -50,12 +63,14 @@ In the chase of one such tool I ended up creating one as I did not find any that
5063
This is open source and has very easy user interface. Here is the link to the tool https://diffviewer.vercel.app/
5164
It has following benefits
5265

53-
1. Since the tool does not store your data on its server there is no server required in the tool
66+
1. Since the tool does not always store your data on its server there is no server required in the tool
5467
2. The tool is blazing fast
5568
3. Most importantly the link can be shared with anyone without security concerns(Unless you share link itself over some insecure network)
5669
4. As the link contains data whomever you share link with can get data too
57-
5. Also note that the data is put with hash in url so server can not read the data
70+
5. Also note that the data is put with hash in url so server can not read the data or encryption key
71+
6. For very large data comparison take a look at [End to End Encryption](#end-to-end-encryption) section above
5872

73+
[Here is sample e2e encryption link](https://diffviewer.vercel.app/v2/diff?id=diff-42812281783313231307#6XrXxuc56r97cXx3Nce8EQ)
5974
[Here is a link to sample diff view](https://diffviewer.vercel.app/v2/diff#H4sIAAAAAAAAA61dXZPUuJL9KwQv-3LHUZLr8z6pu2GAaXqGoIkh5u5sbMi2ylaXbRX-6KL6xv3vq5SrGWDIYy_FA_PBKaASSamTmSdT_35aFu3Tfz797z_rJ0_-Tf948uTPpzb78-k_n4h_PP7_1jZt97-1rgz9_J9PX1tX__n0E1zqL9B3hWvcIXcu--wzptK2HPCy-_SBmUr3ujZlVJvusw_nps5MM3z6V1f_lNhaN8fPPmD3_6uzrDFtO3xILBZRPIvW80jIzZ9P6WP_-cc3TJKsSdeNbTu33dIfyxl241yh628btasCKJQ3Ky9N1PTn2CPnm0hsIhkvIzkD9sTYHs3bclXo7GA4Y9IBlSrpHx62xmRR6irGoEv7-H_88qzjSJBJC7IHLdCcNehlX28bkznepMvS6DbTpfm2UUXyiMeqcg-2LHXkmpyx6mLUqJVfn1kkF_GISQvWpJu-afSRN-iZX8PUleW37amyEzxX-8bW3bax_iuXR7BUP_tf_sVfz99sEv4AiUiuIhGvgE1L1qbfdVkik8yTG1vb1H3bpvvMVAFeKLPXUe7uGUtehP_elr3N0L4T62gWiaWMNjGwZsVa80InieWteX_s_ElpGD-XH07wUu3bPjIZ5xImnCBvwnztF8Wvz2YNTFmzprwr9McOejdbtp3RjDFddYJXKvM_eaxc5y8BsNeGFfrQG-wZlt5rb6K5d9yrObBrw9r13pSJNcDR6caVtmacwiE9wWu117n_d279BjaRPe86ms-iVVgwuQRGiRlr1VvTJwbcsRe1_-MOuukK_W3DGv3XJzaqK0xlts5_ww5ctW9ceRz35Svvyxdz8hExWjHB04cbbVtIIBpbJUfG63UB1KrSR5eW5CzO3oTeGu8l5jLCq8WThxvdpMBN_GLqurFpwVh0d4ITZdMPwJhpW8-78NUiCqu0kcgcnjv8yzW6AI5Cpxdtqm3GGPRQ6VQPH0hVYZP-nBtJ0B0bb8gmKQSyh6cOF5kpgYe4LUxz5ByEbgc0U9suBRfSBB8uZ2tPFebRxpsyh0eHpww_W1NmLVyb3633ad82ZutX5p5go2yRn8npPP9ZLSOxHuMKgicLz_wVAhbmvU137bctyQ6EbZU3AZgxzaF5P72mu5WMQTRBAJ7Q6BTdQZ7mUdDDbbI8_fSBXDXm3jRJrUfu19GTI-fLiPg2cQa423jO8NrcIz99XRpbt1Vfdw9MpLf76xOF6lvduUwjgjqN1kkhKc7z15CMltA0njbc6qQB4dF7f1OWhrmD2sOA2sdgj3ZhsTvjLMVxtPTnaOljCYmctuQZwztXVeAOunJVwoV7XRrAO6Ur_RA2XdRz1kwLXxci2syIImyQy5Y8RbimswDiiDf0hx0MFxvt9o_4ThX7c-_UpbfGu24fF8WIe0ueIFyUFvmHF7pmN5vOA1iq0nuEyrTAmPGYdR5ojljMRpip5MnBC6trcHBudbP1X5Txc-2AVqrtm3vjg4h6Z5A_uBkhB0vvBDzXFqt1tEGOQPLk4NpvEsS0rwofFTTM4uzSAa1VYvPSJcaz6-huf9Z1tFhEfo2Ivy3RtSp5knDb6cbbBDbcS308sHFrWwyoU52tj3tIsMf528wfG7EMQfiIQTxP-MNfQ8icy1LvTMms0TEZ0L3KnP_ZutLNznRnHSPvDfzlKhaUpIPHiGcMF2SCsSAeDxm8fmt2jF_YPeIfVGbazNxHaX3WxltJymRFdBktkFGILxxA6sf_3XeNYShQmZ3gRpkkcAT-DpoW1Ul_ijytE_MohmvEc4SfLfJ0l7osdPVta7ZJAFvVGk_kDIgbpgV1dIDm8xAICRg6xDxBeG_rDNyoF54PVZZhCAc9oN0p-eP_AVdo3C3EfmmWnqB6gwRanpjnCG8NcAlXugH8oElPcK_SCqXmpm01Ch02xN3ikSA1BjkE1-ToHro21d57ZjYbvHvE7ymTZdq9aVr3k4_k69xE2wbaN0q4Kd8TU0bBGypRjBTzxOGt6-8tSmnl_qQw4V6jA3hQOv3Q28Z0hW3pV57lxSmEkLNF5P0ePlM8eaAqCm_R62OdOeZEpWUAPyqduP7M20iEhFz4F3LcMc8YnnlSh3zdW5ebhjMlawb0OKVaNMnfrXzYKmbhTIklPE88Z_AkqEaViNuCzXW3LWEPPhwySel4PjfNOSyjlfcMwm8zZAjPFK5sY8sS1L2ujc0LNn5IdydYzBT5gtL__ujcTMzbe4PoQppvIlT7inmu8EI3dscbdaO7Y2sZ7pNXAyqE6vemrs-rrYiFv1QXxE5H_ADPFC5dAosQL1yWuLL7tjVJPqBCKorwvj8cWqypliKpmLJEVeM5TxJe-y3SZijp80wfMi4c8iSOQBGrru86l9qu03wpZeLxkaFsTEZJ5N3mPFH4wxR99sXX-PoE6cZvoyNTSjnuTrCYTyykjIWtVGYVK0qRCIEyCnOeLrzRXWMfLOKnrm0dw0_3SQDFgjJY_pvpDOUVJqQa_fHxjG4ZR2t0guY8O3jp_wTvp4BDMKblbqCiCqBYqrYkun22d_MbTvi7Zx1toFiBJwY3xkdnLVidF96n2zqnIIEhdPlfnxAr1brcoULKpBCPtAp-34WMMArF5zxTuMgazxXAbfTSNY1N2IKrLh5xsVb7wnUu6VMcj09cs3hFNWS_bqSbgZ6CJw0vKbpBvs_1LScvyQIoNspzhpxKyuel6sTSe3Pv--J5tEYB0pxnDpcm3YGU8DNX66JnzEmyARVabd3H2hzOcxAxuTry5P5UreCZ4hnDM5vuwOK8a3qg_sm6EyySz7P2CRcYTUyZLEIRQlA2aAP3HM8drnWKMt3Py4rVnBnCRKpEX2ciysxZB2guhuXxxHuFLqUFUC24DIRD702S_HTpWNVZc_AfSAgX2SSqOuEQUdlYrkJea40CiQXPHt4VJtF9CejDM5d53sYqZ7ITLIyqvUP_fn7n_XZIm-CE1oInDX98mfP9W0Kr6Vxl-m-bcUxOsNgqv0xAOjfRXxNVFX7PzUhPAg3iWcMbksCRkg-4hUIzbHXfeUjkwV-fVwsnmeYi5LMELN8teMLw2vrvjTLclPNgDk6ZDKgo_h_5kYnSmA3VkOlaXaGIYsEThrcjodFtZQ7-VDAuoR1QYVXrKZ7WgHRPzArHC-J1lMlaIoe94EnCW5cWBu85k-mCSz12ARR3qm87z7yrqDtP5OiNCbLNGSWzkEWgGNFksFz0vE3ddmu_-Iv9nNOZR1zsVGbuPUHsvLM4NwtEvk7Eoe46Q1HFgqcM721Zma6DkXljbMsYdsgHVJSqO9gOl8ImSlKpFLYI9WQJb1meMNwQM4N1Cd22TAW2SgZUVGrQC4-k6yYeKjH35hAX8mbNkQdc8uTheWNQPsh2R9Ji3X_bLlM94qIOcujUdA7lhSau1tp7dgpuiT-gPbjk-cOtbQ0KKt57_8YJttpDAIVTaenZb6LrHfCAE24qT1Yl6VLXsY8CkT08iXhnqwo59EvD5FG6xGixV-3uuB-_mMZWhnKq_iitiNsh8rDkycP7BtVb3rsmY5Oqh8OAig8qO9ZZ3QI6NEUZSNaQsnukfLTk-cMf_Ug6NX1tuIacY6XT0qOiUW3h9j_tG5D0nhQYrUmBOgv9EXNoEM8brnUDtWeUE0-Z_PBuN6CiVd60xrPWzOqzAglPvRcLUm7CvMmSJw2_-N8K1StfeM7GBUZ3eQBFpw6e2yF3PZZ49PEdeQCi3VC4sOS5wjXlb4Ah3lGTKIbN1e2qTx8Qvdr64DdxbnfW4khBQgxJFbARZ8AzheeVQXrAF_7_2Tjc5AMq7lXR52aQmaB8ycQIiWg3yQLX_naFeeIlTxaeef4MVuu1qRntpndv9YM4qLTw59CZmpojzlol760H1aZEHmHFE4Tbom_oVEMhXbO1HVNnafMBFR_9tmtJ9LjX9TnqM0-7Z94hRLAuseKZwS_abwF_naM-vWeaehI5x5ANqDg-5rRGii2jfGdG7VKz0HgoYMJkhboh7i0IZd94mGEIfkE8Jh7UvC009nQTcj8nbSDdrDAqX_EU4ZVDVXFPxFOOIdgqgHJGJSPdlT4kOlNItxAhH0zkDTHRFZA6jjC3301mdmyWYXd_gqVQRx__ukPQmZy1Rp6GSgrzNvNojS7WFc8TfKxd9TVKazWm-Cp_9wUpPcFSqvo4prCd6LgFEbn1wFCRVTxd8F_aQPFZ31QkIGTihiR5xGUc8lvt3p0djw_5rRlptlbQLJ48PDP1EbgGT1FrmzHOwV9IAZVzVfn1snvY6jpBCy2jsFCSunLQ7briWcONzuu-4g36bbu1JbdIlRtQuVB6vy_R7TqtGrH2QSqJoYkNwdPE04WXfbVtLDhNz1OXfNucwnhILif0Vk8UnXnOLdehbARzj2ueMTxD_a6XVF9lNU3JgMqV2lLk3Zy7OKdtFq2iNWILa54tPM9Qe4duyiNnjEkHVK5VadvuJ09Vvec-1yJPuCnMo2sJKQLXPFF4YVyDkt433s0y5by8IkxuVGb88lhHtb3jeXdRUNyH62iJYog1zxYumsy2dyAtrI8l0_iuO8KkVn07UmudkuQRoYpHS4M72tY8V3jmGlSVfEc8nNOiZt2AykQddeEcSYXZfMIIyabsm2cHYraMFoj2rAFDcAfcS-QOpmFUGN0-gDJVe1NH1n337pIxmRFyIsgKnhFc24cHRN7eNK7PSnfPHJjd_hGXmfJb7OianUFebWRdfFgqFhGFCnhZeC7wukctUTfpq_LecBmRskptgKU5Na1peGimJa0o17uMVmOp-TXiA3WNFumivPdxDaf40QMqxwqs47HCasiMSkpcI0vAWAXdZMCQn03DiQAPW8JkrvYJSouOG0EqpTVtsQWyYcNf_1ee2NdQXPG-sO2O42fpYUBloVJdRTrl-x0mqkXWpDUnz7xCN8yG5wCv0kInDtCz10Rb0sbtv22SLR9xadU2QxNWRteHyiKbGTVCSUQ2N_z9P6K2emNSdtxSsQ-gvFPUNHt2US7oXjxtphYo2N-w4W__d7oujiBk-5c1JKFg7pmHAZU7v9ea3NFcH5N29v5c_Qt1fFKQPcP6lw3PBC4bm1tYQ73y1z1bwk_SAZWlqhOUhB8jAoHVDKJzlM3ZAO1iTzNRwBK91sfEcck2XQ6orNSHXtdd6n_tmQkq4mendDykBRueFlz4fYLKWG_Nl8rnzw1qCJO1J2k--ORLpaMMjTo8qXzlbxx0b24AF3CZu_9yKtTXnlp_1ab7ORs4BFC6QXrpfyc0OGFKYxCpFYkNUPIdOjc0b8lVukUNTyTPNDXbQ9glj7jcK5fVbkeV-9ruLD9cbloouho6a0i8CMODDSgr-L9xEI7-qruCDa3rAMoPk2O3abcrCZvj0NAloPxXzHjG8KvD9K3uXPuQPhyZumOtP31ANv5Y-a_8kV-saXfTLIy-mfmz9bhUf9b_8_QfTxt2bmMM2gZeVabMUPu-0dQfzbCHdkBnP2R-XmhmXS-iUGqAQxtB9vfFVzz0b31rQarFJRGaEyyU_2akmTs7J7IKWmBK9MB5BAJwvNvdEcZFut3rhuNFbfWIS7VvSNh4DgOP1yHFM5cR7NyfA0dBOZ4c2UPqf86x59WAxkr739UzvtqmZ9fxN9Fy41krHCXFb7g3pkM5xSYU5DrO9-2TTx-Yq2CQa3Rnz1Sfel8eyzCJScbIn0swYuHnvuxw29e9YXedjyQCulCd21OKMUofznJ61Ge8CV0q0QIO_QIN1b-6JjENkG2_JY7NBLF1E8ClOvj7dpCPnJ3P9oyCgnLvIiRuMwQauTJHzrvjfZ1pA7hSmQ_-EvfxBwgZveteDRwJhrMSMPIbAwfn3aS_Vbbl5uZV3gSPrj3rs_Vu2HZnGkW0aLEODYd4QM4cSH2u-vIeFR6ujbnnckDk7jy4UW3XZ9aFMUZnamO8A6cAg_LacKwHGF9040MFVI28KrS_a5gwo0oHVKs7XSZ9dfasZ6qqztdhvCYk53MwfuX6CIf-3Oj0RcP1DewqneYeTSYJTcd6djcRKdL9SYIlOwEyw5e6Bso_Ep65PeMVkrsBTdW-b8y9K_tz-o9JxrgYpjHJOZyUBbq8bjUWKbzwjplLb7V5ALO_OrzOHSIjaBQBuTkSLkGWOgfjFcIM2h5VutInV7rPWQVgWqXpgJvxtoFJp2gzD-NKBF1HMAiMQdj-aodntDmuWdLuCduq3D5UPvQ_j_-Q1CI0f45UIuWMP0PPK-LCiKe6mh2YZaoA5mrvSHLhA9pzpRabQT4bjwn_JBhKe2tKf-nDEUbPD7ZmLqKW-m7agtRLYbCZj2VPU3--u2Dk18gvEfYMMegkeqYrq4HTftWYUtfMGmV2QO2kRZpQnJBRSBaPZO5isOd-8xFniTr4LywbSDhN2J3K6_5M6XnIqpJsREAvgMre_uooUVr10mh2Do5OArhTnXaJRp5g4sMJ0YbibzFS-RIgp3DRZw3wBK9NnnMaOb9pCCyVbpGkedK6-EsnTKSl4T7fuTIvGuo9QfmeK703JWdNng5opR5slVi0OFOzI8slPdIBx2gK0GB86Vk-kpb6YLrj7tBkP6D1lDGnE-Rj3pUtJDk12OEggdjqrfN_hE0Bebv035hbnSYJoFN3zlU_QG9FTYTzTbSgFBacuQQaCS9dbbdwFPJzm7GCuMQEcK-SvqX5Ce3BGHSMpuWFKY9AqUZPs-EgBQko9pXu0FiIY_WVLP1z6pYN6AeVFjbVuesam_RQSz9lZtFsfcqOjE3IAhfQz42uISn1XDv7aoN-MU08zU8faEbmiY8FDlIOnQ5UqoQzQmc837kqaOQKDB10s3VcmJrmA9qqwh1osOb24JodIglj3fpDPTn8gP2rAgwfeK395VqjA3Vp6u6BrYwlA9r5iOi8NIJ3d-S-F9Ec0YQ5uFZf6qZC9O1W1_mBc3ZFO6C9Mh91hcWyE1pRZiHwIcGPgDEdMOfa1jXwCd4TFq6qODVWcoJ_bMdQMIiO0UiqBzw84rfTHWwY8ofC1jkTNSTlCT4onaSU6Yn0WbXKxZouJNLOwpkXAiUUOtMWsOhfJZlhCyrlCf6oSqzGmFZ7DWOlwrQYCu_g-ylgzoquQdb02rPxih2yshvQozqYpPYE5NyXvUi7EGZoLmGgCvKlv6O6ww2NsmYScfdVAB_U0flfZeHgrwm2-CVZUYPnSD47BozunTU0zhPwbccVV7vUQ2KmMpOZtDov6bsJN6kIsR1y1wJQuReUswJKs-va5gVzl-a7AAqhctsVfcILZ8eSBnKYPbLB0zPnYBLbRWVL4KbDbHC2kVgnj7iQ6mDb9PsTvcPQvziihVnBtDVoC3pBKnE0w-fZf13UXe9qbgB_pgdYxMrUuc7yHzB5bb2mafUregcGLxLP3S6PnopCqYzmnk9KEsLEXO11lxZn9ziFJyTjYfwsns0IUm-_6Nrcgyvnt7ToTFO6mnFsd-7TB8RC2bozKPE2KVwIoTc1D2J-DWT0V2P0-p1jI7u0I0ws_SId9_pcYzzF8aszo8w1nHcMjKFp2xq_KaCbmgbGcfO2k0dcrPwKtZ3OG43eIpp2lsK-W9NLI3AGfwzmvF8FAQi6gtyuZacFpwMq1urenxXXILnFtIwcSRNmNIpfxjgjBybe6KbzBBk4iNdUHSk5EleVJ5imM9qkNDRN_ABfIpqgEpxHcZiLNdJtF4MJje912RWoVvxed5Xrc8b3HQ4nWGhVGdP16KmbKYosak-ZUWV1AaM8QOZuSVAF4iJ6Pqa2teu4N2La_K9PiMSHe2E825kzuMXycUARsTtYJAJlPO80UBro1pAP4BpwqvYEi1Rt_c-PPm46Oq8xTHomceAcVSAkmLHyqrWZA7vvRu85PYmtCBOZquDTphO1JOQfNhGlVKEtaOP9Vpp6h4op_qSxfRFOD6gwqk0tJVyoXpSe3zJNod58eBkCvm86B9HezbHp4PNRV56pc7suJYxGNk5ze1Or4uuhV2Iz9sIpeEjqeaXrHj7M-JKmGRrmAjbFgIqcItnqvFkR5Bt84LehwAk_6APyj56YG1jPuyGxKjtFJq1OsCjUod86lLAbrU_607Qgefd6ZBYykgRSTzHSr9_W7pCxioV2QIVVhxjUJka7PmbhuTIfBeJHJkGb8VvXwifLnmf02hWT0WrMgIo7ldKbdGUJvN00QjSj1E-IMuZQpw443rO-TC1irzc6ZycwZVUAxe5HzdQMHm42DxEG9HIx6Jegt0DR2Jjbjqp3THyRtQMqypH7aHxS9WIRukAXY52tAryicOWSBFhyoDYB9twMqKhG-icnRX2LQY5OOWE44kKiybQ6hQ8tFX1D87yY9q8yfcRFrbLKPZxdp6QiZXinbB1jcXAMZkm9Km0LjHqvbcdrSezhBAunqqOPttJzu_RCH5jYEEf9zi332tgSTgWl6N0w-boyGVCxV9qh6HxiEDtbhn23wp27c-DgvM_Gc7EuTeW_dJYzvKdJHnHxQbVFT85hCwfGjHoG0gXPSKwJo1iQ5Lq4NyV02temsIyD0zvCRKP87wkih2kyjNAu4GO9BZRhgFLrtUW07XeXGzYTtLsfUNGO3z6TXs5dh5CVUsQSDpYTIBt07UzdaPSU10vdtuwY_iKAolMpiuqmvXxFs2b9D_LZME_HJ0uGoA60UtJNytE22wZQ9KqvUbJ70rNKsyAoCb2hcNisABnvd0MXJWLVOn1-b0vu-c-u8u454OLekwPUGTrGRamiH1Koiwhm8AXoePhliFogr-50jXzbXfvpA-Kgij4Zm8M2jZaKaE7hD92t37nzLmrboSGat4UGz2Dp9gSLj6GPN4fjSSbMlgsjDOldbTitbA7G_71B0dwzw3Xu7jMPieMPGQ0cuPU66OrhEEMBJlD_7vd13dk71Cbu79u6KzTrt--bvz4hHv6S0J0tWCDiI8Ye0o1nvHVvvvJmXycc_b2py4zJNu7zEyxnU2bRTuz0mocpH5JWDfIfULUszc7fKRlIzr3U9G4Sd5iKAZXiM7Ujm0SdsA_XsxAW0dvA39tzc6tLC2bl3dLIKE6N3gZQShXuJ3DLTmDbQYKxidaUCoYVPtDWeqW74ognL1y5vunYNxPS9ATLWN1ZPdJ8PKkqFtE0zdnI6zAx8BMvTelgWPSW5IvftqdoCJNz1epygmMYDfIoQ0KqdBIMw0UCr3n5mAelTd-6Q9JzU4ySZkDlQhVpvJydnV4MISsps9DiCDC8NTTR4TEsVaW_-iaf09T0EZdLlTba5m3omfzu3Bw9I7cJRTC4QihqfecaVKnU1b5lK7BdeoLlSplyr-EBGhNnSEnyxkC9oc9GDcfhwXZIVS_qynETDXc6gHKtjG66glpaQWg06UlGKqksR17ugd25tm1RKa_hRoFWuYfkRvlf36NHC6cNMKIyFwmEY9hoAx56uGxg39B703Z7T2wYR3A4wVI_qpnO89NxPOgwlqNMG-XkUB7hF9Ow_TblXQBlMqqXmcbg6NQsQhc4FP9IQOBe6qNBid-jP-bsy5_tgNKARpgunabOnIUZMnEYawqLxGioO1qaMMaIcdB3YYxRIzNFg5m22x8w1ow6i2mOkRh5h2MO3lh7qf21gSRnZr933FyzIhtQSX2rcN7cWPA9dHAEDw2fuRIz0KnWFkib8LMtHfO-kN4SJreqPqLywpShX9RMPLzCM3L-way5K9fATOKVDuMeLKcDTNNPH5C5ovxKeA0zrb_3ulnTuyIkP4fT8-YzPjp4XlWomfjW9Q_MYHDTEiaLUbHphGdKZXiqXc5nEXylNJ7xvvmWRv-jxfndNDVjSntPmLR-SajJodJUOTHIr00QA8fhOQcSA8NwJwZPjtEIXdQAZVviywxPywZU3v3Ah1eXwyhNEUaZwR3He-qLEj9jVZYHxz2ZpJMTLHefZhyf0-1JFIdmfC0ieIAE6vf-mvv_rexIAgXm7mnbAZWlOhQusjVHPCfeo8Ta4jAfdAP3HJps2Cd4edJCVwk7uZlW6PETspr2LOGUlZoJiniCqnEBE3KoyUbjN5QuMq7WkGgPyVqRFd_tq8PsFGrDhUl5ELY9rywclvD8I1vfNoYw6VSt23EN3GjP6mx4e5l-wCgHuIFfzVfvaHydJugzvy2Yc1M3Ayr39PR8W2QOBdQT6AFlrWneCD2YjYWKc94kf_1DbUjXWd0xk-jT6gTLD94km5nwFA8IRUf7HlahYiJirOCJgT23utE_wQYBEtJyW649BFA2KklS2PU97e6ZbcKFul5EnwbRDiMZy6J9TW7n6T-f_kZDc2tdPnnn9_swrfERuirobetsQP7zf73yDBOBowAA)
6075

6176
## TODO/Upcoming features

api/createLink.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { insertRecord } from './db/index.js'
1+
import { getPool } from './db/index.js'
2+
import { insertRecord } from './db/insertRecord.js'
23

34
export const config = { runtime: 'nodejs' }
45

@@ -20,3 +21,7 @@ export default async function handler(req, res) {
2021
res.status(500).json({ message: error.message || 'Internal server error' })
2122
}
2223
}
24+
25+
process.on('SIGTERM', () => {
26+
getPool().end()
27+
})

api/db/dbConstants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const DB_SCHEMA = process.env.DB_SCHEMA

api/db/getRecordById.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { DB_SCHEMA } from './dbConstants.js'
2+
import { getPool } from './index.js'
3+
4+
export async function getRecordById(id) {
5+
const client = await getPool().connect()
6+
try {
7+
const res = await client.query(
8+
`SELECT data, "creationTimestamp" FROM "${DB_SCHEMA}".e2e_data WHERE id = $1;`,
9+
[id]
10+
)
11+
return res.rows
12+
} catch (error) {
13+
console.error(error)
14+
return null
15+
} finally {
16+
await client.release()
17+
}
18+
}

api/db/getTop10Records.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { DB_SCHEMA } from './dbConstants.js'
2+
import { getPool } from './index.js'
3+
4+
export async function getTop10Records() {
5+
const client = await getPool().connect()
6+
try {
7+
const res = await client.query(
8+
`SELECT data, id, "creationTimestamp" FROM "${DB_SCHEMA}".e2e_data limit 10;`
9+
)
10+
return res.rows
11+
} catch (error) {
12+
console.error(error)
13+
return null
14+
} finally {
15+
await client.release()
16+
}
17+
}

api/db/index.js

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,19 @@
1-
import { Client } from 'pg'
1+
import { Pool } from 'pg'
22

3-
const DB_SCHEMA = process.env.DB_SCHEMA
3+
let pool = null
44

5-
const client = new Client({
6-
user: process.env.DB_USER,
7-
host: process.env.DB_HOST,
8-
database: process.env.DB_NAME,
9-
password: process.env.DB_PASSWORD,
10-
port: process.env.DB_PORT,
11-
})
12-
13-
export async function getTop10Records() {
14-
try {
15-
await client.connect()
16-
const res = await client.query(
17-
`SELECT data, id, "creationTimestamp" FROM "${DB_SCHEMA}".e2e_data limit 10;`
18-
)
19-
return res.rows
20-
} catch (error) {
21-
console.error(error)
22-
return null
23-
} finally {
24-
await client.end()
25-
}
26-
}
27-
28-
export async function getRecordById(id) {
29-
try {
30-
await client.connect()
31-
const res = await client.query(
32-
`SELECT data, "creationTimestamp" FROM "${DB_SCHEMA}".e2e_data WHERE id = $1;`,
33-
[id]
34-
)
35-
return res.rows
36-
} catch (error) {
37-
console.error(error)
38-
return null
39-
} finally {
40-
await client.end()
41-
}
42-
}
43-
44-
export async function insertRecord({ data, id }) {
45-
try {
46-
await client.connect()
47-
await client.query(
48-
`INSERT INTO "${DB_SCHEMA}".e2e_data(data, id) VALUES ($1, $2);`,
49-
[data, id]
50-
)
51-
return true
52-
} catch (error) {
53-
console.error(error)
54-
return false
55-
} finally {
56-
await client.end()
5+
export function getPool() {
6+
if (!pool || !pool.connected) {
7+
pool = new Pool({
8+
user: process.env.DB_USER,
9+
host: process.env.DB_HOST,
10+
database: process.env.DB_NAME,
11+
password: process.env.DB_PASSWORD,
12+
port: process.env.DB_PORT,
13+
max: 5, // Maximum number of connections in the pool
14+
idleTimeoutMillis: 30000, // Close idle connections after 30 seconds
15+
connectionTimeoutMillis: 2000, // How long to wait for a connection from the pool
16+
})
5717
}
18+
return pool
5819
}

api/db/insertRecord.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { DB_SCHEMA } from './dbConstants.js'
2+
import { getPool } from './index.js'
3+
export async function insertRecord({ data, id }) {
4+
const client = await getPool().connect()
5+
try {
6+
await client.query(
7+
`INSERT INTO "${DB_SCHEMA}".e2e_data(data, id) VALUES ($1, $2);`,
8+
[data, id]
9+
)
10+
return true
11+
} catch (error) {
12+
console.error(error)
13+
return false
14+
} finally {
15+
await client.release()
16+
}
17+
}

api/getLink.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { getRecordById } from './db/index.js'
1+
import { getRecordById } from './db/getRecordById.js'
2+
import { getPool } from './db/index.js'
23

34
export const config = { runtime: 'nodejs' }
45

@@ -11,3 +12,7 @@ export default async function handler(req, res) {
1112
res.status(500).json({ message: error.message || 'Internal server error' })
1213
}
1314
}
15+
16+
process.on('SIGTERM', () => {
17+
getPool().end()
18+
})

0 commit comments

Comments
 (0)