This commit is contained in:
parent
63f4dce705
commit
4fd34f973f
18
.idea/runConfigurations/Test.xml
Normal file
18
.idea/runConfigurations/Test.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true">
|
||||
<option name="command" value="test" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="withSudo" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs />
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -2,6 +2,8 @@
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/sqlite_bin/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/sqlite_core/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
|
541
Cargo.lock
generated
541
Cargo.lock
generated
@ -11,6 +11,29 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "2.0.0-rc.1"
|
||||
@ -29,6 +52,35 @@ dependencies = [
|
||||
"virtue",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.22"
|
||||
@ -49,18 +101,213 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"derive_builder_core",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discard"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.121"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
@ -79,6 +326,31 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.5"
|
||||
@ -96,6 +368,55 @@ version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rspec"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89389e7c690310e855df3d9b507985ca0d323e2e766b2fedf369b02671e70e0a"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"derive-new",
|
||||
"derive_builder",
|
||||
"rayon",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
@ -117,10 +438,44 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite_clone"
|
||||
name = "serde_json"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
|
||||
dependencies = [
|
||||
"sha1_smol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1_smol"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||
|
||||
[[package]]
|
||||
name = "sqlite_bin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"sqlite_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rspec",
|
||||
"serde",
|
||||
"sscanf",
|
||||
]
|
||||
@ -149,6 +504,70 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
|
||||
dependencies = [
|
||||
"discard",
|
||||
"rustc_version",
|
||||
"stdweb-derive",
|
||||
"stdweb-internal-macros",
|
||||
"stdweb-internal-runtime",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-derive"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-macros"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
|
||||
dependencies = [
|
||||
"base-x",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-runtime"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.89"
|
||||
@ -160,14 +579,134 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
"standback",
|
||||
"stdweb",
|
||||
"time-macros",
|
||||
"version_check",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"time-macros-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros-impl"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"standback",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "virtue"
|
||||
version = "0.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "757cfbfe0d17ee6f22fe97e536d463047d451b47cf9d11e2b7d1398b0ef274dd"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
15
Cargo.toml
15
Cargo.toml
@ -1,11 +1,6 @@
|
||||
[package]
|
||||
name = "sqlite_clone"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
[workspace]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
sscanf = {version="0.2.1"}
|
||||
bincode = "2.0.0-rc.1"
|
||||
serde = {version="1.0.136", features=["derive"]}
|
||||
members = [
|
||||
"sqlite_core",
|
||||
"sqlite_bin"
|
||||
]
|
||||
|
9
sqlite_bin/Cargo.toml
Normal file
9
sqlite_bin/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "sqlite_bin"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
sqlite_core = { path = "../sqlite_core" }
|
9
sqlite_bin/src/main.rs
Normal file
9
sqlite_bin/src/main.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use sqlite_core::app::App;
|
||||
use std::process::exit;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
App::new()
|
||||
.with_commandline_interaction()
|
||||
.with_on_exit_handler(|| exit(0))
|
||||
.run()
|
||||
}
|
14
sqlite_core/Cargo.toml
Normal file
14
sqlite_core/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "sqlite_core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
sscanf = { version = "0.2.1" }
|
||||
bincode = "2.0.0-rc.1"
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
|
||||
[dev_dependencies]
|
||||
rspec = "1.0"
|
71
sqlite_core/src/app.rs
Normal file
71
sqlite_core/src/app.rs
Normal file
@ -0,0 +1,71 @@
|
||||
use crate::input_buffer::InputBuffer;
|
||||
use crate::interaction::{buffer::Buffer, command_line::CommandLine, Interaction};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub struct App {
|
||||
interaction: Option<Arc<dyn Interaction + Send + Sync>>,
|
||||
on_exit: fn(),
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
App::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for App {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("App").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
interaction: None,
|
||||
on_exit: || {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_interaction(
|
||||
&mut self,
|
||||
interaction: Arc<dyn Interaction + Send + Sync>,
|
||||
) -> &mut App {
|
||||
self.interaction = Some(interaction);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_commandline_interaction(&mut self) -> &mut Self {
|
||||
self.with_interaction(Arc::new(CommandLine::new()))
|
||||
}
|
||||
|
||||
pub fn with_buffer_interaction(
|
||||
&mut self,
|
||||
in_buffer: Arc<Mutex<Vec<String>>>,
|
||||
out_buffer: Arc<Mutex<Vec<String>>>,
|
||||
) -> &mut Self {
|
||||
self.with_interaction(Arc::new(Buffer::new(in_buffer, out_buffer)))
|
||||
}
|
||||
|
||||
pub fn with_on_exit_handler(&mut self, on_exit: fn()) -> &mut Self {
|
||||
self.on_exit = on_exit;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<(), String> {
|
||||
if let None = self.interaction {
|
||||
return Err(String::from("missing interaction"));
|
||||
}
|
||||
|
||||
let mut input_buffer = InputBuffer::new(self.interaction.take().unwrap());
|
||||
|
||||
loop {
|
||||
input_buffer
|
||||
.print_prompt()
|
||||
.read_input()?
|
||||
.parse(self.on_exit);
|
||||
}
|
||||
}
|
||||
}
|
92
sqlite_core/src/input_buffer.rs
Normal file
92
sqlite_core/src/input_buffer.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use crate::interaction::Interaction;
|
||||
use crate::statement::{ExecuteResult, StatementResultType};
|
||||
use crate::table::Table;
|
||||
use crate::{interaction, statement};
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct InputBuffer {
|
||||
buffer: Option<String>,
|
||||
table: Table,
|
||||
interaction: Arc<dyn interaction::Interaction>,
|
||||
}
|
||||
|
||||
impl InputBuffer {
|
||||
pub fn new(interaction: Arc<dyn Interaction>) -> Self {
|
||||
return Self {
|
||||
buffer: None,
|
||||
table: Table::new(),
|
||||
interaction,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn print_prompt(&mut self) -> &mut Self {
|
||||
self.interaction.output(String::from("db > "));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn read_input(&mut self) -> Result<&mut Self, String> {
|
||||
self.buffer = Some(String::new());
|
||||
match &mut self.buffer {
|
||||
Some(input_buffer) => {
|
||||
if let Ok(input) = self.interaction.input() {
|
||||
*input_buffer = input.to_string();
|
||||
Ok(self)
|
||||
} else {
|
||||
Err(String::from("could not handle input"))
|
||||
}
|
||||
}
|
||||
_ => Err(String::from("Could not initialize buffer")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(&mut self, on_exit: fn() -> ()) {
|
||||
match &self.buffer {
|
||||
Some(command) => {
|
||||
if command.starts_with(".") {
|
||||
Self::handle_meta_statement(command, on_exit);
|
||||
} else {
|
||||
match Self::prepare_statement(&command.replace("\n", "")) {
|
||||
Ok(statement) => {
|
||||
let execution_result = statement.execute(&mut self.table);
|
||||
match execution_result {
|
||||
ExecuteResult::Success {
|
||||
statement_result_type: StatementResultType::Insert,
|
||||
} => self
|
||||
.interaction
|
||||
.deref()
|
||||
.output(String::from("insert success\n")),
|
||||
ExecuteResult::Success {
|
||||
statement_result_type: StatementResultType::Select { rows },
|
||||
} => {
|
||||
for row in rows {
|
||||
self.interaction.output(row.print())
|
||||
}
|
||||
self.interaction.output(String::from("select success\n"))
|
||||
}
|
||||
_ => self.interaction.output(String::from("failure\n")),
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
self.interaction.output(format!("{}\n", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_statement(command: &String) -> Result<statement::Statement, String> {
|
||||
return statement::Statement::parse_statement(command);
|
||||
}
|
||||
|
||||
fn handle_meta_statement(command: &String, on_exit: fn()) {
|
||||
match command.replace("\n", "").trim() {
|
||||
".exit" => on_exit(),
|
||||
cmd => {
|
||||
println!("Could not handle command: {cmd}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
sqlite_core/src/interaction/buffer.rs
Normal file
33
sqlite_core/src/interaction/buffer.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::interaction::Interaction;
|
||||
|
||||
pub struct Buffer {
|
||||
int_buffer: Arc<Mutex<Vec<String>>>,
|
||||
out_buffer: Arc<Mutex<Vec<String>>>,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new(int_buffer: Arc<Mutex<Vec<String>>>, out_buffer: Arc<Mutex<Vec<String>>>) -> Self {
|
||||
Self {
|
||||
int_buffer,
|
||||
out_buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interaction for Buffer {
|
||||
fn input(&self) -> Result<String, String> {
|
||||
let mut int_buffer = self.int_buffer.lock().unwrap();
|
||||
if let Some(input_string) = int_buffer.pop() {
|
||||
Ok(input_string)
|
||||
} else {
|
||||
Err(String::from("internal_buffer is empty"))
|
||||
}
|
||||
}
|
||||
|
||||
fn output(&self, output: String) {
|
||||
let mut out_buffer = self.out_buffer.lock().unwrap();
|
||||
out_buffer.push(output)
|
||||
}
|
||||
}
|
26
sqlite_core/src/interaction/command_line.rs
Normal file
26
sqlite_core/src/interaction/command_line.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::interaction::Interaction;
|
||||
use std::io::Write;
|
||||
|
||||
pub struct CommandLine {}
|
||||
|
||||
impl CommandLine {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interaction for CommandLine {
|
||||
fn input(&self) -> Result<String, String> {
|
||||
let buffer: &mut String = &mut String::new();
|
||||
if let Ok(_) = std::io::stdin().read_line(buffer) {
|
||||
return Ok(buffer.to_string());
|
||||
} else {
|
||||
return Err(String::from("could not read input buffer"));
|
||||
}
|
||||
}
|
||||
|
||||
fn output(&self, output: String) {
|
||||
let _ = std::io::stdout().write(output.as_bytes());
|
||||
let _ = std::io::stdout().flush();
|
||||
}
|
||||
}
|
7
sqlite_core/src/interaction/mod.rs
Normal file
7
sqlite_core/src/interaction/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub mod buffer;
|
||||
pub mod command_line;
|
||||
|
||||
pub trait Interaction {
|
||||
fn input(&self) -> Result<String, String>;
|
||||
fn output(&self, output: String);
|
||||
}
|
8
sqlite_core/src/lib.rs
Normal file
8
sqlite_core/src/lib.rs
Normal file
@ -0,0 +1,8 @@
|
||||
pub mod app;
|
||||
mod input_buffer;
|
||||
mod interaction;
|
||||
mod page;
|
||||
mod pager;
|
||||
mod row;
|
||||
mod statement;
|
||||
mod table;
|
@ -7,9 +7,7 @@ pub struct Page {
|
||||
|
||||
impl Page {
|
||||
pub fn new(buffer: Vec<u8>) -> Self {
|
||||
Self {
|
||||
buffer,
|
||||
}
|
||||
Self { buffer }
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::{iter, slice};
|
||||
use std::io::Write;
|
||||
use std::{iter, slice};
|
||||
|
||||
use bincode::{Decode, Encode};
|
||||
use bincode::config::Configuration;
|
||||
use bincode::error::{DecodeError, EncodeError};
|
||||
use bincode::{Decode, Encode};
|
||||
|
||||
const COLUMN_USERNAME_SIZE: usize = 32;
|
||||
const COLUMN_EMAIL_SIZE: usize = 255;
|
||||
@ -61,9 +61,13 @@ impl Row {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn print(&self) {
|
||||
println!("({}, {}, {})", self.id, String::from_utf8(self.email.to_vec()).unwrap(), String::from_utf8(self.username.to_vec()).unwrap())
|
||||
pub fn print(&self) -> String {
|
||||
format!(
|
||||
"({}, {}, {})",
|
||||
self.id,
|
||||
String::from_utf8(self.email.to_vec()).unwrap(),
|
||||
String::from_utf8(self.username.to_vec()).unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,24 @@
|
||||
use crate::row;
|
||||
use crate::row::Serialize;
|
||||
use crate::table::Table;
|
||||
use crate::{row};
|
||||
|
||||
|
||||
pub enum StatementType {
|
||||
Insert { row: row::Row },
|
||||
Select,
|
||||
}
|
||||
|
||||
pub enum StatementResultType {
|
||||
Insert,
|
||||
Select { rows: Vec<row::Row> },
|
||||
}
|
||||
|
||||
pub enum ExecuteResult {
|
||||
Error { error: String },
|
||||
Success,
|
||||
Error {
|
||||
error: String,
|
||||
},
|
||||
Success {
|
||||
statement_result_type: StatementResultType,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct Statement {
|
||||
@ -44,7 +52,7 @@ impl Statement {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn execute(&self, table: &mut Table) -> ExecuteResult {
|
||||
pub fn execute(&self, table: &mut Table) -> ExecuteResult {
|
||||
match &self.statement_type {
|
||||
StatementType::Insert { row } => match row.serialize() {
|
||||
Err(e) => ExecuteResult::Error {
|
||||
@ -52,16 +60,17 @@ impl Statement {
|
||||
},
|
||||
Ok(serialization) => {
|
||||
table.append_row(serialization);
|
||||
ExecuteResult::Success
|
||||
ExecuteResult::Success {
|
||||
statement_result_type: StatementResultType::Insert {},
|
||||
}
|
||||
}
|
||||
},
|
||||
StatementType::Select => {
|
||||
let rows = table.get_rows();
|
||||
for row in rows {
|
||||
row.print()
|
||||
}
|
||||
|
||||
return ExecuteResult::Success;
|
||||
return ExecuteResult::Success {
|
||||
statement_result_type: StatementResultType::Select { rows },
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
use crate::pager::Pager;
|
||||
use crate::row;
|
||||
use std::mem::size_of;
|
||||
use std::ops::DerefMut;
|
||||
use crate::row::Row;
|
||||
use crate::row::Serialize;
|
||||
use std::mem::size_of;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
const PAGE_SIZE: usize = 4096;
|
||||
|
||||
@ -20,7 +20,7 @@ impl Table {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn append_row(&mut self, row: Vec<u8>) {
|
||||
pub fn append_row(&mut self, row: Vec<u8>) {
|
||||
let row_size = size_of::<row::Row>();
|
||||
let page_num = self.num_rows / self.rows_per_page(row_size);
|
||||
let row_offset = self.num_rows % self.rows_per_page(row_size);
|
||||
@ -50,7 +50,7 @@ impl Table {
|
||||
PAGE_SIZE / row_size
|
||||
}
|
||||
|
||||
pub(crate) fn get_rows(&mut self) -> Vec<Row> {
|
||||
pub fn get_rows(&mut self) -> Vec<Row> {
|
||||
let mut rows: Vec<Row> = Vec::with_capacity(self.num_rows);
|
||||
for i in 0..self.num_rows {
|
||||
rows.push(self.row(i))
|
118
sqlite_core/tests/acceptance_test.rs
Normal file
118
sqlite_core/tests/acceptance_test.rs
Normal file
@ -0,0 +1,118 @@
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use sqlite_core::app::App;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct EmptyDatabaseEnv {
|
||||
input: Arc<Mutex<Vec<String>>>,
|
||||
output: Arc<Mutex<Vec<String>>>,
|
||||
app: Arc<Mutex<sqlite_core::app::App>>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integration_test() {
|
||||
let env = EmptyDatabaseEnv {
|
||||
input: Arc::new(Mutex::new(Vec::new())),
|
||||
output: Arc::new(Mutex::new(Vec::new())),
|
||||
app: Arc::new(Mutex::new(App::new())),
|
||||
};
|
||||
rspec::run(&rspec::given("a sqlite database", env, |ctx| {
|
||||
ctx.before_each(|env| {
|
||||
env.input = Arc::new(Mutex::new(Vec::new()));
|
||||
env.output = Arc::new(Mutex::new(Vec::new()));
|
||||
env.app = Arc::new(Mutex::new(App::new()));
|
||||
});
|
||||
|
||||
ctx.when("it runs with empty items", |ctx| {
|
||||
ctx.then("it returns input error", |value| {
|
||||
let result = value
|
||||
.app
|
||||
.lock()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.with_buffer_interaction(value.input.clone(), value.output.clone())
|
||||
.run();
|
||||
assert_eq!(result, Err(String::from("could not handle input")));
|
||||
|
||||
assert_eq!(0, value.input.lock().unwrap().deref().len());
|
||||
assert_eq!(1, value.output.lock().unwrap().deref().len());
|
||||
assert_eq!(
|
||||
String::from("db > "),
|
||||
value.output.lock().unwrap().deref()[0]
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
ctx.when("it runs with insert items", |ctx| {
|
||||
ctx.before_all(|value| {
|
||||
let mut input = value.input.lock().unwrap();
|
||||
input.push(String::from("insert 1 username user@email.com"));
|
||||
input.push(String::from("insert 2 username2 user2@email.com"));
|
||||
input.push(String::from(".exit"));
|
||||
input.reverse();
|
||||
});
|
||||
|
||||
ctx.then("returns success", |value| {
|
||||
let result = value
|
||||
.app
|
||||
.lock()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.with_buffer_interaction(value.input.clone(), value.output.clone())
|
||||
.run();
|
||||
assert_eq!(result, Err(String::from("could not handle input")));
|
||||
|
||||
assert_eq!(6, value.output.lock().unwrap().deref().len());
|
||||
assert_eq!(
|
||||
String::from("db > "),
|
||||
value.output.lock().unwrap().deref()[0]
|
||||
);
|
||||
assert_eq!(
|
||||
String::from("insert success\n"),
|
||||
value.output.lock().unwrap().deref()[1]
|
||||
);
|
||||
assert_eq!(
|
||||
String::from("db > "),
|
||||
value.output.lock().unwrap().deref()[2]
|
||||
);
|
||||
assert_eq!(
|
||||
String::from("insert success\n"),
|
||||
value.output.lock().unwrap().deref()[3]
|
||||
);
|
||||
assert_eq!(
|
||||
String::from("db > "),
|
||||
value.output.lock().unwrap().deref()[4]
|
||||
);
|
||||
assert_eq!(
|
||||
String::from("db > "),
|
||||
value.output.lock().unwrap().deref()[5]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
ctx.when("it runs with select items", |ctx| {
|
||||
ctx.before_all(|value| {
|
||||
let mut input = value.input.lock().unwrap();
|
||||
input.push(String::from("insert 1 username user@email.com"));
|
||||
input.push(String::from("insert 2 username2 user2@email.com"));
|
||||
input.push(String::from("select"));
|
||||
input.push(String::from(".exit"));
|
||||
input.reverse();
|
||||
});
|
||||
|
||||
ctx.then("returns success", |value| {
|
||||
let result = value
|
||||
.app
|
||||
.lock()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.with_buffer_interaction(value.input.clone(), value.output.clone())
|
||||
.run();
|
||||
assert_eq!(result, Err(String::from("could not handle input")));
|
||||
|
||||
assert_eq!(10, value.output.lock().unwrap().deref().len());
|
||||
});
|
||||
});
|
||||
}))
|
||||
}
|
98
src/main.rs
98
src/main.rs
@ -1,98 +0,0 @@
|
||||
mod page;
|
||||
mod pager;
|
||||
mod row;
|
||||
mod statement;
|
||||
mod table;
|
||||
|
||||
use crate::statement::ExecuteResult;
|
||||
use crate::table::Table;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::process::exit;
|
||||
|
||||
struct InputBuffer {
|
||||
buffer: Option<String>,
|
||||
table: Table,
|
||||
}
|
||||
|
||||
impl InputBuffer {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
buffer: None,
|
||||
table: Table::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) fn print_prompt(&mut self) -> &mut Self {
|
||||
print!("db > ");
|
||||
if let Err(_) = io::stdout().flush() {
|
||||
panic!("could not print to stdout")
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn read_input(&mut self) -> Result<&mut Self, String> {
|
||||
self.buffer = Some(String::new());
|
||||
match &mut self.buffer {
|
||||
Some(input_buffer) => {
|
||||
if let Ok(_) = io::stdin().read_line(input_buffer) {
|
||||
Ok(self)
|
||||
} else {
|
||||
Err(String::from("could not handle input"))
|
||||
}
|
||||
}
|
||||
_ => Err(String::from("Could not initialize buffer")),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse(&mut self) {
|
||||
match &self.buffer {
|
||||
Some(command) => {
|
||||
if command.starts_with(".") {
|
||||
Self::handle_meta_statement(command);
|
||||
} else {
|
||||
match Self::prepare_statement(&command.replace("\n", "")) {
|
||||
Ok(statement) => {
|
||||
let execution_result = statement.execute(&mut self.table);
|
||||
match execution_result {
|
||||
ExecuteResult::Success => {
|
||||
println!("success")
|
||||
}
|
||||
_ => {
|
||||
println!("failure")
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_statement(command: &String) -> Result<statement::Statement, String> {
|
||||
return statement::Statement::parse_statement(command);
|
||||
}
|
||||
|
||||
fn handle_meta_statement(command: &String) {
|
||||
match command.replace("\n", "").trim() {
|
||||
".exit" => {
|
||||
exit(0);
|
||||
}
|
||||
cmd => {
|
||||
println!("Could not handle command: {cmd}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let mut input_buffer = InputBuffer::new();
|
||||
|
||||
loop {
|
||||
input_buffer.print_prompt().read_input()?.parse()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user