Compare commits
1369 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1e4eb5d6f | |||
| a14c08f122 | |||
| 94b35e3d5f | |||
| dfeb910ac9 | |||
| 98f2b5dd08 | |||
| dca9ea24d7 | |||
| 37d54811e0 | |||
| 0f2af6eb37 | |||
| d6ae3d4f16 | |||
| 9c1819467a | |||
| 417334d140 | |||
| aa7fb74312 | |||
| c741434e3c | |||
| 60fcb1a862 | |||
| 18dc6a3ff5 | |||
| da52dd006b | |||
| ed1655ed8f | |||
| 516c4e32be | |||
| 1e222d806e | |||
| bfb35b198d | |||
| 3a5f36155f | |||
| 82092fab76 | |||
| a432cb886d | |||
| 5fff8c6ba2 | |||
| e1de4f5c5f | |||
| b6145d6f1e | |||
| 3804a87cef | |||
| a7a6c664c8 | |||
| f075515607 | |||
| 84c15bbc69 | |||
| 54e70d490d | |||
| 67c3de1f5d | |||
| 7281b5b1d7 | |||
| 966eb01f1c | |||
| 5bdf072cdf | |||
| 59c3381962 | |||
| 1fa4216b18 | |||
| a98c953876 | |||
| bf995e5861 | |||
| 1b8470df38 | |||
| 98ded8ea30 | |||
| b72a50eb7e | |||
| 9c3f4fbb9d | |||
| 28c68308a9 | |||
| ea3b0c15ac | |||
| 38ce46adb0 | |||
| 0a9a0103dd | |||
| b7b370ff62 | |||
| 7b0c98ad2c | |||
| bfe25e70d6 | |||
| b2409df369 | |||
| e1d8549730 | |||
| 865cc081ce | |||
| 867d5a9eb5 | |||
| ac84b7604b | |||
| 8f860ad93e | |||
| f3b65700d7 | |||
| 8ec1856206 | |||
| 811d2162fc | |||
| 5e2cdca103 | |||
| 23fb5852ba | |||
| 75cbc0d29a | |||
| d08cd684c5 | |||
| 529b297ba6 | |||
| 32193eef49 | |||
| 1f97b90b2d | |||
| 0dd36260e9 | |||
| 3571d49987 | |||
| ad3489c491 | |||
| 2461fa2e25 | |||
| 60e49ba343 | |||
| a709381980 | |||
| c2805c8c1c | |||
| 0346cbe911 | |||
| 74a4d4455b | |||
| 3659e1c91f | |||
| 09da5c6968 | |||
| 2575efd28d | |||
| 78c1c8d2b1 | |||
| d5147f3dbb | |||
| 593580fbc1 | |||
| 67ca1cb638 | |||
| bcf5b64545 | |||
| e37ad663b3 | |||
| 4ce7582a46 | |||
| 1c371bb7bf | |||
| 17fdeb0734 | |||
| 5c6f0c32b3 | |||
| e630280673 | |||
| 7c87961adf | |||
| 0df5ceb7d2 | |||
| 54342f2592 | |||
| fbad558c37 | |||
| b27dfb290c | |||
| 063c930349 | |||
| c1f1e489a7 | |||
| 62960ed8de | |||
| 03305e04a7 | |||
| 4b294b1125 | |||
| 7122a21591 | |||
| 9682e571a2 | |||
| 2cefbfb8aa | |||
| 084062488c | |||
| 4dbe2b5297 | |||
| 0391e5bc3d | |||
| bcbd96c608 | |||
| 6a6633e151 | |||
| 5c4546a54c | |||
| 255e328340 | |||
| aaf9b085d7 | |||
| c7b14c9fab | |||
| 0436ba78e2 | |||
| 1085a1c221 | |||
| 494b33bd7a | |||
| 925e3a67da | |||
| 78026f7fa5 | |||
| 9d77cac4bb | |||
| 6747280964 | |||
| d7dbd79f7c | |||
| aec692c402 | |||
| 113bbead4a | |||
| 1361c196da | |||
| 987995ad68 | |||
| d24db7c053 | |||
| 25a9d52d86 | |||
| 946c632920 | |||
| 94bcbb80fd | |||
| ba58965770 | |||
| e50ddbf348 | |||
| e95f21fa9c | |||
| 7026b765bd | |||
| 53eedd2701 | |||
| 9886c58681 | |||
| 953f6da7d7 | |||
| da1efe880d | |||
| bd0b6dd4d2 | |||
| 1c049fe1fb | |||
| 10b1b87d55 | |||
| 3ec6a3b3f2 | |||
| 8da919d4cd | |||
| 5cd59b795b | |||
| e4dc30d1fb | |||
| 2013cee298 | |||
| 1f89a6304b | |||
| 580e0f9df7 | |||
| 2221c4548e | |||
| e06c226e84 | |||
| 11a4f0ef32 | |||
| ef15f299d2 | |||
| 1d333b9322 | |||
| 5302ed8653 | |||
| 2cf26a10c4 | |||
| deda1e4251 | |||
| c042bf2d15 | |||
| 8ced6aa205 | |||
| 3ca514c85b | |||
| 27b8e7d5ec | |||
| a2d77a3917 | |||
| c0549fe422 | |||
| 0dc8d6fd68 | |||
| cd97647818 | |||
| fcb5811f37 | |||
| a239ba2211 | |||
| e8dc96bcda | |||
| 096ad97a73 | |||
| a5a5517555 | |||
| d9b88a5d8d | |||
| 8493ea22eb | |||
| aebb87aa20 | |||
| 14e97cb24f | |||
| 26cc15b4a2 | |||
| 50ce606e12 | |||
| b052320f98 | |||
| ecb3cebc9f | |||
| 4a32dfc71b | |||
| c913929ff9 | |||
| d7d5b29b07 | |||
| 111a7f72f8 | |||
| 149abdef9b | |||
| 980848f35a | |||
| d1e0c86a71 | |||
| d3872ca8a3 | |||
| 003dec269a | |||
| e88092cde7 | |||
| 98422bd355 | |||
| af83b89812 | |||
| cffb1b8713 | |||
| 0b4895addf | |||
| 08646ea12a | |||
| 40beb7ceeb | |||
| e7963aa324 | |||
| d5894b9fb7 | |||
| 75c47a1113 | |||
| 97923b19bf | |||
| 879c89a285 | |||
| 718727462b | |||
| 63f2fd864a | |||
| 556dda5790 | |||
| aeaa8549e3 | |||
| 1a8a757912 | |||
| c69bb8acc9 | |||
| 4989d67b92 | |||
| b272d342b0 | |||
| 251b2853e0 | |||
| d381c9505f | |||
| eeb3b8f939 | |||
| ee40f32b0c | |||
| 02a69ea6d9 | |||
| d47bb5ecd4 | |||
| d2d6e2f554 | |||
| f48b4a6c62 | |||
| 07f7b7df1b | |||
| 26486f9d63 | |||
| 428aa970b9 | |||
| 2a8c532786 | |||
| 4381829d16 | |||
| 176d75768f | |||
| e28e363bd0 | |||
| 114ce1ea3a | |||
| 78215552bf | |||
| be4fe6ab77 | |||
| ab924f6b48 | |||
| e4bf2b4c9b | |||
| c49b1a46f8 | |||
| 6a56726734 | |||
| 8f6783792f | |||
| b5ab1d6b33 | |||
| 25fe1d03a7 | |||
| 90546ad4a7 | |||
| 939bbc3f2c | |||
| 02ee327595 | |||
| d8081277ee | |||
| 164a112e0c | |||
| 697bde7b53 | |||
| 2fd5244f85 | |||
| 354d925f94 | |||
| 88c74f020c | |||
| 9b7021b1cd | |||
| 30dbb23330 | |||
| b1696ed1cd | |||
| 61f1c99791 | |||
| bb9a559b80 | |||
| 5e20ea4975 | |||
| c5d7e30bed | |||
| de5f3a31ed | |||
| 7913c4135f | |||
| d49345de9c | |||
| 1dbfa71bde | |||
| d46b84f0d6 | |||
| 9d456992cf | |||
| 5dd62ad2aa | |||
| a293eeb398 | |||
| a6b6b5eb70 | |||
| 971af1df5f | |||
| 21641da0bf | |||
| a8d9c145e6 | |||
| bfafcb76ba | |||
| 52f74f1204 | |||
| 00c212ecb2 | |||
| e77d302a49 | |||
| 5183f3729c | |||
| e93102f105 | |||
| a4652689ec | |||
| ede1005087 | |||
| e97c7ed32e | |||
| 9230a2ab73 | |||
| 01ee66ec4f | |||
| 4c12cbd3cc | |||
| d8eeeaaef6 | |||
| 994dae2a7d | |||
| 51da6e928d | |||
| a328ad030e | |||
| ed7605eccd | |||
| de43880a1c | |||
| 32b1a5b22d | |||
| 795992fb42 | |||
| 339eab33c8 | |||
| 489f3aa19d | |||
| 888e284f84 | |||
| d151114f08 | |||
| 4f6a3c23ad | |||
| 4ed437fd4e | |||
| fa0b21ba81 | |||
| a96f1d0b49 | |||
| ac0aebd751 | |||
| 781cbb4668 | |||
| 56ca1911a1 | |||
| c20aec23a2 | |||
| a9cff01579 | |||
| 6af56a61b8 | |||
| 252db191a6 | |||
| 5e2776f264 | |||
| 7ec9fb2c44 | |||
| 34facb6b3b | |||
| 5bb2a1368e | |||
| 85a7bbca66 | |||
| 2b7f27bf8f | |||
| dd57945e7d | |||
| fa02b4fd56 | |||
| c8715eead5 | |||
| 37aae8c10e | |||
| a97ed02e15 | |||
| 38ebb2d06a | |||
| c765bfc946 | |||
| b00ac75f33 | |||
| 36730168c0 | |||
| 4339ece6f6 | |||
| 041c997e59 | |||
| 098ebb38dc | |||
| b99c38a070 | |||
| 07b42d8e74 | |||
| 062d168c97 | |||
| c9be5fb125 | |||
| 06c6716ee1 | |||
| e856d8fddf | |||
| 20339f70c1 | |||
| c2e6cf1eb0 | |||
| 8dfdca97cd | |||
| 6e8cdc24a3 | |||
| 461f1e39fa | |||
| 4892dbce5e | |||
| 9da32a13de | |||
| 9c6908da77 | |||
| ac081e6c86 | |||
| cc9744156c | |||
| 72a874c7f4 | |||
| 2809324b35 | |||
| 58e6c45c73 | |||
| 43aaf192a2 | |||
| c0574bc738 | |||
| 27e5d639ef | |||
| aa9fdd4fc9 | |||
| 7af6d9b2ce | |||
| 0e06d28335 | |||
| e3b86e4d41 | |||
| 5b1bfe7379 | |||
| 76d07b967e | |||
| 4b1932fe52 | |||
| a56de91b1e | |||
| 6b4fb616bc | |||
| d24670e14e | |||
| 13b3ae35ed | |||
| 6860e1f085 | |||
| 74fa1c6628 | |||
| 85f847a4f3 | |||
| 39df72d163 | |||
| 5ca8786802 | |||
| ca145967dc | |||
| 06a3ce7486 | |||
| 9f85b6154d | |||
| 732763689a | |||
| 0ea75f25f1 | |||
| eab27ce0bb | |||
| 29fd381989 | |||
| 06a845697a | |||
| b12587626d | |||
| b49988032e | |||
| a9b4152553 | |||
| 63720045f1 | |||
| aa7529192e | |||
| a162a15a27 | |||
| 457a73efae | |||
| 91c3dd982b | |||
| c171f93c93 | |||
| 0cf9ddb1cd | |||
| 2322537350 | |||
| 6ce50109da | |||
| abe7fdf34d | |||
| ecf2f5ed8c | |||
| 98b4934dd5 | |||
| 0bc7c544ad | |||
| 1f7ad9d418 | |||
| 4b9d3b3dbc | |||
| 571e332ed5 | |||
| d78d22b188 | |||
| d37638240a | |||
| ae7fd3f87b | |||
| e82e63b288 | |||
| 0149d4e27b | |||
| 9fc9c71b6f | |||
| b264f690d1 | |||
| c07e19c898 | |||
| b8e50737d2 | |||
| 082d0aa02f | |||
| ca26d0e450 | |||
| 8cbe021ffc | |||
| 7b39d8025b | |||
| 47bd35b151 | |||
| d7add54a3c | |||
| d3c937569b | |||
| 94ca613201 | |||
| 30f2f635be | |||
| 57f4d31c21 | |||
| 90e4fd7ff5 | |||
| 17835832f2 | |||
| 949817f597 | |||
| 23065f2c4b | |||
| b623b06cf0 | |||
| 55c86d8ec7 | |||
| e955617aa1 | |||
| 6304610713 | |||
| 47d20928e0 | |||
| c9a4d02e0d | |||
| 6513dfb42a | |||
| 3f0412453f | |||
| dcba319071 | |||
| d19851fc0c | |||
| d6eb06cb72 | |||
| 473080d7ee | |||
| c98a6adb09 | |||
| 2cd56d5041 | |||
| 982098672e | |||
| 445ecea3e6 | |||
| db977dfba4 | |||
| a3c12ab9f5 | |||
| 0f7e152650 | |||
| b55c7ba9a1 | |||
| 8256c9f7ad | |||
| 59727d7b0b | |||
| 2dd2210a73 | |||
| 25aafdbebc | |||
| cd5717169c | |||
| a38ad5a11e | |||
| 66d9b56976 | |||
| ac40bd1e17 | |||
| 16d2a9bf99 | |||
| b7e6838d26 | |||
| 21d23b5baa | |||
| 69a2941d57 | |||
| 3cc2abf8b9 | |||
| 6f4173650a | |||
| 0fcb8bdc0a | |||
| c0937cf412 | |||
| d9ab3aab0f | |||
| c8652de78b | |||
| 86dc4e2bd5 | |||
| 1b9c56a9b9 | |||
| 08ab504fac | |||
| 21c0842fae | |||
| 8d10feaa68 | |||
| df2171f253 | |||
| f5fcd94faf | |||
| 15c5dbef00 | |||
| 79df56c096 | |||
| d3fffd9530 | |||
| 527c9c8e6e | |||
| d285be45cb | |||
| 0dda9c73f6 | |||
| d07bf270e7 | |||
| eb24dd5d9e | |||
| ce693c7cd5 | |||
| 3198890269 | |||
| eacc93de43 | |||
| 9795740257 | |||
| 4548f5d8aa | |||
| 8dfd2fb519 | |||
| 83a40f83e1 | |||
| 5b2fcb3c6c | |||
| bcd9adb66d | |||
| 5e2dc114ab | |||
| 1ced4531be | |||
| 05fe39c0ae | |||
| 3769b2b3ea | |||
| f4d5480f6f | |||
| ddf3c0810b | |||
| 6afd6d0aa0 | |||
| 59fe92eb04 | |||
| 0550f32434 | |||
| b702cad549 | |||
| aa5c4d3c5e | |||
| 6a99445d97 | |||
| c9880ef47d | |||
| c16452dfcb | |||
| af802c02fc | |||
| 8028aafeff | |||
| b7469062a1 | |||
| 33b707aa68 | |||
| cd3a1bebff | |||
| 794dd5a797 | |||
| a1465432e8 | |||
| e1f8af0909 | |||
| 88918be329 | |||
| a3fc1dbff0 | |||
| 626c9825cc | |||
| c10a84fc79 | |||
| f14e4fe197 | |||
| 6eb218db5e | |||
| 0e77e053b0 | |||
| b9a4128a3d | |||
| 16f480e1f3 | |||
| 7c42511133 | |||
| 1b252a84c2 | |||
| bf833cadff | |||
| b6f872882a | |||
| a18d6fb441 | |||
| 922e703e81 | |||
| d7f5817b8b | |||
| 92a8a4bfa6 | |||
| b480151fc3 | |||
| 37bdbc1bd5 | |||
| 8eb669139b | |||
| b485e8cacc | |||
| c4bab61c47 | |||
| 72be417ff1 | |||
| 9be483d7a6 | |||
| 910f2cee2c | |||
| 1e47ace527 | |||
| 912b06b145 | |||
| 87d878e287 | |||
| be886d6bce | |||
| 0683deb47e | |||
| 114bb22e27 | |||
| c327ebc3df | |||
| 92cbd1c69c | |||
| 7242515e48 | |||
| 401d1a0ac2 | |||
| 863e042a37 | |||
| 39e6c45ec6 | |||
| 0d364d18c7 | |||
| 61444ea390 | |||
| 106a935efb | |||
| d175d8a853 | |||
| ce6d19a77a | |||
| 0a29273924 | |||
| 5ede64de58 | |||
| 224c6ad798 | |||
| 57b3a0dbe7 | |||
| f381f708e0 | |||
| 63bf149546 | |||
| cb5e671259 | |||
| 3e38173c4e | |||
| efacb643fc | |||
| 1bd153ea0b | |||
| bac3dc5f4c | |||
| 959a853d77 | |||
| 90bbdd563b | |||
| e3c6d05a0a | |||
| 930b3d4538 | |||
| 74b78141b4 | |||
| aa1108cd5b | |||
| f24b1a9db3 | |||
| 71b191e740 | |||
| 8f6341b903 | |||
| 161586db7e | |||
| 052262bef9 | |||
| a5a7144707 | |||
| d945e0426d | |||
| 926970c4eb | |||
| cce36e0f28 | |||
| 48c6dc5be5 | |||
| c641830825 | |||
| eba16cc15d | |||
| bd88b8411e | |||
| fc121e8750 | |||
| d4142fe56a | |||
| f76a3e72bb | |||
| 2d400ae7eb | |||
| edf1632cab | |||
| a648f1ee67 | |||
| d004e6e86c | |||
| fa321d3e8d | |||
| e1e53d323f | |||
| ccb18ca302 | |||
| e170f36bc6 | |||
| 4bd9cc51ee | |||
| 43ffbda1a4 | |||
| 8240485fd1 | |||
| 7f053c0567 | |||
| d2922eb0b7 | |||
| fec10d453f | |||
| 162040545d | |||
| f14577f8bf | |||
| e5720bd1be | |||
| 6d4959bac8 | |||
| d668128a34 | |||
| f2af38da4c | |||
| 4776d18fd7 | |||
| cdd0be7b78 | |||
| cd505abb22 | |||
| 28439c010f | |||
| e85f43beb1 | |||
| a06cbc0840 | |||
| adef9728f8 | |||
| ff1b688b6e | |||
| 3e7574a927 | |||
| f852ea90ad | |||
| d8f6247c32 | |||
| 9dc28393a5 | |||
| c442c98ecf | |||
| 71e0109927 | |||
| 9c7dd5ed1c | |||
| 83620848f2 | |||
| d548a5b4f3 | |||
| b6e5307755 | |||
| 4c5dc5a145 | |||
| 69ed9172b8 | |||
| 68551ae176 | |||
| c97d9d35ba | |||
| e86cc97cdf | |||
| 9bff8608c1 | |||
| a10fe6994a | |||
| 67e6a37b59 | |||
| 3075a56735 | |||
| 7e4a862cc3 | |||
| ed2078ee3b | |||
| f99c23a622 | |||
| 41e7317764 | |||
| e0a78c2399 | |||
| 95ad39d2d4 | |||
| b831f827b1 | |||
| c5d8413d9c | |||
| 4648ea3424 | |||
| e05bd6f231 | |||
| caadee7901 | |||
| 18c524117d | |||
| ad30fb8b04 | |||
| a8077965a9 | |||
| 532ab85ebb | |||
| 546227eb37 | |||
| 7ec3b262d3 | |||
| c435000d24 | |||
| eaa60c281e | |||
| cd7cf63144 | |||
| 6a704aa079 | |||
| d6b5a1cec8 | |||
| 9a24ad31cc | |||
| 9331630b54 | |||
| 904e869d7f | |||
| 307fa4f5e6 | |||
| 131d16d3ea | |||
| dbc54c45dd | |||
| a96a84d509 | |||
| 3eb8863f67 | |||
| 8737ab077b | |||
| 50bb6a1d19 | |||
| 4181b75af7 | |||
| 620705c87a | |||
| 50b7b93529 | |||
| 6f18f6bd5c | |||
| 01d256eeee | |||
| a1405412a8 | |||
| 58589b3a15 | |||
| 2983266fdf | |||
| e33df8f12d | |||
| 0e0e8e9d18 | |||
| 37f8b54752 | |||
| e9a086ad23 | |||
| 7c06a8ac41 | |||
| 70801d958e | |||
| cf3f95c952 | |||
| d708616a6a | |||
| 17711bc5c9 | |||
| 1e2474921b | |||
| 3f37b2b728 | |||
| 18b11df672 | |||
| c34f2d4da7 | |||
| d61792581a | |||
| 76d9a511b8 | |||
| 4248326697 | |||
| a540b38151 | |||
| 8fb5ef0c1d | |||
| 2da4979e59 | |||
| 0146e4a1dd | |||
| 34bdb72ffd | |||
| 2ef7c63047 | |||
| 95f5417761 | |||
| 4922ec4499 | |||
| 20d947a199 | |||
| c9444c5318 | |||
| 871dc90ee4 | |||
| d1925945b4 | |||
| 6625080fde | |||
| 1110609e39 | |||
| f21d2c7253 | |||
| 9c1d330945 | |||
| cd7800056c | |||
| 7ff4bec3bc | |||
| d305cf2167 | |||
| e77b83bd92 | |||
| 171d58658a | |||
| a6f6bc4c0a | |||
| f03cffe3f8 | |||
| 809dca184e | |||
| ecda226949 | |||
| ff1b58ebd8 | |||
| 5760ada3b4 | |||
| b74b6b3284 | |||
| e4cc4b6f58 | |||
| dd90851477 | |||
| da9b127468 | |||
| d6b05e44cb | |||
| 58c1b5b98d | |||
| c270cba8d6 | |||
| 58f1f749fc | |||
| 38d87a7c8f | |||
| 4e13598708 | |||
| 4177448d32 | |||
| e4911a6f82 | |||
| 159224700f | |||
| 696d4e7342 | |||
| ffb6cfaa4a | |||
| b8899fcafa | |||
| aba829c991 | |||
| 8f4c61c259 | |||
| a19648a6e8 | |||
| d5c0f7045e | |||
| 6f69205818 | |||
| 8166da548c | |||
| d54f7293b7 | |||
| 225520a765 | |||
| af1eccde8e | |||
| 5d37280643 | |||
| 80597039f5 | |||
| 2766aedc01 | |||
| da3e12cb7e | |||
| 8baff1b0d2 | |||
| 4ff5f9204e | |||
| 515339bbd8 | |||
| 943634b0e2 | |||
| 212b26b960 | |||
| c0b41987aa | |||
| b4ef640052 | |||
| db6b7f52eb | |||
| 55b4b9e02a | |||
| 4e6ae93b13 | |||
| c9a5fe5676 | |||
| a5adfb7c7f | |||
| 1794b86041 | |||
| f405124ce4 | |||
| 25060c1477 | |||
| 6ad218f354 | |||
| d1c52548b0 | |||
| 9dc847b72f | |||
| 5b04adb21f | |||
| 356d25e548 | |||
| a9958af818 | |||
| fb359b7f87 | |||
| 7f087819a6 | |||
| e836fa3d38 | |||
| 9a69f1108d | |||
| 2c5c58dc90 | |||
| cb50d2838a | |||
| aff7125914 | |||
| 45d82dce04 | |||
| 7a3b27227a | |||
| 7b50a19b2c | |||
| 741b942dea | |||
| f7ca64a49d | |||
| 2f7b3455e5 | |||
| 1568dfc183 | |||
| d3a5df0007 | |||
| c20cac621a | |||
| 74560c3289 | |||
| f94bf3f8ce | |||
| d26db7096d | |||
| afde0a7423 | |||
| cc930a3ff9 | |||
| 60ecdadc74 | |||
| 82fc1850cf | |||
| 88f937f73e | |||
| b3497c7306 | |||
| 366ab2e0cd | |||
| 98e4fabd2e | |||
| 716c3573fd | |||
| 842d8dd780 | |||
| c767dfb22e | |||
| f94901c3b2 | |||
| c9638aefe9 | |||
| 8bd4721686 | |||
| 808f7504c3 | |||
| 8ea7d3d5e8 | |||
| d4931890ae | |||
| f4a879a452 | |||
| 78521ffdb4 | |||
| 8ea3f80b97 | |||
| 0d8d87857c | |||
| 3a3a261d9c | |||
| 2e00daf63c | |||
| 1b8bb0c1fd | |||
| 5c33579544 | |||
| f8081ff09e | |||
| 01b7eeeecf | |||
| d2f4c374a9 | |||
| 07073eebe9 | |||
| 590a4ae476 | |||
| b553a81d47 | |||
| 7d4e53e413 | |||
| 839b0f6f5e | |||
| 893c5da4ef | |||
| f9b893edfa | |||
| b4fadb39bf | |||
| 310f8bf6f7 | |||
| 903a26a330 | |||
| 41ebd39810 | |||
| 281de5196e | |||
| a9ab864cbb | |||
| f3ff910821 | |||
| ba5179f1e8 | |||
| 05e8f6ed78 | |||
| 23150815a0 | |||
| a50f223fe3 | |||
| 9329345d98 | |||
| c71c32b363 | |||
| 5590aa7234 | |||
| 4a3491e0b5 | |||
| e8cb87ae3d | |||
| 2f6427af32 | |||
| 5564047001 | |||
| 22577c5f87 | |||
| 4dc2627da2 | |||
| 05aaf0de9f | |||
| 951bfa23f3 | |||
| 7ac6cfcf25 | |||
| 06055a7c4c | |||
| b33198d1bf | |||
| f826b9eb6e | |||
| 2b58121552 | |||
| 762547d0e9 | |||
| 727523eb3f | |||
| 5bbdb66eb2 | |||
| c6eff4f90d | |||
| 2559173c2c | |||
| 8adea132ef | |||
| 9d924f8d1c | |||
| 1b297fed90 | |||
| 2c2a93c440 | |||
| bb076cce5d | |||
| b16b02c3f1 | |||
| 3e0f834796 | |||
| 0af38c6e0e | |||
| 85f7011e03 | |||
| e8d5412e14 | |||
| 170cf4753e | |||
| 660e76145e | |||
| 31a6f7b621 | |||
| f6699ad93b | |||
| 6e508e4454 | |||
| 2b101844e9 | |||
| fb036935e6 | |||
| c3e09ddab0 | |||
| 36ae07074d | |||
| a4518ce261 | |||
| 861ea7ef94 | |||
| 541af0b77e | |||
| 3fd3de1828 | |||
| 3e2840ca15 | |||
| 839ec9a456 | |||
| bac8bd0006 | |||
| 8c1b51b7e9 | |||
| a71c4fe7ec | |||
| b9d4197b5c | |||
| ce7559087e | |||
| 110d87e512 | |||
| cd817714cd | |||
| 23db345756 | |||
| 16990bd0c3 | |||
| 2e3b770bea | |||
| 28f62623bf | |||
| c9f3e8cb9f | |||
| 6b751eb715 | |||
| 5d953da267 | |||
| e87ae31a51 | |||
| 9f029b892b | |||
| 40a9ced0f7 | |||
| 87fbd7e5da | |||
| bca5514a76 | |||
| 62ddbb20ac | |||
| 9d376961f4 | |||
| e77aa00bcd | |||
| 465330820d | |||
| ec9cbba67e | |||
| 8961ea6fc9 | |||
| ca7ca9da81 | |||
| 2a234f14df | |||
| 3ff97bf628 | |||
| 416d6f2aef | |||
| ecaafaca69 | |||
| fdb14cd49b | |||
| 070e955b89 | |||
| 9390ab3c6c | |||
| f67221ee01 | |||
| e09294d9aa | |||
| 5675acb71a | |||
| 0305a5dcef | |||
| 5f03340454 | |||
| 0f69ba46c5 | |||
| 71ecb6bd4e | |||
| 2b712cc808 | |||
| 3a68b7b554 | |||
| e41727a1fc | |||
| 857d0f3316 | |||
| 1f68f62689 | |||
| 09b43a8e95 | |||
| b8d765d229 | |||
| 06a919ff8d | |||
| ea1e7769b1 | |||
| d5e6f99819 | |||
| a5ab9726dd | |||
| 6464fc56d8 | |||
| 156e1b928c | |||
| edf17b8100 | |||
| 5ab980ce1a | |||
| f1d80fadc4 | |||
| d331d48ca2 | |||
| e740db11ed | |||
| 6cff7b3c30 | |||
| 88cdd2fcbf | |||
| 55896be694 | |||
| c4f17e42e1 | |||
| e8b11bd42a | |||
| a566fb3988 | |||
| de071b37eb | |||
| 7b4d408733 | |||
| 06478d89ea | |||
| 7cedf4c620 | |||
| ef1ea5eeee | |||
| 96f222db94 | |||
| 065eb9b878 | |||
| ed583d80a3 | |||
| 7752db3916 | |||
| e18254e4d8 | |||
| 555fc97e8f | |||
| f135adfdba | |||
| 72b766f32a | |||
| 5278861ccd | |||
| ebcf88070c | |||
| 273811bbb8 | |||
| 26b53e725d | |||
| 5434ec85e2 | |||
| 91f438aeff | |||
| 501f67ebe7 | |||
| be52fef0bb | |||
| 2c0cf40a15 | |||
| 8566070d9b | |||
| 8f4118a6b8 | |||
| 54c53f0b56 | |||
| eafcee8c67 | |||
| 5c8e1e0f4a | |||
| 76043d5876 | |||
| 936f3b0752 | |||
| 9380608781 | |||
| 544b75bcd5 | |||
| 2ae63d2323 | |||
| f24717a3a3 | |||
| f0f5558f3e | |||
| 3d8c732258 | |||
| f312237bd5 | |||
| 952dde3fef | |||
| e5387f6d06 | |||
| 93d6697b4e | |||
| bad2f3415a | |||
| d2f5d97282 | |||
| f8c3fef839 | |||
| 14b47a929f | |||
| 4b3c0466eb | |||
| 041397b137 | |||
| 6548c286a6 | |||
| ccf78285b6 | |||
| 5e9366fa92 | |||
| 0e30cb1439 | |||
| b8d86518e7 | |||
| 725399ac7c | |||
| ca18994092 | |||
| caefc438b9 | |||
| 0ece8c7dec | |||
| e7c42f3623 | |||
| 18faf89b89 | |||
| 3a750ae6a2 | |||
| 48c614d8c3 | |||
| c37d502c27 | |||
| 3fed7a081d | |||
| e75497d03b | |||
| 6d1421f1b7 | |||
| dd210be037 | |||
| 7c7d6ad548 | |||
| 2f471c0e3f | |||
| cff219674f | |||
| e35f9eb75b | |||
| ef1eff2ecb | |||
| 244ff61fb3 | |||
| 50e2623f19 | |||
| fd0b997c13 | |||
| 13d057e4f7 | |||
| d1a6be6ca6 | |||
| edece02c13 | |||
| d68cf4e44d | |||
| 9d85a58634 | |||
| c4a4cd0957 | |||
| 5af7615054 | |||
| a68a1334fc | |||
| dd3e38355c | |||
| 890461bcf8 | |||
| 750265cb79 | |||
| 004de824ba | |||
| fc43b35628 | |||
| 696653f945 | |||
| 157dca50e9 | |||
| 7d2130b229 | |||
| 2cc81211af | |||
| ea9a5b0eb0 | |||
| e60cee6a73 | |||
| a3ee60a464 | |||
| 28595cbeb3 | |||
| dbdbf5210e | |||
| a4876f6f14 | |||
| 9835ae7e50 | |||
| 59f763162c | |||
| a9412b418f | |||
| 742c5b76fe | |||
| 7a85fc0179 | |||
| 73e73ffe58 | |||
| 3c5523894d | |||
| 4b9c76d3db | |||
| 0a694eea8a | |||
| 87f48dad79 | |||
| 68ef50ca46 | |||
| 8b1da33ffe | |||
| 9a9b18a3ef | |||
| 83f69d89ff | |||
| 0bd7d23114 | |||
| 9b860a6aa6 | |||
| 4812519a4c | |||
| f3ce6ad467 | |||
| 78d9b48854 | |||
| b37d0eba04 | |||
| 5289b3f54c | |||
| 5c08fe0611 | |||
| 4bc9b70882 | |||
| 3f98f9ff39 | |||
| e78a7bfbf1 | |||
| b8b1412bf8 | |||
| a81d66ace3 | |||
| dcfd72b7e7 | |||
| 6467db4a21 | |||
| f2570c97f3 | |||
| 98ad518b5d | |||
| 7a5e17a345 | |||
| fde257c722 | |||
| 97357f082d | |||
| 6875bd82fc | |||
| b1f6cad741 | |||
| fb28fec60d | |||
| 500130be59 | |||
| 101173c87c | |||
| 4fb1b0dbd1 | |||
| 4270d5e8ec | |||
| fe9f1146ce | |||
| 6fce43a122 | |||
| a8a8f9b3e5 | |||
| 0dd0125e9f | |||
| d3d97b5924 | |||
| c8462fb50b | |||
| c99ca9edcc | |||
| fc7e96feb9 | |||
| 31dd7be296 | |||
| 2899373e42 | |||
| 7640c3d0ef | |||
| af7772f617 | |||
| a1670caf06 | |||
| 61e35b9773 | |||
| e4671ffdb3 | |||
| 3035f923cb | |||
| 97e83def48 | |||
| ba31deaebf | |||
| bd571dc93d | |||
| c1da8321ac | |||
| 0a1972b854 | |||
| 96f387e90b | |||
| e034fc1019 | |||
| d539912762 | |||
| 85b72af3bb | |||
| 3004f4b583 | |||
| 78dbd7eacd | |||
| add73e6f16 | |||
| 2c5a7d103d | |||
| f8f855d5d2 | |||
| f2c109116c | |||
| 41c63fab96 | |||
| de94651fca | |||
| 611c468b70 | |||
| fd2207e39e | |||
| 10564442e2 | |||
| a44307ca2d | |||
| cfea2ed954 | |||
| 62e59605ed | |||
| 2644b1b7ac | |||
| 6e4c6d0c54 | |||
| 2b7d950a9f | |||
| 5ece8d67f9 | |||
| 8511b67811 | |||
| a0a444e476 | |||
| 6fec92926d | |||
| 2cbefb261b | |||
| 4bebbb158c | |||
| 8fe2172c0a | |||
| f52ef2d57e | |||
| 3f1c005548 | |||
| 821bd2b2d8 | |||
| d8405feab3 | |||
| bd94437c05 | |||
| b290bdb473 | |||
| f8e2af4fd4 | |||
| 97c8dfa5b9 | |||
| 37cce68e2e | |||
| 1f87a71b98 | |||
| 5511ea1887 | |||
| e371081a1d | |||
| 70816b48e8 | |||
| 2c9fc7b4a7 | |||
| 3bb4652a49 | |||
| d5f8e01dd8 | |||
| 27e0517f9a | |||
| f59aeda28e | |||
| a8a69f8c36 | |||
| 4ae6b8328e | |||
| 6d4337e4ce | |||
| 3df928caf4 | |||
| faeb33fdc0 | |||
| bacdeb20eb | |||
| 781c426b2f | |||
| d5c9fb8dec | |||
| 78c372b9d8 | |||
| ea31069609 | |||
| 3f9a3e8f64 | |||
| 2f02715efd | |||
| c94fa64a33 | |||
| e2cb666b3c | |||
| 9f24e0145b | |||
| 41413471aa | |||
| f8a11166f0 | |||
| 27517b3b47 | |||
| 834c0d92b4 | |||
| e04215f0e1 | |||
| 9fa8d98ae8 | |||
| 31621f273b | |||
| 41f158dac1 | |||
| e5687f3a7c | |||
| 1a5b684e1f | |||
| bf70c487ca | |||
| 4e1d34ba77 | |||
| 3a75ad61f3 | |||
| c7db9ef481 | |||
| fb709c9eb0 | |||
| dfe4d2811a | |||
| 6e4d16749b | |||
| 75b2debf0a | |||
| ba9e124527 | |||
| d684ab0e5e | |||
| 2e8205f458 | |||
| 35855297eb | |||
| d365ecce46 | |||
| f4edc45507 | |||
| d165d81df0 | |||
| ba0eba7132 | |||
| 2b7f4281c2 | |||
| 0046575a4f | |||
| 58b88d66be | |||
| 57f1019e51 | |||
| b40168182a | |||
| 0ece662d8c | |||
| 9265e52d68 | |||
| 3a04166747 | |||
| 75bf58359c | |||
| e7f63e0460 | |||
| 1fdd1c6e88 | |||
| 391b9e91e9 | |||
| 1e67ca3794 | |||
| ceebf6dbe1 | |||
| 8d4f9fd953 | |||
| 1c3032068e | |||
| 7b4b72166f | |||
| 707e5bb8b0 | |||
| ad5d364c57 | |||
| 138fadf672 | |||
| 82eabc41fe | |||
| 3e6aab6b00 | |||
| 5396b3f1fb | |||
| b1ba887922 | |||
| 93a1c593fe | |||
| b7044248cb | |||
| ea5e2f660b | |||
| e9779a3d2f | |||
| 1c6ec0f8e3 | |||
| 84bd81e525 | |||
| a84cbee9db | |||
| 97b16c8c0c | |||
| 0a6a35b022 | |||
| 6565b4101b | |||
| fbbcc1172d | |||
| 53dc50c0dd | |||
| 7b56485c74 | |||
| cfc9b809fc | |||
| 4015e2566e | |||
| 1d474a967c | |||
| bffc34485a | |||
| 3bf22a8606 | |||
| 257ffa3cc4 | |||
| 0c104d5d29 | |||
| 2a59faec17 | |||
| 00534f7edd | |||
| 4006f03444 | |||
| beca5c6e45 | |||
| 69f781d3de | |||
| 3f3160406f | |||
| 8067cff9bd | |||
| 7d776bb2af | |||
| 880bb0d7cb | |||
| 3aea01fb78 | |||
| 7025f4701d | |||
| 9d98b06132 | |||
| 47cb83c1ff | |||
| 6ff8847251 | |||
| 9d9367d127 | |||
| ae7c1ae666 | |||
| 44fe3cb7bd | |||
| bc783eb511 | |||
| 0491bd5364 | |||
| cf47cccc97 | |||
| c65ab35107 | |||
| b8ea16f4d4 | |||
| b40b5f0c1c | |||
| b193e29fdb | |||
| 1b602c134f | |||
| e462c6d412 | |||
| d0c83f3c96 | |||
| 0547aa2095 | |||
| 322907b972 | |||
| 189b9a7ad6 | |||
| 1d02927f6b | |||
| 2ad739419a | |||
| 093ace1a89 | |||
| 4c982a762b | |||
| a30efd6e81 | |||
| 1c0fc0bff2 | |||
| 7da0c204df | |||
| a35421d8ab | |||
| 450ce53dcf | |||
| e80ccfcb19 | |||
| 9ad612bd78 | |||
| 288857999f | |||
| 217823652c | |||
| 268e1670c7 | |||
| ce7b155f72 | |||
| 2a71d84580 | |||
| 8f73dce934 | |||
| 5953e32988 | |||
| df74322b05 | |||
| 22d941ae45 | |||
| 4fd7c1c4e9 | |||
| ee1aa6d42c | |||
| 1343aba26e | |||
| 1483d84d8c | |||
| 02d58d66c9 | |||
| 2eb6ca28f7 | |||
| 7575a9ce02 | |||
| 039b832be2 | |||
| e0ed025507 | |||
| f2bd08f02a | |||
| 63314b54bc | |||
| 65165cd15f | |||
| d5ddbca067 | |||
| 517027e1fe | |||
| b843ccc898 | |||
| fffd81267d | |||
| 7d26dd5348 | |||
| a4d3189dac | |||
| ec02743f83 | |||
| 10e807751a | |||
| a8e827b5e2 | |||
| f0eaba5857 | |||
| 7516b056a5 | |||
| 312c3b8295 | |||
| 0a777dc909 | |||
| ec24376608 | |||
| c9f45da217 | |||
| 34cfbabf51 | |||
| f7e7a4c99c | |||
| 58c318b5cf | |||
| 10b1644d8d | |||
| 599f59fc39 | |||
| da4b8f6cb9 | |||
| 5f2e882ed9 | |||
| f20abe8878 | |||
| a6ab37f21c | |||
| 13fc3ee25e | |||
| 2268086eac | |||
| 9e9dec5389 | |||
| 11d193a6dd | |||
| f81207737c | |||
| 191c25a26b | |||
| 9c7727b7f3 | |||
| 8bea9b8312 | |||
| 805a063fa1 | |||
| 20a1cc89ae | |||
| 963994b1e5 | |||
| afcb226111 | |||
| 5b246fe44c | |||
| d79f82e9b8 | |||
| bdd9dc8c9d | |||
| 8bdd24aa1e | |||
| 13c0da5c8a | |||
| d31cfb15db | |||
| 8453bd3c26 | |||
| 457bf311c3 | |||
| ea2ec9ef54 | |||
| d0c84ea469 | |||
| cdec56b661 | |||
| 8bc2d7cb05 | |||
| 21f3de0a18 | |||
| 65b497c9f1 | |||
| f37f1e794e | |||
| 0096a40132 | |||
| b6b9b67836 | |||
| 2b80a98a96 | |||
| 8c5d47bfa0 | |||
| 00c0a0505f | |||
| 01ba8b4f3f | |||
| 919249215b | |||
| a62394a67c | |||
| 332fff279b | |||
| 27df4c435f | |||
| a9998ebca7 | |||
| 82a8baabef | |||
| 2af6d4ef29 | |||
| c2526c1e2d | |||
| 6021fa721e | |||
| 0bd59dc0f8 | |||
| 1af0c34ac0 | |||
| 77f5b6d0c8 | |||
| cb3fdf1112 | |||
| 482d3d9188 | |||
| bb4c64f478 | |||
| a9d6e42add | |||
| 5fa6cf8eca | |||
| 7c0de7b634 | |||
| 691f3238c5 | |||
| 43163c787d | |||
| a86693d950 | |||
| 6388129e27 | |||
| 7788806a8d | |||
| 30037dad83 | |||
| d49c7d5e45 | |||
| 502109cdcb | |||
| 3de775a163 | |||
| d4de917895 | |||
| 35cb718f1f | |||
| 60a72f4d45 | |||
| 6ae536d035 | |||
| 23daa7a91c | |||
| 771f93b5fa | |||
| 19826636c7 | |||
| 57ba9b52ba | |||
| 38c0d9bbc3 | |||
| 5fb3e0b941 | |||
| 9aa09d138a | |||
| f48efcc02d | |||
| 1703e9e8c6 | |||
| 940cf02935 | |||
| 355aefc62a | |||
| 0c0c9b2dad | |||
| d3df844917 | |||
| e227f1f182 | |||
| f97b49bc53 | |||
| 788b6def6c | |||
| 8550707485 | |||
| aa8dfa1c87 | |||
| 7b68dd0f47 | |||
| cac3e6efec | |||
| d76786e344 |
@@ -5,10 +5,10 @@ name: Electron app BETA
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -53,12 +53,6 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
@@ -71,16 +65,16 @@ jobs:
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
WIN_CSC_LINK: ${{ secrets.WINCERT_2025 }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.WINCERT_2025_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -92,6 +86,7 @@ jobs:
|
||||
cp app/dist/*win*.exe artifacts/dbgate-beta.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-beta.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-beta-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-beta-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-beta.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-beta-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-beta-arm64.dmg || true
|
||||
@@ -111,16 +106,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Electron app check build
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- check-[0-9]+-[0-9]+-[0-9]+.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- macos-14
|
||||
- windows-2022
|
||||
- ubuntu-22.04
|
||||
steps:
|
||||
- name: Install python 3.11 (MacOS)
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
brew install python@3.11
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: adjustPackageJson
|
||||
run: |
|
||||
|
||||
node adjustPackageJson --community
|
||||
- name: yarn set timeout
|
||||
run: |
|
||||
|
||||
yarn config set network-timeout 100000
|
||||
- name: yarn install
|
||||
run: |
|
||||
|
||||
yarn install
|
||||
- name: setCurrentVersion
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
yarn fillPackagedPlugins
|
||||
- name: Install Snapcraft
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
uses: samuelmeuli/action-snapcraft@v1
|
||||
- name: Publish
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
WIN_CSC_LINK: ${{ secrets.WINCERT_2025 }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.WINCERT_2025_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
|
||||
cp app/dist/*.deb artifacts/dbgate-check.deb || true
|
||||
cp app/dist/*x86*.AppImage artifacts/dbgate-check.AppImage || true
|
||||
cp app/dist/*arm64*.AppImage artifacts/dbgate-check-arm64.AppImage || true
|
||||
cp app/dist/*armv7l*.AppImage artifacts/dbgate-check-armv7l.AppImage || true
|
||||
cp app/dist/*win*.exe artifacts/dbgate-check.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-check.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-check-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-check-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-check.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-check-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-check-arm64.dmg || true
|
||||
mv app/dist/*.snap artifacts/dbgate-check.snap || true
|
||||
|
||||
mv app/dist/*.exe artifacts/ || true
|
||||
mv app/dist/*.zip artifacts/ || true
|
||||
mv app/dist/*.tar.gz artifacts/ || true
|
||||
mv app/dist/*.AppImage artifacts/ || true
|
||||
mv app/dist/*.deb artifacts/ || true
|
||||
mv app/dist/*.snap artifacts/ || true
|
||||
mv app/dist/*.dmg artifacts/ || true
|
||||
mv app/dist/*.blockmap artifacts/ || true
|
||||
|
||||
mv app/dist/*.yml artifacts/ || true
|
||||
rm artifacts/builder-debug.yml
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
find . -type f -name "notarization-error.log" -exec echo "=== Start of {} ===" \; -exec cat {} \; -exec echo "=== End of {} ===" \;
|
||||
@@ -5,10 +5,10 @@ name: Electron app PREMIUM BETA
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -37,9 +37,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -81,14 +81,6 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
cd ..
|
||||
@@ -102,16 +94,16 @@ jobs:
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
WIN_CSC_LINK: ${{ secrets.WINCERT_2025 }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.WINCERT_2025_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -123,6 +115,7 @@ jobs:
|
||||
cp ../dbgate-merged/app/dist/*win*.exe artifacts/dbgate-premium-beta.exe || true
|
||||
cp ../dbgate-merged/app/dist/*win_x64.zip artifacts/dbgate-windows-premium-beta.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.zip artifacts/dbgate-windows-premium-beta-arm64.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.exe artifacts/dbgate-windows-premium-beta-arm64.exe || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_universal.dmg artifacts/dbgate-premium-beta.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_x64.dmg artifacts/dbgate-premium-beta-x64.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_arm64.dmg artifacts/dbgate-premium-beta-arm64.dmg || true
|
||||
@@ -142,16 +135,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -5,10 +5,10 @@ name: Electron app PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -37,9 +37,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -81,14 +81,6 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
cd ..
|
||||
@@ -102,16 +94,16 @@ jobs:
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
WIN_CSC_LINK: ${{ secrets.WINCERT_2025 }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.WINCERT_2025_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -123,6 +115,7 @@ jobs:
|
||||
cp ../dbgate-merged/app/dist/*win*.exe artifacts/dbgate-premium-latest.exe || true
|
||||
cp ../dbgate-merged/app/dist/*win_x64.zip artifacts/dbgate-windows-premium-latest.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.zip artifacts/dbgate-windows-premium-latest-arm64.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.exe artifacts/dbgate-windows-premium-latest-arm64.exe || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_universal.dmg artifacts/dbgate-premium-latest.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_x64.dmg artifacts/dbgate-premium-latest-x64.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_arm64.dmg artifacts/dbgate-premium-latest-arm64.dmg || true
|
||||
@@ -142,16 +135,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -5,10 +5,10 @@ name: Electron app
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -49,12 +49,6 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
@@ -67,16 +61,16 @@ jobs:
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
WIN_CSC_LINK: ${{ secrets.WINCERT_2025 }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.WINCERT_2025_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: generatePadFile
|
||||
run: |
|
||||
yarn generatePadFile
|
||||
@@ -91,6 +85,7 @@ jobs:
|
||||
cp app/dist/*win*.exe artifacts/dbgate-latest.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-latest.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-latest-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-latest-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-latest.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-latest-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-latest-arm64.dmg || true
|
||||
@@ -114,16 +109,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: AWS image PREMIUM
|
||||
name: Cloud images PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-packer-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-packer-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,15 +17,18 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Install jq
|
||||
run: |
|
||||
sudo apt-get install jq -y
|
||||
- name: Setup `packer`
|
||||
uses: hashicorp/setup-packer@main
|
||||
with:
|
||||
@@ -34,9 +37,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -63,13 +66,6 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare packer build
|
||||
run: |
|
||||
cd ..
|
||||
@@ -84,41 +80,56 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
- name: Run `packer init`
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run `packer init` for Azure
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer init ./azure-ubuntu.pkr.hcl
|
||||
- name: Run `packer build` for Azure
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer build ./azure-ubuntu.pkr.hcl
|
||||
- name: Run `packer init` for AWS
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer init ./aws-ubuntu.pkr.hcl
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
- name: Run `packer build`
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
- name: Run `packer build` for AWS
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer build ./aws-ubuntu.pkr.hcl
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
- name: Install jq
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
- name: Delete old Azure VMs
|
||||
run: |
|
||||
sudo apt-get install jq -y
|
||||
- name: Delete old AMIs
|
||||
cd ../dbgate-merged/packer
|
||||
chmod +x delete-old-azure-images.sh
|
||||
./delete-old-azure-images.sh
|
||||
env:
|
||||
AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}}
|
||||
AZURE_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}}
|
||||
AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}}
|
||||
AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}}
|
||||
- name: Delete old AMIs (AWS)
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
chmod +x delete-old-amis.sh
|
||||
./delete-old-amis.sh
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
@@ -5,11 +5,11 @@ name: Docker image PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -34,17 +34,17 @@ jobs:
|
||||
|
||||
type=match,pattern=\d+.\d+.\d+,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/dbgate-pro
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -76,31 +76,25 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare docker image
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run prepare:docker
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: '${{ secrets.DOCKER_USERNAME }}'
|
||||
password: '${{ secrets.DOCKER_PASSWORD }}'
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ../dbgate-merged/docker
|
||||
tags: '${{ steps.meta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64'
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
@@ -5,11 +5,11 @@ name: Docker image Community
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -47,10 +47,10 @@ jobs:
|
||||
|
||||
type=match,pattern=\d+.\d+.\d+,suffix=-alpine,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
type=raw,value=alpine,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: adjustPackageJson
|
||||
run: |
|
||||
|
||||
@@ -65,35 +65,31 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare docker image
|
||||
run: |
|
||||
|
||||
yarn run prepare:docker
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: '${{ secrets.DOCKER_USERNAME }}'
|
||||
password: '${{ secrets.DOCKER_PASSWORD }}'
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ./docker
|
||||
tags: '${{ steps.meta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v7'
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Build and push alpine
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ./docker
|
||||
file: ./docker/Dockerfile-alpine
|
||||
tags: '${{ steps.alpmeta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v7'
|
||||
tags: ${{ steps.alpmeta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
|
||||
@@ -5,11 +5,11 @@ name: NPM packages PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,22 +17,22 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/dbgate-pro
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
node adjustNpmPackageJsonPremium
|
||||
- name: Configure NPM token
|
||||
env:
|
||||
NPM_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
@@ -71,13 +71,6 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Publish dbgate-api-premium
|
||||
run: |
|
||||
cd ..
|
||||
@@ -98,3 +91,8 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged/plugins/dbgate-plugin-cosmosdb
|
||||
npm publish
|
||||
- name: Publish dbgate-plugin-firestore
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/plugins/dbgate-plugin-firestore
|
||||
npm publish
|
||||
|
||||
@@ -5,11 +5,11 @@ name: NPM packages
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,18 +17,18 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Configure NPM token
|
||||
env:
|
||||
NPM_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
|
||||
- name: yarn install
|
||||
@@ -37,11 +37,6 @@ jobs:
|
||||
- name: setCurrentVersion
|
||||
run: |
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Publish types
|
||||
working-directory: packages/types
|
||||
run: |
|
||||
@@ -123,3 +118,11 @@ jobs:
|
||||
working-directory: plugins/dbgate-plugin-clickhouse
|
||||
run: |
|
||||
npm publish
|
||||
- name: Publish dbgate-plugin-dbf
|
||||
working-directory: plugins/dbgate-plugin-dbf
|
||||
run: |
|
||||
npm publish
|
||||
- name: Publish dbgate-plugin-cassandra
|
||||
working-directory: plugins/dbgate-plugin-cassandra
|
||||
run: |
|
||||
npm publish
|
||||
|
||||
@@ -30,8 +30,8 @@ jobs:
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: '${{ github.actor }}'
|
||||
password: '${{ secrets.GITHUB_TOKEN }}'
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Push mysql-ssh-login to GHCR
|
||||
run: |
|
||||
docker tag dbgate/mysql-ssh-login:latest ghcr.io/dbgate/mysql-ssh-login:latest
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Diflow merge
|
||||
'on':
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/diflow
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/diflow
|
||||
path: diflow
|
||||
- name: Diflow install
|
||||
run: |
|
||||
cd diflow
|
||||
npm install
|
||||
npm run build
|
||||
- name: Git config
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.io"
|
||||
git config --global user.name "Diflow"
|
||||
- name: Diflow run
|
||||
run: |
|
||||
cd diflow
|
||||
node dist/diflow.js sync -r https://DIFLOW_GIT_SECRET@github.com/dbgate/dbgate-diflow-config.git -b master
|
||||
env:
|
||||
DIFLOW_GIT_SECRET: ${{ secrets.DIFLOW_GIT_SECRET }}
|
||||
@@ -13,10 +13,10 @@ jobs:
|
||||
e2e-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@@ -24,9 +24,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: ca1a1664e4c45945d7afe9534c43ca6cbb0b06e3
|
||||
ref: 11203754aad94189b565c2816d37760b15c8e07f
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -69,6 +69,17 @@ jobs:
|
||||
with:
|
||||
name: screenshots
|
||||
path: screenshots
|
||||
- name: Push E2E screenshots
|
||||
if: ${{ github.ref_name == 'master' }}
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.info"
|
||||
git config --global user.name "GitHub Actions"
|
||||
git clone https://${{ secrets.DIFLOW_GIT_SECRET }}@github.com/dbgate/dbgate-img.git
|
||||
cp ../dbgate-merged/e2e-tests/screenshots/*.png dbgate-img/static/img
|
||||
cd dbgate-img/static/img
|
||||
git add .
|
||||
git commit --amend --no-edit
|
||||
git push --force
|
||||
services:
|
||||
postgres-cypress:
|
||||
image: postgres
|
||||
@@ -78,25 +89,25 @@ jobs:
|
||||
ports:
|
||||
- '16000:5432'
|
||||
mysql-cypress:
|
||||
image: 'mysql:8.0.18'
|
||||
image: mysql:8.0.18
|
||||
ports:
|
||||
- '16004:3306'
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: Pwd2020Db
|
||||
mysql-ssh-login:
|
||||
image: 'ghcr.io/dbgate/mysql-ssh-login:latest'
|
||||
image: ghcr.io/dbgate/mysql-ssh-login:latest
|
||||
ports:
|
||||
- '16012:22'
|
||||
mysql-ssh-keyfile:
|
||||
image: 'ghcr.io/dbgate/mysql-ssh-keyfile:latest'
|
||||
image: ghcr.io/dbgate/mysql-ssh-keyfile:latest
|
||||
ports:
|
||||
- '16008:22'
|
||||
dex:
|
||||
image: 'ghcr.io/dbgate/dex:latest'
|
||||
image: ghcr.io/dbgate/dex:latest
|
||||
ports:
|
||||
- '16009:5556'
|
||||
mongo:
|
||||
image: 'mongo:4.0.12'
|
||||
image: mongo:4.4.29
|
||||
env:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: Pwd2020Db
|
||||
@@ -106,3 +117,17 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- '16011:6379'
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
ports:
|
||||
- '16014:1433'
|
||||
env:
|
||||
ACCEPT_EULA: 'Y'
|
||||
SA_PASSWORD: Pwd2020Db
|
||||
MSSQL_PID: Express
|
||||
oracle:
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
env:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '16013:1521'
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Update Workflows
|
||||
'on':
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- workflow-templates/**
|
||||
jobs:
|
||||
update-workflows:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.WORKFLOW_CHANGE_ACCESS_TOKEN }}
|
||||
- name: git pull
|
||||
run: |
|
||||
git pull
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
rm package.json
|
||||
rm yarn.lock
|
||||
yarn add -W js-yaml lodash
|
||||
- name: Run workflow generation
|
||||
run: |
|
||||
node common/processWorkflows.js
|
||||
- name: Git config
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.io"
|
||||
git config --global user.name "CI workflows"
|
||||
- name: Commit changes
|
||||
run: |
|
||||
# Only commit if there are changes
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
git add .github/workflows
|
||||
git commit -m "chore: auto-update github workflows"
|
||||
else
|
||||
echo "No changes to commit"
|
||||
fi
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@v0.6.0
|
||||
with:
|
||||
github_token: ${{ secrets.WORKFLOW_CHANGE_ACCESS_TOKEN }}
|
||||
branch: master
|
||||
@@ -13,10 +13,10 @@ jobs:
|
||||
all-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@@ -37,22 +37,27 @@ jobs:
|
||||
run: |
|
||||
cd packages/datalib
|
||||
yarn test:ci
|
||||
- name: Tools tests
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/tools
|
||||
yarn test:ci
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: integration-tests/result.json
|
||||
action-name: Integration tests
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/filterparser/result.json
|
||||
action-name: Filter parser test results
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/datalib/result.json
|
||||
action-name: Datalib (perspectives) test results
|
||||
services:
|
||||
@@ -64,7 +69,7 @@ jobs:
|
||||
ports:
|
||||
- '15000:5432'
|
||||
mysql-integr:
|
||||
image: 'mysql:8.0.18'
|
||||
image: mysql:8.0.18
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
@@ -78,18 +83,33 @@ jobs:
|
||||
ports:
|
||||
- '15002:1433'
|
||||
clickhouse-integr:
|
||||
image: 'bitnami/clickhouse:24.8.4'
|
||||
image: bitnamilegacy/clickhouse:24.8.4
|
||||
env:
|
||||
CLICKHOUSE_ADMIN_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '15005:8123'
|
||||
oracle-integr:
|
||||
image: 'gvenzl/oracle-xe:21-slim'
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
env:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '15006:1521'
|
||||
cassandradb:
|
||||
image: 'cassandra:5.0.2'
|
||||
image: cassandra:5.0.2
|
||||
ports:
|
||||
- '15942:9042'
|
||||
libsql:
|
||||
image: ghcr.io/tursodatabase/libsql-server:latest
|
||||
ports:
|
||||
- '8080:8080'
|
||||
firebird:
|
||||
image: firebirdsql/firebird:latest
|
||||
env:
|
||||
FIREBIRD_DATABASE: mydatabase.fdb
|
||||
FIREBIRD_USER: dbuser
|
||||
FIREBIRD_PASSWORD: dbpassword
|
||||
ISC_PASSWORD: masterkey
|
||||
FIREBIRD_TRACE: false
|
||||
FIREBIRD_USE_LEGACY_AUTH: true
|
||||
ports:
|
||||
- '3050:3050'
|
||||
|
||||
+3
-1
@@ -32,4 +32,6 @@ packages/api/src/packagedPluginsContent.js
|
||||
.VSCodeCounter
|
||||
|
||||
packages/web/public/*.html
|
||||
e2e-tests/screenshots/*.png
|
||||
e2e-tests/screenshots/*.png
|
||||
my_guitar_shop.db
|
||||
.aider*
|
||||
|
||||
Vendored
+40
-19
@@ -1,20 +1,41 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch API",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug App",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"envFile": "${workspaceFolder}/packages/api/.env",
|
||||
"args": ["--listen-api"],
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "node",
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
},
|
||||
{
|
||||
"name": "Debug App (Break on Start)",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"args": ["--listen-api"],
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "node",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"stopOnEntry": true
|
||||
},
|
||||
{
|
||||
"name": "Attach to Process",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"restart": true,
|
||||
"localRoot": "${workspaceFolder}",
|
||||
"remoteRoot": "${workspaceFolder}",
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
+193
-1
@@ -8,6 +8,198 @@ Builds:
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
## 6.6.5
|
||||
- ADDED: SQL AI assistant - powered by database chat, could help you to write SQL queries (Premium)
|
||||
- ADDED: Explain SQL error (powered by AI) (Premium)
|
||||
- ADDED: Database chat (and SQL AI Assistant) now supports showing charts (Premium)
|
||||
- FIXED: Fxied editing new files and roles (Team Premium)
|
||||
- FIXED: Connection to standalone database could be now pinned
|
||||
|
||||
## 6.6.4
|
||||
- ADDED: AI Database chat now supports much more LLM models. (Premium)
|
||||
- ADDED: Possibility to use your own API key with OPENAI-compatible providers (OpenRouter, Antropic...)
|
||||
- ADDED: Possibility to use self-hosted own LLM (eg. Llama)
|
||||
- ADDED: Team files - save SQL files and define shared charts, assign roles and users to these objects (Team Premium)
|
||||
- FIXED: BUG: does no longer work with Cockroach DB #1202
|
||||
- FIXED: DbGate Web UI Connections do not display 'Databases' #1199
|
||||
- CHANGED: Redesign fof applications. Applications are now storted in single JSON file
|
||||
- ADDED: Application editor (Premium)
|
||||
- ADDED: Posibility to filter only tables with rows
|
||||
- FIXED: Fixed several issues with large Firebird databases
|
||||
- CHANGED: Community edition now supports shared folders in read-only mode
|
||||
|
||||
## 6.6.3
|
||||
- FIXED: Error “db.getCollection(…).renameCollection is not a function” when renaming collection in dbGate #1198
|
||||
- FIXED: Can't list databases from Azure SQL SERVER #1197
|
||||
- ADDED: Save zoom level in electron apps
|
||||
|
||||
## 6.6.2
|
||||
- ADDED: List of processes, ability to kill process (Server summary) #1178
|
||||
- ADDED: Database and table permissions (Team Premium edition)
|
||||
- ADDED: Redis search box - Scan all #1191
|
||||
- FIXED: Optimalized loading SQL server with descriptions #1187
|
||||
- CHANGED: Allow a much greater page size #1185
|
||||
- FIXED: Optimalized loading SQL server with descriptions #1187
|
||||
- FIXED: Executing queries for SQLite crash #1195
|
||||
|
||||
## 6.6.1
|
||||
- ADDED: Support for Mongo shell (Premium) - #1114
|
||||
- FIXED: Support for BLOB in Oracle #1181
|
||||
- ADDED: Connect to named SQL Server instance #340
|
||||
- ADDED: Support for SQL Server descriptions #1137
|
||||
- ADDED: Application log viewer
|
||||
- FIXED: Selecting default database in connection dialog
|
||||
- CHANGED: Improved logging system, added related database and connection to logs metadata
|
||||
|
||||
## 6.6.0
|
||||
- ADDED: Database chat - AI powered chatbot, which knows your database (Premium)
|
||||
- ADDED: Firestore support (Premium)
|
||||
- REMOVED: Query AI assistant (replaced by Database Chat) (Premium)
|
||||
- FIXED: Chart permissions were ignored (Premium)
|
||||
|
||||
## 6.5.6
|
||||
- ADDED: New object window - quick access to most common functions
|
||||
- ADDED: Possibility to disable split query by empty line #1162
|
||||
- ADDED: Possibility to opt out authentication #1152
|
||||
- FIXED: Separate schema mode now works in Team Premium edition
|
||||
- FIXED: Handled situation, when user enters expired license, which is already prolonged
|
||||
- FIXED: Fixed some minor problems of charts
|
||||
|
||||
## 6.5.5
|
||||
- ADDED: Administer cloud folder window
|
||||
- CHANGED: Cloud menu redesign
|
||||
- ADDED: Audit log (for Team Premium edition)
|
||||
- ADDED: Added new timeline chart type (line chart with time axis)
|
||||
- ADDED: Chart grouping (more measure determined from data)
|
||||
- CHANGED: Improved chart autodetection - string X axis (with bar type), COUNT as measure, split different measures
|
||||
- ADDED: Added chart data type detection
|
||||
- FIXED: Fixed chart displaying problems
|
||||
- FIXED: Fixed exporting chart to HTML
|
||||
- CHANGED: Choose COUNT measure without selecting underlying ID field (use virtual __count)
|
||||
- FIXED: Problems with authentification administration, especially for Postgres storage
|
||||
- CHANGED: Anonymous autentification (in Team Premium) is now by default disabled
|
||||
|
||||
## 6.5.3
|
||||
- CHANGED: Improved DbGate Cloud sign-in workflow
|
||||
- FIXED: Some fixes and error handling in new charts engine
|
||||
- ADDED: Charts - ability to choose aggregate function
|
||||
- CHANGED: Improved About window
|
||||
|
||||
## 6.5.2
|
||||
- CHANGED: Autodetecting charts is disabled by default #1145
|
||||
- CHANGED: Improved chart displaying workflow
|
||||
- ADDED: Ability to close chart
|
||||
|
||||
## 6.5.1
|
||||
- FIXED: DbGate Cloud e-mail sign-in method for desktop clients
|
||||
|
||||
## 6.5.0
|
||||
- ADDED: DbGate cloud - online storage for connections, SQL scripts and other objects
|
||||
- ADDED: Public knowledge base - common SQL scripts for specific DB engines (table sizes, index stats etc.)
|
||||
- ADDED: Query results could be visualised in charts (Premium)
|
||||
- REMOVED: Chart from selection, active charts - replaced by query result charts
|
||||
- ADDED: FirebirdSQL support
|
||||
- ADDED: SQL front matter - properties of SQL script
|
||||
- ADDED: Auto-execute SQL script on open (saved in SQL front matter)
|
||||
- CHANGED: Smaller widget icon panel
|
||||
- CHANGED: Applications and Single-connection mode removed from widget icon panel
|
||||
- CHANGED: Temporarily disabled MongoDB profiler support
|
||||
- FIXED: Pie chart distorted if settings change #838
|
||||
- FIXED: SQL server generated insert statement should exclude computed and timestamp columns #1111
|
||||
- ADDED: Added option "Show all columns when searching" #1118
|
||||
- ADDED: Copy cells/rows (e.g. column names) from Structure view #1119
|
||||
- ADDED: Setting "Show table aliases in code completion" #1122
|
||||
- FIXED: Vulnerability - check file paths in web version
|
||||
- FIXED: Very slow render of tables with very log cells
|
||||
|
||||
## 6.4.2
|
||||
|
||||
- ADDED: Source label to docker container #1105
|
||||
- FIXED: DbGate restart needed to take effect after trigger is created/deleted on mariadb #1112
|
||||
- ADDED: View PostgreSQL query console output #1108
|
||||
- FIXED: Single quote generete MySql error #1107
|
||||
- ADDED: Ability to limit query result count #1098
|
||||
- CHANGED: Correct processing of bigint columns #1087 #1055 #583
|
||||
- CHANGED: Improved and optimalized algorithm of loading redis keys #1062, #1034
|
||||
- FIXED: Fixed loading Redis keys with :: in key name
|
||||
|
||||
## 6.4.0
|
||||
- ADDED: DuckDB support
|
||||
- ADDED: Data deployer (Premium)
|
||||
- ADDED: Compare data between JSON lines file in archive and database table
|
||||
- CHANGED: Data Duplicator => Data Replicator (suitable for update, create and delete data, much more customizable)
|
||||
- REMOVED: Data duplicator GUI (replaced with Data Deployer)
|
||||
- ADDED: Exporting to ZIP file
|
||||
- ADDED: Download SQL and SQLite files
|
||||
- ADDED: Upload SQLite files
|
||||
- ADDED: Upload archive as ZIP folder (Premium)
|
||||
- ADDED: Compress, uncompress archive folder (Premium)
|
||||
- ADDED: Export connections and settings #357
|
||||
- ADDED: Filtering by MongoDB ObjectId works now also without ObjectId(...) wrapper
|
||||
- ADDED: Split queries using blank lines #1089
|
||||
- FIXED: JSON-to-Grid only works if there is no newline #1085
|
||||
- CHANGED: When running multiple commands in script, stop execution after first error #1070
|
||||
- FIXED: Selection rectangle remains visible after closing JSONB edit cell value form #1031
|
||||
- FIXED: Diplaying numeric FK column with right alignement #1021
|
||||
- ADDED: Additional arguments for MySQL and PostgreSQL backup #1092
|
||||
- CHANGED: Amazon and Azure instalations are not auto-upgraded by default
|
||||
|
||||
## 6.3.3
|
||||
- CHANGED: New administration UI, redesigned administration of users, connections and roles
|
||||
- ADDED: Encrypting passwords in team-premium edition
|
||||
- ADDED: Show scale bar on map #1090
|
||||
- FIXED: Fixed native backup/restore for MySQL+PostgreSQL over SSH tunnel #1092
|
||||
- CHANGED: Column mapping dialog - fixes and improvements for copying from one existing table into another
|
||||
- ADDED: Search in columns in table editor
|
||||
- ADDED: Line Wrap for JSON viewer #768
|
||||
|
||||
### 6.3.2
|
||||
- ADDED: "Use system theme" switch, use changed system theme without restart #1084
|
||||
- ADDED: "Skip SETNAME instruction" option for Redis #1077
|
||||
- FIXED: Clickhouse views are now available even for user with limited permissions #1076
|
||||
- ADDED: Multiple-token search delimited with comma (=OR) in structure search boxes
|
||||
- CHANGED: When filtering columns in data browser, data view shows only filtered columns
|
||||
- ADDED: Advanced settings for diagrams (Premium)
|
||||
- ADDED: Diagrams - zoom with Ctrl+mouse wheel
|
||||
- FIXED: Scrollable diagram exports + scroll by mouse drag
|
||||
- FIXED: Fixed many problems in diagrams when zoom is applied
|
||||
- FIXED: Correctly end connection process after succesful/unsuccesful connect
|
||||
|
||||
### 6.3.0
|
||||
- ADDED: Support for libSQL and Turso (Premium)
|
||||
- ADDED: Native backup and restore database for MySQL and PostgreSQL (Premium)
|
||||
- REMOVED: DbGate internal dump export for MySQL (replaced with call of mysqldump)
|
||||
- REMOVED: Import SQL dump with internal DbGate capabilities (replaced by calling of mysql and psql utilities)
|
||||
- FIXED: Many fixes in stream processing (imoprt/export), especialy for MongoDB
|
||||
- ADDED: Indicating progress of import/export tasks, better error reporting
|
||||
- CHANGED: #1060 - Changed shortcut for AI assistant
|
||||
- ADDED: /health endpoint with diagnostic info
|
||||
- FIXED: Linux Appimage crash => A JavaScript error occurred in the main process #1065 , #1067
|
||||
|
||||
### 6.2.1
|
||||
- ADDED: Commit/rollback and autocommit in scripts #1039
|
||||
- FIXED: Doesn't import all the records from MongoDB #1044
|
||||
- ADDED: Show server name alongside database name in title of the tab group #1041
|
||||
- ADDED: Can't open Sqlite through web #956
|
||||
- FIXED: Crashed after text input at columns search #1049
|
||||
- FIXED: Incorrect autojoin for foreign keys with more columns #1051
|
||||
- FIXED: Scroll in XML cell view, XML view respect themes
|
||||
- REMOVED: armv7l build for Linux (because of problems with glibc compatibility)
|
||||
- CHANGED: Upgraded to node:22 for docker builds
|
||||
- CHANGED: Upgraded SQLite engine version
|
||||
|
||||
### 6.2.0
|
||||
- ADDED: Query AI Assistant (Premium)
|
||||
- ADDED: Cassandra database support
|
||||
- ADDED: XML cell data view
|
||||
- FIXED: Filtering by value in Oracle #1009
|
||||
- FIXED: Operand type clash: uniqueidentifier is incompatible with int #565
|
||||
- FIXED: UX in administration
|
||||
- FIXED: Error reporting of broken connections (sometimes it caused infinite loading of data grid)
|
||||
- ADDED: Azure managed identity support (Team Premium)
|
||||
- ADDED: Expanded JSON cell view
|
||||
- CHANGED: Open real executed query, when datagrid shows loading error
|
||||
|
||||
### 6.1.6
|
||||
- FIXED: Hotfix build process for premium edition
|
||||
|
||||
@@ -306,7 +498,7 @@ Builds:
|
||||
- FIXED: Creating SQLite autoincrement column
|
||||
- FIXED: Better error reporting from exports/import/dulicator
|
||||
- CHANGED: Optimalizede OracleDB analysing algorithm
|
||||
- ADDED: Mutli column filter for perspectives
|
||||
- ADDED: Multi column filter for perspectives
|
||||
- FIXED: Fixed some scenarios using tables from different DBs
|
||||
- FIXED: Sessions with long-running queries are not killed
|
||||
|
||||
|
||||
@@ -15,10 +15,13 @@ But there are also many advanced features like schema compare, visual query desi
|
||||
DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
|
||||
* Try it online - [demo.dbgate.org](https://demo.dbgate.org) - online demo application
|
||||
* **Download** application for Windows, Linux or Mac from [dbgate.org](https://dbgate.org/download/)
|
||||
* **Download** application for Windows, Linux or Mac from [dbgate.io](https://www.dbgate.io/download/)
|
||||
* Looking for DbGate Community? **Download** from [dbgate.org](https://dbgate.org/download/)
|
||||
* Run web version as [NPM package](https://www.npmjs.com/package/dbgate-serve) or as [docker image](https://hub.docker.com/r/dbgate/dbgate)
|
||||
* Use nodeJs [scripting interface](https://dbgate.org/docs/scripting) ([API documentation](https://dbgate.org/docs/apidoc))
|
||||
* Use nodeJs [scripting interface](https://docs.dbgate.io/scripting) ([API documentation](https://docs.dbgate.io/apidoc))
|
||||
* [Recommend DbGate](https://testimonial.to/dbgate) | [Rate on G2](https://www.g2.com/products/dbgate/reviews)
|
||||
* [Give us feedback](https://dbgate.org/feedback) - it will help us to decide, how to improve DbGate in future
|
||||
* We [offer 2-year PREMIUM license](https://dbgate.org/review/) for any honest review on these platforms (time-limited offer)
|
||||
|
||||
## Supported databases
|
||||
* MySQL
|
||||
@@ -33,8 +36,11 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
* MariaDB
|
||||
* CosmosDB (Premium)
|
||||
* ClickHouse
|
||||
|
||||
<!-- Learn more about DbGate features at the [DbGate website](https://dbgate.org/), or try our online [demo application](https://demo.dbgate.org) -->
|
||||
* Apache Cassandra
|
||||
* libSQL/Turso (Premium)
|
||||
* DuckDB
|
||||
* Firebird
|
||||
* Firestore (Premium)
|
||||
|
||||
|
||||
<a href="https://raw.githubusercontent.com/dbgate/dbgate/master/img/screenshot1.png">
|
||||
@@ -77,6 +83,7 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
* Archives - backup your data in NDJSON files on local filesystem (or on DbGate server, when using web application)
|
||||
* NDJSON data viewer and editor - browse NDJSON data, edit data and structure directly on NDJSON files. Works also for big NDSON files
|
||||
* Charts, export chart to HTML page
|
||||
* AI powered database chat
|
||||
* Show GEO data on map, export map to HTML page
|
||||
* For detailed info, how to run DbGate in docker container, visit [docker hub](https://hub.docker.com/r/dbgate/dbgate)
|
||||
* Extensible plugin architecture
|
||||
@@ -85,11 +92,13 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
Any contributions are welcome. If you want to contribute without coding, consider following:
|
||||
|
||||
* Tell your friends about DbGate or share on social networks - when more people will use DbGate, it will grow to be better
|
||||
* Write review on [Slant.co](https://www.slant.co/improve/options/41086/~dbgate-review) or [G2](https://www.g2.com/products/dbgate/reviews)
|
||||
* Purchase a [DbGate Premium](https://www.dbgate.io/purchase/premium/) license
|
||||
* Write review on [Product Hunt](https://www.producthunt.com/products/dbgate) or [G2](https://www.g2.com/products/dbgate/reviews) - we offer [2-year PREMIUM license](https://dbgate.org/review/) for reviewers (time limited offer)
|
||||
* Create issue, if you find problem in app, or you have idea to new feature. If issue already exists, you could leave comment on it, to prioritise most wanted issues
|
||||
* Create some tutorial video on [youtube](https://www.youtube.com/playlist?list=PLCo7KjCVXhr0RfUSjM9wJMsp_ShL1q61A)
|
||||
* Become a backer on [GitHub sponsors](https://github.com/sponsors/dbgate) or [Open collective](https://opencollective.com/dbgate)
|
||||
* Where a small coding is acceptable for you, you could [create plugin](https://dbgate.org/docs/plugin-development). Plugins for new themes can be created actually without JS coding
|
||||
* Add a SQL script to [Public Knowledge Base](https://github.com/dbgate/dbgate-knowledge-base)
|
||||
* Where a small coding is acceptable for you, you could [create plugin](https://docs.dbgate.io/plugin-development). Plugins for new themes can be created actually without JS coding
|
||||
|
||||
Thank you!
|
||||
|
||||
@@ -184,4 +193,4 @@ yarn plugin # this compiles plugin and copies it into existing DbGate installati
|
||||
After restarting DbGate, you could use your new plugin from DbGate.
|
||||
|
||||
## Logging
|
||||
DbGate uses [pinomin logger](https://github.com/dbgate/pinomin). So by default, it produces JSON log messages into console and log files. If you want to see formatted logs, please use [pino-pretty](https://github.com/pinojs/pino-pretty) log formatter.
|
||||
DbGate uses [pinomin logger](https://github.com/dbgate/pinomin). So by default, it produces JSON log messages into console and log files. If you want to see formatted logs, please use [pino-pretty](https://github.com/pinojs/pino-pretty) log formatter.
|
||||
|
||||
@@ -43,6 +43,8 @@ function adjustFile(file, isApp = false) {
|
||||
|
||||
if (process.argv.includes('--community')) {
|
||||
delete json.optionalDependencies['mongodb-client-encryption'];
|
||||
delete json.dependencies['@mongosh/service-provider-node-driver'];
|
||||
delete json.dependencies['@mongosh/browser-runtime-electron'];
|
||||
}
|
||||
|
||||
if (isApp && process.argv.includes('--premium')) {
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"armv7l",
|
||||
"arm64"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -212,6 +212,10 @@ ipcMain.on('app-started', async (event, arg) => {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
if (initialConfig['winZoomLevel'] != null) {
|
||||
mainWindow.webContents.zoomLevel = initialConfig['winZoomLevel'];
|
||||
}
|
||||
});
|
||||
ipcMain.on('window-action', async (event, arg) => {
|
||||
if (!mainWindow) {
|
||||
@@ -357,6 +361,7 @@ function createWindow() {
|
||||
title: isProApp() ? 'DbGate Premium' : 'DbGate',
|
||||
frame: useNativeMenu,
|
||||
titleBarStyle: useNativeMenu ? undefined : 'hidden',
|
||||
backgroundColor: electron.nativeTheme.shouldUseDarkColors ? '#111111' : undefined,
|
||||
...bounds,
|
||||
icon: os.platform() == 'win32' ? 'icon.ico' : path.resolve(__dirname, '../icon.png'),
|
||||
partition: isProApp() ? 'persist:dbgate-premium' : 'persist:dbgate',
|
||||
@@ -393,6 +398,7 @@ function createWindow() {
|
||||
JSON.stringify({
|
||||
winBounds: mainWindow.getBounds(),
|
||||
winIsMaximized: mainWindow.isMaximized(),
|
||||
winZoomLevel: mainWindow.webContents.zoomLevel,
|
||||
}),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
@@ -4,11 +4,13 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
submenu: [
|
||||
{ command: 'new.connection', hideDisabled: true },
|
||||
{ command: 'new.sqliteDatabase', hideDisabled: true },
|
||||
{ command: 'new.duckdbDatabase', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'new.query', hideDisabled: true },
|
||||
{ command: 'new.queryDesign', hideDisabled: true },
|
||||
{ command: 'new.diagram', hideDisabled: true },
|
||||
{ command: 'new.perspective', hideDisabled: true },
|
||||
{ command: 'new.application', hideDisabled: true },
|
||||
{ command: 'new.shell', hideDisabled: true },
|
||||
{ command: 'new.jsonl', hideDisabled: true },
|
||||
{ command: 'new.modelTransform', hideDisabled: true },
|
||||
@@ -85,8 +87,10 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
{ divider: true },
|
||||
{ command: 'folder.showLogs', hideDisabled: true },
|
||||
{ command: 'folder.showData', hideDisabled: true },
|
||||
{ command: 'new.gist', hideDisabled: true },
|
||||
{ command: 'app.resetSettings', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'app.exportConnections', hideDisabled: true },
|
||||
{ command: 'app.importConnections', hideDisabled: true },
|
||||
],
|
||||
},
|
||||
...(isMac
|
||||
@@ -104,6 +108,7 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
{ command: 'app.openWeb', hideDisabled: true },
|
||||
{ command: 'app.openIssue', hideDisabled: true },
|
||||
{ command: 'app.openSponsoring', hideDisabled: true },
|
||||
// { command: 'app.giveFeedback', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'settings.commands', hideDisabled: true },
|
||||
{ command: 'tabs.changelog', hideDisabled: true },
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
// this file is generated automatically by script fillNativeModules.js, do not edit it manually
|
||||
const content = {};
|
||||
|
||||
content['better-sqlite3'] = () => require('better-sqlite3');
|
||||
content['oracledb'] = () => require('oracledb');
|
||||
|
||||
|
||||
module.exports = content;
|
||||
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env node
|
||||
// assign-dbgm-codes.mjs
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
const PLACEHOLDER = 'DBGM-00000';
|
||||
const CODE_RE = /DBGM-(\d{5})/g;
|
||||
const JS_TS_RE = /\.(mjs|cjs|js|ts|jsx|tsx)$/i;
|
||||
|
||||
const IGNORE_DIRS = new Set([
|
||||
'node_modules',
|
||||
'.git',
|
||||
'.hg',
|
||||
'.svn',
|
||||
'dist',
|
||||
'build',
|
||||
'out',
|
||||
'.next',
|
||||
'.turbo',
|
||||
'.cache',
|
||||
]);
|
||||
const IGNORE_FILES = ['assign-dbgm-codes.mjs', 'package.json', 'README.md'];
|
||||
|
||||
// --- CLI ---
|
||||
const args = process.argv.slice(2);
|
||||
const dryRun = args.includes('--dry');
|
||||
const rootArg = args.find(a => a !== '--dry') || process.cwd();
|
||||
const root = path.resolve(rootArg);
|
||||
|
||||
// --- helpers ---
|
||||
async function* walk(dir) {
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory()) {
|
||||
if (IGNORE_DIRS.has(e.name)) continue;
|
||||
yield* walk(path.join(dir, e.name));
|
||||
} else if (e.isFile()) {
|
||||
if (JS_TS_RE.test(e.name) && !IGNORE_FILES.includes(e.name)) yield path.join(dir, e.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formatCode(n) {
|
||||
return `DBGM-${String(n).padStart(5, '0')}`;
|
||||
}
|
||||
|
||||
// Find the smallest positive integer not in `taken`
|
||||
function makeNextCodeFn(taken) {
|
||||
let n = 1;
|
||||
// advance n to first free
|
||||
while (taken.has(n)) n++;
|
||||
return () => {
|
||||
const code = n;
|
||||
taken.add(code);
|
||||
// move n to next free for next call
|
||||
do {
|
||||
n++;
|
||||
} while (taken.has(n));
|
||||
return formatCode(code);
|
||||
};
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
(async () => {
|
||||
console.log(`Scanning: ${root} ${dryRun ? '(dry run)' : ''}`);
|
||||
|
||||
// 1) Collect all taken codes across the repo
|
||||
const taken = new Set(); // numeric parts only
|
||||
const files = [];
|
||||
for await (const file of walk(root)) files.push(file);
|
||||
|
||||
await Promise.all(
|
||||
files.map(async file => {
|
||||
try {
|
||||
const text = await fs.readFile(file, 'utf8');
|
||||
for (const m of text.matchAll(CODE_RE)) {
|
||||
const num = Number(m[1]);
|
||||
if (Number.isInteger(num) && num > 0) taken.add(num);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to read ${file}: ${err.message}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
console.log(`Found ${taken.size} occupied code(s).`);
|
||||
|
||||
// 2) Replace placeholders with next available unique code
|
||||
const nextCode = makeNextCodeFn(taken);
|
||||
|
||||
let filesChanged = 0;
|
||||
let placeholdersReplaced = 0;
|
||||
|
||||
for (const file of files) {
|
||||
let text;
|
||||
try {
|
||||
text = await fs.readFile(file, 'utf8');
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to read ${file}: ${err.message}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!text.includes(PLACEHOLDER)) continue;
|
||||
|
||||
let countInFile = 0;
|
||||
const updated = text.replaceAll(PLACEHOLDER, () => {
|
||||
countInFile++;
|
||||
return nextCode();
|
||||
});
|
||||
|
||||
if (countInFile > 0) {
|
||||
placeholdersReplaced += countInFile;
|
||||
filesChanged++;
|
||||
console.log(`${dryRun ? '[dry]' : '[write]'} ${file} — ${countInFile} replacement(s)`);
|
||||
if (!dryRun) {
|
||||
try {
|
||||
await fs.writeFile(file, updated, 'utf8');
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to write ${file}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Done. Files changed: ${filesChanged}, placeholders replaced: ${placeholdersReplaced}.`);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
//@ts-check
|
||||
const { getDefaultTranslations, getLanguageTranslations } = require('./helpers');
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*/
|
||||
function getMissingTranslations(language) {
|
||||
const source = getDefaultTranslations();
|
||||
/** @type {Record<string, string>} */
|
||||
let target;
|
||||
|
||||
try {
|
||||
target = getLanguageTranslations(language);
|
||||
} catch {
|
||||
console.log(`Language ${language} not found, creating a new one`);
|
||||
target = {};
|
||||
}
|
||||
|
||||
let added = 0;
|
||||
let removed = 0;
|
||||
|
||||
for (const key in source) {
|
||||
if (!target[key]) {
|
||||
target[key] = `*** ${source[key]}`;
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in target) {
|
||||
if (!source[key]) {
|
||||
delete target[key];
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
const newLength = Object.keys(target).length;
|
||||
|
||||
return { result: target, stats: { added, removed, newLength } };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getMissingTranslations,
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
// @ts-check
|
||||
//
|
||||
const defaultLanguage = 'en';
|
||||
|
||||
/** @typedef {{ extensions: string[], directories: string[] }} ExtractConfig
|
||||
|
||||
/** @type {ExtractConfig} */
|
||||
const defaultExtractConfig = {
|
||||
extensions: ['.js', '.ts', '.svelte'],
|
||||
directories: ['app', 'packages/web'],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
defaultLanguage,
|
||||
defaultExtractConfig,
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
//@ts-check
|
||||
const fs = require('fs');
|
||||
const { promisify } = require('util');
|
||||
|
||||
const { getFiles } = require('./helpers');
|
||||
|
||||
const readFilePromise = promisify(fs.readFile);
|
||||
|
||||
const translationRegex = /_t\(\s*['"]([^'"]+)['"]\s*,\s*\{\s*defaultMessage\s*:\s*['"]([^'"]+)['"]\s*\}/g;
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
*
|
||||
* @returns {Promise<Record<string, string>>}
|
||||
*/
|
||||
async function extractTranslationsFromFile(file) {
|
||||
/** @type {Record<string, string>} */
|
||||
const translations = {};
|
||||
const content = await readFilePromise(file, 'utf-8');
|
||||
let match;
|
||||
|
||||
while ((match = translationRegex.exec(content)) !== null) {
|
||||
const [_, key, defaultText] = match;
|
||||
translations[key] = defaultText;
|
||||
}
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
/** @typedef {{ ignoreDuplicates?: boolean }} ExtractOptions */
|
||||
|
||||
/**
|
||||
* @param {string[]} directories
|
||||
* @param {string[]} extensions
|
||||
* @param {ExtractOptions} options
|
||||
*
|
||||
* @returns {Promise<Record<string, string>>}
|
||||
*/
|
||||
async function extractAllTranslations(directories, extensions, options = {}) {
|
||||
const { ignoreDuplicates } = options;
|
||||
|
||||
try {
|
||||
/** @type {Record<string, string>} */
|
||||
const allTranslations = {};
|
||||
/** @type {Record<string, string[]>} */
|
||||
const translationKeyToFiles = {};
|
||||
|
||||
for (const dir of directories) {
|
||||
const files = await getFiles(dir, extensions);
|
||||
|
||||
for (const file of files) {
|
||||
const fileTranslations = await extractTranslationsFromFile(file);
|
||||
|
||||
for (const key in fileTranslations) {
|
||||
if (!translationKeyToFiles[key]) {
|
||||
translationKeyToFiles[key] = [];
|
||||
}
|
||||
|
||||
translationKeyToFiles[key].push(file);
|
||||
|
||||
if (!ignoreDuplicates && allTranslations[key] && allTranslations[key] !== fileTranslations[key]) {
|
||||
console.error(
|
||||
`Different translations for the same key [${key}] found. ${file}: ${
|
||||
fileTranslations[key]
|
||||
}. Previous value: ${allTranslations[key]} was found in ${translationKeyToFiles[key].join(', ')}`
|
||||
);
|
||||
throw new Error(`Duplicate translation key found: ${key}`);
|
||||
}
|
||||
|
||||
allTranslations[key] = fileTranslations[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allTranslations;
|
||||
} catch (error) {
|
||||
console.error('Error extracting translations:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
extractTranslationsFromFile,
|
||||
extractAllTranslations,
|
||||
};
|
||||
@@ -0,0 +1,198 @@
|
||||
//@ts-check
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { defaultLanguage } = require('./constants');
|
||||
const sortJsonKeysAlphabetically = require('./sortJsonKeysAlphabetically');
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasValidExtension(file, extensions) {
|
||||
return extensions.includes(path.extname(file).toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dir
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function getFiles(dir, extensions) {
|
||||
const files = await fs.promises.readdir(dir);
|
||||
const allFiles = await Promise.all(
|
||||
files.map(async file => {
|
||||
const filePath = path.join(dir, file);
|
||||
const stats = await fs.promises.stat(filePath);
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return getFiles(filePath, extensions);
|
||||
} else if (stats.isFile() && hasValidExtension(file, extensions)) {
|
||||
const slashPath = filePath.replace(/\\/g, '/');
|
||||
if (slashPath.includes('/node_modules/') || slashPath.includes('/build/') || slashPath.includes('/dist/')) {
|
||||
return null;
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
);
|
||||
|
||||
const validFiles = /** @type {string[]} */ (allFiles.flat().filter(file => file !== null));
|
||||
|
||||
return validFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | string[]} value
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDefaultValue(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(', ');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const scriptDir = getScriptDir();
|
||||
/** @param {string} file
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolveFile(file) {
|
||||
if (path.isAbsolute(file)) {
|
||||
return file;
|
||||
}
|
||||
|
||||
return path.resolve(scriptDir, '..', '..', file);
|
||||
}
|
||||
|
||||
/** @param {string[]} dirs
|
||||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function resolveDirs(dirs) {
|
||||
return dirs.map(resolveFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function resolveExtensions(extensions) {
|
||||
return extensions.map(ext => (ext.startsWith('.') ? ext : `.${ext}`));
|
||||
}
|
||||
|
||||
function getScriptDir() {
|
||||
if (require.main?.filename) {
|
||||
return path.dirname(require.main.filename);
|
||||
}
|
||||
|
||||
if ('pkg' in process && process.pkg) {
|
||||
return path.dirname(process.execPath);
|
||||
}
|
||||
|
||||
return __dirname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
*/
|
||||
function ensureFileDirExists(file) {
|
||||
const dir = path.dirname(file);
|
||||
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, string>} existingTranslations - Previously extracted translations
|
||||
* @param {Record<string, string>} newTranslations - Newly extracted translations
|
||||
* @returns {{ added: string[], removed: string[], updated: string[] }} Translation changes
|
||||
*/
|
||||
const getTranslationChanges = (existingTranslations, newTranslations) => {
|
||||
const existingKeys = new Set(Object.keys(existingTranslations || {}));
|
||||
const newKeys = new Set(Object.keys(newTranslations));
|
||||
|
||||
const added = [...newKeys].filter(key => !existingKeys.has(key));
|
||||
const removed = [...existingKeys].filter(key => !newKeys.has(key));
|
||||
const updated = [...newKeys].filter(
|
||||
key => existingKeys.has(key) && existingTranslations[key] !== newTranslations[key]
|
||||
);
|
||||
|
||||
return { added, removed, updated };
|
||||
};
|
||||
|
||||
function getDefaultTranslations() {
|
||||
return getLanguageTranslations(defaultLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*
|
||||
* @returns {Record<string, string>}
|
||||
*/
|
||||
function getLanguageTranslations(language) {
|
||||
const file = resolveFile(`translations/${language}.json`);
|
||||
const content = fs.readFileSync(file, 'utf-8');
|
||||
|
||||
return JSON.parse(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} translations
|
||||
*/
|
||||
function setLanguageTranslations(language, translations) {
|
||||
const file = resolveFile(`translations/${language}.json`);
|
||||
const sorted = sortJsonKeysAlphabetically(translations);
|
||||
|
||||
fs.writeFileSync(file, JSON.stringify(sorted, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} newTranslations
|
||||
*/
|
||||
function updateLanguageTranslations(language, newTranslations) {
|
||||
const translations = getLanguageTranslations(language);
|
||||
const updatedTranslations = { ...translations, ...newTranslations };
|
||||
const sorted = sortJsonKeysAlphabetically(updatedTranslations);
|
||||
|
||||
setLanguageTranslations(language, sorted);
|
||||
}
|
||||
|
||||
function getAllLanguages() {
|
||||
const dir = resolveFile('translations');
|
||||
|
||||
const files = fs.readdirSync(dir);
|
||||
const languages = files.filter(file => file.endsWith('.json')).map(file => file.replace('.json', ''));
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
function getAllNonDefaultLanguages() {
|
||||
return getAllLanguages().filter(language => language !== defaultLanguage);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hasValidExtension,
|
||||
getFiles,
|
||||
formatDefaultValue,
|
||||
resolveFile,
|
||||
resolveDirs,
|
||||
resolveExtensions,
|
||||
ensureFileDirExists,
|
||||
getTranslationChanges,
|
||||
getDefaultTranslations,
|
||||
getLanguageTranslations,
|
||||
setLanguageTranslations,
|
||||
updateLanguageTranslations,
|
||||
getAllLanguages,
|
||||
getAllNonDefaultLanguages,
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
const { program } = require('./program');
|
||||
|
||||
program.parse();
|
||||
@@ -0,0 +1,163 @@
|
||||
//@ts-check
|
||||
const fs = require('fs');
|
||||
const { program } = require('commander');
|
||||
const {
|
||||
resolveDirs,
|
||||
resolveExtensions,
|
||||
getTranslationChanges,
|
||||
setLanguageTranslations,
|
||||
getAllNonDefaultLanguages,
|
||||
updateLanguageTranslations,
|
||||
getDefaultTranslations,
|
||||
} = require('./helpers');
|
||||
const { extractAllTranslations } = require('./extract');
|
||||
const { getMissingTranslations } = require('./addMissing');
|
||||
const { defaultLanguage, defaultExtractConfig } = require('./constants');
|
||||
const { removeUnusedAllTranslations, removeUnusedForSignelLanguage } = require('./removeUnused');
|
||||
|
||||
/**
|
||||
* @typedef {import('./constants').ExtractConfig & { verbose?: boolean, ignoreUnused?: boolean }} ExtractOptions
|
||||
*/
|
||||
|
||||
program.name('dbgate-translations-cli').description('CLI tool for managing translation').version('1.0.0');
|
||||
|
||||
program
|
||||
.command('extract')
|
||||
.description('Extract translation keys from source files')
|
||||
.option('-d, --directories <directories...>', 'directories to search', defaultExtractConfig.directories)
|
||||
.option('-e, --extensions <extensions...>', 'file extensions to process', defaultExtractConfig.extensions)
|
||||
.option('-r, --ignoreUnused', 'Ignore unused keys in the output file')
|
||||
.option('-v, --verbose', 'verbose mode')
|
||||
.action(async (/** @type {ExtractOptions} */ options) => {
|
||||
try {
|
||||
const { directories, extensions, verbose, ignoreUnused } = options;
|
||||
|
||||
const resolvedRirectories = resolveDirs(directories);
|
||||
const resolvedExtensions = resolveExtensions(extensions);
|
||||
|
||||
const extractedTranslations = await extractAllTranslations(resolvedRirectories, resolvedExtensions);
|
||||
const defaultTranslations = getDefaultTranslations();
|
||||
|
||||
const { added, removed, updated } = getTranslationChanges(defaultTranslations, extractedTranslations);
|
||||
|
||||
console.log('\nTranslation changes:');
|
||||
console.log(`- Added: ${added.length} keys`);
|
||||
console.log(`- ${ignoreUnused ? 'Unused' : 'Removed'}: ${removed.length} keys`);
|
||||
console.log(`- Updated: ${updated.length} keys`);
|
||||
console.log(`- Total: ${Object.keys(extractedTranslations).length} keys`);
|
||||
|
||||
if (verbose) {
|
||||
if (added.length > 0) {
|
||||
console.log('\nNew keys:');
|
||||
added.forEach(key => console.log(` + ${key}`));
|
||||
}
|
||||
|
||||
if (removed.length > 0) {
|
||||
console.log('\nRemoved keys:');
|
||||
removed.forEach(key => console.log(` - ${key}`));
|
||||
}
|
||||
|
||||
if (updated.length > 0) {
|
||||
console.log('\nUpdated keys:');
|
||||
updated.forEach(key => {
|
||||
console.log(` ~ ${key}`);
|
||||
console.log(` Old: ${defaultLanguage[key]}`);
|
||||
console.log(` New: ${extractedTranslations[key]}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreUnused) {
|
||||
console.log('New translations were saved. Unused keys are kept.\n');
|
||||
updateLanguageTranslations(defaultLanguage, extractedTranslations);
|
||||
|
||||
if (verbose) {
|
||||
console.log('\nUnused keys:');
|
||||
for (const key of removed) {
|
||||
console.log(`${key}: "${defaultTranslations[key]}"`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Unused keys were removed.\n');
|
||||
setLanguageTranslations(defaultLanguage, extractedTranslations);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during extraction:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
const ALL_LANGUAGES = 'all';
|
||||
|
||||
/**
|
||||
* @param {string} target
|
||||
*/
|
||||
function addMissingTranslations(target) {
|
||||
console.log(`Adding missing keys for language: ${target}`);
|
||||
const { result, stats } = getMissingTranslations(target);
|
||||
console.log(`Added: ${stats.added}, Removed: ${stats.removed}, Total: ${stats.newLength}`);
|
||||
setLanguageTranslations(target, result);
|
||||
console.log(`New translations for ${target} were saved.`);
|
||||
}
|
||||
|
||||
program
|
||||
.command('add-missing')
|
||||
.description('Add missing keys for a langauge to the translation file')
|
||||
.option('-t, --target <target>', 'language to add missing translations to', ALL_LANGUAGES)
|
||||
.action(options => {
|
||||
try {
|
||||
const { target } = options;
|
||||
const languages = getAllNonDefaultLanguages();
|
||||
|
||||
if (target === ALL_LANGUAGES) {
|
||||
console.log('Adding missing keys for all languages\n');
|
||||
for (const language of languages) {
|
||||
addMissingTranslations(language);
|
||||
console.log();
|
||||
}
|
||||
} else {
|
||||
addMissingTranslations(target);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during add-missing:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('remove-unused')
|
||||
.description('Remove unused keys from the translation files')
|
||||
.option('-t, --target <target>', 'language to add missing translations to', ALL_LANGUAGES)
|
||||
.action(async options => {
|
||||
try {
|
||||
const { target } = options;
|
||||
if (target === ALL_LANGUAGES) {
|
||||
console.log('Removing unused keys from all languages\n');
|
||||
await removeUnusedAllTranslations();
|
||||
} else {
|
||||
await removeUnusedForSignelLanguage(target);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during add-missing:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('check')
|
||||
.description('Check if there are multiple default values for the same key')
|
||||
.action(async () => {
|
||||
try {
|
||||
await extractAllTranslations(defaultExtractConfig.directories, defaultExtractConfig.extensions);
|
||||
console.log('No problems found while extracting translations.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during check:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = { program };
|
||||
@@ -0,0 +1,46 @@
|
||||
// @ts-check
|
||||
const { defaultExtractConfig } = require('./constants');
|
||||
const { extractAllTranslations } = require('./extract');
|
||||
const { getLanguageTranslations, getAllLanguages, setLanguageTranslations } = require('./helpers');
|
||||
|
||||
const { directories, extensions } = defaultExtractConfig;
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} source
|
||||
*/
|
||||
function getUsedTranslations(language, source) {
|
||||
const languageTranslations = getLanguageTranslations(language);
|
||||
|
||||
for (const key in languageTranslations) {
|
||||
if (!(key in source)) {
|
||||
delete languageTranslations[key];
|
||||
}
|
||||
}
|
||||
|
||||
return languageTranslations;
|
||||
}
|
||||
|
||||
async function removeUnusedAllTranslations() {
|
||||
const source = await extractAllTranslations(directories, extensions);
|
||||
const languages = getAllLanguages();
|
||||
|
||||
for (const language of languages) {
|
||||
const newTranslations = getUsedTranslations(language, source);
|
||||
setLanguageTranslations(language, newTranslations);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*/
|
||||
async function removeUnusedForSignelLanguage(language) {
|
||||
const source = await extractAllTranslations(directories, extensions);
|
||||
const newTranslations = getUsedTranslations(language, source);
|
||||
setLanguageTranslations(language, newTranslations);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
removeUnusedAllTranslations,
|
||||
removeUnusedForSignelLanguage,
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @param {object|string} json
|
||||
* @returns {object}
|
||||
*/
|
||||
function sortJsonKeysAlphabetically(json) {
|
||||
const obj = typeof json === 'string' ? JSON.parse(json) : json;
|
||||
|
||||
if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const sortedObj = Object.keys(obj)
|
||||
.sort()
|
||||
.reduce((result, key) => {
|
||||
result[key] = obj[key];
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
return sortedObj;
|
||||
}
|
||||
|
||||
module.exports = sortJsonKeysAlphabetically;
|
||||
@@ -14,12 +14,16 @@ const volatilePackages = [
|
||||
'ioredis',
|
||||
'node-redis-dump2',
|
||||
'better-sqlite3',
|
||||
'libsql',
|
||||
'@azure/cosmos',
|
||||
'@aws-sdk/rds-signer',
|
||||
'activedirectory2',
|
||||
'axios',
|
||||
'ssh2',
|
||||
'wkx',
|
||||
'@duckdb/node-api',
|
||||
'@mongosh/browser-runtime-electron',
|
||||
'@mongosh/service-provider-node-driver',
|
||||
];
|
||||
|
||||
module.exports = volatilePackages;
|
||||
|
||||
+4
-13
@@ -1,21 +1,12 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM node:22
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/dbgate/dbgate"
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
gnupg \
|
||||
iputils-ping \
|
||||
iproute2 \
|
||||
unixodbc \
|
||||
gcc \
|
||||
g++ \
|
||||
make
|
||||
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource-archive-keyring.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/nodesource-archive-keyring.gpg] https://deb.nodesource.com/node_18.x jammy main" | tee /etc/apt/sources.list.d/nodesource.list \
|
||||
&& echo "deb-src [signed-by=/usr/share/keyrings/nodesource-archive-keyring.gpg] https://deb.nodesource.com/node_18.x jammy main" | tee -a /etc/apt/sources.list.d/nodesource.list \
|
||||
&& apt-get update && apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& npm install -g yarn
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /home/dbgate-docker
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/dbgate/dbgate"
|
||||
|
||||
WORKDIR /home/dbgate-docker
|
||||
|
||||
RUN apk --no-cache upgrade \
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
mssql: true,
|
||||
oracle: true,
|
||||
sqlite: true,
|
||||
mongo: true
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
function clearTestingData() {
|
||||
if (fs.existsSync(path.join(baseDir, 'connections-e2etests.jsonl'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'connections-e2etests.jsonl'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'settings-e2etests.json'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'settings-e2etests.json'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'files-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'files-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'archive-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'archive-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(__dirname, 'tmpdata', 'my_guitar_shop.db'))) {
|
||||
fs.unlinkSync(path.join(__dirname, 'tmpdata', 'my_guitar_shop.db'));
|
||||
}
|
||||
}
|
||||
|
||||
clearTestingData();
|
||||
@@ -1,6 +1,5 @@
|
||||
const { defineConfig } = require('cypress');
|
||||
const killPort = require('kill-port');
|
||||
const { clearTestingData } = require('./e2eTestTools');
|
||||
const waitOn = require('wait-on');
|
||||
const { exec } = require('child_process');
|
||||
const fs = require('fs');
|
||||
@@ -8,13 +7,14 @@ const path = require('path');
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
// baseUrl: 'http://localhost:3000',
|
||||
// trashAssetsBeforeRuns: false,
|
||||
chromeWebSecurity: false,
|
||||
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
|
||||
on('before:spec', async details => {
|
||||
await clearTestingData();
|
||||
// console.log('********************* DETAILS *********************', JSON.stringify(details));
|
||||
|
||||
if (config.isInteractive) {
|
||||
@@ -39,6 +39,15 @@ module.exports = defineConfig({
|
||||
case 'team':
|
||||
serverProcess = exec('yarn start:team');
|
||||
break;
|
||||
case 'multi-sql':
|
||||
serverProcess = exec('yarn start:multi-sql');
|
||||
break;
|
||||
case 'cloud':
|
||||
serverProcess = exec('yarn start:cloud');
|
||||
break;
|
||||
case 'charts':
|
||||
serverProcess = exec('yarn start:charts');
|
||||
break;
|
||||
}
|
||||
|
||||
await waitOn({ resources: ['http://localhost:3000'] });
|
||||
|
||||
@@ -13,16 +13,22 @@ describe('Add connection', () => {
|
||||
it('adds connection', () => {
|
||||
// cy.get('[data-testid=ConnectionList_buttonNewConnection]').click();
|
||||
cy.get('[data-testid=ConnectionDriverFields_connectionType]').select('MySQL');
|
||||
cy.themeshot('connection');
|
||||
cy.themeshot('new-connection');
|
||||
cy.get('[data-testid=ConnectionDriverFields_user]').clear().type('root');
|
||||
cy.get('[data-testid=ConnectionDriverFields_password]').clear().type('Pwd2020Db');
|
||||
cy.get('[data-testid=ConnectionDriverFields_port]').clear().type('16004');
|
||||
cy.get('[data-testid=ConnectionDriverFields_displayName]').clear().type('test-mysql-1');
|
||||
|
||||
// test connection
|
||||
cy.get('[data-testid=ConnectionTab_buttonTest]').click();
|
||||
cy.testid('ConnectionTab_buttonTest').click();
|
||||
cy.contains('Connected:');
|
||||
|
||||
cy.testid('ConnectionTab_tabSshTunnel').click();
|
||||
cy.testid('ConnectionTab_tabControlContent').themeshot('connection-sshtunnel-window', { padding: 50 });
|
||||
|
||||
cy.testid('ConnectionTab_tabSsl').click();
|
||||
cy.testid('ConnectionTab_tabControlContent').themeshot('connection-ssl-window', { padding: 50 });
|
||||
|
||||
// save and connect
|
||||
cy.get('[data-testid=ConnectionTab_buttonSave]').click();
|
||||
cy.get('[data-testid=ConnectionTab_buttonConnect]').click();
|
||||
@@ -106,4 +112,24 @@ describe('Add connection', () => {
|
||||
|
||||
cy.contains('performance_schema');
|
||||
});
|
||||
|
||||
it('export connections', () => {
|
||||
cy.testid('WidgetIconPanel_menu').click();
|
||||
cy.contains('Tools').click();
|
||||
cy.contains('Export connections').click();
|
||||
cy.themeshot('export-connections');
|
||||
});
|
||||
|
||||
it('configure LLM provider', () => {
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Settings').click();
|
||||
cy.contains('AI').click();
|
||||
cy.testid('AiSupportedProvidersInfo_add_OpenRouter').click();
|
||||
cy.testid('AiProviderCard_apikey_OpenRouter').clear().type('xxx');
|
||||
cy.testid('AiProviderCard_testButton_OpenRouter').click();
|
||||
cy.testid('AiProviderCard_statusValid_OpenRouter').should('exist');
|
||||
cy.testid('AiProviderCard_editButton_OpenRouter').click();
|
||||
cy.wait(1000);
|
||||
cy.themeshot('llm-providers-settings');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,18 +15,23 @@ beforeEach(() => {
|
||||
describe('Data browser data', () => {
|
||||
it('Export window', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').rightclick();
|
||||
cy.contains('Export').click();
|
||||
cy.contains('Export advanced').click();
|
||||
cy.wait(1000);
|
||||
// cy.testid('SourceTargetConfig_buttonCurrentArchive_target').click();
|
||||
cy.testid('FormTablesSelect_buttonAll_tables').click();
|
||||
// cy.testid('FormTablesSelect_buttonAll_tables').click();
|
||||
// cy.testid('SourceTargetConfig_tablesSelect_source').click();
|
||||
// cy.find('.listContainer').contains('Album').click();
|
||||
// cy.find('.listContainer').contains('Track').click();
|
||||
// cy.wait(4000);
|
||||
// cy.contains('All tables').click();
|
||||
cy.contains('Run').click();
|
||||
cy.contains('Finished job script');
|
||||
cy.contains('Album.csv');
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.themeshot('exportcsv');
|
||||
cy.themeshot('configure-export-csv');
|
||||
});
|
||||
|
||||
it('Data archive editor - macros', () => {
|
||||
@@ -37,7 +42,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Out Of Exile').click({ shiftKey: true });
|
||||
cy.contains('Change text case').click();
|
||||
cy.contains('AUDIOSLAVE');
|
||||
cy.themeshot('freetable');
|
||||
cy.themeshot('data-archive-macros');
|
||||
});
|
||||
|
||||
it('Load table data', () => {
|
||||
@@ -76,11 +81,25 @@ describe('Data browser data', () => {
|
||||
cy.contains('Aerosmith').should('not.exist');
|
||||
});
|
||||
|
||||
it('Data filter', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').click();
|
||||
cy.testid('DataFilterControl_input_Title').type('Rock{enter}');
|
||||
cy.contains('Rows: 7');
|
||||
cy.testid('DataFilterControl_input_AlbumId').type('>10xxx{enter}');
|
||||
cy.contains('Rows: 7');
|
||||
cy.testid('DataFilterControl_filtermenu_Title').click();
|
||||
// hide what is not needed
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.testid('DataGrid_itemReferences').click();
|
||||
cy.themeshot('data-browser-filter');
|
||||
cy.testid('DataGridCore_button_clearFilters').click();
|
||||
cy.contains('Rows: 347');
|
||||
});
|
||||
|
||||
it('Data grid screenshots', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.window().then(win => {
|
||||
win.__changeCurrentTheme('theme-dark');
|
||||
});
|
||||
|
||||
cy.contains('MyChinook').click();
|
||||
|
||||
@@ -95,16 +114,25 @@ describe('Data browser data', () => {
|
||||
cy.contains('PgChinook').click();
|
||||
cy.contains('customer').click();
|
||||
cy.contains('Leonie').click();
|
||||
cy.themeshot('datagrid');
|
||||
cy.themeshot('common-data-browser');
|
||||
|
||||
cy.contains('invoice').click();
|
||||
cy.contains('invoice_line (invoice_id)').click();
|
||||
cy.themeshot('masterdetail');
|
||||
cy.themeshot('data-browser-master-detail');
|
||||
|
||||
cy.contains('9, Place Louis Barthou').click();
|
||||
cy.contains('Switch to form').click();
|
||||
cy.contains('Switch to table'); // test that we are in form view
|
||||
cy.themeshot('formview');
|
||||
cy.themeshot('data-browser-form-view');
|
||||
});
|
||||
|
||||
it('Column search', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Customer').click();
|
||||
cy.testid('ColumnManager_searchColumns').clear().type('name,id{enter}');
|
||||
cy.contains('Company').should('not.exist');
|
||||
cy.themeshot('data-browser-column-search');
|
||||
});
|
||||
|
||||
it('SQL Gen', () => {
|
||||
@@ -112,7 +140,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('PgChinook').rightclick();
|
||||
cy.contains('SQL Generator').click();
|
||||
cy.contains('Check all').click();
|
||||
cy.themeshot('sqlgen');
|
||||
cy.themeshot('sql-generator');
|
||||
});
|
||||
|
||||
it('Macros in DB', () => {
|
||||
@@ -127,7 +155,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('DataGrid_itemMacros').click();
|
||||
cy.contains('Change text case').click();
|
||||
cy.contains('NIELSEN');
|
||||
cy.themeshot('macros');
|
||||
cy.themeshot('data-browser-macros');
|
||||
});
|
||||
|
||||
it('Perspectives', () => {
|
||||
@@ -143,7 +171,7 @@ describe('Data browser data', () => {
|
||||
// check track is loaded
|
||||
cy.contains('Put The Finger On You');
|
||||
|
||||
cy.themeshot('perspective1');
|
||||
cy.themeshot('perspective-designer');
|
||||
});
|
||||
|
||||
it('Query editor - code completion', () => {
|
||||
@@ -152,24 +180,26 @@ describe('Data browser data', () => {
|
||||
cy.contains('Customer').rightclick();
|
||||
cy.contains('SQL template').click();
|
||||
cy.contains('CREATE TABLE').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realPress('PageDown');
|
||||
cy.get('body').realType('select * from Album where Album.');
|
||||
// code completion
|
||||
cy.contains('ArtistId');
|
||||
cy.themeshot('query');
|
||||
cy.themeshot('query-editor-code-completion');
|
||||
});
|
||||
|
||||
it('Query editor - join wizard', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewQuery').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('select * from Invoice');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.get('body').realPress(['Control', 'j']);
|
||||
// JOIN wizard
|
||||
cy.contains('INNER JOIN Customer ON Invoice.CustomerId = Customer.CustomerId');
|
||||
cy.themeshot('joinwizard');
|
||||
cy.themeshot('query-editor-join-wizard');
|
||||
});
|
||||
|
||||
it('Mongo JSON data view', () => {
|
||||
@@ -186,7 +216,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
// test JSON view
|
||||
cy.contains('Country: "Brazil"');
|
||||
cy.themeshot('mongoquery');
|
||||
cy.themeshot('mongo-query-json-view');
|
||||
});
|
||||
|
||||
it('SQL preview', () => {
|
||||
@@ -196,7 +226,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Show SQL').click();
|
||||
// index should be part of create script
|
||||
cy.contains('CREATE INDEX `IFK_CustomerSupportRepId`');
|
||||
cy.themeshot('sqlpreview');
|
||||
cy.themeshot('sql-preview-create-index');
|
||||
});
|
||||
|
||||
it('Query designer', () => {
|
||||
@@ -205,7 +235,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('customer').click();
|
||||
// cy.contains('left join').rightclick();
|
||||
cy.themeshot('querydesigner');
|
||||
cy.themeshot('query-designer');
|
||||
});
|
||||
|
||||
it('Database diagram', () => {
|
||||
@@ -216,24 +246,24 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
// check diagram is shown
|
||||
cy.contains('MediaTypeId');
|
||||
cy.themeshot('diagram');
|
||||
cy.themeshot('database-diagram');
|
||||
});
|
||||
|
||||
it('Charts', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('pie-chart').click();
|
||||
cy.contains('line-chart').click();
|
||||
cy.testid('TabsPanel_buttonSplit').click();
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.themeshot('charts');
|
||||
});
|
||||
// it('Charts', () => {
|
||||
// cy.testid('WidgetIconPanel_file').click();
|
||||
// cy.contains('pie-chart').click();
|
||||
// cy.contains('line-chart').click();
|
||||
// cy.testid('TabsPanel_buttonSplit').click();
|
||||
// cy.testid('WidgetIconPanel_file').click();
|
||||
// cy.themeshot('view-split-charts');
|
||||
// });
|
||||
|
||||
it('Keyboard configuration', () => {
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Keyboard shortcuts').click();
|
||||
cy.contains('dataForm.refresh').click();
|
||||
cy.testid('CommandModal_keyboardButton').click();
|
||||
cy.themeshot('keyboard');
|
||||
cy.themeshot('keyboard-configuration');
|
||||
});
|
||||
|
||||
it('Command palette', () => {
|
||||
@@ -244,7 +274,15 @@ describe('Data browser data', () => {
|
||||
// cy.realPress('F1');
|
||||
cy.realPress('PageDown');
|
||||
cy.realPress('PageDown');
|
||||
cy.testid('CommandPalette_main').themeshot('commandpalette', { padding: 50 });
|
||||
cy.testid('CommandPalette_main').themeshot('command-palette', { padding: 50 });
|
||||
});
|
||||
|
||||
it('About window', () => {
|
||||
cy.contains('Connections');
|
||||
cy.testid('WidgetIconPanel_menu').click();
|
||||
cy.contains('Help').click();
|
||||
cy.contains('About').click();
|
||||
cy.testid('ModalBase_window').themeshot('about-window', { padding: 50 });
|
||||
});
|
||||
|
||||
it('Show map', () => {
|
||||
@@ -257,7 +295,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('13.9').click({ shiftKey: true });
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
cy.wait(2000);
|
||||
cy.themeshot('map');
|
||||
cy.themeshot('cell-map-view');
|
||||
});
|
||||
|
||||
it('Search in connections', () => {
|
||||
@@ -269,17 +307,18 @@ describe('Data browser data', () => {
|
||||
cy.contains('Album').click();
|
||||
cy.testid('SqlObjectList_searchMenuDropDown').click();
|
||||
cy.contains('Column name').click();
|
||||
cy.themeshot('connsearch');
|
||||
cy.themeshot('search-in-connections');
|
||||
});
|
||||
|
||||
it('Plugin tab', () => {
|
||||
cy.testid('WidgetIconPanel_plugins').click();
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Manage plugins').click();
|
||||
cy.contains('dbgate-plugin-theme-total-white').click();
|
||||
// text from plugin markdown
|
||||
cy.contains('Total white theme');
|
||||
// wait for load logos
|
||||
cy.wait(2000);
|
||||
cy.themeshot('plugin');
|
||||
cy.themeshot('view-plugin-tab');
|
||||
});
|
||||
|
||||
it('Edit mongo data JSON', () => {
|
||||
@@ -306,7 +345,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Helena').rightclick();
|
||||
cy.contains('Delete document').click();
|
||||
cy.contains('Save').click();
|
||||
cy.themeshot('mongosave');
|
||||
cy.themeshot('save-changes-mongodb');
|
||||
});
|
||||
|
||||
it('Edit mongo data JSON', () => {
|
||||
@@ -320,7 +359,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('ColumnManagerRow_checkbox__id').click();
|
||||
cy.testid('DataFilterControl_input_countries.1').type('EXISTS{enter}');
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
cy.themeshot('collection');
|
||||
cy.themeshot('mongodb-json-cell-view');
|
||||
});
|
||||
|
||||
it('Table structure editor', () => {
|
||||
@@ -329,10 +368,10 @@ describe('Data browser data', () => {
|
||||
cy.contains('Customer').rightclick();
|
||||
cy.contains('Open structure').click();
|
||||
cy.contains('varchar(40)');
|
||||
cy.themeshot('structure');
|
||||
cy.themeshot('table-structure-editor');
|
||||
cy.contains('EmployeeId').click();
|
||||
cy.contains('Ref column - Employee');
|
||||
cy.themeshot('fkeditor');
|
||||
cy.themeshot('foreign-key-editor');
|
||||
});
|
||||
|
||||
it('Compare database', () => {
|
||||
@@ -344,25 +383,10 @@ describe('Data browser data', () => {
|
||||
cy.testid('CompareModelTab_gridObjects_Customer_Customer').click();
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.testid('CompareModelTab_tabDdl').click();
|
||||
cy.themeshot('dbcompare');
|
||||
cy.themeshot('compare-database-models');
|
||||
cy.contains('Settings').click();
|
||||
cy.testid('CompareModelTab_tabOperations').click();
|
||||
cy.themeshot('comparesettings');
|
||||
});
|
||||
|
||||
it('Query editor - AI assistant', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewQuery').click();
|
||||
cy.testid('QueryTab_switchAiAssistantButton').click();
|
||||
cy.testid('QueryAiAssistant_allowSendToAiServiceButton').click();
|
||||
cy.testid('ConfirmModal_okButton').click();
|
||||
cy.testid('QueryAiAssistant_promptInput').type('album names');
|
||||
cy.testid('QueryAiAssistant_queryFromQuestionButton').click();
|
||||
cy.contains('Use this').click();
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Balls to the Wall');
|
||||
cy.themeshot('aiassistant');
|
||||
cy.themeshot('compare-database-settings');
|
||||
});
|
||||
|
||||
it('Modify data', () => {
|
||||
@@ -388,7 +412,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('INSERT INTO `Employee`');
|
||||
cy.contains("SET `FirstName`='Jane'");
|
||||
cy.contains('DELETE FROM `Employee`');
|
||||
cy.themeshot('modifydata');
|
||||
cy.themeshot('data-browser-save-changes');
|
||||
|
||||
// cy.testid('ConfirmSqlModal_okButton').click();
|
||||
// cy.contains('Cannot delete or update a parent row')
|
||||
@@ -403,4 +427,60 @@ describe('Data browser data', () => {
|
||||
cy.contains('Novak');
|
||||
cy.contains('Rows: 8');
|
||||
});
|
||||
|
||||
it('Export menu', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').click();
|
||||
cy.testid('DataFilterControl_input_ArtistId').type('22{enter}');
|
||||
// cy.contains('Presence').rightclick();
|
||||
// cy.contains('Coda').rightclick();
|
||||
// cy.testid('DropDownMenu-container-0').contains('Export').click();
|
||||
cy.contains('Export').click();
|
||||
// cy.wait(1000);
|
||||
cy.themeshot('data-browser-export-menu');
|
||||
});
|
||||
|
||||
it('MySQL native backup', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('Create database backup').click();
|
||||
cy.contains('Customer');
|
||||
cy.themeshot('mysql-backup-configuration');
|
||||
});
|
||||
|
||||
it('View table YAML model', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('Export DB model').click();
|
||||
cy.testid('ExportDbModelModal_archiveFolder').select('(Create new)');
|
||||
cy.testid('InputTextModal_value').clear().type('test-model');
|
||||
cy.testid('InputTextModal_ok').click();
|
||||
cy.testid('ModalBase_window').themeshot('export-database-model-window', { padding: 50 });
|
||||
cy.testid('ExportDbModelModal_exportButton').click();
|
||||
cy.contains('Album').click();
|
||||
cy.contains('autoIncrement');
|
||||
cy.themeshot('database-model-table-yaml');
|
||||
});
|
||||
|
||||
it('Data replicator', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('WidgetIconPanel_archive').click();
|
||||
cy.contains('chinook-archive').rightclick();
|
||||
cy.contains('Data deployer').click();
|
||||
cy.contains('Dry run').click();
|
||||
cy.testid('TableControl_row_2_checkbox').click();
|
||||
cy.testid('TableControl_row_2').click();
|
||||
cy.testid('DataDeploySettings_find_checkbox').click();
|
||||
cy.testid('DataDeploySettings_create_checkbox').click();
|
||||
cy.testid('WidgetIconPanel_archive').click();
|
||||
cy.themeshot('data-deployer');
|
||||
cy.testid('DataDeployTab_importIntoDb').click();
|
||||
cy.testid('ConfirmDataDeployModal_okButton').click();
|
||||
cy.contains('Replicated Customer, inserted 59 rows');
|
||||
cy.contains('Finished job script');
|
||||
cy.testid('DataDeployTab_importIntoDb').click();
|
||||
cy.themeshot('data-replicator');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
describe('Charts', () => {
|
||||
it('Auto detect chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('charts_sample').click();
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('chart1').click();
|
||||
cy.contains('department_name');
|
||||
// cy.testid('QueryTab_executeButton').click();
|
||||
// cy.testid('QueryTab_openChartButton').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('choose-detected-chart');
|
||||
});
|
||||
|
||||
it('Two line charts', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('SELECT InvoiceDate, Total from Invoice');
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('two-line-charts');
|
||||
});
|
||||
|
||||
it('Invoice naive autodetection', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('SELECT * from Invoice');
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-naive-autodetection');
|
||||
});
|
||||
|
||||
it('Invoice by country - grouped chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType(
|
||||
"SELECT InvoiceDate, Total, BillingCountry from Invoice where BillingCountry in ('USA', 'Canada', 'Brazil', 'France', 'Germany')"
|
||||
);
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('ChartSelector_chart_1').click();
|
||||
cy.testid('JslChart_customizeButton').click();
|
||||
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-grouped-autodetected');
|
||||
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Bar');
|
||||
cy.testid('ChartDefinitionEditor_xAxisTransformSelect').select('Date (Year)');
|
||||
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-grouped-bars');
|
||||
});
|
||||
|
||||
it('Public Knowledge base - show chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('WidgetIconPanel_cloud-public').click();
|
||||
cy.testid('public-cloud-file-tag-mysql/folder-MySQL/tag-premium/top-tables-row-count.sql').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('public-knowledge-base-tables-sizes');
|
||||
});
|
||||
|
||||
it('Auto detect chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Invoice').rightclick();
|
||||
cy.contains('SQL template').click();
|
||||
cy.contains('SELECT').click();
|
||||
cy.testid('QueryTab_detectChartButton').click();
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Chart 1').click();
|
||||
cy.testid('ChartSelector_chart_0').click();
|
||||
cy.testid('JslChart_customizeButton').click();
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Bar');
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Line');
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('query-result-chart');
|
||||
});
|
||||
|
||||
it('New object window', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Invoice').click();
|
||||
cy.testid('WidgetIconPanel_addButton').click();
|
||||
cy.contains('Compare database');
|
||||
cy.themeshot('new-object-window');
|
||||
});
|
||||
|
||||
it('Database chat - charts', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_databaseChat').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('show me chart of most popular genres');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
cy.wait(5000);
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('database-chat-chart');
|
||||
});
|
||||
|
||||
it('Database chat', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_databaseChat').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('find most popular artist');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
cy.wait(30000);
|
||||
// cy.contains('Iron Maiden');
|
||||
cy.themeshot('database-chat');
|
||||
|
||||
// cy.testid('DatabaseChatTab_promptInput').click();
|
||||
// cy.get('body').realType('I need top 10 songs with the biggest income');
|
||||
// cy.get('body').realPress('{enter}');
|
||||
// cy.contains('Hot Girl', { timeout: 20000 });
|
||||
// cy.wait(1000);
|
||||
// cy.themeshot('database-chat');
|
||||
});
|
||||
|
||||
it('Explain query error', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('select * from Invoice2');
|
||||
cy.contains('Execute').click();
|
||||
cy.testid('MessageViewRow-explainErrorButton-1').click();
|
||||
cy.testid('ChatCodeRenderer_useSqlButton', { timeout: 30000 });
|
||||
cy.themeshot('explain-query-error');
|
||||
|
||||
// cy.testid('TabsPanel_buttonNewObject').click();
|
||||
// cy.testid('NewObjectModal_databaseChat').click();
|
||||
// cy.wait(1000);
|
||||
// cy.get('body').realType('show me chart of most popular genres');
|
||||
// cy.get('body').realPress('{enter}');
|
||||
// cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
// cy.wait(5000);
|
||||
// cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
// cy.themeshot('database-chat-chart');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
describe('Cloud tests', () => {
|
||||
it('Private cloud', () => {
|
||||
cy.testid('WidgetIconPanel_cloudAccount');
|
||||
cy.window().then(win => {
|
||||
win.__loginToCloudTest('dbgate.test@gmail.com');
|
||||
});
|
||||
cy.contains('dbgate.test@gmail.com');
|
||||
|
||||
// cy.testid('WidgetIconPanel_cloudAccount').click();
|
||||
|
||||
// cy.origin('https://identity.dbgate.io', () => {
|
||||
// cy.contains('Sign in with GitHub').click();
|
||||
// });
|
||||
|
||||
// cy.origin('https://github.com', () => {
|
||||
// cy.get('#login_field').type('dbgatetest');
|
||||
// cy.get('#password').type('Pwd2020Db');
|
||||
// cy.get('input[type="submit"]').click();
|
||||
// });
|
||||
|
||||
// cy.wait(3000);
|
||||
|
||||
// cy.location('origin').then(origin => {
|
||||
// if (origin === 'https://github.com') {
|
||||
// // Still on github.com → an authorization step is waiting
|
||||
// cy.origin('https://github.com', () => {
|
||||
// // Try once, don't wait the full default timeout
|
||||
// cy.get('button[data-octo-click="oauth_application_authorization"]', { timeout: 500, log: false }).click(); // if the button exists it will be clicked
|
||||
// // if not, the short timeout elapses and we drop out
|
||||
// });
|
||||
// } else {
|
||||
// // Already back on localhost – nothing to authorize
|
||||
// cy.log('OAuth redirect skipped the Authorize screen');
|
||||
// }
|
||||
// });
|
||||
|
||||
cy.contains('Testing Connections').rightclick();
|
||||
cy.contains('Administrate access').click();
|
||||
cy.contains('User email');
|
||||
cy.themeshot('administer-shared-folder');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,203 @@
|
||||
const localconfig = require('../../.localconfig');
|
||||
const { formatQueryWithoutParams } = require('dbgate-tools');
|
||||
|
||||
global.DBGATE_PACKAGES = {
|
||||
'dbgate-tools': require('dbgate-tools'),
|
||||
};
|
||||
|
||||
function requireEngineDriver(engine) {
|
||||
const [shortName, packageName] = engine.split('@');
|
||||
const plugin = require(`../../../plugins/${packageName}/src/frontend/index`);
|
||||
if (plugin.drivers) {
|
||||
return plugin.drivers.find(x => x.engine == engine);
|
||||
}
|
||||
throw new Error(`Could not find engine driver ${engine}`);
|
||||
}
|
||||
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
function multiTest(testProps, testDefinition) {
|
||||
if (localconfig.mysql) {
|
||||
it('MySQL', () => testDefinition('MySql-connection', 'my_guitar_shop', 'mysql@dbgate-plugin-mysql'));
|
||||
}
|
||||
if (localconfig.postgres) {
|
||||
it('Postgres', () => testDefinition('Postgres-connection', 'my_guitar_shop', 'postgres@dbgate-plugin-postgres'));
|
||||
}
|
||||
if (localconfig.mssql) {
|
||||
it('Mssql', () => testDefinition('Mssql-connection', 'my_guitar_shop', 'mssql@dbgate-plugin-mssql'));
|
||||
}
|
||||
if (localconfig.oracle) {
|
||||
it('Oracle', () =>
|
||||
testDefinition('Oracle-connection', 'C##MY_GUITAR_SHOP', 'oracle@dbgate-plugin-oracle', {
|
||||
implicitTransactions: true,
|
||||
}));
|
||||
}
|
||||
if (localconfig.sqlite) {
|
||||
it('Sqlite', () => testDefinition('Sqlite-connection', null, 'sqlite@dbgate-plugin-sqlite'));
|
||||
}
|
||||
if (localconfig.mongo && !testProps.skipMongo) {
|
||||
it('MongoDB', () => testDefinition('Mongo-connection', 'my_guitar_shop', 'mongo@dbgate-plugin-mongo'));
|
||||
}
|
||||
}
|
||||
|
||||
describe('Transactions', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
const driver = requireEngineDriver(engine);
|
||||
const implicitTransactions = options.implicitTransactions ?? false;
|
||||
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').type(
|
||||
formatQueryWithoutParams(driver, "INSERT INTO ~categories (~category_id, ~category_name) VALUES (5, 'test');")
|
||||
);
|
||||
|
||||
// rollback
|
||||
if (!implicitTransactions) {
|
||||
cy.testid('QueryTab_beginTransactionButton').click();
|
||||
cy.contains('Begin Transaction finished');
|
||||
}
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Query execution finished');
|
||||
cy.testid('QueryTab_rollbackTransactionButton').click();
|
||||
cy.contains('Rollback Transaction finished');
|
||||
|
||||
// should contain 4 rows
|
||||
cy.testid('SqlObjectList_container').contains('categories').click();
|
||||
cy.contains('Guitars').click();
|
||||
cy.testid('TableDataTab_refreshGrid').click();
|
||||
cy.contains('Rows: 4');
|
||||
|
||||
// commit
|
||||
cy.contains('Query #1').click();
|
||||
if (!implicitTransactions) {
|
||||
cy.testid('QueryTab_beginTransactionButton').click();
|
||||
cy.contains('Begin Transaction finished');
|
||||
}
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Query execution finished');
|
||||
cy.testid('QueryTab_commitTransactionButton').click();
|
||||
cy.contains('Commit Transaction finished');
|
||||
|
||||
// should contain 5 rows
|
||||
cy.testid('SqlObjectList_container').contains('categories').click();
|
||||
cy.contains('Guitars').click();
|
||||
cy.testid('TableDataTab_refreshGrid').click();
|
||||
cy.contains('Rows: 5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Backup table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('customers').rightclick();
|
||||
cy.contains('Create table backup').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('_customers').click();
|
||||
cy.contains('Rows: 8').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Truncate table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('order_items').rightclick();
|
||||
cy.contains('Truncate table').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('order_items').click();
|
||||
cy.contains('No rows loaded').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Drop table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('order_items').rightclick();
|
||||
cy.contains('Drop table').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('order_items').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20.csv', { force: true });
|
||||
cy.contains('customers-20');
|
||||
cy.testid('ImportExportTab_preview_content').contains('50ddd99fAdF48B3').should('be.visible');
|
||||
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.contains('20 rows written').should('be.visible');
|
||||
|
||||
cy.testid('SqlObjectList_refreshButton').click();
|
||||
cy.testid('SqlObjectList_container').contains('customers-20').click();
|
||||
cy.contains('Rows: 20').should('be.visible');
|
||||
|
||||
// cy.get('table tbody tr')
|
||||
// .eq(1)
|
||||
// .within(() => {
|
||||
// cy.get('select').select('Append data');
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV - source error', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20-err.csv', { force: true });
|
||||
cy.contains('customers-20-err');
|
||||
cy.testid('ImportExportTab_preview_content').contains('Invalid Closing Quote').should('be.visible');
|
||||
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20-err').click();
|
||||
|
||||
cy.testid('ErrorMessageModal_message').contains('Invalid Closing Quote').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV - target error', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20.csv', { force: true });
|
||||
cy.contains('customers-20');
|
||||
cy.testid('ImportExportConfigurator_targetName_customers-20').clear().type('system."]`');
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20').click();
|
||||
cy.testid('ErrorMessageModal_message').should('be.visible');
|
||||
});
|
||||
});
|
||||
@@ -45,36 +45,36 @@ describe('Run as portal', () => {
|
||||
cy.get('[data-testid=InputTextModal_ok]').click();
|
||||
});
|
||||
|
||||
it('Import Chinook MySQL', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
cy.contains('Chinook').rightclick();
|
||||
cy.contains('Restore/import SQL dump').click();
|
||||
cy.get('#uploadFileButton').selectFile('data/chinook-mysql.sql', { force: true });
|
||||
cy.wait(500);
|
||||
cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
cy.contains('Importing database');
|
||||
cy.contains('Finished job script');
|
||||
cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('Album');
|
||||
});
|
||||
// it('Import Chinook MySQL', () => {
|
||||
// cy.visit('http://localhost:3000');
|
||||
// cy.contains('MySql-connection').click();
|
||||
// cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
// cy.contains('Chinook').rightclick();
|
||||
// cy.contains('Restore/import SQL dump').click();
|
||||
// cy.get('#uploadFileButton').selectFile('data/chinook-mysql.sql', { force: true });
|
||||
// cy.wait(500);
|
||||
// cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
// cy.contains('Importing database');
|
||||
// cy.contains('Finished job script');
|
||||
// cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
// cy.contains('Chinook').click();
|
||||
// cy.contains('Album');
|
||||
// });
|
||||
|
||||
it('Import Chinook Postgres', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.contains('Postgres-connection').click();
|
||||
cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
cy.contains('Restore/import SQL dump').click();
|
||||
cy.get('#uploadFileButton').selectFile('data/chinook-postgres.sql', { force: true });
|
||||
cy.wait(500);
|
||||
cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
cy.contains('Importing database');
|
||||
cy.contains('Finished job script');
|
||||
cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('album');
|
||||
});
|
||||
// it('Import Chinook Postgres', () => {
|
||||
// cy.visit('http://localhost:3000');
|
||||
// cy.contains('Postgres-connection').click();
|
||||
// cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
// cy.contains('Restore/import SQL dump').click();
|
||||
// cy.get('#uploadFileButton').selectFile('data/chinook-postgres.sql', { force: true });
|
||||
// cy.wait(500);
|
||||
// cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
// cy.contains('Importing database');
|
||||
// cy.contains('Finished job script');
|
||||
// cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
// cy.contains('Chinook').click();
|
||||
// cy.contains('album');
|
||||
// });
|
||||
|
||||
it('Open ask pwd connection', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
@@ -83,7 +83,7 @@ describe('Run as portal', () => {
|
||||
cy.testid('DatabaseLoginModal_password').clear().type('Pwd2020Db');
|
||||
cy.testid('DatabaseLoginModal_connect').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('album');
|
||||
// cy.contains('album');
|
||||
});
|
||||
|
||||
// it('import chinook DB', () => {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
@@ -11,21 +20,27 @@ describe('Team edition tests', () => {
|
||||
|
||||
cy.testid('AdminMenuWidget_itemConnections').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.testid('ConnectionDriverFields_connectionType').select('PostgreSQL');
|
||||
cy.themeshot('connadmin');
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('connection-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemRoles').click();
|
||||
cy.contains('Permissions').click();
|
||||
cy.themeshot('roleadmin');
|
||||
cy.contains('logged-user').click();
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('role-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('New user').click();
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('user-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuthentication').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('Use database login').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('OAuth 2.0').click();
|
||||
cy.themeshot('authadmin');
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('authentication-administration');
|
||||
});
|
||||
|
||||
it('OAuth authentication', () => {
|
||||
@@ -77,6 +92,60 @@ describe('Team edition tests', () => {
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('test@example.com');
|
||||
cy.contains('Rows: 1');
|
||||
});
|
||||
|
||||
it('Audit logging', () => {
|
||||
cy.testid('LoginPage_linkAdmin').click();
|
||||
cy.testid('LoginPage_password').type('adminpwd');
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.contains('Audit log is not enabled');
|
||||
cy.testid('AdminMenuWidget_itemSettings').click();
|
||||
cy.testid('AdminSettingsTab_auditLogCheckbox').click();
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.contains('No data for selected date');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemConnections').click();
|
||||
cy.contains('Open table').click();
|
||||
cy.contains('displayName');
|
||||
cy.get('.toolstrip').contains('Export').click();
|
||||
cy.contains('CSV file').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('Open table').click();
|
||||
cy.contains('login');
|
||||
cy.get('.toolstrip').contains('Export').click();
|
||||
cy.contains('XML file').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.testid('AdminAuditLogTab_refreshButton').click();
|
||||
cy.contains('Exporting query').click();
|
||||
cy.themeshot('auditlog');
|
||||
});
|
||||
|
||||
it('Edit database permissions', () => {
|
||||
cy.testid('LoginPage_linkAdmin').click();
|
||||
cy.testid('LoginPage_password').type('adminpwd');
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemRoles').click();
|
||||
cy.testid('AdminRolesTab_table').contains('superadmin').click();
|
||||
cy.testid('AdminRolesTab_databases').click();
|
||||
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
|
||||
cy.testid('AdminListOrRegexEditor_1_regexInput').type('^Chinook[\\d]*$');
|
||||
cy.testid('AdminListOrRegexEditor_2_listSwitch').click();
|
||||
cy.testid('AdminListOrRegexEditor_2_listInput').type('Nortwind\nSales');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_0').select('-2');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_1').select('-3');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_2').select('-4');
|
||||
|
||||
cy.contains('not granted').should('not.exist');
|
||||
|
||||
cy.themeshot('database-permissions');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Index,Customer Id,First Name,Last Name,Company,City,Country,Phone 1,Phone 2,Email,Subscription Date,Website
|
||||
1,50ddd99fAdF48B3,Jessica,Navarro,"Tran, Odom and Graham",Port Terranceview,Jersey,(883)287-7947,479-044-3187,wmcintyre@myers.net,2023-03-11,http://pennington.com/
|
||||
"2,BD1AB97979DDcDe,Preston,Andrews,"Townsend, Lawrence and Davenport",Harringtonmouth,Croatia,188-270-5676x63873,001-428-148-4270,bradley63@jacobs.net,2023-11-15,http://burke.com/
|
||||
3,0FDDD9aCa501acE,Melissa,Mckay,Rivas-Cooke,Oliviabury,Cook Islands,8257631531,001-650-689-5600x927,ugalloway@maxwell-mcclain.com,2025-01-25,https://patrick.com/
|
||||
4,A7dA284B7c4AfaD,Frank,Livingston,"Lambert, Garner and Mathews",Mallorytown,Faroe Islands,766.182.6201x689,+1-476-912-2027x4370,tracie00@webster.biz,2021-03-27,https://www.hart.com/
|
||||
5,38bb1624e4f8211,Ross,Mendoza,Cook and Sons,New Perry,Bolivia,001-440-468-2236,165.562.4328x9274,austincarmen@abbott.com,2024-12-12,http://harmon.com/
|
||||
6,55c9Fda2BABFE1a,Jane,Tate,Knapp PLC,West Kathyshire,Morocco,001-606-447-0584x07975,(003)872-1307x285,carlosgomez@mcpherson-ramos.biz,2021-09-13,http://www.yu.com/
|
||||
7,A15eccAc67cCc5b,Tanya,Chung,Frost Inc,South Julieburgh,United States of America,778-360-8301x268,+1-034-169-4237,onewton@crosby.com,2024-10-01,http://www.gill-velez.biz/
|
||||
8,aFdab04acACaf90,Jackson,Moyer,Bowen Ltd,Port Triciabury,Bahrain,001-187-882-2891x169,154.903.2525,gabriela16@mejia.org,2023-06-20,http://www.david.biz/
|
||||
9,A2EaeAd3c6529B9,Kelly,Douglas,Phillips PLC,Weissberg,Qatar,767.177.3199x5576,5156730935,wigginsmercedes@tanner.com,2021-06-30,https://gonzalez.net/
|
||||
10,188175A5641d080,Mariah,Riddle,"Mata, Fuller and Good",Choiton,Namibia,092-993-3559x342,190.937.3937,eileen32@greer.biz,2021-04-17,http://www.bowen.info/
|
||||
11,B2BA817C7bC09f0,Kristine,Pennington,"Koch, Diaz and Valdez",Port Rachael,Suriname,877.152.6488x921,790-804-9979x3290,tonya00@flynn.com,2024-03-28,https://www.rocha.net/
|
||||
12,fFAD70B5Febc43a,Robert,Adams,Bender-Wolfe,Billfort,Tanzania,219-696-1912x93626,518-969-4058,jeffersoncolton@moss-ashley.com,2022-07-31,https://www.alvarez.com/
|
||||
13,9a44524E1261Ed6,Franklin,Costa,Werner Group,North Bradley,Cook Islands,(895)448-4681x1999,648-345-3083x88242,marksmith@novak.com,2024-12-03,http://thornton.com/
|
||||
14,0C360EfE17D06cc,Dan,Ballard,Sampson-Huff,Michaelchester,Sao Tome and Principe,+1-803-469-5237x2580,(729)574-6101x0605,molly54@acevedo.info,2022-10-24,https://www.sloan-gonzales.biz/
|
||||
15,fb5cE8cb1eF2954,Clifford,Moyer,Fry-Whitehead,Lake Gary,Japan,(504)263-0450,247.514.1614x551,rhonda34@orr.com,2020-03-08,https://norton.com/
|
||||
16,3e53DcaD1cB0054,Tonya,Durham,"Lowe, West and Reynolds",South Sylviaton,Brunei Darussalam,(613)893-8183,(461)399-6120,kiara96@meadows.biz,2022-08-04,https://www.reeves.com/
|
||||
17,83fDDE5812EbEde,Dale,Bishop,Shaw-Ray,Lake Miranda,Congo,(082)202-9241,+1-413-610-1854x79378,bhoward@hodges.biz,2023-05-08,http://www.escobar.com/
|
||||
18,8dB7ACe2C5758cE,Priscilla,Mills,Pope PLC,North Cliffordshire,South Georgia and the South Sandwich Islands,+1-465-802-4573x30191,044-393-6049x598,nathaniel28@hess.com,2020-09-08,https://www.watts.org/
|
||||
19,c1092ebDaF2ceED,Alice,Bond,Chan-Liu,West Wesley,Lithuania,+1-333-285-8515,(715)759-3158x77103,jose92@peters.com,2024-05-30,http://www.marquez.com/
|
||||
20,4d0c95579D095aF,Cole,Compton,Calderon PLC,Robertaville,Saudi Arabia,029.862.3387x470,001-319-474-2394,sspence@dorsey.com,2020-08-02,http://hamilton.net/
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 36.
|
@@ -0,0 +1,21 @@
|
||||
Index,Customer Id,First Name,Last Name,Company,City,Country,Phone 1,Phone 2,Email,Subscription Date,Website
|
||||
1,50ddd99fAdF48B3,Jessica,Navarro,"Tran, Odom and Graham",Port Terranceview,Jersey,(883)287-7947,479-044-3187,wmcintyre@myers.net,2023-03-11,http://pennington.com/
|
||||
2,BD1AB97979DDcDe,Preston,Andrews,"Townsend, Lawrence and Davenport",Harringtonmouth,Croatia,188-270-5676x63873,001-428-148-4270,bradley63@jacobs.net,2023-11-15,http://burke.com/
|
||||
3,0FDDD9aCa501acE,Melissa,Mckay,Rivas-Cooke,Oliviabury,Cook Islands,8257631531,001-650-689-5600x927,ugalloway@maxwell-mcclain.com,2025-01-25,https://patrick.com/
|
||||
4,A7dA284B7c4AfaD,Frank,Livingston,"Lambert, Garner and Mathews",Mallorytown,Faroe Islands,766.182.6201x689,+1-476-912-2027x4370,tracie00@webster.biz,2021-03-27,https://www.hart.com/
|
||||
5,38bb1624e4f8211,Ross,Mendoza,Cook and Sons,New Perry,Bolivia,001-440-468-2236,165.562.4328x9274,austincarmen@abbott.com,2024-12-12,http://harmon.com/
|
||||
6,55c9Fda2BABFE1a,Jane,Tate,Knapp PLC,West Kathyshire,Morocco,001-606-447-0584x07975,(003)872-1307x285,carlosgomez@mcpherson-ramos.biz,2021-09-13,http://www.yu.com/
|
||||
7,A15eccAc67cCc5b,Tanya,Chung,Frost Inc,South Julieburgh,United States of America,778-360-8301x268,+1-034-169-4237,onewton@crosby.com,2024-10-01,http://www.gill-velez.biz/
|
||||
8,aFdab04acACaf90,Jackson,Moyer,Bowen Ltd,Port Triciabury,Bahrain,001-187-882-2891x169,154.903.2525,gabriela16@mejia.org,2023-06-20,http://www.david.biz/
|
||||
9,A2EaeAd3c6529B9,Kelly,Douglas,Phillips PLC,Weissberg,Qatar,767.177.3199x5576,5156730935,wigginsmercedes@tanner.com,2021-06-30,https://gonzalez.net/
|
||||
10,188175A5641d080,Mariah,Riddle,"Mata, Fuller and Good",Choiton,Namibia,092-993-3559x342,190.937.3937,eileen32@greer.biz,2021-04-17,http://www.bowen.info/
|
||||
11,B2BA817C7bC09f0,Kristine,Pennington,"Koch, Diaz and Valdez",Port Rachael,Suriname,877.152.6488x921,790-804-9979x3290,tonya00@flynn.com,2024-03-28,https://www.rocha.net/
|
||||
12,fFAD70B5Febc43a,Robert,Adams,Bender-Wolfe,Billfort,Tanzania,219-696-1912x93626,518-969-4058,jeffersoncolton@moss-ashley.com,2022-07-31,https://www.alvarez.com/
|
||||
13,9a44524E1261Ed6,Franklin,Costa,Werner Group,North Bradley,Cook Islands,(895)448-4681x1999,648-345-3083x88242,marksmith@novak.com,2024-12-03,http://thornton.com/
|
||||
14,0C360EfE17D06cc,Dan,Ballard,Sampson-Huff,Michaelchester,Sao Tome and Principe,+1-803-469-5237x2580,(729)574-6101x0605,molly54@acevedo.info,2022-10-24,https://www.sloan-gonzales.biz/
|
||||
15,fb5cE8cb1eF2954,Clifford,Moyer,Fry-Whitehead,Lake Gary,Japan,(504)263-0450,247.514.1614x551,rhonda34@orr.com,2020-03-08,https://norton.com/
|
||||
16,3e53DcaD1cB0054,Tonya,Durham,"Lowe, West and Reynolds",South Sylviaton,Brunei Darussalam,(613)893-8183,(461)399-6120,kiara96@meadows.biz,2022-08-04,https://www.reeves.com/
|
||||
17,83fDDE5812EbEde,Dale,Bishop,Shaw-Ray,Lake Miranda,Congo,(082)202-9241,+1-413-610-1854x79378,bhoward@hodges.biz,2023-05-08,http://www.escobar.com/
|
||||
18,8dB7ACe2C5758cE,Priscilla,Mills,Pope PLC,North Cliffordshire,South Georgia and the South Sandwich Islands,+1-465-802-4573x30191,044-393-6049x598,nathaniel28@hess.com,2020-09-08,https://www.watts.org/
|
||||
19,c1092ebDaF2ceED,Alice,Bond,Chan-Liu,West Wesley,Lithuania,+1-333-285-8515,(715)759-3158x77103,jose92@peters.com,2024-05-30,http://www.marquez.com/
|
||||
20,4d0c95579D095aF,Cole,Compton,Calderon PLC,Robertaville,Saudi Arabia,029.862.3387x470,001-319-474-2394,sspence@dorsey.com,2020-08-02,http://hamilton.net/
|
||||
|
@@ -42,3 +42,11 @@ beforeEach(() => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Cypress.Screenshot.defaults({
|
||||
// onBeforeScreenshot() {
|
||||
// if (window.Chart) {
|
||||
// Object.values(window.Chart.instances).forEach(c => c.resize());
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{"__isStreamHeader":true,"pureName":"departments","schemaName":"dbo","objectId":1205579333,"createDate":"2025-06-12T10:30:34.083Z","modifyDate":"2025-06-12T10:30:34.120Z","contentHash":"2025-06-12T10:30:34.120Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__departme__3213E83FE8E7043D","schemaName":"dbo","pureName":"departments","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"IT"}
|
||||
{"id":2,"name":"Marketing"}
|
||||
{"id":3,"name":"Finance"}
|
||||
{"id":4,"name":"Human Resources"}
|
||||
{"id":5,"name":"Research and Development"}
|
||||
@@ -0,0 +1,12 @@
|
||||
name: departments
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- id
|
||||
@@ -0,0 +1,39 @@
|
||||
{"__isStreamHeader":true,"pureName":"employee_project","schemaName":"dbo","objectId":1333579789,"createDate":"2025-06-12T10:30:34.133Z","modifyDate":"2025-06-12T10:30:34.133Z","contentHash":"2025-06-12T10:30:34.133Z","columns":[{"columnName":"employee_id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"project_id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"role","dataType":"varchar(50)","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__employee__2EE9924949ED9668","schemaName":"dbo","pureName":"employee_project","constraintType":"primaryKey","columns":[{"columnName":"employee_id"},{"columnName":"project_id"}]},"foreignKeys":[{"constraintName":"FK__employee___emplo__5165187F","constraintType":"foreignKey","schemaName":"dbo","pureName":"employee_project","refSchemaName":"dbo","refTableName":"employees","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"employee_id","refColumnName":"id"}]},{"constraintName":"FK__employee___proje__52593CB8","constraintType":"foreignKey","schemaName":"dbo","pureName":"employee_project","refSchemaName":"dbo","refTableName":"projects","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"project_id","refColumnName":"id"}]}],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"employee_id":1,"project_id":6,"role":"Manager"}
|
||||
{"employee_id":1,"project_id":8,"role":"Developer"}
|
||||
{"employee_id":2,"project_id":7,"role":"Tester"}
|
||||
{"employee_id":2,"project_id":8,"role":"Developer"}
|
||||
{"employee_id":3,"project_id":4,"role":"Analyst"}
|
||||
{"employee_id":3,"project_id":6,"role":"Developer"}
|
||||
{"employee_id":4,"project_id":2,"role":"Manager"}
|
||||
{"employee_id":4,"project_id":4,"role":"Analyst"}
|
||||
{"employee_id":4,"project_id":5,"role":"Analyst"}
|
||||
{"employee_id":5,"project_id":5,"role":"Tester"}
|
||||
{"employee_id":6,"project_id":1,"role":"Analyst"}
|
||||
{"employee_id":6,"project_id":6,"role":"Tester"}
|
||||
{"employee_id":6,"project_id":9,"role":"Manager"}
|
||||
{"employee_id":7,"project_id":8,"role":"Manager"}
|
||||
{"employee_id":8,"project_id":10,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":2,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":7,"role":"Developer"}
|
||||
{"employee_id":10,"project_id":2,"role":"Manager"}
|
||||
{"employee_id":10,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":11,"project_id":1,"role":"Tester"}
|
||||
{"employee_id":12,"project_id":4,"role":"Tester"}
|
||||
{"employee_id":13,"project_id":2,"role":"Developer"}
|
||||
{"employee_id":13,"project_id":3,"role":"Analyst"}
|
||||
{"employee_id":13,"project_id":7,"role":"Developer"}
|
||||
{"employee_id":14,"project_id":3,"role":"Developer"}
|
||||
{"employee_id":14,"project_id":9,"role":"Manager"}
|
||||
{"employee_id":15,"project_id":1,"role":"Developer"}
|
||||
{"employee_id":15,"project_id":5,"role":"Manager"}
|
||||
{"employee_id":16,"project_id":3,"role":"Tester"}
|
||||
{"employee_id":16,"project_id":5,"role":"Developer"}
|
||||
{"employee_id":17,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":18,"project_id":1,"role":"Tester"}
|
||||
{"employee_id":18,"project_id":5,"role":"Tester"}
|
||||
{"employee_id":18,"project_id":6,"role":"Manager"}
|
||||
{"employee_id":19,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":20,"project_id":2,"role":"Developer"}
|
||||
{"employee_id":20,"project_id":4,"role":"Developer"}
|
||||
@@ -0,0 +1,18 @@
|
||||
name: employee_project
|
||||
columns:
|
||||
- name: employee_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: employees
|
||||
- name: project_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: projects
|
||||
- name: role
|
||||
type: varchar(50)
|
||||
default: null
|
||||
primaryKey:
|
||||
- employee_id
|
||||
- project_id
|
||||
@@ -0,0 +1,21 @@
|
||||
{"__isStreamHeader":true,"pureName":"employees","schemaName":"dbo","objectId":1237579447,"createDate":"2025-06-12T10:30:34.113Z","modifyDate":"2025-06-12T12:35:22.140Z","contentHash":"2025-06-12T12:35:22.140Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"email","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"hire_date","dataType":"date","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"department_id","dataType":"int","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__employee__3213E83FE576E55A","schemaName":"dbo","pureName":"employees","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[{"constraintName":"FK__employees__depar__4CA06362","constraintType":"foreignKey","schemaName":"dbo","pureName":"employees","refSchemaName":"dbo","refTableName":"departments","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"department_id","refColumnName":"id"}]}],"indexes":[],"uniques":[{"constraintName":"UQ__employee__AB6E6164E18D883F","columns":[{"columnName":"email"}]}],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"John Smith","email":"john.smith@example.com","hire_date":"2018-07-09T00:00:00.000Z","department_id":2}
|
||||
{"id":2,"name":"Jane Garcia","email":"jane.garcia@example.com","hire_date":"2019-10-13T00:00:00.000Z","department_id":5}
|
||||
{"id":3,"name":"Grace Smith","email":"grace.smith@example.com","hire_date":"2019-03-16T00:00:00.000Z","department_id":1}
|
||||
{"id":4,"name":"Charlie Williams","email":"charlie.williams@example.com","hire_date":"2020-10-18T00:00:00.000Z","department_id":2}
|
||||
{"id":5,"name":"Eve Brown","email":"eve.brown@example.com","hire_date":"2018-04-12T00:00:00.000Z","department_id":4}
|
||||
{"id":6,"name":"Alice Moore","email":"alice.moore@example.com","hire_date":"2019-04-20T00:00:00.000Z","department_id":2}
|
||||
{"id":7,"name":"Eve Williams","email":"eve.williams@example.com","hire_date":"2020-04-26T00:00:00.000Z","department_id":4}
|
||||
{"id":8,"name":"Eve Jones","email":"eve.jones@example.com","hire_date":"2022-10-04T00:00:00.000Z","department_id":3}
|
||||
{"id":9,"name":"Diana Miller","email":"diana.miller@example.com","hire_date":"2021-03-28T00:00:00.000Z","department_id":1}
|
||||
{"id":10,"name":"Diana Smith","email":"diana.smith@example.com","hire_date":"2018-04-12T00:00:00.000Z","department_id":2}
|
||||
{"id":11,"name":"Hank Johnson","email":"hank.johnson@example.com","hire_date":"2020-09-16T00:00:00.000Z","department_id":2}
|
||||
{"id":12,"name":"Frank Miller","email":"frank.miller@example.com","hire_date":"2023-01-12T00:00:00.000Z","department_id":4}
|
||||
{"id":13,"name":"Jane Brown","email":"jane.brown@example.com","hire_date":"2023-05-07T00:00:00.000Z","department_id":3}
|
||||
{"id":14,"name":"Grace Davis","email":"grace.davis@example.com","hire_date":"2019-08-22T00:00:00.000Z","department_id":3}
|
||||
{"id":15,"name":"Jane Black","email":"jane.black@example.com","hire_date":"2019-04-28T00:00:00.000Z","department_id":2}
|
||||
{"id":16,"name":"Charlie Smith","email":"charlie.smith@example.com","hire_date":"2019-06-12T00:00:00.000Z","department_id":5}
|
||||
{"id":17,"name":"Eve Johnson","email":"eve.johnson@example.com","hire_date":"2020-11-07T00:00:00.000Z","department_id":5}
|
||||
{"id":18,"name":"Jane Johnson","email":"jane.johnson@example.com","hire_date":"2020-04-06T00:00:00.000Z","department_id":2}
|
||||
{"id":19,"name":"Hank Brown","email":"hank.brown@example.com","hire_date":"2023-05-10T00:00:00.000Z","department_id":2}
|
||||
{"id":20,"name":"Frank Jones","email":"frank.jones@example.com","hire_date":"2020-10-26T00:00:00.000Z","department_id":1}
|
||||
@@ -0,0 +1,28 @@
|
||||
name: employees
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: email
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: hire_date
|
||||
type: date
|
||||
default: null
|
||||
notNull: true
|
||||
- name: department_id
|
||||
type: int
|
||||
default: null
|
||||
references: departments
|
||||
primaryKey:
|
||||
- id
|
||||
uniques:
|
||||
- name: UQ__employee__AB6E6164E18D883F
|
||||
columns:
|
||||
- email
|
||||
@@ -0,0 +1,141 @@
|
||||
{"__isStreamHeader":true,"pureName":"finance_reports","schemaName":"dbo","objectId":338100245,"createDate":"2025-06-23T12:15:08.727Z","modifyDate":"2025-06-23T12:15:08.750Z","contentHash":"2025-06-23T12:15:08.750Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"date","dataType":"date","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"profit","dataType":"money","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"foreignKeys":[{"constraintName":"project_id","constraintType":"foreignKey","schemaName":"dbo","pureName":"finance_reports","refSchemaName":"dbo","refTableName":"projects","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"id","refColumnName":"id"}]}],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"date":"2022-01-01T00:00:00.000Z","profit":73923.4}
|
||||
{"id":1,"date":"2022-01-31T00:00:00.000Z","profit":21837.75}
|
||||
{"id":1,"date":"2022-03-02T00:00:00.000Z","profit":67859.8}
|
||||
{"id":1,"date":"2022-04-01T00:00:00.000Z","profit":77403.3}
|
||||
{"id":1,"date":"2022-05-01T00:00:00.000Z","profit":84083.19}
|
||||
{"id":1,"date":"2022-05-31T00:00:00.000Z","profit":30040.55}
|
||||
{"id":1,"date":"2022-06-30T00:00:00.000Z","profit":50947.14}
|
||||
{"id":1,"date":"2022-07-30T00:00:00.000Z","profit":63345.62}
|
||||
{"id":1,"date":"2022-08-29T00:00:00.000Z","profit":23819.45}
|
||||
{"id":1,"date":"2022-09-28T00:00:00.000Z","profit":-25919.19}
|
||||
{"id":1,"date":"2022-10-28T00:00:00.000Z","profit":27967.6}
|
||||
{"id":1,"date":"2022-11-27T00:00:00.000Z","profit":-37402.36}
|
||||
{"id":1,"date":"2022-12-27T00:00:00.000Z","profit":94528.8}
|
||||
{"id":1,"date":"2023-01-26T00:00:00.000Z","profit":29491.03}
|
||||
{"id":1,"date":"2023-02-25T00:00:00.000Z","profit":81541.29}
|
||||
{"id":2,"date":"2022-01-01T00:00:00.000Z","profit":18070.94}
|
||||
{"id":2,"date":"2022-01-31T00:00:00.000Z","profit":-40609.87}
|
||||
{"id":2,"date":"2022-03-02T00:00:00.000Z","profit":42435.51}
|
||||
{"id":2,"date":"2022-04-01T00:00:00.000Z","profit":-11915.15}
|
||||
{"id":2,"date":"2022-05-01T00:00:00.000Z","profit":-37417.4}
|
||||
{"id":2,"date":"2022-05-31T00:00:00.000Z","profit":23028.66}
|
||||
{"id":2,"date":"2022-06-30T00:00:00.000Z","profit":-6895.49}
|
||||
{"id":2,"date":"2022-07-30T00:00:00.000Z","profit":63114.54}
|
||||
{"id":2,"date":"2022-08-29T00:00:00.000Z","profit":94646.99}
|
||||
{"id":2,"date":"2022-09-28T00:00:00.000Z","profit":99560.77}
|
||||
{"id":2,"date":"2022-10-28T00:00:00.000Z","profit":62216.22}
|
||||
{"id":2,"date":"2022-11-27T00:00:00.000Z","profit":85094.32}
|
||||
{"id":2,"date":"2022-12-27T00:00:00.000Z","profit":-23378.37}
|
||||
{"id":2,"date":"2023-01-26T00:00:00.000Z","profit":47635.86}
|
||||
{"id":2,"date":"2023-02-25T00:00:00.000Z","profit":33727.72}
|
||||
{"id":3,"date":"2022-01-01T00:00:00.000Z","profit":33088.03}
|
||||
{"id":3,"date":"2022-01-31T00:00:00.000Z","profit":66668.91}
|
||||
{"id":3,"date":"2022-03-02T00:00:00.000Z","profit":5344.27}
|
||||
{"id":3,"date":"2022-04-01T00:00:00.000Z","profit":22122.99}
|
||||
{"id":3,"date":"2022-05-01T00:00:00.000Z","profit":27342.01}
|
||||
{"id":3,"date":"2022-05-31T00:00:00.000Z","profit":55479.42}
|
||||
{"id":3,"date":"2022-06-30T00:00:00.000Z","profit":35956.11}
|
||||
{"id":3,"date":"2022-07-30T00:00:00.000Z","profit":9667.12}
|
||||
{"id":3,"date":"2022-08-29T00:00:00.000Z","profit":63430.18}
|
||||
{"id":3,"date":"2022-09-28T00:00:00.000Z","profit":-4883.41}
|
||||
{"id":3,"date":"2022-10-28T00:00:00.000Z","profit":38902.8}
|
||||
{"id":3,"date":"2022-11-27T00:00:00.000Z","profit":-25500.13}
|
||||
{"id":3,"date":"2022-12-27T00:00:00.000Z","profit":65074.21}
|
||||
{"id":3,"date":"2023-01-26T00:00:00.000Z","profit":12570.27}
|
||||
{"id":3,"date":"2023-02-25T00:00:00.000Z","profit":35418.36}
|
||||
{"id":4,"date":"2022-01-01T00:00:00.000Z","profit":68282.98}
|
||||
{"id":4,"date":"2022-01-31T00:00:00.000Z","profit":77778.99}
|
||||
{"id":4,"date":"2022-03-02T00:00:00.000Z","profit":95490.49}
|
||||
{"id":4,"date":"2022-04-01T00:00:00.000Z","profit":-44466.37}
|
||||
{"id":4,"date":"2022-05-01T00:00:00.000Z","profit":40215.71}
|
||||
{"id":4,"date":"2022-05-31T00:00:00.000Z","profit":-31228.87}
|
||||
{"id":4,"date":"2022-06-30T00:00:00.000Z","profit":60667.69}
|
||||
{"id":4,"date":"2022-07-30T00:00:00.000Z","profit":71439.16}
|
||||
{"id":4,"date":"2022-08-29T00:00:00.000Z","profit":-25077.4}
|
||||
{"id":4,"date":"2022-09-28T00:00:00.000Z","profit":-36128.2}
|
||||
{"id":4,"date":"2022-10-28T00:00:00.000Z","profit":36727.68}
|
||||
{"id":4,"date":"2022-11-27T00:00:00.000Z","profit":-24207.2}
|
||||
{"id":4,"date":"2022-12-27T00:00:00.000Z","profit":63846.96}
|
||||
{"id":5,"date":"2022-01-01T00:00:00.000Z","profit":21648.3}
|
||||
{"id":5,"date":"2022-01-31T00:00:00.000Z","profit":59263.22}
|
||||
{"id":5,"date":"2022-03-02T00:00:00.000Z","profit":49154.51}
|
||||
{"id":5,"date":"2022-04-01T00:00:00.000Z","profit":34787.48}
|
||||
{"id":5,"date":"2022-05-01T00:00:00.000Z","profit":-24120.19}
|
||||
{"id":5,"date":"2022-05-31T00:00:00.000Z","profit":98437.86}
|
||||
{"id":5,"date":"2022-06-30T00:00:00.000Z","profit":18614.77}
|
||||
{"id":5,"date":"2022-07-30T00:00:00.000Z","profit":17680.34}
|
||||
{"id":5,"date":"2022-08-29T00:00:00.000Z","profit":74406.86}
|
||||
{"id":5,"date":"2022-09-28T00:00:00.000Z","profit":61845.3}
|
||||
{"id":5,"date":"2022-10-28T00:00:00.000Z","profit":-37889.59}
|
||||
{"id":5,"date":"2022-11-27T00:00:00.000Z","profit":76651.05}
|
||||
{"id":5,"date":"2022-12-27T00:00:00.000Z","profit":58739.6}
|
||||
{"id":5,"date":"2023-01-26T00:00:00.000Z","profit":82605.85}
|
||||
{"id":6,"date":"2022-01-01T00:00:00.000Z","profit":-5206.8}
|
||||
{"id":6,"date":"2022-01-31T00:00:00.000Z","profit":27498.27}
|
||||
{"id":6,"date":"2022-03-02T00:00:00.000Z","profit":-2939.84}
|
||||
{"id":6,"date":"2022-04-01T00:00:00.000Z","profit":-37261.08}
|
||||
{"id":6,"date":"2022-05-01T00:00:00.000Z","profit":37069.04}
|
||||
{"id":6,"date":"2022-05-31T00:00:00.000Z","profit":524.88}
|
||||
{"id":6,"date":"2022-06-30T00:00:00.000Z","profit":-29620.85}
|
||||
{"id":6,"date":"2022-07-30T00:00:00.000Z","profit":35540.81}
|
||||
{"id":6,"date":"2022-08-29T00:00:00.000Z","profit":20608.94}
|
||||
{"id":6,"date":"2022-09-28T00:00:00.000Z","profit":34809.33}
|
||||
{"id":6,"date":"2022-10-28T00:00:00.000Z","profit":-44949.05}
|
||||
{"id":6,"date":"2022-11-27T00:00:00.000Z","profit":-22524.26}
|
||||
{"id":6,"date":"2022-12-27T00:00:00.000Z","profit":37841.58}
|
||||
{"id":7,"date":"2022-01-01T00:00:00.000Z","profit":6903.17}
|
||||
{"id":7,"date":"2022-01-31T00:00:00.000Z","profit":58480.84}
|
||||
{"id":7,"date":"2022-03-02T00:00:00.000Z","profit":48217.34}
|
||||
{"id":7,"date":"2022-04-01T00:00:00.000Z","profit":73592.44}
|
||||
{"id":7,"date":"2022-05-01T00:00:00.000Z","profit":-21831.18}
|
||||
{"id":7,"date":"2022-05-31T00:00:00.000Z","profit":-40926.16}
|
||||
{"id":7,"date":"2022-06-30T00:00:00.000Z","profit":62299.5}
|
||||
{"id":7,"date":"2022-07-30T00:00:00.000Z","profit":95376.53}
|
||||
{"id":7,"date":"2022-08-29T00:00:00.000Z","profit":-13317.36}
|
||||
{"id":7,"date":"2022-09-28T00:00:00.000Z","profit":81565.05}
|
||||
{"id":7,"date":"2022-10-28T00:00:00.000Z","profit":77420.52}
|
||||
{"id":7,"date":"2022-11-27T00:00:00.000Z","profit":-12052.47}
|
||||
{"id":7,"date":"2022-12-27T00:00:00.000Z","profit":37742.07}
|
||||
{"id":7,"date":"2023-01-26T00:00:00.000Z","profit":-8057.99}
|
||||
{"id":8,"date":"2022-01-01T00:00:00.000Z","profit":27213.73}
|
||||
{"id":8,"date":"2022-01-31T00:00:00.000Z","profit":34271.75}
|
||||
{"id":8,"date":"2022-03-02T00:00:00.000Z","profit":-44549.47}
|
||||
{"id":8,"date":"2022-04-01T00:00:00.000Z","profit":15236.34}
|
||||
{"id":8,"date":"2022-05-01T00:00:00.000Z","profit":-27759.81}
|
||||
{"id":8,"date":"2022-05-31T00:00:00.000Z","profit":7955.12}
|
||||
{"id":8,"date":"2022-06-30T00:00:00.000Z","profit":-34484.38}
|
||||
{"id":8,"date":"2022-07-30T00:00:00.000Z","profit":-49758.7}
|
||||
{"id":8,"date":"2022-08-29T00:00:00.000Z","profit":-41990.86}
|
||||
{"id":8,"date":"2022-09-28T00:00:00.000Z","profit":58123.01}
|
||||
{"id":8,"date":"2022-10-28T00:00:00.000Z","profit":30128.78}
|
||||
{"id":8,"date":"2022-11-27T00:00:00.000Z","profit":-10151.17}
|
||||
{"id":8,"date":"2022-12-27T00:00:00.000Z","profit":54048.33}
|
||||
{"id":8,"date":"2023-01-26T00:00:00.000Z","profit":-43123.17}
|
||||
{"id":9,"date":"2022-01-01T00:00:00.000Z","profit":61031.83}
|
||||
{"id":9,"date":"2022-01-31T00:00:00.000Z","profit":68577.58}
|
||||
{"id":9,"date":"2022-03-02T00:00:00.000Z","profit":88698.97}
|
||||
{"id":9,"date":"2022-04-01T00:00:00.000Z","profit":8906.03}
|
||||
{"id":9,"date":"2022-05-01T00:00:00.000Z","profit":28824.73}
|
||||
{"id":9,"date":"2022-05-31T00:00:00.000Z","profit":88280.34}
|
||||
{"id":9,"date":"2022-06-30T00:00:00.000Z","profit":35266.09}
|
||||
{"id":9,"date":"2022-07-30T00:00:00.000Z","profit":-38025.36}
|
||||
{"id":9,"date":"2022-08-29T00:00:00.000Z","profit":-12118.53}
|
||||
{"id":9,"date":"2022-09-28T00:00:00.000Z","profit":-27265.86}
|
||||
{"id":9,"date":"2022-10-28T00:00:00.000Z","profit":56870.57}
|
||||
{"id":9,"date":"2022-11-27T00:00:00.000Z","profit":88078.95}
|
||||
{"id":9,"date":"2022-12-27T00:00:00.000Z","profit":-24059.67}
|
||||
{"id":9,"date":"2023-01-26T00:00:00.000Z","profit":-13301.43}
|
||||
{"id":10,"date":"2022-01-01T00:00:00.000Z","profit":-22479.23}
|
||||
{"id":10,"date":"2022-01-31T00:00:00.000Z","profit":8106.27}
|
||||
{"id":10,"date":"2022-03-02T00:00:00.000Z","profit":69372.19}
|
||||
{"id":10,"date":"2022-04-01T00:00:00.000Z","profit":-11895.74}
|
||||
{"id":10,"date":"2022-05-01T00:00:00.000Z","profit":-33206.5}
|
||||
{"id":10,"date":"2022-05-31T00:00:00.000Z","profit":56073.34}
|
||||
{"id":10,"date":"2022-06-30T00:00:00.000Z","profit":67488.3}
|
||||
{"id":10,"date":"2022-07-30T00:00:00.000Z","profit":48529.23}
|
||||
{"id":10,"date":"2022-08-29T00:00:00.000Z","profit":28680.2}
|
||||
{"id":10,"date":"2022-09-28T00:00:00.000Z","profit":59311.16}
|
||||
{"id":10,"date":"2022-10-28T00:00:00.000Z","profit":25315.78}
|
||||
{"id":10,"date":"2022-11-27T00:00:00.000Z","profit":36116.38}
|
||||
{"id":10,"date":"2022-12-27T00:00:00.000Z","profit":-42040.4}
|
||||
@@ -0,0 +1,15 @@
|
||||
name: finance_reports
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: projects
|
||||
- name: date
|
||||
type: date
|
||||
default: null
|
||||
notNull: true
|
||||
- name: profit
|
||||
type: money
|
||||
default: null
|
||||
notNull: true
|
||||
@@ -0,0 +1,11 @@
|
||||
{"__isStreamHeader":true,"pureName":"projects","schemaName":"dbo","objectId":1301579675,"createDate":"2025-06-12T10:30:34.127Z","modifyDate":"2025-06-23T12:15:08.750Z","contentHash":"2025-06-23T12:15:08.750Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"start_date","dataType":"date","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"end_date","dataType":"date","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__projects__3213E83F26A7ED11","schemaName":"dbo","pureName":"projects","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"Apollo Upgrade","start_date":"2020-04-27T00:00:00.000Z","end_date":"2020-10-19T00:00:00.000Z"}
|
||||
{"id":2,"name":"Market Expansion","start_date":"2022-08-04T00:00:00.000Z","end_date":"2023-06-20T00:00:00.000Z"}
|
||||
{"id":3,"name":"AI Integration","start_date":"2020-05-11T00:00:00.000Z","end_date":"2021-07-10T00:00:00.000Z"}
|
||||
{"id":4,"name":"Cost Reduction","start_date":"2022-01-08T00:00:00.000Z","end_date":"2022-07-12T00:00:00.000Z"}
|
||||
{"id":5,"name":"Cloud Migration","start_date":"2021-01-11T00:00:00.000Z","end_date":"2021-05-27T00:00:00.000Z"}
|
||||
{"id":6,"name":"Customer Portal","start_date":"2021-07-13T00:00:00.000Z","end_date":"2022-09-22T00:00:00.000Z"}
|
||||
{"id":7,"name":"Data Lake","start_date":"2021-02-25T00:00:00.000Z","end_date":"2021-08-21T00:00:00.000Z"}
|
||||
{"id":8,"name":"UX Overhaul","start_date":"2021-05-20T00:00:00.000Z","end_date":"2022-09-10T00:00:00.000Z"}
|
||||
{"id":9,"name":"Security Hardening","start_date":"2021-05-28T00:00:00.000Z","end_date":"2022-07-28T00:00:00.000Z"}
|
||||
{"id":10,"name":"Mobile App Revamp","start_date":"2021-11-17T00:00:00.000Z","end_date":"2022-06-04T00:00:00.000Z"}
|
||||
@@ -0,0 +1,18 @@
|
||||
name: projects
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: start_date
|
||||
type: date
|
||||
default: null
|
||||
- name: end_date
|
||||
type: date
|
||||
default: null
|
||||
primaryKey:
|
||||
- id
|
||||
@@ -0,0 +1,23 @@
|
||||
-- >>>
|
||||
-- autoExecute: true
|
||||
-- splitterInitialValue: 20%
|
||||
-- selected-chart: 1
|
||||
-- <<<
|
||||
|
||||
SELECT
|
||||
d.name AS department_name,
|
||||
FORMAT(fr.date, 'yyyy-MM') AS month,
|
||||
SUM(fr.profit) AS total_monthly_profit
|
||||
FROM
|
||||
departments d
|
||||
JOIN
|
||||
employees e ON d.id = e.department_id
|
||||
JOIN
|
||||
employee_project ep ON e.id = ep.employee_id
|
||||
JOIN
|
||||
finance_reports fr ON ep.project_id = fr.id
|
||||
GROUP BY
|
||||
d.name, FORMAT(fr.date, 'yyyy-MM')
|
||||
ORDER BY
|
||||
d.name, month;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{"__isStreamHeader":true,"pureName":"addresses","tableRowCount":"12","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"addresses","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"line1","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"line2","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"city","columnComment":"","dataType":"varchar(40)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"state","columnComment":"","dataType":"varchar(2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"zip_code","columnComment":"","dataType":"varchar(10)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"phone","columnComment":"","dataType":"varchar(12)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"disabled","columnComment":"","dataType":"tinyint","defaultValue":"0","isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"addresses","constraintType":"primaryKey","columns":[{"columnName":"address_id"}]},"foreignKeys":[{"constraintName":"addresses_fk_customers","constraintType":"foreignKey","pureName":"addresses","refTableName":"customers","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"customer_id","refColumnName":"customer_id"}]}],"indexes":[{"constraintName":"addresses_fk_customers","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"customer_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"address_id":1,"customer_id":1,"line1":"100 East Ridgewood Ave.","line2":"","city":"Paramus","state":"NJ","zip_code":"07652","phone":"201-653-4472","disabled":0}
|
||||
{"address_id":2,"customer_id":1,"line1":"21 Rosewood Rd.","line2":"","city":"Woodcliff Lake","state":"NJ","zip_code":"07677","phone":"201-653-4472","disabled":0}
|
||||
{"address_id":3,"customer_id":2,"line1":"16285 Wendell St.","line2":"","city":"Omaha","state":"NE","zip_code":"68135","phone":"402-896-2576","disabled":0}
|
||||
{"address_id":4,"customer_id":3,"line1":"19270 NW Cornell Rd.","line2":"","city":"Beaverton","state":"OR","zip_code":"97006","phone":"503-654-1291","disabled":0}
|
||||
{"address_id":5,"customer_id":4,"line1":"186 Vermont St.","line2":"Apt. 2","city":"San Francisco","state":"CA","zip_code":"94110","phone":"415-292-6651","disabled":0}
|
||||
{"address_id":6,"customer_id":4,"line1":"1374 46th Ave.","line2":"","city":"San Francisco","state":"CA","zip_code":"94129","phone":"415-292-6651","disabled":0}
|
||||
{"address_id":7,"customer_id":5,"line1":"6982 Palm Ave.","line2":"","city":"Fresno","state":"CA","zip_code":"93711","phone":"559-431-2398","disabled":0}
|
||||
{"address_id":8,"customer_id":6,"line1":"23 Mountain View St.","line2":"","city":"Denver","state":"CO","zip_code":"80208","phone":"303-912-3852","disabled":0}
|
||||
{"address_id":9,"customer_id":7,"line1":"7361 N. 41st St.","line2":"Apt. B","city":"New York","state":"NY","zip_code":"10012","phone":"212-335-2093","disabled":0}
|
||||
{"address_id":10,"customer_id":7,"line1":"3829 Broadway Ave.","line2":"Suite 2","city":"New York","state":"NY","zip_code":"10012","phone":"212-239-1208","disabled":0}
|
||||
{"address_id":11,"customer_id":8,"line1":"2381 Buena Vista St.","line2":"","city":"Los Angeles","state":"CA","zip_code":"90023","phone":"213-772-5033","disabled":0}
|
||||
{"address_id":12,"customer_id":8,"line1":"291 W. Hollywood Blvd.","line2":"","city":"Los Angeles","state":"CA","zip_code":"90024","phone":"213-391-2938","disabled":0}
|
||||
@@ -0,0 +1,46 @@
|
||||
name: addresses
|
||||
columns:
|
||||
- name: address_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: customers
|
||||
- name: line1
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: line2
|
||||
type: varchar(60)
|
||||
default: null
|
||||
- name: city
|
||||
type: varchar(40)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: state
|
||||
type: varchar(2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: zip_code
|
||||
type: varchar(10)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: phone
|
||||
type: varchar(12)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: disabled
|
||||
type: int
|
||||
default: 0
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- address_id
|
||||
indexes:
|
||||
- name: addresses_fk_customers
|
||||
unique: false
|
||||
columns:
|
||||
- customer_id
|
||||
@@ -0,0 +1,4 @@
|
||||
{"__isStreamHeader":true,"pureName":"administrators","tableRowCount":"3","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:33","objectId":"administrators","contentHash":"2025-02-03 02:56:33","columns":[{"notNull":true,"autoIncrement":true,"columnName":"admin_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"email_address","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"password","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"first_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"last_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"administrators","constraintType":"primaryKey","columns":[{"columnName":"admin_id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"admin_id":1,"email_address":"admin@myguitarshop.com","password":"6a718fbd768c2378b511f8249b54897f940e9022","first_name":"Admin","last_name":"User"}
|
||||
{"admin_id":2,"email_address":"joel@murach.com","password":"971e95957d3b74d70d79c20c94e9cd91b85f7aae","first_name":"Joel","last_name":"Murach"}
|
||||
{"admin_id":3,"email_address":"mike@murach.com","password":"3f2975c819cefc686282456aeae3a137bf896ee8","first_name":"Mike","last_name":"Murach"}
|
||||
@@ -0,0 +1,25 @@
|
||||
name: administrators
|
||||
columns:
|
||||
- name: admin_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: email_address
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: password
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: first_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: last_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- admin_id
|
||||
@@ -0,0 +1,5 @@
|
||||
{"__isStreamHeader":true,"pureName":"categories","tableRowCount":"4","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"categories","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"category_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"category_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"categories","constraintType":"primaryKey","columns":[{"columnName":"category_id"}]},"foreignKeys":[],"indexes":[],"uniques":[{"constraintName":"category_name","columns":[{"columnName":"category_name"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"category_id":2,"category_name":"Basses"}
|
||||
{"category_id":3,"category_name":"Drums"}
|
||||
{"category_id":1,"category_name":"Guitars"}
|
||||
{"category_id":4,"category_name":"Keyboards"}
|
||||
@@ -0,0 +1,12 @@
|
||||
name: categories
|
||||
columns:
|
||||
- name: category_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: category_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- category_id
|
||||
@@ -0,0 +1,9 @@
|
||||
{"__isStreamHeader":true,"pureName":"customers","tableRowCount":"8","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"customers","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"email_address","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"password","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"first_name","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"last_name","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"shipping_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"billing_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"customers","constraintType":"primaryKey","columns":[{"columnName":"customer_id"}]},"foreignKeys":[],"indexes":[],"uniques":[{"constraintName":"email_address","columns":[{"columnName":"email_address"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"customer_id":1,"email_address":"allan.sherwood@yahoo.com","password":"650215acec746f0e32bdfff387439eefc1358737","first_name":"Allan","last_name":"Sherwood","shipping_address_id":1,"billing_address_id":2}
|
||||
{"customer_id":2,"email_address":"barryz@gmail.com","password":"3f563468d42a448cb1e56924529f6e7bbe529cc7","first_name":"Barry","last_name":"Zimmer","shipping_address_id":3,"billing_address_id":3}
|
||||
{"customer_id":3,"email_address":"christineb@solarone.com","password":"ed19f5c0833094026a2f1e9e6f08a35d26037066","first_name":"Christine","last_name":"Brown","shipping_address_id":4,"billing_address_id":4}
|
||||
{"customer_id":4,"email_address":"david.goldstein@hotmail.com","password":"b444ac06613fc8d63795be9ad0beaf55011936ac","first_name":"David","last_name":"Goldstein","shipping_address_id":5,"billing_address_id":6}
|
||||
{"customer_id":5,"email_address":"erinv@gmail.com","password":"109f4b3c50d7b0df729d299bc6f8e9ef9066971f","first_name":"Erin","last_name":"Valentino","shipping_address_id":7,"billing_address_id":7}
|
||||
{"customer_id":6,"email_address":"frankwilson@sbcglobal.net","password":"3ebfa301dc59196f18593c45e519287a23297589","first_name":"Frank Lee","last_name":"Wilson","shipping_address_id":8,"billing_address_id":8}
|
||||
{"customer_id":7,"email_address":"gary_hernandez@yahoo.com","password":"1ff2b3704aede04eecb51e50ca698efd50a1379b","first_name":"Gary","last_name":"Hernandez","shipping_address_id":9,"billing_address_id":10}
|
||||
{"customer_id":8,"email_address":"heatheresway@mac.com","password":"911ddc3b8f9a13b5499b6bc4638a2b4f3f68bf23","first_name":"Heather","last_name":"Esway","shipping_address_id":11,"billing_address_id":12}
|
||||
@@ -0,0 +1,31 @@
|
||||
name: customers
|
||||
columns:
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: email_address
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: password
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: first_name
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: last_name
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: shipping_address_id
|
||||
type: int
|
||||
default: null
|
||||
- name: billing_address_id
|
||||
type: int
|
||||
default: null
|
||||
primaryKey:
|
||||
- customer_id
|
||||
@@ -0,0 +1,13 @@
|
||||
{"__isStreamHeader":true,"pureName":"order_items","tableRowCount":"12","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:33","objectId":"order_items","contentHash":"2025-02-03 02:56:33","columns":[{"notNull":true,"autoIncrement":true,"columnName":"item_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"order_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"item_price","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"discount_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"quantity","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"order_items","constraintType":"primaryKey","columns":[{"columnName":"item_id"}]},"foreignKeys":[{"constraintName":"items_fk_products","constraintType":"foreignKey","pureName":"order_items","refTableName":"products","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"product_id","refColumnName":"product_id"}]},{"constraintName":"items_fk_orders","constraintType":"foreignKey","pureName":"order_items","refTableName":"orders","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"order_id","refColumnName":"order_id"}]}],"indexes":[{"constraintName":"items_fk_orders","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"order_id","isDescending":0}]},{"constraintName":"items_fk_products","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"product_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"item_id":1,"order_id":1,"product_id":2,"item_price":"1199.00","discount_amount":"359.70","quantity":1}
|
||||
{"item_id":2,"order_id":2,"product_id":4,"item_price":"489.99","discount_amount":"186.20","quantity":1}
|
||||
{"item_id":3,"order_id":3,"product_id":3,"item_price":"2517.00","discount_amount":"1308.84","quantity":1}
|
||||
{"item_id":4,"order_id":3,"product_id":6,"item_price":"415.00","discount_amount":"161.85","quantity":1}
|
||||
{"item_id":5,"order_id":4,"product_id":2,"item_price":"1199.00","discount_amount":"359.70","quantity":2}
|
||||
{"item_id":6,"order_id":5,"product_id":5,"item_price":"299.00","discount_amount":"0.00","quantity":1}
|
||||
{"item_id":7,"order_id":6,"product_id":5,"item_price":"299.00","discount_amount":"0.00","quantity":1}
|
||||
{"item_id":8,"order_id":7,"product_id":1,"item_price":"699.00","discount_amount":"209.70","quantity":1}
|
||||
{"item_id":9,"order_id":7,"product_id":7,"item_price":"799.99","discount_amount":"240.00","quantity":1}
|
||||
{"item_id":10,"order_id":7,"product_id":9,"item_price":"699.99","discount_amount":"210.00","quantity":1}
|
||||
{"item_id":11,"order_id":8,"product_id":10,"item_price":"799.99","discount_amount":"120.00","quantity":1}
|
||||
{"item_id":12,"order_id":9,"product_id":1,"item_price":"699.00","discount_amount":"209.70","quantity":1}
|
||||
@@ -0,0 +1,40 @@
|
||||
name: order_items
|
||||
columns:
|
||||
- name: item_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: order_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: orders
|
||||
- name: product_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: products
|
||||
- name: item_price
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: discount_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: quantity
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- item_id
|
||||
indexes:
|
||||
- name: items_fk_orders
|
||||
unique: false
|
||||
columns:
|
||||
- order_id
|
||||
- name: items_fk_products
|
||||
unique: false
|
||||
columns:
|
||||
- product_id
|
||||
@@ -0,0 +1,10 @@
|
||||
{"__isStreamHeader":true,"pureName":"orders","tableRowCount":"9","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03T02:56:32","objectId":"orders","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"order_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"order_date","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"ship_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"tax_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"ship_date","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"ship_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_type","columnComment":"","dataType":"varchar(50)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_number","columnComment":"","dataType":"char(16)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_expires","columnComment":"","dataType":"char(7)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"billing_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"orders","constraintType":"primaryKey","columns":[{"columnName":"order_id"}]},"foreignKeys":[{"constraintName":"orders_fk_customers","constraintType":"foreignKey","pureName":"orders","refTableName":"customers","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"customer_id","refColumnName":"customer_id"}]}],"indexes":[{"constraintName":"orders_fk_customers","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"customer_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"order_id":1,"customer_id":1,"order_date":"2018-03-28T09:40:28","ship_amount":"5.00","tax_amount":"32.32","ship_date":"2018-03-30T15:32:51","ship_address_id":1,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2020","billing_address_id":2}
|
||||
{"order_id":2,"customer_id":2,"order_date":"2018-03-28T11:23:20","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-03-29T12:52:14","ship_address_id":3,"card_type":"Visa","card_number":"4012888888881881","card_expires":"08/2019","billing_address_id":3}
|
||||
{"order_id":3,"customer_id":1,"order_date":"2018-03-29T09:44:58","ship_amount":"10.00","tax_amount":"89.92","ship_date":"2018-03-31T09:11:41","ship_address_id":1,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2017","billing_address_id":2}
|
||||
{"order_id":4,"customer_id":3,"order_date":"2018-03-30T15:22:31","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-04-03T16:32:21","ship_address_id":4,"card_type":"American Express","card_number":"378282246310005","card_expires":"04/2016","billing_address_id":4}
|
||||
{"order_id":5,"customer_id":4,"order_date":"2018-03-31T05:43:11","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-04-02T14:21:12","ship_address_id":5,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2019","billing_address_id":6}
|
||||
{"order_id":6,"customer_id":5,"order_date":"2018-03-31T18:37:22","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":7,"card_type":"Discover","card_number":"6011111111111117","card_expires":"04/2019","billing_address_id":7}
|
||||
{"order_id":7,"customer_id":6,"order_date":"2018-04-01T23:11:12","ship_amount":"15.00","tax_amount":"0.00","ship_date":"2018-04-03T10:21:35","ship_address_id":8,"card_type":"MasterCard","card_number":"5555555555554444","card_expires":"04/2019","billing_address_id":8}
|
||||
{"order_id":8,"customer_id":7,"order_date":"2018-04-02T11:26:38","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":9,"card_type":"Visa","card_number":"4012888888881881","card_expires":"04/2019","billing_address_id":10}
|
||||
{"order_id":9,"customer_id":4,"order_date":"2018-04-03T12:22:31","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":5,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2019","billing_address_id":6}
|
||||
@@ -0,0 +1,54 @@
|
||||
name: orders
|
||||
columns:
|
||||
- name: order_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: customers
|
||||
- name: order_date
|
||||
type: datetime
|
||||
default: null
|
||||
notNull: true
|
||||
- name: ship_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: tax_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: ship_date
|
||||
type: datetime
|
||||
default: null
|
||||
- name: ship_address_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_type
|
||||
type: varchar(50)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_number
|
||||
type: char(16)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_expires
|
||||
type: char(7)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: billing_address_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- order_id
|
||||
indexes:
|
||||
- name: orders_fk_customers
|
||||
unique: false
|
||||
columns:
|
||||
- customer_id
|
||||
@@ -0,0 +1,11 @@
|
||||
{"__isStreamHeader":true,"pureName":"products","tableRowCount":"10","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"products","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"product_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"category_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_code","columnComment":"","dataType":"varchar(10)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"description","columnComment":"","dataType":"text","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"list_price","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"discount_percent","columnComment":"","dataType":"decimal(10,2)","defaultValue":"0.00","isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"date_added","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"products","constraintType":"primaryKey","columns":[{"columnName":"product_id"}]},"foreignKeys":[{"constraintName":"products_fk_categories","constraintType":"foreignKey","pureName":"products","refTableName":"categories","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"category_id","refColumnName":"category_id"}]}],"indexes":[{"constraintName":"products_fk_categories","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"category_id","isDescending":0}]}],"uniques":[{"constraintName":"product_code","columns":[{"columnName":"product_code"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"product_id":1,"category_id":1,"product_code":"strat","product_name":"Fender Stratocaster","description":"The Fender Stratocaster is the electric guitar design that changed the world. New features include a tinted neck, parchment pickguard and control knobs, and a '70s-style logo. Includes select alder body, 21-fret maple neck with your choice of a rosewood or maple fretboard, 3 single-coil pickups, vintage-style tremolo, and die-cast tuning keys. This guitar features a thicker bridge block for increased sustain and a more stable point of contact with the strings. At this low price, why play anything but the real thing?\r\n\r\nFeatures:\r\n\r\n* New features:\r\n* Thicker bridge block\r\n* 3-ply parchment pick guard\r\n* Tinted neck","list_price":"699.00","discount_percent":"30.00","date_added":"2017-10-30T09:32:40"}
|
||||
{"product_id":2,"category_id":1,"product_code":"les_paul","product_name":"Gibson Les Paul","description":"This Les Paul guitar offers a carved top and humbucking pickups. It has a simple yet elegant design. Cutting-yet-rich tone?the hallmark of the Les Paul?pours out of the 490R and 498T Alnico II magnet humbucker pickups, which are mounted on a carved maple top with a mahogany back. The faded finish models are equipped with BurstBucker Pro pickups and a mahogany top. This guitar includes a Gibson hardshell case (Faded and satin finish models come with a gig bag) and a limited lifetime warranty.\r\n\r\nFeatures:\r\n\r\n* Carved maple top and mahogany back (Mahogany top on faded finish models)\r\n* Mahogany neck, '59 Rounded Les Paul\r\n* Rosewood fingerboard (Ebony on Alpine white)\r\n* Tune-O-Matic bridge with stopbar\r\n* Chrome or gold hardware\r\n* 490R and 498T Alnico 2 magnet humbucker pickups (BurstBucker Pro on faded finish models)\r\n* 2 volume and 2 tone knobs, 3-way switch","list_price":"1199.00","discount_percent":"30.00","date_added":"2017-12-05T16:33:13"}
|
||||
{"product_id":3,"category_id":1,"product_code":"sg","product_name":"Gibson SG","description":"This Gibson SG electric guitar takes the best of the '62 original and adds the longer and sturdier neck joint of the late '60s models. All the classic features you'd expect from a historic guitar. Hot humbuckers go from rich, sweet lightning to warm, tingling waves of sustain. A silky-fast rosewood fretboard plays like a dream. The original-style beveled mahogany body looks like a million bucks. Plus, Tune-O-Matic bridge and chrome hardware. Limited lifetime warranty. Includes hardshell case.\r\n\r\nFeatures:\r\n\r\n* Double-cutaway beveled mahogany body\r\n* Set mahogany neck with rounded '50s profile\r\n* Bound rosewood fingerboard with trapezoid inlays\r\n* Tune-O-Matic bridge with stopbar tailpiece\r\n* Chrome hardware\r\n* 490R humbucker in the neck position\r\n* 498T humbucker in the bridge position\r\n* 2 volume knobs, 2 tone knobs, 3-way switch\r\n* 24-3/4\" scale","list_price":"2517.00","discount_percent":"52.00","date_added":"2018-02-04T11:04:31"}
|
||||
{"product_id":4,"category_id":1,"product_code":"fg700s","product_name":"Yamaha FG700S","description":"The Yamaha FG700S solid top acoustic guitar has the ultimate combo for projection and pure tone. The expertly braced spruce top speaks clearly atop the rosewood body. It has a rosewood fingerboard, rosewood bridge, die-cast tuners, body and neck binding, and a tortoise pickguard.\r\n\r\nFeatures:\r\n\r\n* Solid Sitka spruce top\r\n* Rosewood back and sides\r\n* Rosewood fingerboard\r\n* Rosewood bridge\r\n* White/black body and neck binding\r\n* Die-cast tuners\r\n* Tortoise pickguard\r\n* Limited lifetime warranty","list_price":"489.99","discount_percent":"38.00","date_added":"2018-06-01T11:12:59"}
|
||||
{"product_id":5,"category_id":1,"product_code":"washburn","product_name":"Washburn D10S","description":"The Washburn D10S acoustic guitar is superbly crafted with a solid spruce top and mahogany back and sides for exceptional tone. A mahogany neck and rosewood fingerboard make fretwork a breeze, while chrome Grover-style machines keep you perfectly tuned. The Washburn D10S comes with a limited lifetime warranty.\r\n\r\nFeatures:\r\n\r\n * Spruce top\r\n * Mahogany back, sides\r\n * Mahogany neck Rosewood fingerboard\r\n * Chrome Grover-style machines","list_price":"299.00","discount_percent":"0.00","date_added":"2018-07-30T13:58:35"}
|
||||
{"product_id":6,"category_id":1,"product_code":"rodriguez","product_name":"Rodriguez Caballero 11","description":"Featuring a carefully chosen, solid Canadian cedar top and laminated bubinga back and sides, the Caballero 11 classical guitar is a beauty to behold and play. The headstock and fretboard are of Indian rosewood. Nickel-plated tuners and Silver-plated frets are installed to last a lifetime. The body binding and wood rosette are exquisite.\r\n\r\nThe Rodriguez Guitar is hand crafted and glued to create precise balances. From the invisible careful sanding, even inside the body, that ensures the finished instrument's purity of tone, to the beautifully unique rosette inlays around the soundhole and on the back of the neck, each guitar is a credit to its luthier and worthy of being handed down from one generation to another.\r\n\r\nThe tone, resonance and beauty of fine guitars are all dependent upon the wood from which they are made. The wood used in the construction of Rodriguez guitars is carefully chosen and aged to guarantee the highest quality. No wood is purchased before the tree has been cut down, and at least 2 years must elapse before the tree is turned into lumber. The wood has to be well cut from the log. The grain must be close and absolutely vertical. The shop is totally free from humidity.","list_price":"415.00","discount_percent":"39.00","date_added":"2018-07-30T14:12:41"}
|
||||
{"product_id":7,"category_id":2,"product_code":"precision","product_name":"Fender Precision","description":"The Fender Precision bass guitar delivers the sound, look, and feel today's bass players demand. This bass features that classic P-Bass old-school design. Each Precision bass boasts contemporary features and refinements that make it an excellent value. Featuring an alder body and a split single-coil pickup, this classic electric bass guitar lives up to its Fender legacy.\r\n\r\nFeatures:\r\n\r\n* Body: Alder\r\n* Neck: Maple, modern C shape, tinted satin urethane finish\r\n* Fingerboard: Rosewood or maple (depending on color)\r\n* 9-1/2\" Radius (241 mm)\r\n* Frets: 20 Medium-jumbo frets\r\n* Pickups: 1 Standard Precision Bass split single-coil pickup (Mid)\r\n* Controls: Volume, Tone\r\n* Bridge: Standard vintage style with single groove saddles\r\n* Machine heads: Standard\r\n* Hardware: Chrome\r\n* Pickguard: 3-Ply Parchment\r\n* Scale Length: 34\" (864 mm)\r\n* Width at Nut: 1-5/8\" (41.3 mm)\r\n* Unique features: Knurled chrome P Bass knobs, Fender transition logo","list_price":"799.99","discount_percent":"30.00","date_added":"2018-06-01T11:29:35"}
|
||||
{"product_id":8,"category_id":2,"product_code":"hofner","product_name":"Hofner Icon","description":"With authentic details inspired by the original, the Hofner Icon makes the legendary violin bass available to the rest of us. Don't get the idea that this a just a \"nowhere man\" look-alike. This quality instrument features a real spruce top and beautiful flamed maple back and sides. The semi-hollow body and set neck will give you the warm, round tone you expect from the violin bass.\r\n\r\nFeatures:\r\n\r\n* Authentic details inspired by the original\r\n* Spruce top\r\n* Flamed maple back and sides\r\n* Set neck\r\n* Rosewood fretboard\r\n* 30\" scale\r\n* 22 frets\r\n* Dot inlay","list_price":"499.99","discount_percent":"25.00","date_added":"2018-07-30T14:18:33"}
|
||||
{"product_id":9,"category_id":3,"product_code":"ludwig","product_name":"Ludwig 5-piece Drum Set with Cymbals","description":"This product includes a Ludwig 5-piece drum set and a Zildjian starter cymbal pack.\r\n\r\nWith the Ludwig drum set, you get famous Ludwig quality. This set features a bass drum, two toms, a floor tom, and a snare?each with a wrapped finish. Drum hardware includes LA214FP bass pedal, snare stand, cymbal stand, hi-hat stand, and a throne.\r\n\r\nWith the Zildjian cymbal pack, you get a 14\" crash, 18\" crash/ride, and a pair of 13\" hi-hats. Sound grooves and round hammer strikes in a simple circular pattern on the top surface of these cymbals magnify the basic sound of the distinctive alloy.\r\n\r\nFeatures:\r\n\r\n* Famous Ludwig quality\r\n* Wrapped finishes\r\n* 22\" x 16\" kick drum\r\n* 12\" x 10\" and 13\" x 11\" toms\r\n* 16\" x 16\" floor tom\r\n* 14\" x 6-1/2\" snare drum kick pedal\r\n* Snare stand\r\n* Straight cymbal stand hi-hat stand\r\n* FREE throne","list_price":"699.99","discount_percent":"30.00","date_added":"2018-07-30T12:46:40"}
|
||||
{"product_id":10,"category_id":3,"product_code":"tama","product_name":"Tama 5-Piece Drum Set with Cymbals","description":"The Tama 5-piece Drum Set is the most affordable Tama drum kit ever to incorporate so many high-end features.\r\n\r\nWith over 40 years of experience, Tama knows what drummers really want. Which is why, no matter how long you've been playing the drums, no matter what budget you have to work with, Tama has the set you need, want, and can afford. Every aspect of the modern drum kit was exhaustively examined and reexamined and then improved before it was accepted as part of the Tama design. Which is why, if you start playing Tama now as a beginner, you'll still enjoy playing it when you've achieved pro-status. That's how good these groundbreaking new drums are.\r\n\r\nOnly Tama comes with a complete set of genuine Meinl HCS cymbals. These high-quality brass cymbals are made in Germany and are sonically matched so they sound great together. They are even lathed for a more refined tonal character. The set includes 14\" hi-hats, 16\" crash cymbal, and a 20\" ride cymbal.\r\n\r\nFeatures:\r\n\r\n* 100% poplar 6-ply/7.5mm shells\r\n* Precise bearing edges\r\n* 100% glued finishes\r\n* Original small lugs\r\n* Drum heads\r\n* Accu-tune bass drum hoops\r\n* Spur brackets\r\n* Tom holder\r\n* Tom brackets","list_price":"799.99","discount_percent":"15.00","date_added":"2018-07-30T13:14:15"}
|
||||
@@ -0,0 +1,42 @@
|
||||
name: products
|
||||
columns:
|
||||
- name: product_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: category_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: categories
|
||||
- name: product_code
|
||||
type: varchar(10)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: product_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: description
|
||||
type: text
|
||||
default: null
|
||||
notNull: true
|
||||
- name: list_price
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: discount_percent
|
||||
type: decimal(10,2)
|
||||
default: '0.00'
|
||||
notNull: true
|
||||
- name: date_added
|
||||
type: datetime
|
||||
default: null
|
||||
primaryKey:
|
||||
- product_id
|
||||
indexes:
|
||||
- name: products_fk_categories
|
||||
unique: false
|
||||
columns:
|
||||
- category_id
|
||||
@@ -21,7 +21,7 @@ services:
|
||||
build: containers/mysql-ssh-login
|
||||
restart: always
|
||||
ports:
|
||||
- 16005:3306
|
||||
- 16017:3306
|
||||
- "16012:22"
|
||||
|
||||
mysql-ssh-keyfile:
|
||||
@@ -37,7 +37,7 @@ services:
|
||||
- "16009:5556"
|
||||
|
||||
mongo:
|
||||
image: mongo:4.0.12
|
||||
image: mongo:4.4.29
|
||||
restart: always
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
@@ -49,3 +49,20 @@ services:
|
||||
image: redis
|
||||
ports:
|
||||
- 16011:6379
|
||||
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
restart: always
|
||||
ports:
|
||||
- 16014:1433
|
||||
environment:
|
||||
- ACCEPT_EULA=Y
|
||||
- SA_PASSWORD=Pwd2020Db
|
||||
- MSSQL_PID=Express
|
||||
|
||||
oracle:
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
environment:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- 16013:1521
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
// function createTimeStamp() {
|
||||
// const now = new Date();
|
||||
// const year = now.getFullYear();
|
||||
// const month = String(now.getMonth() + 1).padStart(2, '0'); // měsíc je 0-indexovaný
|
||||
// const day = String(now.getDate()).padStart(2, '0');
|
||||
// const hours = String(now.getHours()).padStart(2, '0');
|
||||
// const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
// const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
|
||||
// // Poskládáme datum a čas do názvu souboru
|
||||
// const ts = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
|
||||
// return ts;
|
||||
// }
|
||||
|
||||
function clearTestingData() {
|
||||
if (fs.existsSync(path.join(baseDir, 'connections-e2etests.jsonl'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'connections-e2etests.jsonl'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'settings-e2etests.jsonl'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'settings-e2etests.jsonl'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'files-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'files-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'archive-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'archive-e2etests'), { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
clearTestingData,
|
||||
};
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
CONNECTIONS=mysql
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
SERVER_mysql=localhost
|
||||
USER_mysql=root
|
||||
PASSWORD_mysql=Pwd2020Db
|
||||
PORT_mysql=16004
|
||||
ENGINE_mysql=mysql@dbgate-plugin-mysql
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
ALLOW_DBGATE_PRIVATE_CLOUD=1
|
||||
REDIRECT_TO_DBGATE_CLOUD_LOGIN=1
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
CONNECTIONS=mysql,postgres,mssql,oracle,sqlite,mongo
|
||||
LOG_CONNECTION_SENSITIVE_VALUES=true
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
SERVER_mysql=localhost
|
||||
USER_mysql=root
|
||||
PASSWORD_mysql=Pwd2020Db
|
||||
PORT_mysql=16004
|
||||
ENGINE_mysql=mysql@dbgate-plugin-mysql
|
||||
DBCONFIG_mysql=[{"name":"MyChinook","connectionColor":"cyan"}]
|
||||
|
||||
LABEL_postgres=Postgres-connection
|
||||
SERVER_postgres=localhost
|
||||
USER_postgres=postgres
|
||||
PASSWORD_postgres=Pwd2020Db
|
||||
PORT_postgres=16000
|
||||
ENGINE_postgres=postgres@dbgate-plugin-postgres
|
||||
DBCONFIG_postgres=[{"name":"PgChinook","connectionColor":"red"}]
|
||||
|
||||
LABEL_oracle=Oracle-connection
|
||||
SERVER_oracle=localhost
|
||||
USER_oracle=system
|
||||
PASSWORD_oracle=Pwd2020Db
|
||||
PORT_oracle=16013
|
||||
ENGINE_oracle=oracle@dbgate-plugin-oracle
|
||||
SERVICE_NAME_oracle=xe
|
||||
|
||||
LABEL_mssql=Mssql-connection
|
||||
SERVER_mssql=localhost
|
||||
USER_mssql=sa
|
||||
PASSWORD_mssql=Pwd2020Db
|
||||
PORT_mssql=16014
|
||||
ENGINE_mssql=mssql@dbgate-plugin-mssql
|
||||
|
||||
LABEL_sqlite=Sqlite-connection
|
||||
FILE_sqlite=%%E2E_TEST_DATA_DIRECTORY%%/my_guitar_shop.db
|
||||
ENGINE_sqlite=sqlite@dbgate-plugin-sqlite
|
||||
|
||||
LABEL_mongo=Mongo-connection
|
||||
SERVER_mongo=localhost
|
||||
USER_mongo=root
|
||||
PASSWORD_mongo=Pwd2020Db
|
||||
PORT_mongo=16010
|
||||
ENGINE_mongo=mongo@dbgate-plugin-mongo
|
||||
|
||||
@@ -195,6 +195,11 @@ async function run() {
|
||||
path.join(baseDir, 'archive-e2etests', 'default')
|
||||
);
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/chinook-jsonl')),
|
||||
path.join(baseDir, 'archive-e2etests', 'chinook-archive')
|
||||
);
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/files/query')),
|
||||
path.join(baseDir, 'files-e2etests', 'query')
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
const dbgateApi = require('dbgate-api');
|
||||
dbgateApi.initializeApiEnvironment();
|
||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
|
||||
async function copyFolder(source, target) {
|
||||
if (!fs.existsSync(target)) {
|
||||
fs.mkdirSync(target, { recursive: true });
|
||||
}
|
||||
for (const file of fs.readdirSync(source)) {
|
||||
fs.copyFileSync(path.join(source, file), path.join(target, file));
|
||||
}
|
||||
}
|
||||
|
||||
async function initMySqlDatabase(dbname, inputFile) {
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
sql: `drop database if exists ${dbname}`,
|
||||
});
|
||||
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
sql: `create database ${dbname}`,
|
||||
});
|
||||
|
||||
await dbgateApi.importDatabase({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
database: dbname,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
inputFile,
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const connection = {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
};
|
||||
|
||||
try {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: 'drop database if exists charts_sample',
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to drop database', err);
|
||||
}
|
||||
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: 'create database charts_sample',
|
||||
});
|
||||
|
||||
await dbgateApi.importDbFromFolder({
|
||||
connection: {
|
||||
...connection,
|
||||
database: 'charts_sample',
|
||||
},
|
||||
folder: path.resolve(path.join(__dirname, '../data/charts-sample')),
|
||||
});
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/files/sql')),
|
||||
path.join(baseDir, 'files-e2etests', 'sql')
|
||||
);
|
||||
|
||||
await initMySqlDatabase('MyChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql.sql')));
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
@@ -0,0 +1,130 @@
|
||||
const path = require('path');
|
||||
const localconfig = require('../.localconfig');
|
||||
|
||||
const dbgateApi = require('dbgate-api');
|
||||
dbgateApi.initializeApiEnvironment();
|
||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
const dbgatePluginPostgres = require('dbgate-plugin-postgres');
|
||||
dbgateApi.registerPlugins(dbgatePluginPostgres);
|
||||
|
||||
async function createDb(connection, dropDbSql, createDbSql, database = 'my_guitar_shop', { dropDatabaseName } = {}) {
|
||||
if (dropDbSql) {
|
||||
try {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: dropDbSql,
|
||||
database: dropDatabaseName,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to drop database', err);
|
||||
}
|
||||
}
|
||||
|
||||
if (createDbSql) {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: createDbSql,
|
||||
});
|
||||
}
|
||||
|
||||
await dbgateApi.importDbFromFolder({
|
||||
connection: {
|
||||
...connection,
|
||||
database,
|
||||
},
|
||||
folder: path.resolve(path.join(__dirname, '../data/my-guitar-shop')),
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
if (localconfig.postgres) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_postgres,
|
||||
user: process.env.USER_postgres,
|
||||
password: process.env.PASSWORD_postgres,
|
||||
port: process.env.PORT_postgres,
|
||||
engine: 'postgres@dbgate-plugin-postgres',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mysql) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mssql) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mssql,
|
||||
user: process.env.USER_mssql,
|
||||
password: process.env.PASSWORD_mssql,
|
||||
port: process.env.PORT_mssql,
|
||||
engine: 'mssql@dbgate-plugin-mssql',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.oracle) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_oracle,
|
||||
user: process.env.USER_oracle,
|
||||
password: process.env.PASSWORD_oracle,
|
||||
port: process.env.PORT_oracle,
|
||||
engine: 'oracle@dbgate-plugin-oracle',
|
||||
},
|
||||
'DROP USER c##my_guitar_shop CASCADE',
|
||||
'CREATE USER c##my_guitar_shop IDENTIFIED BY my_guitar_shop DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA 10M ON users',
|
||||
'C##my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.sqlite) {
|
||||
await createDb(
|
||||
{
|
||||
databaseFile: process.env.FILE_sqlite.replace(
|
||||
'%%E2E_TEST_DATA_DIRECTORY%%',
|
||||
path.join(path.dirname(__dirname), 'tmpdata')
|
||||
),
|
||||
singleDatabase: true,
|
||||
engine: 'sqlite@dbgate-plugin-sqlite',
|
||||
},
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mongo) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mongo,
|
||||
user: process.env.USER_mongo,
|
||||
password: process.env.PASSWORD_mongo,
|
||||
port: process.env.PORT_mongo,
|
||||
engine: 'mongo@dbgate-plugin-mongo',
|
||||
},
|
||||
'db.dropDatabase()',
|
||||
null,
|
||||
'my_guitar_shop',
|
||||
{ dropDatabaseName: 'my_guitar_shop' }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
+15
-6
@@ -20,20 +20,29 @@
|
||||
"cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js",
|
||||
"cy:run:browse-data": "cypress run --spec cypress/e2e/browse-data.cy.js",
|
||||
"cy:run:team": "cypress run --spec cypress/e2e/team.cy.js",
|
||||
"cy:run:multi-sql": "cypress run --spec cypress/e2e/multi-sql.cy.js",
|
||||
"cy:run:cloud": "cypress run --spec cypress/e2e/cloud.cy.js",
|
||||
"cy:run:charts": "cypress run --spec cypress/e2e/charts.cy.js",
|
||||
|
||||
"start:add-connection": "cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:portal": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:oauth": "cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:browse-data": "cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:team": "cd .. && env-cmd -f e2e-tests/env/team/.env node e2e-tests/init/team.js && env-cmd -f e2e-tests/env/team/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:add-connection": "node clearTestingData && cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:portal": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:oauth": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:browse-data": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:team": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/team/.env node e2e-tests/init/team.js && env-cmd -f e2e-tests/env/team/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:multi-sql": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/multi-sql/.env node e2e-tests/init/multi-sql.js && env-cmd -f e2e-tests/env/multi-sql/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:cloud": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/cloud/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:charts": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/charts/.env node e2e-tests/init/charts.js && env-cmd -f e2e-tests/env/charts/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
|
||||
"test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection",
|
||||
"test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal",
|
||||
"test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth",
|
||||
"test:browse-data": "start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
||||
"test:team": "start-server-and-test start:team http://localhost:3000 cy:run:team",
|
||||
"test:multi-sql": "start-server-and-test start:multi-sql http://localhost:3000 cy:run:multi-sql",
|
||||
"test:cloud": "start-server-and-test start:cloud http://localhost:3000 cy:run:cloud",
|
||||
"test:charts": "start-server-and-test start:charts http://localhost:3000 cy:run:charts",
|
||||
|
||||
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team",
|
||||
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team && yarn test:multi-sql && yarn test:cloud && yarn test:charts",
|
||||
"test:ci": "yarn test"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Folder with screenshots
|
||||
@@ -29,7 +29,7 @@ async function testDatabaseDiff(conn, driver, mangle, createObject = null) {
|
||||
driver,
|
||||
`create table ~t2 (
|
||||
~id int not null primary key,
|
||||
~t1_id int null references ~t1(~id)
|
||||
~t1_id int ${driver.dialect.implicitNullDeclaration ? '' : 'null'} references ~t1(~id)
|
||||
)`
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ async function testDatabaseDiff(conn, driver, mangle, createObject = null) {
|
||||
}
|
||||
|
||||
describe('Alter database', () => {
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipReferences && !x.skipDropReferences).map(engine => [engine.label, engine]))(
|
||||
'Drop referenced table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDiff(conn, driver, db => {
|
||||
|
||||
@@ -60,7 +60,9 @@ async function testTableDiff(engine, conn, driver, mangle) {
|
||||
if (!engine.skipReferences) {
|
||||
const query = formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t2 (~id int not null primary key, ~fkval int null references ~t1(~col_ref))`
|
||||
`create table ~t2 (~id int not null primary key, ~fkval int ${
|
||||
driver.dialect.implicitNullDeclaration ? '' : 'null'
|
||||
} references ~t1(~col_ref))`
|
||||
);
|
||||
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
@@ -90,7 +92,7 @@ const TESTED_COLUMNS = ['col_pk', 'col_std', 'col_def', 'col_fk', 'col_ref', 'co
|
||||
// const TESTED_COLUMNS = ['col_std'];
|
||||
// const TESTED_COLUMNS = ['col_ref'];
|
||||
|
||||
function create_engines_columns_source(engines) {
|
||||
function createEnginesColumnsSource(engines) {
|
||||
return _.flatten(
|
||||
engines.map(engine =>
|
||||
TESTED_COLUMNS.filter(col => col.endsWith('_pk') || !engine.skipNonPkRename)
|
||||
@@ -116,45 +118,55 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const columnsSource = create_engines_columns_source(engines);
|
||||
const dropableColumnsSrouce = columnsSource.filter(
|
||||
([_label, col, engine]) => !engine.skipPkDrop || !col.endsWith('_pk')
|
||||
test.each(engines.filter(i => i.supportTableComments).map(engine => [engine.label, engine]))(
|
||||
'Add comment to table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.objectComment = 'Added table comment';
|
||||
});
|
||||
})
|
||||
);
|
||||
const hasDropableColumns = dropableColumnsSrouce.length > 0;
|
||||
|
||||
if (hasDropableColumns) {
|
||||
test.each(dropableColumnsSrouce)(
|
||||
'Drop column - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
engine,
|
||||
conn,
|
||||
driver,
|
||||
tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
test.each(engines.filter(i => i.supportColumnComments).map(engine => [engine.label, engine]))(
|
||||
'Add comment to column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.push({
|
||||
columnName: 'added',
|
||||
columnComment: 'Added column comment',
|
||||
dataType: 'int',
|
||||
pairingId: crypto.randomUUID(),
|
||||
notNull: false,
|
||||
autoIncrement: false,
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const hasEnginesWithNullable = engines.filter(x => !x.skipNullable).length > 0;
|
||||
test.each(
|
||||
createEnginesColumnsSource(engines.filter(x => !x.skipDropColumn)).filter(
|
||||
([_label, col, engine]) => !engine.skipPkDrop || !col.endsWith('_pk')
|
||||
)
|
||||
)(
|
||||
'Drop column - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column)));
|
||||
})
|
||||
);
|
||||
|
||||
if (hasEnginesWithNullable) {
|
||||
const source = create_engines_columns_source(engines.filter(x => !x.skipNullable));
|
||||
test.each(createEnginesColumnsSource(engines.filter(x => !x.skipNullable && !x.skipChangeNullability)))(
|
||||
'Change nullability - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
engine,
|
||||
conn,
|
||||
driver,
|
||||
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, notNull: true } : x)))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(source)(
|
||||
'Change nullability - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
engine,
|
||||
conn,
|
||||
driver,
|
||||
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, notNull: true } : x)))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
test.each(columnsSource)(
|
||||
test.each(createEnginesColumnsSource(engines.filter(x => !x.skipRenameColumn)))(
|
||||
'Rename column - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
@@ -175,37 +187,32 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const enginesWithDefault = engines.filter(x => !x.skipDefaultValue);
|
||||
const hasEnginesWithDefault = enginesWithDefault.length > 0;
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Add default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_std').defaultValue = '123';
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
if (hasEnginesWithDefault) {
|
||||
test.each(enginesWithDefault.map(engine => [engine.label, engine]))(
|
||||
'Add default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_std').defaultValue = '123';
|
||||
});
|
||||
})
|
||||
);
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Unset default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_def').defaultValue = undefined;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(enginesWithDefault.map(engine => [engine.label, engine]))(
|
||||
'Unset default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_def').defaultValue = undefined;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(enginesWithDefault.map(engine => [engine.label, engine]))(
|
||||
'Change default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_def').defaultValue = '567';
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Change default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.find(x => x.columnName == 'col_def').defaultValue = '567';
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
// test.each(engines.map(engine => [engine.label, engine]))(
|
||||
// 'Change autoincrement - %s',
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const { testWrapper } = require('../tools');
|
||||
const dataDuplicator = require('dbgate-api/src/shell/dataDuplicator');
|
||||
const { runCommandOnDriver, runQueryOnDriver } = require('dbgate-tools');
|
||||
|
||||
describe('Data duplicator', () => {
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
'Insert simple data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: true },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
|
||||
const gett1 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1' },
|
||||
{ id: 2, val: 'v2' },
|
||||
{ id: 3, val: 'v3' },
|
||||
]);
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
{ id: 3, val: 'v3', valfk: 3 },
|
||||
]);
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
operation: 'copy',
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
operation: 'copy',
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
'Skip nullable weak refs - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: false },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp => dmp.put("insert into ~t1 (~id, ~val) values (1, 'first')"));
|
||||
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
]);
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
options: {
|
||||
setNullForUnresolvedNullableRefs: true,
|
||||
},
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('1');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('2');
|
||||
|
||||
const res3 = await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`select count(*) as ~cnt from ~t2 where ~valfk is not null`)
|
||||
);
|
||||
expect(res3.rows[0].cnt.toString()).toEqual('1');
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,306 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const { testWrapper } = require('../tools');
|
||||
const dataReplicator = require('dbgate-api/src/shell/dataReplicator');
|
||||
const deployDb = require('dbgate-api/src/shell/deployDb');
|
||||
const storageModel = require('dbgate-api/src/storageModel');
|
||||
const { runCommandOnDriver, runQueryOnDriver, adaptDatabaseInfo } = require('dbgate-tools');
|
||||
|
||||
describe('Data replicator', () => {
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Insert simple data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: true },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
|
||||
const gett1 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1' },
|
||||
{ id: 2, val: 'v2' },
|
||||
{ id: 3, val: 'v3' },
|
||||
]);
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
{ id: 3, val: 'v3', valfk: 3 },
|
||||
]);
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
createNew: true,
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
createNew: true,
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Skip nullable weak refs - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: false },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp => dmp.put("insert into ~t1 (~id, ~val) values (1, 'first')"));
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
jsonArray: [
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
setNullForUnresolvedNullableRefs: true,
|
||||
},
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('1');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('2');
|
||||
|
||||
const res3 = await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`select count(*) as ~cnt from ~t2 where ~valfk is not null`)
|
||||
);
|
||||
expect(res3.rows[0].cnt.toString()).toEqual('1');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Import storage DB - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await deployDb({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
loadedDbModel: adaptDatabaseInfo(storageModel, driver),
|
||||
targetSchema: engine.defaultSchemaName,
|
||||
});
|
||||
|
||||
async function queryValue(sql) {
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(sql));
|
||||
return res1.rows[0].val?.toString();
|
||||
}
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('2');
|
||||
expect(
|
||||
await queryValue(
|
||||
`select ~is_disabled as ~val from ~auth_methods where ~amoid='790ca4d2-7f01-4800-955b-d691b890cc50'`
|
||||
)
|
||||
).toBeTruthy();
|
||||
|
||||
const DB1 = {
|
||||
auth_methods: [
|
||||
{ id: -1, name: 'Anonymous', amoid: '790ca4d2-7f01-4800-955b-d691b890cc50', is_disabled: 0 },
|
||||
{ id: 10, name: 'OAuth', amoid: '4269b660-54b6-11ef-a3aa-a9021250bf4b' },
|
||||
],
|
||||
auth_methods_config: [{ id: 20, auth_method_id: 10, key: 'oauthClient', value: 'dbgate' }],
|
||||
config: [
|
||||
{ group: 'admin', key: 'encyptKey', value: '1234' },
|
||||
{ group: 'admin', key: 'adminPasswordState', value: 'set' },
|
||||
{ group: 'license', key: 'licenseKey', value: '123467' },
|
||||
],
|
||||
roles: [
|
||||
{ id: -3, name: 'superadmin' },
|
||||
{ id: -2, name: 'logged-user' },
|
||||
{ id: -1, name: 'anonymous-user' },
|
||||
],
|
||||
role_permissions: [
|
||||
{ id: 14, role_id: -1, permission: 'perm1' },
|
||||
{ id: 29, role_id: -1, permission: 'perm2' },
|
||||
{ id: 1, role_id: -1, permission: 'perm3' },
|
||||
],
|
||||
};
|
||||
|
||||
const DB2 = {
|
||||
auth_methods: [{ id: 10, name: 'My Auth', amoid: 'myauth1' }],
|
||||
auth_methods_config: [{ id: 20, auth_method_id: 10, key: 'my authClient', value: 'mydbgate' }],
|
||||
config: [],
|
||||
roles: [{ id: 1, name: 'test' }],
|
||||
role_permissions: [{ id: 14, role_id: 1, permission: 'permxx' }],
|
||||
};
|
||||
|
||||
function createDuplConfig(db) {
|
||||
return {
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 'auth_methods',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['amoid'],
|
||||
jsonArray: db.auth_methods,
|
||||
},
|
||||
{
|
||||
name: 'auth_methods_config',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['auth_method_id', 'key'],
|
||||
jsonArray: db.auth_methods_config,
|
||||
},
|
||||
{
|
||||
name: 'config',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['group', 'key'],
|
||||
jsonArray: db.config,
|
||||
},
|
||||
{
|
||||
name: 'roles',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['name'],
|
||||
jsonArray: db.roles,
|
||||
},
|
||||
{
|
||||
name: 'role_permissions',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
deleteMissing: true,
|
||||
matchColumns: ['role_id', 'permission'],
|
||||
deleteRestrictionColumns: ['role_id'],
|
||||
jsonArray: db.role_permissions,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
|
||||
expect(
|
||||
await queryValue(
|
||||
`select ~is_disabled as ~val from ~auth_methods where ~amoid='790ca4d2-7f01-4800-955b-d691b890cc50'`
|
||||
)
|
||||
).toEqual('0');
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('3');
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('1');
|
||||
expect(await queryValue(`select count(*) as ~val from ~config`)).toEqual('3');
|
||||
expect(await queryValue(`select ~value as ~val from ~auth_methods_config`)).toEqual('dbgate');
|
||||
expect(
|
||||
await queryValue(`select ~value as ~val from ~config where ~group='license' and ~key='licenseKey'`)
|
||||
).toEqual('123467');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('3');
|
||||
|
||||
DB1.auth_methods_config[0].value = 'dbgate2';
|
||||
DB1.config[2].value = '567';
|
||||
DB1.role_permissions.splice(2, 1);
|
||||
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('1');
|
||||
expect(await queryValue(`select count(*) as ~val from ~config`)).toEqual('3');
|
||||
expect(await queryValue(`select ~value as ~val from ~auth_methods_config`)).toEqual('dbgate2');
|
||||
expect(
|
||||
await queryValue(`select ~value as ~val from ~config where ~group='license' and ~key='licenseKey'`)
|
||||
).toEqual('567');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('2');
|
||||
|
||||
// now add DB2
|
||||
await dataReplicator(createDuplConfig(DB2));
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('4');
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('2');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('3');
|
||||
|
||||
DB1.role_permissions.splice(1, 1);
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('2');
|
||||
}),
|
||||
15 * 1000
|
||||
);
|
||||
});
|
||||
@@ -1,11 +1,12 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const path = require('path');
|
||||
const { testWrapper } = require('../tools');
|
||||
const tableWriter = require('dbgate-api/src/shell/tableWriter');
|
||||
const tableReader = require('dbgate-api/src/shell/tableReader');
|
||||
const copyStream = require('dbgate-api/src/shell/copyStream');
|
||||
const importDatabase = require('dbgate-api/src/shell/importDatabase');
|
||||
const fakeObjectReader = require('dbgate-api/src/shell/fakeObjectReader');
|
||||
const importDbFromFolder = require('dbgate-api/src/shell/importDbFromFolder');
|
||||
const { runQueryOnDriver, runCommandOnDriver } = require('dbgate-tools');
|
||||
|
||||
function createImportStream() {
|
||||
@@ -50,7 +51,8 @@ describe('DB Import/export', () => {
|
||||
await copyStream(reader, writer);
|
||||
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt = parseInt(res.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -74,7 +76,8 @@ describe('DB Import/export', () => {
|
||||
await copyStream(reader, writer);
|
||||
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt = parseInt(res.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -102,13 +105,14 @@ describe('DB Import/export', () => {
|
||||
await copyStream(reader2, writer2);
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt = parseInt(res1.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt2 = parseInt(res2.rows[0].cnt.toString());
|
||||
expect(cnt2).toEqual(6);
|
||||
})
|
||||
);
|
||||
|
||||
const enginesWithDumpFile = engines.filter(x => x.dumpFile);
|
||||
const hasEnginesWithDumpFile = enginesWithDumpFile.length > 0;
|
||||
|
||||
@@ -181,4 +185,19 @@ describe('DB Import/export', () => {
|
||||
expect(result).toEqual(data);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(engine => !engine.skipImportModel).map(engine => [engine.label, engine]))(
|
||||
'Import guitar shop - schema + data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await importDbFromFolder({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
folder: path.join(__dirname, '../../e2e-tests/data/my-guitar-shop'),
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~categories`));
|
||||
const cnt1 = parseInt(res1.rows[0].cnt.toString());
|
||||
expect(cnt1).toEqual(4);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -106,7 +106,9 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
||||
|
||||
for (const loadedDbModel of dbModelsYaml) {
|
||||
if (_.isString(loadedDbModel)) {
|
||||
await driver.script(conn, formatQueryWithoutParams(driver, loadedDbModel));
|
||||
await driver.script(conn, formatQueryWithoutParams(driver, loadedDbModel), {
|
||||
useTransaction: engine.runDeployInTransaction,
|
||||
});
|
||||
} else {
|
||||
const { sql, isEmpty } = await generateDeploySql({
|
||||
systemConnection: conn.isPreparedOnly ? undefined : conn,
|
||||
@@ -131,6 +133,7 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
||||
driver,
|
||||
loadedDbModel: convertModelToEngine(loadedDbModel, driver),
|
||||
dbdiffOptionsExtra,
|
||||
useTransaction: engine.runDeployInTransaction,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -606,7 +609,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy && !i.skipRenameTable).map(engine => [engine.label, engine]))(
|
||||
'Mark table removed - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], [], []], {
|
||||
@@ -822,7 +825,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy && !i.skipRenameTable).map(engine => [engine.label, engine]))(
|
||||
'Mark table removed, one remains - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1, T2], [T2], [T2]], {
|
||||
|
||||
@@ -20,7 +20,11 @@ function flatSourceParameters() {
|
||||
}
|
||||
|
||||
function flatSourceTriggers() {
|
||||
return _.flatten(engines.map(engine => (engine.triggers || []).map(trigger => [engine.label, trigger, engine])));
|
||||
return _.flatten(
|
||||
engines
|
||||
.filter(engine => !engine.skipTriggers)
|
||||
.map(engine => (engine.triggers || []).map(trigger => [engine.label, trigger, engine]))
|
||||
);
|
||||
}
|
||||
|
||||
function flatSourceSchedulerEvents() {
|
||||
|
||||
@@ -49,6 +49,32 @@ class StreamHandler {
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryTestStreamHandler {
|
||||
constructor(resolve, reject, expectedValue) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.expectedValue = expectedValue;
|
||||
this.rowsReceived = [];
|
||||
}
|
||||
row(row) {
|
||||
try {
|
||||
this.rowsReceived.push(row);
|
||||
if (this.expectedValue) {
|
||||
expect(row).toEqual(this.expectedValue);
|
||||
}
|
||||
} catch (error) {
|
||||
this.reject(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
recordset(columns) {}
|
||||
done(result) {
|
||||
this.resolve(this.rowsReceived);
|
||||
}
|
||||
info(msg) {}
|
||||
}
|
||||
|
||||
|
||||
function executeStreamItem(driver, conn, sql) {
|
||||
return new Promise(resolve => {
|
||||
const handler = new StreamHandler(resolve);
|
||||
@@ -183,12 +209,12 @@ describe('Query', () => {
|
||||
{ discardResult: true }
|
||||
);
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put('SELECT COUNT(*) AS ~cnt FROM ~t1'));
|
||||
// console.log(res);
|
||||
expect(res.rows[0].cnt == 3).toBeTruthy();
|
||||
const cnt = parseInt(res.rows[0].cnt);
|
||||
expect(cnt).toEqual(3);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Select scope identity - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp =>
|
||||
@@ -223,4 +249,51 @@ describe('Query', () => {
|
||||
expect(row[keys[0]] == 1).toBeTruthy();
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => x.binaryDataType).map(engine => [engine.label, engine]))(
|
||||
'Binary',
|
||||
testWrapper(async (dbhan, driver, engine) => {
|
||||
await runCommandOnDriver(dbhan, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true, autoIncrement: true },
|
||||
{ columnName: 'val', dataType: engine.binaryDataType },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
const structure = await driver.analyseFull(dbhan);
|
||||
const table = structure.tables.find(x => x.pureName == 't1');
|
||||
|
||||
const dmp = driver.createDumper();
|
||||
dmp.putCmd("INSERT INTO ~t1 (~val) VALUES (%v)", {
|
||||
$binary: { base64: 'iVBORw0KWgo=' },
|
||||
});
|
||||
await driver.query(dbhan, dmp.s, {discardResult: true});
|
||||
|
||||
const dmp2 = driver.createDumper();
|
||||
dmp2.put('SELECT ~val FROM ~t1');
|
||||
const res = await driver.query(dbhan, dmp2.s);
|
||||
|
||||
const row = res.rows[0];
|
||||
const keys = Object.keys(row);
|
||||
expect(keys.length).toEqual(1);
|
||||
expect(row[keys[0]]).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
|
||||
|
||||
const res2 = await driver.readQuery(dbhan, dmp2.s);
|
||||
const rows = await Array.fromAsync(res2);
|
||||
const rowsVal = rows.filter(r => r.val != null);
|
||||
|
||||
expect(rowsVal.length).toEqual(1);
|
||||
expect(rowsVal[0].val).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
|
||||
|
||||
const res3 = await new Promise((resolve, reject) => {
|
||||
const handler = new BinaryTestStreamHandler(resolve, reject, {val: {$binary: {base64: 'iVBORw0KWgo='}}});
|
||||
driver.stream(dbhan, dmp2.s, handler);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -94,7 +94,7 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table add - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
|
||||
@@ -112,7 +112,7 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table remove - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
@@ -130,7 +130,7 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table change - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
|
||||
@@ -64,6 +64,40 @@ describe('Table create', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(
|
||||
engines.filter(i => i.supportTableComments || i.supportColumnComments).map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Simple table with comment - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
...(engine.supportTableComments && {
|
||||
schemaName: 'dbo',
|
||||
objectComment: 'table comment',
|
||||
}),
|
||||
...(engine.defaultSchemaName && {
|
||||
schemaName: engine.defaultSchemaName,
|
||||
}),
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
dataType: 'int',
|
||||
pureName: 'tested',
|
||||
...(engine.skipNullability ? {} : { notNull: true }),
|
||||
...(engine.supportColumnComments && {
|
||||
columnComment: 'column comment',
|
||||
}),
|
||||
...(engine.defaultSchemaName && {
|
||||
schemaName: engine.defaultSchemaName,
|
||||
}),
|
||||
},
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'col1' }],
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipIndexes).map(engine => [engine.label, engine]))(
|
||||
'Table with index - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
|
||||
@@ -8,14 +8,25 @@ services:
|
||||
# ports:
|
||||
# - 15000:5432
|
||||
#
|
||||
# mariadb:
|
||||
# image: mariadb
|
||||
# command: --default-authentication-plugin=mysql_native_password
|
||||
# restart: always
|
||||
# ports:
|
||||
# - 15004:3306
|
||||
# environment:
|
||||
# - MYSQL_ROOT_PASSWORD=Pwd2020Db
|
||||
mariadb:
|
||||
image: mariadb
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
restart: always
|
||||
ports:
|
||||
- 15004:3306
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=Pwd2020Db
|
||||
|
||||
db2:
|
||||
image: icr.io/db2_community/db2:11.5.8.0
|
||||
privileged: true
|
||||
ports:
|
||||
- "15055:50000"
|
||||
environment:
|
||||
LICENSE: accept
|
||||
DB2INST1_PASSWORD: Pwd2020Db
|
||||
DBNAME: testdb
|
||||
DB2INSTANCE: db2inst1
|
||||
|
||||
# mysql:
|
||||
# image: mysql:8.0.18
|
||||
@@ -25,13 +36,13 @@ services:
|
||||
# - 15001:3306
|
||||
# environment:
|
||||
# - MYSQL_ROOT_PASSWORD=Pwd2020Db
|
||||
|
||||
|
||||
# cassandradb:
|
||||
# image: cassandra:5.0.2
|
||||
# ports:
|
||||
# - 15942:9042
|
||||
#
|
||||
|
||||
cassandradb:
|
||||
image: cassandra:5.0.2
|
||||
ports:
|
||||
- 15942:9042
|
||||
|
||||
# clickhouse:
|
||||
# image: bitnami/clickhouse:24.8.4
|
||||
# restart: always
|
||||
@@ -55,28 +66,62 @@ services:
|
||||
# ports:
|
||||
# - 15003:26257
|
||||
# command: start-single-node --insecure
|
||||
# mongodb:
|
||||
# image: mongo:4.0.12
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - mongo-data:/data/db
|
||||
# - mongo-config:/data/configdb
|
||||
# ports:
|
||||
# - 27017:27017
|
||||
# mongodb:
|
||||
# image: mongo:4.0.12
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - mongo-data:/data/db
|
||||
# - mongo-config:/data/configdb
|
||||
# ports:
|
||||
# - 27017:27017
|
||||
|
||||
# cockroachdb-init:
|
||||
# image: cockroachdb/cockroach
|
||||
# # build: cockroach
|
||||
# # entrypoint: /cockroach/init.sh
|
||||
# entrypoint: ./cockroach sql --insecure --host="cockroachdb" --execute="CREATE DATABASE IF NOT EXISTS test;"
|
||||
# cockroachdb-init:
|
||||
# image: cockroachdb/cockroach
|
||||
# # build: cockroach
|
||||
# # entrypoint: /cockroach/init.sh
|
||||
# entrypoint: ./cockroach sql --insecure --host="cockroachdb" --execute="CREATE DATABASE IF NOT EXISTS test;"
|
||||
|
||||
# depends_on:
|
||||
# - cockroachdb
|
||||
# restart: on-failure
|
||||
# depends_on:
|
||||
# - cockroachdb
|
||||
# restart: on-failure
|
||||
|
||||
# oracle:
|
||||
# image: gvenzl/oracle-xe:21-slim
|
||||
# environment:
|
||||
# ORACLE_PASSWORD: Pwd2020Db
|
||||
# ports:
|
||||
# - 15006:1521
|
||||
# oracle:
|
||||
# image: gvenzl/oracle-xe:21-slim
|
||||
# environment:
|
||||
# ORACLE_PASSWORD: Pwd2020Db
|
||||
# ports:
|
||||
# - 15006:1521
|
||||
|
||||
# libsql:
|
||||
# image: ghcr.io/tursodatabase/libsql-server:latest
|
||||
# platform: linux/amd64
|
||||
# ports:
|
||||
# - '8080:8080'
|
||||
# - '5002:5001'
|
||||
# volumes:
|
||||
# - ./data/libsql:/var/lib/sqld
|
||||
|
||||
firebird:
|
||||
image: firebirdsql/firebird:latest
|
||||
container_name: firebird-db
|
||||
environment:
|
||||
- FIREBIRD_DATABASE=mydatabase.fdb
|
||||
- FIREBIRD_USER=dbuser
|
||||
- FIREBIRD_PASSWORD=dbpassword
|
||||
- ISC_PASSWORD=masterkey
|
||||
- FIREBIRD_TRACE=false
|
||||
- FIREBIRD_USE_LEGACY_AUTH=true
|
||||
ports:
|
||||
- '3050:3050'
|
||||
volumes:
|
||||
- firebird-data:/firebird/data
|
||||
- ./firebird.conf:/firebird/firebird.conf # Mount custom config file
|
||||
healthcheck:
|
||||
test: ['CMD', 'nc', '-z', 'localhost', '3050']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
volumes:
|
||||
firebird-data:
|
||||
|
||||
@@ -44,6 +44,7 @@ const mysqlEngine = {
|
||||
supportRenameSqlObject: false,
|
||||
dbSnapshotBySeconds: true,
|
||||
dumpFile: 'data/chinook-mysql.sql',
|
||||
binaryDataType: 'blob',
|
||||
dumpChecks: [
|
||||
{
|
||||
sql: 'select count(*) as res from genre',
|
||||
@@ -216,6 +217,7 @@ const postgreSqlEngine = {
|
||||
supportSchemas: true,
|
||||
supportRenameSqlObject: true,
|
||||
defaultSchemaName: 'public',
|
||||
binaryDataType: 'bytea',
|
||||
dumpFile: 'data/chinook-postgre.sql',
|
||||
dumpChecks: [
|
||||
{
|
||||
@@ -443,7 +445,10 @@ const sqlServerEngine = {
|
||||
supportSchemas: true,
|
||||
supportRenameSqlObject: true,
|
||||
defaultSchemaName: 'dbo',
|
||||
supportTableComments: true,
|
||||
supportColumnComments: true,
|
||||
// skipSeparateSchemas: true,
|
||||
binaryDataType: 'varbinary(100)',
|
||||
triggers: [
|
||||
{
|
||||
testName: 'triggers before each row',
|
||||
@@ -504,6 +509,24 @@ const sqliteEngine = {
|
||||
},
|
||||
},
|
||||
],
|
||||
binaryDataType: 'blob',
|
||||
};
|
||||
|
||||
const libsqlFileEngine = {
|
||||
...sqliteEngine,
|
||||
label: 'LibSQL FILE',
|
||||
connection: {
|
||||
engine: 'libsql@dbgate-plugin-sqlite',
|
||||
},
|
||||
};
|
||||
|
||||
const libsqlWsEngine = {
|
||||
...sqliteEngine,
|
||||
label: 'LibSQL WS',
|
||||
connection: {
|
||||
engine: 'libsql@dbgate-plugin-sqlite',
|
||||
databaseUrl: 'ws://localhost:8080',
|
||||
},
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
@@ -534,11 +557,12 @@ const clickhouseEngine = {
|
||||
skipUnique: true,
|
||||
skipAutoIncrement: true,
|
||||
skipPkColumnTesting: true,
|
||||
skipDataDuplicator: true,
|
||||
skipDataReplicator: true,
|
||||
skipStringLength: true,
|
||||
alterTableAddColumnSyntax: true,
|
||||
dbSnapshotBySeconds: true,
|
||||
skipChangeColumn: true,
|
||||
skipImportModel: true,
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
@@ -599,6 +623,7 @@ const oracleEngine = {
|
||||
},
|
||||
},
|
||||
],
|
||||
binaryDataType: 'blob',
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
@@ -625,8 +650,9 @@ const cassandraEngine = {
|
||||
skipOrderBy: true,
|
||||
skipAutoIncrement: true,
|
||||
skipDataModifications: true,
|
||||
skipDataDuplicator: true,
|
||||
skipDataReplicator: true,
|
||||
skipDeploy: true,
|
||||
skipImportModel: true,
|
||||
|
||||
forceSortResults: true,
|
||||
forceSortStructureColumns: true,
|
||||
@@ -635,6 +661,82 @@ const cassandraEngine = {
|
||||
objects: [],
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
const duckdbEngine = {
|
||||
label: 'DuckDB',
|
||||
generateDbFile: true,
|
||||
defaultSchemaName: 'main',
|
||||
connection: {
|
||||
engine: 'duckdb@dbgate-plugin-duckdb',
|
||||
},
|
||||
objects: [views],
|
||||
skipOnCI: false,
|
||||
skipChangeColumn: true,
|
||||
// skipIndexes: true,
|
||||
skipStringLength: true,
|
||||
skipTriggers: true,
|
||||
skipDataReplicator: true,
|
||||
skipAutoIncrement: true,
|
||||
skipDropColumn: true,
|
||||
skipRenameColumn: true,
|
||||
skipChangeNullability: true,
|
||||
skipDeploy: true,
|
||||
supportRenameSqlObject: true,
|
||||
skipIncrementalAnalysis: true,
|
||||
skipDefaultValue: true,
|
||||
skipDropReferences: true,
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
const firebirdEngine = {
|
||||
label: 'Firebird',
|
||||
generateDbFile: true,
|
||||
databaseFileLocationOnServer: '/var/lib/firebird/data/',
|
||||
defaultSchemaName: 'main',
|
||||
connection: {
|
||||
engine: 'firebird@dbgate-plugin-firebird',
|
||||
server: 'localhost',
|
||||
port: 3050,
|
||||
// databaseUrl: '/var/lib/firebird/data/mydatabase.fdb',
|
||||
// databaseFile: '/var/lib/firebird/data/mydatabase.fdb',
|
||||
user: 'SYSDBA',
|
||||
password: 'masterkey',
|
||||
},
|
||||
objects: [],
|
||||
triggers: [
|
||||
{
|
||||
testName: 'triggers after each row',
|
||||
create: `CREATE OR ALTER TRIGGER ~obj1 AFTER INSERT ON ~t1 AS BEGIN END;`,
|
||||
drop: 'DROP TRIGGER ~obj1;',
|
||||
objectTypeField: 'triggers',
|
||||
expected: {
|
||||
pureName: 'obj1',
|
||||
tableName: 't1',
|
||||
eventType: 'INSERT',
|
||||
triggerTiming: 'AFTER',
|
||||
},
|
||||
},
|
||||
],
|
||||
skipOnCI: false,
|
||||
runDeployInTransaction: true,
|
||||
skipDataModifications: true,
|
||||
skipChangeColumn: true,
|
||||
// skipIndexes: true,
|
||||
// skipStringLength: true,
|
||||
// skipTriggers: true,
|
||||
skipDataReplicator: true,
|
||||
skipAutoIncrement: true,
|
||||
// skipDropColumn: true,
|
||||
skipRenameColumn: true,
|
||||
// skipChangeNullability: true,
|
||||
// skipDeploy: true,
|
||||
// supportRenameSqlObject: true,
|
||||
skipIncrementalAnalysis: true,
|
||||
skipRenameTable: true,
|
||||
// skipDefaultValue: true,
|
||||
skipDropReferences: true,
|
||||
};
|
||||
|
||||
const enginesOnCi = [
|
||||
// all engines, which would be run on GitHub actions
|
||||
mysqlEngine,
|
||||
@@ -642,23 +744,31 @@ const enginesOnCi = [
|
||||
postgreSqlEngine,
|
||||
sqlServerEngine,
|
||||
sqliteEngine,
|
||||
libsqlFileEngine,
|
||||
libsqlWsEngine,
|
||||
// cockroachDbEngine,
|
||||
clickhouseEngine,
|
||||
oracleEngine,
|
||||
cassandraEngine,
|
||||
duckdbEngine,
|
||||
firebirdEngine,
|
||||
];
|
||||
|
||||
const enginesOnLocal = [
|
||||
// all engines, which would be run on local test
|
||||
cassandraEngine,
|
||||
// mysqlEngine,
|
||||
// cassandraEngine,
|
||||
//mysqlEngine,
|
||||
// mariaDbEngine,
|
||||
// postgreSqlEngine,
|
||||
// sqlServerEngine,
|
||||
// sqliteEngine,
|
||||
//postgreSqlEngine,
|
||||
//sqlServerEngine,
|
||||
sqliteEngine,
|
||||
// cockroachDbEngine,
|
||||
// clickhouseEngine,
|
||||
// oracleEngine,
|
||||
// libsqlFileEngine,
|
||||
// libsqlWsEngine,
|
||||
//oracleEngine,
|
||||
// duckdbEngine,
|
||||
//firebirdEngine,
|
||||
];
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo[] & Record<string, import('dbgate-types').TestEngineInfo>} */
|
||||
@@ -673,3 +783,7 @@ module.exports.cockroachDbEngine = cockroachDbEngine;
|
||||
module.exports.clickhouseEngine = clickhouseEngine;
|
||||
module.exports.oracleEngine = oracleEngine;
|
||||
module.exports.cassandraEngine = cassandraEngine;
|
||||
module.exports.libsqlFileEngine = libsqlFileEngine;
|
||||
module.exports.libsqlWsEngine = libsqlWsEngine;
|
||||
module.exports.duckdbEngine = duckdbEngine;
|
||||
module.exports.firebirdEngine = firebirdEngine;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# Custom Firebird Configuration
|
||||
|
||||
# Wire encryption settings
|
||||
# Options: Enabled, Required, Disabled
|
||||
WireCrypt = Disabled
|
||||
|
||||
# Authentication settings
|
||||
# Add Legacy_Auth to support older clients
|
||||
AuthServer = Legacy_Auth
|
||||
|
||||
# User manager plugin
|
||||
UserManager = Legacy_UserManager
|
||||
|
||||
# Default character set
|
||||
DefaultCharSet = UTF8
|
||||
|
||||
# Buffer settings for better performance
|
||||
DefaultDbCachePages = 2048
|
||||
TempCacheLimit = 512M
|
||||
|
||||
# Connection settings
|
||||
ConnectionTimeout = 180
|
||||
DatabaseGrowthIncrement = 128M
|
||||
|
||||
# TCP Protocol settings
|
||||
TcpRemoteBufferSize = 8192
|
||||
TcpNoNagle = 1
|
||||
|
||||
# Security settings
|
||||
RemoteServiceName = gds_db
|
||||
RemoteServicePort = 3050
|
||||
RemoteAuxPort = 0
|
||||
RemotePipeName = firebird
|
||||
|
||||
# Lock settings
|
||||
LockMemSize = 1M
|
||||
LockHashSlots = 8191
|
||||
LockAcquireSpins = 0
|
||||
|
||||
# Log settings
|
||||
FileSystemCacheThreshold = 65536
|
||||
FileSystemCacheSize = 0
|
||||
|
||||
# Compatibility settings for older clients
|
||||
CompatiblityDialect = 3
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user