diff --git a/Cargo.lock b/Cargo.lock index e4d4195..c038707 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1090,6 +1090,7 @@ dependencies = [ "config", "serde", "serial_test", + "tempfile", "tide", "tide-testing", ] @@ -1441,6 +1442,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "ron" version = "0.7.0" @@ -1775,6 +1785,20 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.30" diff --git a/Cargo.toml b/Cargo.toml index 0982732..90d7dc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ tide = "*" [dev-dependencies] serial_test = "*" tide-testing = "*" +tempfile="*" diff --git a/Pipfile.lock b/Pipfile.lock index e9a219a..7482d00 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -24,11 +24,13 @@ "markers": "python_version >= '3.5'", "version": "==22.1.0" }, - "glob2": { + "exceptiongroup": { "hashes": [ - "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c" + "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828", + "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec" ], - "version": "==0.7" + "markers": "python_version < '3.11'", + "version": "==1.0.4" }, "iniconfig": { "hashes": [ @@ -39,11 +41,11 @@ }, "mako": { "hashes": [ - "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257", - "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307" + "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", + "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" ], "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "version": "==1.2.4" }, "markupsafe": { "hashes": [ @@ -122,14 +124,6 @@ "markers": "python_version >= '3.6'", "version": "==1.0.0" }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, "pyparsing": { "hashes": [ "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", @@ -140,19 +134,19 @@ }, "pytest": { "hashes": [ - "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c", - "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45" + "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", + "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" ], "markers": "python_version >= '3.7'", - "version": "==7.1.2" + "version": "==7.2.0" }, "pytest-bdd": { "hashes": [ - "sha256:1dcea36d5fb59291a5d3c186f4cbbd04cdb62a304341f9a360a07682ba1aba18", - "sha256:f894e589c9ee9e6a66c54e4917fafbbd11801fce9ce01e9b56dc15ccc57e4620" + "sha256:138af3592bcce5d4684b0d690777cf199b39ce45d423ca28086047ffe6111010", + "sha256:57eba5878d77036f356a85fb1d108cb061d8af4fb4d032b1a424fa9abe9e498b" ], "index": "pypi", - "version": "==6.0.1" + "version": "==6.1.1" }, "six": { "hashes": [ @@ -167,47 +161,53 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" + }, + "typing-extensions": { + "hashes": [ + "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", + "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" + ], + "markers": "python_version >= '3.7'", + "version": "==4.4.0" } }, "develop": { "astroid": { "hashes": [ - "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b", - "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946" + "sha256:10e0ad5f7b79c435179d0d0f0df69998c4eef4597534aae44910db060baeb907", + "sha256:1493fe8bd3dfd73dc35bd53c9d5b6e49ead98497c47b2307662556a5692d29d7" ], - "markers": "python_full_version >= '3.6.2'", - "version": "==2.11.7" + "markers": "python_full_version >= '3.7.2'", + "version": "==2.12.13" }, "black": { "hashes": [ - "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90", - "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c", - "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78", - "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4", - "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee", - "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e", - "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e", - "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6", - "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9", - "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c", - "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256", - "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f", - "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2", - "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c", - "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b", - "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807", - "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf", - "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def", - "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad", - "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d", - "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849", - "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69", - "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666" + "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7", + "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6", + "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650", + "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb", + "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d", + "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d", + "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de", + "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395", + "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae", + "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa", + "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef", + "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383", + "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66", + "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87", + "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d", + "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0", + "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b", + "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458", + "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4", + "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1", + "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff" ], "index": "pypi", - "version": "==22.6.0" + "version": "==22.10.0" }, "click": { "hashes": [ @@ -219,11 +219,11 @@ }, "dill": { "hashes": [ - "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302", - "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86" + "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0", + "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.3.5.1" + "markers": "python_version >= '3.7'", + "version": "==0.3.6" }, "isort": { "hashes": [ @@ -235,46 +235,28 @@ }, "lazy-object-proxy": { "hashes": [ - "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7", - "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a", - "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c", - "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc", - "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f", - "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09", - "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442", - "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e", - "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029", - "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61", - "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb", - "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0", - "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35", - "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42", - "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1", - "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad", - "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443", - "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd", - "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9", - "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148", - "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38", - "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55", - "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36", - "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a", - "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b", - "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44", - "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6", - "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69", - "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4", - "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84", - "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de", - "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28", - "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c", - "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1", - "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8", - "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", - "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" + "sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada", + "sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d", + "sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7", + "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe", + "sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd", + "sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c", + "sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858", + "sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288", + "sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec", + "sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f", + "sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891", + "sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c", + "sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25", + "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156", + "sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8", + "sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f", + "sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e", + "sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0", + "sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.1" + "markers": "python_version >= '3.7'", + "version": "==1.8.0" }, "mccabe": { "hashes": [ @@ -293,42 +275,43 @@ }, "pathspec": { "hashes": [ - "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1" + "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5", + "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0" ], - "version": "==0.9.0" + "markers": "python_version >= '3.7'", + "version": "==0.10.2" }, "platformdirs": { "hashes": [ - "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", - "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7", + "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10" ], "markers": "python_version >= '3.7'", - "version": "==2.5.2" + "version": "==2.5.4" }, "pylint": { "hashes": [ - "sha256:487ce2192eee48211269a0e976421f334cf94de1806ca9d0a99449adcdf0285e", - "sha256:fabe30000de7d07636d2e82c9a518ad5ad7908590fe135ace169b44839c15f90" + "sha256:15060cc22ed6830a4049cf40bc24977744df2e554d38da1b2657591de5bcd052", + "sha256:25b13ddcf5af7d112cf96935e21806c1da60e676f952efb650130f2a4483421c" ], "index": "pypi", - "version": "==2.14.5" + "version": "==2.15.6" }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "tomlkit": { "hashes": [ - "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5", - "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e" + "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b", + "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==0.11.1" + "markers": "python_version >= '3.6'", + "version": "==0.11.6" }, "wrapt": { "hashes": [ @@ -397,7 +380,7 @@ "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "markers": "python_version < '3.11'", "version": "==1.14.1" } } diff --git a/src/main.rs b/src/main.rs index 98c5002..8fbfa36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,14 +13,14 @@ use settings::Settings; #[async_std::main] async fn main() -> tide::Result<()> { let sett = Settings::new().unwrap(); - let app = app_setup().await; + let app = app_setup(sett.data_dir.as_str()).await; app.listen(format!("{}:{}", sett.address, sett.port)) .await?; Ok(()) } -async fn app_setup() -> tide::Server { - let db = MoreThanText::new().await; +async fn app_setup(data_dir: &str) -> tide::Server { + let db = MoreThanText::new(data_dir).await.unwrap(); let mut app = tide::with_state(db); app.at("/").get(home); app.with( @@ -48,11 +48,13 @@ async fn home(_req: Request) -> tide::Result { #[cfg(test)] mod server_app { use super::*; + use tempfile::tempdir; use tide_testing::TideTestingExt; #[async_std::test] async fn home_page_available() { - let app = app_setup().await; + let dir = tempdir().unwrap(); + let app = app_setup(dir.path().to_str().unwrap()).await; let response = app.get("/").await.unwrap(); assert_eq!(response.status(), StatusCode::Ok); } diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 9f0df21..1e4c13e 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -1,135 +1,66 @@ pub mod error; +use async_std::{fs::create_dir, path::Path}; -use async_std::sync::{Arc, RwLock}; use error::DBError; -use std::collections::HashMap; + +const DATA: &str = "data"; #[derive(Clone)] -pub struct MoreThanText { - databases: Arc>>, -} +pub struct MoreThanText; impl MoreThanText { - pub async fn new() -> Self { - Self { - databases: Arc::new(RwLock::new(HashMap::new())), - } - } - - async fn create_database(&self, name: &str) -> Result<(), DBError> { - let mut databases = self.databases.write().await; - match databases.get(name) { - Some(_) => Err(DBError::new("duplicate database name")), - None => { - let db = Database::new().await; - databases.insert(name.to_string(), db); - Ok(()) - } - } - } - - async fn use_database(&self, name: &str) -> Result { - let databases = self.databases.read().await; - match databases.get(name) { - Some(db) => Ok(db.clone()), - None => Err(DBError::new("database name not found")), - } - } -} - -#[derive(Clone)] -struct Database; - -impl Database { - async fn new() -> Self { - Self {} - } - - async fn add_table(&self, _name: &str) {} -} - -#[cfg(test)] -mod engine_functions { - use super::*; - - #[async_std::test] - async fn create_database() { - let mtt = MoreThanText::new().await; - mtt.create_database("smith").await.unwrap(); - } - - #[async_std::test] - async fn database_names_must_be_unique() -> Result<(), DBError> { - let mtt = MoreThanText::new().await; - let msg = "duplicate database name"; - mtt.create_database("john").await.unwrap(); - match mtt.create_database("john").await { - Ok(_) => Err(DBError::new("Duplicate names should cause error")), - Err(err) => { - if err.to_string() == msg { - Ok(()) - } else { - Err(DBError::new(format!( - "incorrect err message: got: '{}' want: '{}'", - err.to_string(), - msg - ))) + pub async fn new(dir: &str) -> Result { + let data_dir = Path::new(dir).join(DATA); + if !data_dir.is_dir().await { + match create_dir(data_dir).await { + Ok(_) => (), + Err(err) => { + let mut error = DBError::new("failed to initialize"); + error.add_source(err); + return Err(error); } } } - } - - #[async_std::test] - async fn use_database() -> Result<(), DBError> { - let mtt = MoreThanText::new().await; - let dbname = "Johnson"; - mtt.create_database(dbname).await.unwrap(); - mtt.use_database(dbname).await.unwrap(); - Ok(()) - } - - #[async_std::test] - async fn use_missing_database() -> Result<(), DBError> { - let error = "database name not found"; - let mtt = MoreThanText::new().await; - match mtt.use_database("ssmith").await { - Ok(_) => Err(DBError::new("Should raise database missing error")), - Err(err) => { - if err.to_string() == error { - Ok(()) - } else { - Err(DBError::new(format!( - "Incorrect error message: Got '{}' Want '{}'", - err.to_string(), - error - ))) - } - } - } - } - - #[async_std::test] - async fn create_get_table() { - let db = "thedatabase"; - let mtt = MoreThanText::new().await; - mtt.create_database(db).await.unwrap(); - let dbase = mtt.use_database(db).await.unwrap(); - dbase.add_table("melvin").await; + Ok(Self {}) } } #[cfg(test)] -mod database_functions { +mod init { use super::*; + use std::error::Error; + use tempfile::tempdir; #[async_std::test] - async fn new_database() { - Database::new().await; + async fn create_data_dir() { + let dir = tempdir().unwrap(); + MoreThanText::new(dir.path().to_str().unwrap()) + .await + .unwrap(); + let data_dir = dir.path().join(DATA); + assert!(data_dir.is_dir(), "Did not create the data directory."); + dir.close().unwrap(); } #[async_std::test] - async fn new_table() { - let db = Database::new().await; - db.add_table("fred").await; + async fn existing_data_dir() { + let dir = tempdir().unwrap(); + let data_dir = dir.path().join(DATA); + create_dir(data_dir).await.unwrap(); + MoreThanText::new(dir.path().to_str().unwrap()) + .await + .unwrap(); + dir.close().unwrap(); + } + + #[async_std::test] + async fn bad_data_dir() { + match MoreThanText::new("kljsdgfhslkfrh").await { + Ok(_) => assert!(false, "This test should fail to create a data directory"), + Err(err) => { + assert_eq!(err.to_string(), "failed to initialize"); + assert!(err.source().is_some(), "Must include the source error."); + } + }; } } diff --git a/src/morethantext/old-mod3.rs b/src/morethantext/old-mod3.rs new file mode 100644 index 0000000..0e8f33a --- /dev/null +++ b/src/morethantext/old-mod3.rs @@ -0,0 +1,153 @@ +pub mod error; + +use async_std::sync::{Arc, RwLock}; +use error::DBError; +use std::collections::HashMap; + +#[derive(Clone)] +pub struct MoreThanText { + databases: Arc>>, +} + +impl MoreThanText { + pub async fn new() -> Self { + Self { + databases: Arc::new(RwLock::new(HashMap::new())), + } + } + + async fn create_database(&self, name: &str) -> Result<(), DBError> { + let mut databases = self.databases.write().await; + match databases.get(name) { + Some(_) => Err(DBError::new("duplicate database name")), + None => { + let db = Database::new().await; + databases.insert(name.to_string(), db); + Ok(()) + } + } + } + + async fn use_database(&self, name: &str) -> Result { + let databases = self.databases.read().await; + match databases.get(name) { + Some(db) => Ok(db.clone()), + None => Err(DBError::new("database name not found")), + } + } +} + +#[derive(Clone)] +struct Database; + +impl Database { + async fn new() -> Self { + Self {} + } + + async fn add_table(&self, _name: &str) {} +} + +struct Table; + +impl Table { + async fn new() -> Self { + Self {} + } +} + +#[cfg(test)] +mod engine_functions { + use super::*; + + #[async_std::test] + async fn create_database() { + let mtt = MoreThanText::new().await; + mtt.create_database("smith").await.unwrap(); + } + + #[async_std::test] + async fn database_names_must_be_unique() -> Result<(), DBError> { + let mtt = MoreThanText::new().await; + let msg = "duplicate database name"; + mtt.create_database("john").await.unwrap(); + match mtt.create_database("john").await { + Ok(_) => Err(DBError::new("Duplicate names should cause error")), + Err(err) => { + if err.to_string() == msg { + Ok(()) + } else { + Err(DBError::new(format!( + "incorrect err message: got: '{}' want: '{}'", + err.to_string(), + msg + ))) + } + } + } + } + + #[async_std::test] + async fn use_database() -> Result<(), DBError> { + let mtt = MoreThanText::new().await; + let dbname = "Johnson"; + mtt.create_database(dbname).await.unwrap(); + mtt.use_database(dbname).await.unwrap(); + Ok(()) + } + + #[async_std::test] + async fn use_missing_database() -> Result<(), DBError> { + let error = "database name not found"; + let mtt = MoreThanText::new().await; + match mtt.use_database("ssmith").await { + Ok(_) => Err(DBError::new("Should raise database missing error")), + Err(err) => { + if err.to_string() == error { + Ok(()) + } else { + Err(DBError::new(format!( + "Incorrect error message: Got '{}' Want '{}'", + err.to_string(), + error + ))) + } + } + } + } + + #[async_std::test] + async fn create_get_table() { + let db = "thedatabase"; + let mtt = MoreThanText::new().await; + mtt.create_database(db).await.unwrap(); + let dbase = mtt.use_database(db).await.unwrap(); + dbase.add_table("melvin").await; + } +} + +#[cfg(test)] +mod database_functions { + use super::*; + + #[async_std::test] + async fn new_database() { + Database::new().await; + } + + #[async_std::test] + async fn new_table() { + let db = Database::new().await; + db.add_table("fred").await; + } +} + +#[cfg(test)] +mod table_functions { + use super::*; + + #[async_std::test] + async fn new_table() { + Table::new().await; + } +} diff --git a/src/settings.rs b/src/settings.rs index e626b3c..6dd32cd 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,18 +1,23 @@ use config::{Config, ConfigError}; use serde::Deserialize; +use std::env::current_dir; #[derive(Debug, Deserialize)] //#[allow(unused)] pub struct Settings { pub address: String, pub port: u16, + pub data_dir: String, } impl Settings { pub fn new() -> Result { + let working_dir = current_dir().unwrap(); + let data_dir = working_dir.to_str().unwrap(); let s = Config::builder() .set_default("port", 9090)? .set_default("address", "127.0.0.1")? + .set_default("data_dir", data_dir)? .add_source(config::File::with_name("morethantext").required(false)) .add_source( config::Environment::with_prefix("MTT") @@ -34,9 +39,12 @@ mod settings_tests { #[serial] fn defaults() { let set = Settings::new().unwrap(); + let working_dir = current_dir().unwrap(); + let data_dir = working_dir.to_str().unwrap(); println!("{:?}", set); assert_eq!(set.port, 9090); assert_eq!(set.address, "127.0.0.1"); + assert_eq!(set.data_dir, data_dir); } #[test]