diff --git a/Cargo.lock b/Cargo.lock
index d3d38a3ef3c2e792c8245b43ddde5bdfb521cd7d..934436523a9cc7e988451653a8b84671c69faa4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,12 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "Inflector"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+
 [[package]]
 name = "actix-codec"
 version = "0.3.0"
@@ -309,6 +315,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "aliasable"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
+
 [[package]]
 name = "ansi_term"
 version = "0.12.1"
@@ -318,6 +330,12 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
 [[package]]
 name = "async-channel"
 version = "1.6.1"
@@ -396,18 +414,6 @@ dependencies = [
  "event-listener",
 ]
 
-[[package]]
-name = "async-native-tls"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33"
-dependencies = [
- "async-std",
- "native-tls",
- "thiserror",
- "url",
-]
-
 [[package]]
 name = "async-process"
 version = "1.3.0"
@@ -425,6 +431,17 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "async-rustls"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c86f33abd5a4f3e2d6d9251a9e0c6a7e52eb1113caf893dae8429bf4a53f378"
+dependencies = [
+ "futures-lite",
+ "rustls",
+ "webpki",
+]
+
 [[package]]
 name = "async-std"
 version = "1.10.0"
@@ -453,6 +470,27 @@ dependencies = [
  "wasm-bindgen-futures",
 ]
 
+[[package]]
+name = "async-stream"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "async-task"
 version = "4.0.3"
@@ -496,6 +534,12 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
 [[package]]
 name = "autocfg"
 version = "1.0.1"
@@ -526,6 +570,19 @@ dependencies = [
  "serde_urlencoded",
 ]
 
+[[package]]
+name = "bae"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "base-x"
 version = "0.2.8"
@@ -720,22 +777,6 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
 
-[[package]]
-name = "core-foundation"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
-
 [[package]]
 name = "cpufeatures"
 version = "0.2.1"
@@ -799,6 +840,16 @@ dependencies = [
  "lazy_static",
 ]
 
+[[package]]
+name = "crypto-mac"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
 [[package]]
 name = "ctor"
 version = "0.1.21"
@@ -831,6 +882,26 @@ dependencies = [
  "generic-array",
 ]
 
+[[package]]
+name = "dirs"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "discard"
 version = "1.0.4"
@@ -903,21 +974,6 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
 [[package]]
 name = "form_urlencoded"
 version = "1.0.1"
@@ -952,6 +1008,7 @@ checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
 dependencies = [
  "futures-channel",
  "futures-core",
+ "futures-executor",
  "futures-io",
  "futures-sink",
  "futures-task",
@@ -974,6 +1031,17 @@ version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
 
+[[package]]
+name = "futures-executor"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
 [[package]]
 name = "futures-intrusive"
 version = "0.4.0"
@@ -1012,7 +1080,7 @@ version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "proc-macro-hack",
  "proc-macro2",
  "quote",
@@ -1037,7 +1105,7 @@ version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "futures-channel",
  "futures-core",
  "futures-io",
@@ -1071,6 +1139,16 @@ dependencies = [
  "version_check 0.9.3",
 ]
 
+[[package]]
+name = "gethostname"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "getrandom"
 version = "0.1.16"
@@ -1168,6 +1246,16 @@ version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
+[[package]]
+name = "hmac"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
+dependencies = [
+ "crypto-mac",
+ "digest",
+]
+
 [[package]]
 name = "hostname"
 version = "0.3.1"
@@ -1213,7 +1301,7 @@ version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "hashbrown",
 ]
 
@@ -1307,6 +1395,9 @@ name = "lazy_static"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+dependencies = [
+ "spin",
+]
 
 [[package]]
 name = "libc"
@@ -1314,6 +1405,12 @@ version = "0.2.112"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
 
+[[package]]
+name = "libm"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
+
 [[package]]
 name = "libsqlite3-sys"
 version = "0.22.2"
@@ -1371,6 +1468,17 @@ version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
 
+[[package]]
+name = "md-5"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "opaque-debug",
+]
+
 [[package]]
 name = "memchr"
 version = "2.4.1"
@@ -1406,7 +1514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
 dependencies = [
  "adler",
- "autocfg",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -1451,24 +1559,6 @@ dependencies = [
  "ws2_32-sys",
 ]
 
-[[package]]
-name = "native-tls"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
 [[package]]
 name = "net2"
 version = "0.2.37"
@@ -1501,13 +1591,64 @@ dependencies = [
  "version_check 0.9.3",
 ]
 
+[[package]]
+name = "num-bigint"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3"
+dependencies = [
+ "autocfg 1.0.1",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+dependencies = [
+ "autocfg 1.0.1",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-bigint-dig"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4547ee5541c18742396ae2c895d0717d0f886d8823b8399cdaf7b07d63ad0480"
+dependencies = [
+ "autocfg 0.1.7",
+ "byteorder",
+ "lazy_static",
+ "libm",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "rand 0.8.4",
+ "smallvec",
+ "zeroize",
+]
+
 [[package]]
 name = "num-integer"
 version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
+dependencies = [
+ "autocfg 1.0.1",
+ "num-integer",
  "num-traits",
 ]
 
@@ -1517,7 +1658,8 @@ version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
+ "libm",
 ]
 
 [[package]]
@@ -1543,36 +1685,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
-name = "openssl"
-version = "0.10.38"
+name = "ouroboros"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
+checksum = "3518a68fc597f6a42f83a31e41c039c3cbaa10fa8bb239c936c235e81cce873f"
 dependencies = [
- "bitflags",
- "cfg-if 1.0.0",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-sys",
+ "aliasable",
+ "ouroboros_macro",
+ "stable_deref_trait",
 ]
 
 [[package]]
-name = "openssl-probe"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.72"
+name = "ouroboros_macro"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
+checksum = "4e23813b1bcb2d41a838849a2bbae40ae5c03c85ecabf04ba97086f438484714"
 dependencies = [
- "autocfg",
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
+ "Inflector",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -1606,6 +1739,17 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "pem"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb"
+dependencies = [
+ "base64",
+ "once_cell",
+ "regex",
+]
+
 [[package]]
 name = "percent-encoding"
 version = "2.1.0"
@@ -1851,6 +1995,16 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "redox_users"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
+dependencies = [
+ "getrandom 0.2.3",
+ "redox_syscall 0.2.10",
+]
+
 [[package]]
 name = "regex"
 version = "1.5.4"
@@ -1869,22 +2023,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
 
 [[package]]
-name = "remove_dir_all"
-version = "0.5.3"
+name = "resolv-conf"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
 dependencies = [
+ "hostname",
+ "quick-error",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
  "winapi 0.3.9",
 ]
 
 [[package]]
-name = "resolv-conf"
-version = "0.7.0"
+name = "rsa"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
+checksum = "7b0aeddcca1082112a6eeb43bf25fd7820b066aaf6eaef776e19d0a1febe38fe"
 dependencies = [
- "hostname",
- "quick-error",
+ "byteorder",
+ "digest",
+ "lazy_static",
+ "num-bigint-dig",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "pem",
+ "rand 0.8.4",
+ "simple_asn1",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rust_decimal"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71b5a9625a7e6060b23db692facf49082cc78889a7e6ac94a735356ae49db4b0"
+dependencies = [
+ "arrayvec",
+ "num-traits",
+ "serde",
 ]
 
 [[package]]
@@ -1905,6 +2096,19 @@ dependencies = [
  "semver 1.0.4",
 ]
 
+[[package]]
+name = "rustls"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
+dependencies = [
+ "base64",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
 [[package]]
 name = "rustus"
 version = "0.1.0"
@@ -1916,15 +2120,17 @@ dependencies = [
  "base64",
  "chrono",
  "derive_more",
+ "gethostname",
  "log",
+ "sea-orm",
  "serde",
  "serde_json",
  "simple-logging",
- "sqlx",
+ "strfmt",
  "structopt",
  "thiserror",
  "url",
- "uuid",
+ "uuid 1.0.0-alpha.1",
 ]
 
 [[package]]
@@ -1934,42 +2140,102 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
 
 [[package]]
-name = "schannel"
-version = "0.1.19"
+name = "scopeguard"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "sct"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
 dependencies = [
- "lazy_static",
- "winapi 0.3.9",
+ "ring",
+ "untrusted",
 ]
 
 [[package]]
-name = "scopeguard"
-version = "1.1.0"
+name = "sea-orm"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+checksum = "4f594c2a48a3f2c7c911187c67a39d08f63af932801073737358bef0b5f06576"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "chrono",
+ "futures",
+ "futures-util",
+ "ouroboros",
+ "rust_decimal",
+ "sea-orm-macros",
+ "sea-query",
+ "sea-strum",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "url",
+ "uuid 0.8.2",
+]
 
 [[package]]
-name = "security-framework"
-version = "2.4.2"
+name = "sea-orm-macros"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87"
+checksum = "73786f2ccb8f697d83e80a1ddd3c580ead76dddd068ebb4349b5ab648e625cd2"
 dependencies = [
- "bitflags",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
+ "bae",
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
-name = "security-framework-sys"
-version = "2.4.2"
+name = "sea-query"
+version = "0.19.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
+checksum = "57c6353d854a61e47b2691feded408c6ffd07ba9913311f0ff17c889ef2f102f"
 dependencies = [
- "core-foundation-sys",
- "libc",
+ "chrono",
+ "rust_decimal",
+ "sea-query-derive",
+ "serde_json",
+ "uuid 0.8.2",
+]
+
+[[package]]
+name = "sea-query-derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34cdc022b4f606353fe5dc85b09713a04e433323b70163e81513b141c6ae6eb5"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "thiserror",
+]
+
+[[package]]
+name = "sea-strum"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c77c6c6c8b3950fccb65edd5d04985b5377f4c8f669cb9a215553f0369ec001"
+dependencies = [
+ "sea-strum_macros",
+]
+
+[[package]]
+name = "sea-strum_macros"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51c247af6c2c4ffd372fe97e9afa579b4438e4c306c9aa3f11cbf72f1e845180"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -2019,6 +2285,7 @@ version = "1.0.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
 dependencies = [
+ "indexmap",
  "itoa 1.0.1",
  "ryu",
  "serde",
@@ -2098,6 +2365,18 @@ dependencies = [
  "thread-id",
 ]
 
+[[package]]
+name = "simple_asn1"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eb4ea60fb301dc81dfc113df680571045d375ab7345d171c5dc7d7e13107a80"
+dependencies = [
+ "chrono",
+ "num-bigint 0.4.3",
+ "num-traits",
+ "thiserror",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.5"
@@ -2131,6 +2410,12 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
 [[package]]
 name = "sqlformat"
 version = "0.1.8"
@@ -2160,29 +2445,44 @@ checksum = "aec89bfaca8f7737439bad16d52b07f1ccd0730520d3bf6ae9d069fe4b641fb1"
 dependencies = [
  "ahash",
  "atoi",
+ "base64",
  "bitflags",
  "byteorder",
  "bytes 1.1.0",
+ "chrono",
  "crc",
  "crossbeam-channel",
  "crossbeam-queue",
  "crossbeam-utils",
+ "digest",
+ "dirs",
  "either",
  "futures-channel",
  "futures-core",
  "futures-intrusive",
  "futures-util",
+ "generic-array",
  "hashlink",
  "hex",
+ "hmac",
  "indexmap",
  "itoa 0.4.8",
  "libc",
  "libsqlite3-sys",
  "log",
+ "md-5",
  "memchr",
+ "num-bigint 0.3.3",
  "once_cell",
  "parking_lot",
  "percent-encoding",
+ "rand 0.8.4",
+ "rsa",
+ "rust_decimal",
+ "rustls",
+ "serde",
+ "serde_json",
+ "sha-1",
  "sha2",
  "smallvec",
  "sqlformat",
@@ -2190,6 +2490,9 @@ dependencies = [
  "stringprep",
  "thiserror",
  "url",
+ "uuid 0.8.2",
+ "webpki",
+ "webpki-roots",
  "whoami",
 ]
 
@@ -2205,6 +2508,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
+ "serde_json",
  "sha2",
  "sqlx-core",
  "sqlx-rt",
@@ -2218,11 +2522,16 @@ version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0d1bd069de53442e7a320f525a6d4deb8bb0621ac7a55f7eccbc2b58b57f43d0"
 dependencies = [
- "async-native-tls",
+ "async-rustls",
  "async-std",
- "native-tls",
 ]
 
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
 [[package]]
 name = "standback"
 version = "0.2.17"
@@ -2281,6 +2590,12 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
 
+[[package]]
+name = "strfmt"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b278b244ef7aa5852b277f52dd0c6cac3a109919e1f6d699adde63251227a30f"
+
 [[package]]
 name = "stringprep"
 version = "0.1.2"
@@ -2321,6 +2636,12 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
 [[package]]
 name = "syn"
 version = "1.0.82"
@@ -2333,17 +2654,15 @@ dependencies = [
 ]
 
 [[package]]
-name = "tempfile"
-version = "3.2.0"
+name = "synstructure"
+version = "0.12.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
 dependencies = [
- "cfg-if 1.0.0",
- "libc",
- "rand 0.8.4",
- "redox_syscall 0.2.10",
- "remove_dir_all",
- "winapi 0.3.9",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -2617,6 +2936,12 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
 
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
 [[package]]
 name = "url"
 version = "2.2.2"
@@ -2629,6 +2954,16 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+dependencies = [
+ "getrandom 0.2.3",
+ "serde",
+]
+
 [[package]]
 name = "uuid"
 version = "1.0.0-alpha.1"
@@ -2798,6 +3133,25 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "webpki"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
+dependencies = [
+ "webpki",
+]
+
 [[package]]
 name = "wepoll-ffi"
 version = "0.1.2"
@@ -2875,3 +3229,24 @@ dependencies = [
  "winapi 0.2.8",
  "winapi-build",
 ]
+
+[[package]]
+name = "zeroize"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
diff --git a/Cargo.toml b/Cargo.toml
index bf9322d865f2789e689cf035d6bfb4160fafb31e..4d77239ed5033b11dc668a30c6f70dafef01ff4b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,4 +24,6 @@ log = "^0.4.14"
 url = "2.2.2"
 base64 = "^0.13.0"
 simple-logging = { version = "^2.0.2" }
-sqlx = { version = "0.5", features = ["runtime-async-std-native-tls", "sqlite"] }
\ No newline at end of file
+gethostname = "0.2.1"
+strfmt = "^0.1.6"
+sea-orm = { version = "^0.4.2", features = ["runtime-async-std-rustls", "sqlx-all", "sqlx-chrono"] }
\ No newline at end of file
diff --git a/src/config.rs b/src/config.rs
index 9609d3a65f2111bef026ecc9994df2edab66d8b3..18e3ec9ee6f09e7f55732aacb3dc42461851d50e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,5 +1,7 @@
+use std::collections::HashMap;
 use std::path::PathBuf;
 
+use chrono::{Datelike, Timelike};
 use structopt::StructOpt;
 
 use crate::errors::RustusError;
@@ -19,13 +21,11 @@ pub struct StorageOptions {
     ///
     /// This directory is used to store files
     /// for all *file_storage storages.
-    #[structopt(
-        long,
-        default_value = "./data",
-        required_if("storage", "file_storage"),
-        required_if("storage", "sqlite_file_storage")
-    )]
+    #[structopt(long, default_value = "./data")]
     pub data_dir: PathBuf,
+
+    #[structopt(long, short = "dstruct", default_value = "")]
+    pub dis_structure: String,
 }
 
 #[derive(StructOpt, Debug, Clone)]
@@ -50,13 +50,15 @@ pub struct InfoStoreOptions {
     ///
     /// This directory is used to store .info files
     /// for `file_info_storage`.
+    #[structopt(long, default_value = "./data", env = "RUSTUS_INFO_DIR")]
+    pub info_dir: PathBuf,
+
     #[structopt(
         long,
-        default_value = "./data",
-        required_if("info_storage", "file_info_storage"),
-        env = "RUSTUS_INFO_DIR"
+        required_if("info-storage", "db_info_storage"),
+        env = "RUSTUS_INFO_DB_DSN"
     )]
-    pub info_dir: PathBuf,
+    pub info_db_dsn: Option<String>,
 }
 
 #[derive(Debug, StructOpt, Clone)]
@@ -180,6 +182,21 @@ impl RustusConf {
         )
     }
 
+    pub fn dir_struct(&self) -> String {
+        let hostname = gethostname::gethostname();
+
+        let now = chrono::Utc::now();
+        let mut vars: HashMap<String, String> = HashMap::new();
+        vars.insert("day".into(), now.day().to_string());
+        vars.insert("month".into(), now.month().to_string());
+        vars.insert("year".into(), now.year().to_string());
+        vars.insert("hour".into(), now.hour().to_string());
+        vars.insert("minute".into(), now.minute().to_string());
+        vars.insert("hostname".into(), hostname.to_string_lossy().into());
+        strfmt::strfmt(self.storage_opts.dis_structure.as_str(), &vars)
+            .unwrap_or_else(|_| "".into())
+    }
+
     /// List of extensions.
     ///
     /// This function will parse list of extensions from CLI
diff --git a/src/errors.rs b/src/errors.rs
index ba591c138a4bd431fcbf8c5a2c2b9b2fa6de120f..b6f635f35c16b172748ddc60db9fa642527e42cd 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -1,8 +1,8 @@
 use std::io::{Error, ErrorKind};
 
-use actix_web::{HttpResponse, ResponseError};
 use actix_web::dev::HttpResponseBuilder;
 use actix_web::http::StatusCode;
+use actix_web::{HttpResponse, ResponseError};
 
 pub type RustusResult<T> = Result<T, RustusError>;
 
@@ -19,7 +19,7 @@ pub enum RustusError {
     #[error("Unable to serialize object")]
     UnableToSerialize(#[from] serde_json::Error),
     #[error("Database error: {0}")]
-    DatabaseError(#[from] sqlx::Error),
+    DatabaseError(#[from] sea_orm::error::DbErr),
     #[error("Unable to get file information")]
     UnableToReadInfo,
     #[error("Unable to write file {0}")]
diff --git a/src/info_storages/db_info_storage.rs b/src/info_storages/db_info_storage.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c3c2730eaa62f1ed1b2a4ca55be0a3580689ff6e
--- /dev/null
+++ b/src/info_storages/db_info_storage.rs
@@ -0,0 +1,97 @@
+use async_trait::async_trait;
+use sea_orm::ActiveModelTrait;
+use sea_orm::EntityTrait;
+use sea_orm::{ConnectOptions, ConnectionTrait, Database, DatabaseConnection, Schema, Set};
+
+use crate::errors::{RustusError, RustusResult};
+use crate::info_storages::db_model;
+use crate::info_storages::{FileInfo, InfoStorage};
+use crate::RustusConf;
+
+pub struct DBInfoStorage {
+    db: DatabaseConnection,
+}
+
+impl DBInfoStorage {
+    pub async fn new(app_conf: RustusConf) -> RustusResult<Self> {
+        let db = Database::connect(ConnectOptions::new(
+            app_conf.info_storage_opts.info_db_dsn.unwrap().clone(),
+        ))
+        .await
+        .map_err(RustusError::from)?;
+        Ok(Self { db })
+    }
+}
+
+#[async_trait]
+impl InfoStorage for DBInfoStorage {
+    async fn prepare(&mut self) -> RustusResult<()> {
+        let builder = self.db.get_database_backend();
+        let schema = Schema::new(builder);
+        let create_statement = builder.build(
+            schema
+                .create_table_from_entity(db_model::Entity)
+                .if_not_exists(),
+        );
+        self.db
+            .execute(create_statement)
+            .await
+            .map_err(RustusError::from)?;
+        Ok(())
+    }
+
+    async fn set_info(&self, file_info: &FileInfo) -> RustusResult<()> {
+        let db_model: Option<db_model::Model> = db_model::Entity::find_by_id(file_info.id.clone())
+            .one(&self.db)
+            .await
+            .map_err(RustusError::from)?;
+
+        let model = db_model::Model::try_from(file_info.clone())?;
+
+        if let Some(db_model) = db_model {
+            let mut active_model: db_model::ActiveModel = db_model.into();
+            active_model.file_info = Set(model.file_info.clone());
+            active_model.update(&self.db).await?;
+        } else {
+            db_model::ActiveModel {
+                id: Set(model.id.clone()),
+                file_info: Set(model.file_info.clone()),
+            }
+            .insert(&self.db)
+            .await?;
+        }
+
+        Ok(())
+    }
+
+    async fn get_info(&self, file_id: &str) -> RustusResult<FileInfo> {
+        let model_opt: Option<db_model::Model> =
+            db_model::Entity::find_by_id(String::from(file_id))
+                .one(&self.db)
+                .await
+                .map_err(RustusError::from)?;
+        if let Some(model) = model_opt {
+            serde_json::from_str(model.file_info.as_str()).map_err(RustusError::from)
+        } else {
+            Err(RustusError::FileNotFound)
+        }
+    }
+
+    async fn remove_info(&self, file_id: &str) -> RustusResult<()> {
+        let model_opt: Option<db_model::Model> =
+            db_model::Entity::find_by_id(String::from(file_id))
+                .one(&self.db)
+                .await
+                .map_err(RustusError::from)?;
+        if let Some(model) = model_opt {
+            let active_model: db_model::ActiveModel = model.into();
+            active_model
+                .delete(&self.db)
+                .await
+                .map_err(RustusError::from)?;
+            Ok(())
+        } else {
+            Err(RustusError::FileNotFound)
+        }
+    }
+}
diff --git a/src/info_storages/db_model.rs b/src/info_storages/db_model.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1bcd876ec18d5630862bb43b07e675d2a3589f30
--- /dev/null
+++ b/src/info_storages/db_model.rs
@@ -0,0 +1,29 @@
+use sea_orm::entity::prelude::*;
+
+use crate::errors::RustusError;
+use crate::info_storages::FileInfo;
+
+#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
+#[sea_orm(table_name = "file_info")]
+pub struct Model {
+    #[sea_orm(primary_key, auto_increment = false)]
+    pub id: String,
+    pub file_info: String,
+}
+
+#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
+pub enum Relation {}
+
+impl ActiveModelBehavior for ActiveModel {}
+
+impl TryFrom<FileInfo> for Model {
+    type Error = RustusError;
+
+    fn try_from(value: FileInfo) -> Result<Self, Self::Error> {
+        let info_str = serde_json::to_string(&value).map_err(RustusError::from)?;
+        Ok(Self {
+            id: value.id,
+            file_info: info_str,
+        })
+    }
+}
diff --git a/src/info_storages/file_info.rs b/src/info_storages/file_info.rs
index 208343b70f89d73edc6d724e7c270fcc89ad97a5..4d2ff9ad41a88bfc6e86a0d20c7d3587f31eb2fc 100644
--- a/src/info_storages/file_info.rs
+++ b/src/info_storages/file_info.rs
@@ -1,6 +1,7 @@
 use std::collections::HashMap;
 
-
+use chrono::serde::ts_seconds;
+use chrono::{DateTime, Utc};
 use serde::{Deserialize, Serialize};
 
 /// Information about file.
@@ -11,7 +12,8 @@ pub struct FileInfo {
     pub offset: usize,
     pub length: usize,
     pub path: String,
-    pub created_at: i64,
+    #[serde(with = "ts_seconds")]
+    pub created_at: DateTime<Utc>,
     pub deferred_size: bool,
     pub metadata: HashMap<String, String>,
 }
@@ -51,7 +53,7 @@ impl FileInfo {
             metadata,
             deferred_size,
             offset: 0,
-            created_at: chrono::Utc::now().timestamp(),
+            created_at: chrono::Utc::now(),
         }
     }
 }
diff --git a/src/info_storages/file_info_storage.rs b/src/info_storages/file_info_storage.rs
index 7341d6e473c569f8263d28adeffab461bdbb4845..2d0de946dfde961d2cb8059aa98b7cfff930826f 100644
--- a/src/info_storages/file_info_storage.rs
+++ b/src/info_storages/file_info_storage.rs
@@ -1,6 +1,6 @@
 use std::path::PathBuf;
 
-use async_std::fs::{DirBuilder, OpenOptions, read_to_string, remove_file};
+use async_std::fs::{read_to_string, remove_file, DirBuilder, OpenOptions};
 use async_std::prelude::*;
 use async_trait::async_trait;
 use log::error;
diff --git a/src/info_storages/mod.rs b/src/info_storages/mod.rs
index f88bce07bffd7952994abede6de4e13094982040..c13dbfd6bc1d7e399d5d2cabd800bfb3ac63e2c9 100644
--- a/src/info_storages/mod.rs
+++ b/src/info_storages/mod.rs
@@ -10,13 +10,16 @@ use crate::RustusConf;
 
 mod file_info;
 
+pub mod db_info_storage;
+pub mod db_model;
 pub mod file_info_storage;
 
-
 #[derive(PartialEq, From, Display, Clone, Debug)]
 pub enum AvailableInfoStores {
-    #[display(fmt = "FileStorage")]
+    #[display(fmt = "FileInfoStorage")]
     FileInfoStorage,
+    #[display(fmt = "DBInfoStorage")]
+    DBInfoStorage,
 }
 
 impl FromStr for AvailableInfoStores {
@@ -25,6 +28,7 @@ impl FromStr for AvailableInfoStores {
     fn from_str(input: &str) -> Result<Self, Self::Err> {
         match input {
             "file_info_storage" => Ok(AvailableInfoStores::FileInfoStorage),
+            "db_info_storage" => Ok(AvailableInfoStores::DBInfoStorage),
             _ => Err(String::from("Unknown storage type")),
         }
     }
@@ -36,10 +40,17 @@ impl AvailableInfoStores {
     /// # Params
     /// `config` - Rustus configuration.
     ///
-    pub fn get(&self, config: &RustusConf) -> Box<dyn InfoStorage + Sync + Send> {
-        #[allow(clippy::single_match)]
+    pub async fn get(
+        &self,
+        config: &RustusConf,
+    ) -> RustusResult<Box<dyn InfoStorage + Sync + Send>> {
         match self {
-            Self::FileInfoStorage => Box::new(file_info_storage::FileInfoStorage::new(config.clone())),
+            Self::FileInfoStorage => Ok(Box::new(file_info_storage::FileInfoStorage::new(
+                config.clone(),
+            ))),
+            Self::DBInfoStorage => Ok(Box::new(
+                db_info_storage::DBInfoStorage::new(config.clone()).await?,
+            )),
         }
     }
 }
diff --git a/src/main.rs b/src/main.rs
index 4a71395976e2e739c67d9036276df6fb978271c8..78f5fec377106adaee54ce6faca66ad631f6b3e5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,11 +1,11 @@
 use std::str::FromStr;
 use std::sync::Arc;
 
+use actix_web::http::Method;
 use actix_web::{
-    App,
-    dev::{Server, Service}, HttpServer, middleware, web,
+    dev::{Server, Service},
+    middleware, web, App, HttpServer,
 };
-use actix_web::http::Method;
 use log::{error, info};
 
 use config::RustusConf;
@@ -83,7 +83,7 @@ pub fn create_server(
             // It returns 404 status_code.
             .default_service(web::route().to(routes::not_found))
     })
-        .bind((host, port))?;
+    .bind((host, port))?;
 
     // If custom workers count variable is provided.
     if let Some(workers_count) = workers {
@@ -99,7 +99,11 @@ async fn main() -> std::io::Result<()> {
     let app_conf = RustusConf::from_args();
     simple_logging::log_to_stderr(app_conf.log_level);
 
-    let mut info_storage = app_conf.info_storage_opts.info_storage.get(&app_conf);
+    let mut info_storage = app_conf
+        .info_storage_opts
+        .info_storage
+        .get(&app_conf)
+        .await?;
     info_storage.prepare().await?;
     let mut storage = app_conf.storage_opts.storage.get(&app_conf, info_storage);
     if let Err(err) = storage.prepare().await {
diff --git a/src/storages/file_storage.rs b/src/storages/file_storage.rs
index 75b2628b6488914783ad9e6d359eae094866d252..c2434aedd4e41c3e6b44ebb7f337ef2946dc3296 100644
--- a/src/storages/file_storage.rs
+++ b/src/storages/file_storage.rs
@@ -2,7 +2,8 @@ use std::collections::HashMap;
 use std::path::PathBuf;
 
 use actix_files::NamedFile;
-use async_std::fs::{DirBuilder, OpenOptions, remove_file};
+use async_std::fs::create_dir_all;
+use async_std::fs::{remove_file, DirBuilder, OpenOptions};
 use async_std::prelude::*;
 use async_trait::async_trait;
 use log::error;
@@ -10,8 +11,8 @@ use uuid::Uuid;
 
 use crate::errors::{RustusError, RustusResult};
 use crate::info_storages::{FileInfo, InfoStorage};
-use crate::RustusConf;
 use crate::storages::Storage;
+use crate::RustusConf;
 
 pub struct FileStorage {
     app_conf: RustusConf,
@@ -19,18 +20,27 @@ pub struct FileStorage {
 }
 
 impl FileStorage {
-    pub fn new(app_conf: RustusConf, info_storage: Box<dyn InfoStorage + Send + Sync>) -> FileStorage {
+    pub fn new(
+        app_conf: RustusConf,
+        info_storage: Box<dyn InfoStorage + Send + Sync>,
+    ) -> FileStorage {
         FileStorage {
             app_conf,
             info_storage,
         }
     }
 
-    pub fn data_file_path(&self, file_id: &str) -> PathBuf {
-        self.app_conf
+    pub async fn data_file_path(&self, file_id: &str) -> RustusResult<PathBuf> {
+        let dir = self
+            .app_conf
             .storage_opts
             .data_dir
-            .join(file_id.to_string())
+            .join(self.app_conf.dir_struct());
+        create_dir_all(dir.as_path()).await.map_err(|err| {
+            error!("{}", err);
+            RustusError::UnableToWrite(err.to_string())
+        })?;
+        Ok(dir.join(file_id.to_string()))
     }
 }
 
@@ -51,7 +61,8 @@ impl Storage for FileStorage {
     }
 
     async fn get_contents(&self, file_id: &str) -> RustusResult<NamedFile> {
-        NamedFile::open(self.data_file_path(file_id)).map_err(|err| {
+        let info = self.info_storage.get_info(file_id).await?;
+        NamedFile::open(info.path.as_str()).map_err(|err| {
             error!("{:?}", err);
             RustusError::FileNotFound
         })
@@ -71,7 +82,7 @@ impl Storage for FileStorage {
             .write(true)
             .append(true)
             .create(false)
-            .open(self.data_file_path(file_id))
+            .open(info.path.as_str())
             .await
             .map_err(|err| {
                 error!("{:?}", err);
@@ -79,7 +90,7 @@ impl Storage for FileStorage {
             })?;
         file.write_all(bytes).await.map_err(|err| {
             error!("{:?}", err);
-            RustusError::UnableToWrite(self.data_file_path(file_id).as_path().display().to_string())
+            RustusError::UnableToWrite(info.path.clone())
         })?;
         info.offset += bytes.len();
         self.info_storage.set_info(&info).await?;
@@ -92,12 +103,12 @@ impl Storage for FileStorage {
         metadata: Option<HashMap<String, String>>,
     ) -> RustusResult<String> {
         let file_id = Uuid::new_v4().simple().to_string();
-
+        let file_path = self.data_file_path(file_id.as_str()).await?;
         let mut file = OpenOptions::new()
             .write(true)
             .create(true)
             .create_new(true)
-            .open(self.data_file_path(file_id.as_str()).as_path())
+            .open(file_path.as_path())
             .await
             .map_err(|err| {
                 error!("{:?}", err);
@@ -107,21 +118,13 @@ impl Storage for FileStorage {
         // We write empty file here.
         file.write_all(b"").await.map_err(|err| {
             error!("{:?}", err);
-            RustusError::UnableToWrite(
-                self.data_file_path(file_id.as_str())
-                    .as_path()
-                    .display()
-                    .to_string(),
-            )
+            RustusError::UnableToWrite(file_path.display().to_string())
         })?;
 
         let file_info = FileInfo::new(
             file_id.as_str(),
             file_size,
-            self.data_file_path(file_id.as_str())
-                .as_path()
-                .display()
-                .to_string(),
+            file_path.display().to_string(),
             metadata,
         );
 
@@ -131,8 +134,10 @@ impl Storage for FileStorage {
     }
 
     async fn remove_file(&self, file_id: &str) -> RustusResult<()> {
+        let info = self.info_storage.get_info(file_id).await?;
         self.info_storage.remove_info(file_id).await?;
-        let data_path = self.data_file_path(file_id);
+
+        let data_path = PathBuf::from(info.path.clone());
         if !data_path.exists() {
             return Err(RustusError::FileNotFound);
         }
diff --git a/src/storages/mod.rs b/src/storages/mod.rs
index 2a5cac9761557ecfb577a44a696418820f686e36..520e4ac3dbd915a50e7db99c1eda296b40ac5bf9 100644
--- a/src/storages/mod.rs
+++ b/src/storages/mod.rs
@@ -4,10 +4,8 @@ use std::str::FromStr;
 use actix_files::NamedFile;
 use async_trait::async_trait;
 
-
 use derive_more::{Display, From};
 
-
 use crate::errors::RustusResult;
 use crate::info_storages::{FileInfo, InfoStorage};
 use crate::RustusConf;
@@ -50,7 +48,9 @@ impl AvailableStores {
     ) -> Box<dyn Storage + Send + Sync> {
         #[allow(clippy::single_match)]
         match self {
-            Self::FileStorage => Box::new(file_storage::FileStorage::new(config.clone(), info_storage)),
+            Self::FileStorage => {
+                Box::new(file_storage::FileStorage::new(config.clone(), info_storage))
+            }
         }
     }
 }