Skip to content
Snippets Groups Projects
Commit a9187014 authored by Éloïs's avatar Éloïs
Browse files

[fix] gva: use once_cell to init db handler without unsafe code

parent 7d6a36b4
Branches
Tags
1 merge request!254[fix] gva: use once_cell to init db handler without unsafe code
Showing with 69 additions and 28 deletions
...@@ -1095,6 +1095,7 @@ dependencies = [ ...@@ -1095,6 +1095,7 @@ dependencies = [
"juniper-from-schema 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "juniper-from-schema 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
...@@ -2029,6 +2030,11 @@ name = "numtoa" ...@@ -2029,6 +2030,11 @@ name = "numtoa"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "once_cell"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.2.3" version = "0.2.3"
...@@ -3348,6 +3354,7 @@ dependencies = [ ...@@ -3348,6 +3354,7 @@ dependencies = [
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" "checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585"
"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" "checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f"
......
...@@ -85,6 +85,15 @@ where ...@@ -85,6 +85,15 @@ where
pub r: Reader<'r>, pub r: Reader<'r>,
} }
impl<'r, 'db: 'r, DB> std::fmt::Debug for BcDbWithReaderStruct<'r, 'db, DB>
where
DB: DbReadable,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "BcDbWithReaderStruct {{}}")
}
}
pub type BcDbRoWithReader<'r, 'db> = BcDbWithReaderStruct<'r, 'db, BcDbRo>; pub type BcDbRoWithReader<'r, 'db> = BcDbWithReaderStruct<'r, 'db, BcDbRo>;
impl<'r, 'db: 'r, DB> BcDbWithReader for BcDbWithReaderStruct<'r, 'db, DB> impl<'r, 'db: 'r, DB> BcDbWithReader for BcDbWithReaderStruct<'r, 'db, DB>
......
...@@ -50,7 +50,7 @@ where ...@@ -50,7 +50,7 @@ where
} }
} }
pub trait BcDbWithReader { pub trait BcDbWithReader: std::fmt::Debug {
type DB: DbReadable; type DB: DbReadable;
type R: DbReader; type R: DbReader;
...@@ -71,6 +71,13 @@ impl<'a> BcDbWithReader for MockBcDbInReadTx { ...@@ -71,6 +71,13 @@ impl<'a> BcDbWithReader for MockBcDbInReadTx {
} }
} }
#[cfg(feature = "mock")]
impl std::fmt::Debug for MockBcDbInReadTx {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "MockBcDbInReadTx {{}}")
}
}
#[cfg_attr(feature = "mock", automock)] #[cfg_attr(feature = "mock", automock)]
pub trait BcDbInReadTx: BcDbWithReader { pub trait BcDbInReadTx: BcDbWithReader {
fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError>; fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError>;
......
...@@ -81,6 +81,12 @@ pub struct BcDbRwWithWriter<'w, 'db: 'w> { ...@@ -81,6 +81,12 @@ pub struct BcDbRwWithWriter<'w, 'db: 'w> {
pub w: &'w DbWriter<'w>, pub w: &'w DbWriter<'w>,
} }
impl<'w, 'db: 'w> std::fmt::Debug for BcDbRwWithWriter<'w, 'db> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "BcDbRwWithWriter {{}}")
}
}
impl<'w, 'db: 'w> durs_bc_db_reader::BcDbWithReader for BcDbRwWithWriter<'w, 'db> { impl<'w, 'db: 'w> durs_bc_db_reader::BcDbWithReader for BcDbRwWithWriter<'w, 'db> {
type DB = Db; type DB = Db;
type R = DbWriter<'w>; type R = DbWriter<'w>;
......
...@@ -29,6 +29,7 @@ failure = "0.1.5" ...@@ -29,6 +29,7 @@ failure = "0.1.5"
juniper = "0.14.1" juniper = "0.14.1"
juniper-from-schema = "0.5.0" juniper-from-schema = "0.5.0"
log = "0.4.8" log = "0.4.8"
once_cell = "1.3.1"
serde = "1.0.102" serde = "1.0.102"
serde_derive = "1.0.102" serde_derive = "1.0.102"
serde_json = "1.0.41" serde_json = "1.0.41"
......
...@@ -17,9 +17,10 @@ ...@@ -17,9 +17,10 @@
use crate::db::BcDbRo; use crate::db::BcDbRo;
use crate::schema::Schema; use crate::schema::Schema;
use once_cell::sync::OnceCell;
pub struct GlobalContext { pub struct GlobalContext {
db: &'static BcDbRo, db: &'static OnceCell<BcDbRo>,
pub(crate) schema: Schema, pub(crate) schema: Schema,
software_name: &'static str, software_name: &'static str,
software_version: &'static str, software_version: &'static str,
...@@ -27,7 +28,7 @@ pub struct GlobalContext { ...@@ -27,7 +28,7 @@ pub struct GlobalContext {
impl GlobalContext { impl GlobalContext {
pub(crate) fn new( pub(crate) fn new(
db: &'static BcDbRo, db: &'static OnceCell<BcDbRo>,
schema: Schema, schema: Schema,
software_name: &'static str, software_name: &'static str,
software_version: &'static str, software_version: &'static str,
...@@ -42,7 +43,7 @@ impl GlobalContext { ...@@ -42,7 +43,7 @@ impl GlobalContext {
} }
pub struct QueryContext { pub struct QueryContext {
db: &'static BcDbRo, db: &'static OnceCell<BcDbRo>,
software_name: &'static str, software_name: &'static str,
software_version: &'static str, software_version: &'static str,
} }
...@@ -52,7 +53,7 @@ impl juniper::Context for QueryContext {} ...@@ -52,7 +53,7 @@ impl juniper::Context for QueryContext {}
impl From<&GlobalContext> for QueryContext { impl From<&GlobalContext> for QueryContext {
fn from(global_context: &GlobalContext) -> Self { fn from(global_context: &GlobalContext) -> Self {
QueryContext { QueryContext {
db: global_context.db, db: &global_context.db,
software_name: global_context.software_name, software_name: global_context.software_name,
software_version: global_context.software_version, software_version: global_context.software_version,
} }
...@@ -61,7 +62,7 @@ impl From<&GlobalContext> for QueryContext { ...@@ -61,7 +62,7 @@ impl From<&GlobalContext> for QueryContext {
impl QueryContext { impl QueryContext {
pub(crate) fn get_db(&self) -> &BcDbRo { pub(crate) fn get_db(&self) -> &BcDbRo {
&self.db &self.db.get().expect("DB not initialised.")
} }
pub fn get_software_name(&self) -> &'static str { pub fn get_software_name(&self) -> &'static str {
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
missing_copy_implementations, missing_copy_implementations,
trivial_casts, trivial_casts,
trivial_numeric_casts, trivial_numeric_casts,
unsafe_code,
unstable_features, unstable_features,
unused_import_braces, unused_import_braces,
unused_qualifications unused_qualifications
......
...@@ -31,18 +31,19 @@ mod tests { ...@@ -31,18 +31,19 @@ mod tests {
use actix_web::web; use actix_web::web;
use assert_json_diff::assert_json_eq; use assert_json_diff::assert_json_eq;
use juniper::http::GraphQLRequest; use juniper::http::GraphQLRequest;
use once_cell::sync::OnceCell;
use std::sync::Arc; use std::sync::Arc;
pub(crate) fn setup( pub(crate) fn setup(
mock_db: BcDbRo, mock_db: BcDbRo,
db_container: &'static mut Option<BcDbRo>, db_container: &'static OnceCell<BcDbRo>,
) -> web::Data<Arc<GlobalContext>> { ) -> web::Data<Arc<GlobalContext>> {
// Give a static lifetime to the DB // Give a static lifetime to the DB
let db = durs_common_tools::fns::r#static::to_static_ref(mock_db, db_container); db_container.set(mock_db).expect("DB already initialized.");
// Init global context // Init global context
web::Data::new(std::sync::Arc::new(GlobalContext::new( web::Data::new(std::sync::Arc::new(GlobalContext::new(
db, &db_container,
create_schema(), create_schema(),
"soft_name", "soft_name",
"soft_version", "soft_version",
......
...@@ -48,9 +48,10 @@ mod tests { ...@@ -48,9 +48,10 @@ mod tests {
use dup_crypto_tests_tools::mocks::{hash, pubkey}; use dup_crypto_tests_tools::mocks::{hash, pubkey};
use durs_bc_db_reader::blocks::BlockDb; use durs_bc_db_reader::blocks::BlockDb;
use mockall::predicate::eq; use mockall::predicate::eq;
use once_cell::sync::OnceCell;
use serde_json::json; use serde_json::json;
static mut DB_BLOCK_1: Option<BcDbRo> = None; static DB_BLOCK_1: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_block() { fn test_graphql_block() {
...@@ -82,7 +83,7 @@ mod tests { ...@@ -82,7 +83,7 @@ mod tests {
.with(eq(pubkey('B'))) .with(eq(pubkey('B')))
.returning(|_| Ok(Some("issuerName".to_owned()))); .returning(|_| Ok(Some("issuerName".to_owned())));
let schema = tests::setup(mock_db, unsafe { &mut DB_BLOCK_1 }); let schema = tests::setup(mock_db, &DB_BLOCK_1);
tests::test_gql_query( tests::test_gql_query(
schema.clone(), schema.clone(),
......
...@@ -108,6 +108,7 @@ mod tests { ...@@ -108,6 +108,7 @@ mod tests {
use dup_crypto_tests_tools::mocks::{hash, pubkey}; use dup_crypto_tests_tools::mocks::{hash, pubkey};
use durs_bc_db_reader::blocks::BlockDb; use durs_bc_db_reader::blocks::BlockDb;
use mockall::predicate::eq; use mockall::predicate::eq;
use once_cell::sync::OnceCell;
use serde_json::json; use serde_json::json;
fn block_0() -> BlockDocumentV10 { fn block_0() -> BlockDocumentV10 {
...@@ -225,7 +226,7 @@ mod tests { ...@@ -225,7 +226,7 @@ mod tests {
}) })
} }
static mut DB_TEST_BLOCKS_FROM_2: Option<BcDbRo> = None; static DB_TEST_BLOCKS_FROM_2: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_blocks_from_2() { fn test_graphql_blocks_from_2() {
...@@ -261,7 +262,7 @@ mod tests { ...@@ -261,7 +262,7 @@ mod tests {
]) ])
}); });
let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS_FROM_2 }); let schema = tests::setup(mock_db, &DB_TEST_BLOCKS_FROM_2);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
...@@ -288,7 +289,7 @@ mod tests { ...@@ -288,7 +289,7 @@ mod tests {
); );
} }
static mut DB_TEST_BLOCKS_STEP_2: Option<BcDbRo> = None; static DB_TEST_BLOCKS_STEP_2: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_blocks_with_step_2() { fn test_graphql_blocks_with_step_2() {
...@@ -319,7 +320,7 @@ mod tests { ...@@ -319,7 +320,7 @@ mod tests {
]) ])
}); });
let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS_STEP_2 }); let schema = tests::setup(mock_db, &DB_TEST_BLOCKS_STEP_2);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
...@@ -357,7 +358,7 @@ mod tests { ...@@ -357,7 +358,7 @@ mod tests {
); );
} }
static mut DB_TEST_BLOCKS_DESC: Option<BcDbRo> = None; static DB_TEST_BLOCKS_DESC: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_blocks_order_desc() { fn test_graphql_blocks_order_desc() {
...@@ -393,7 +394,7 @@ mod tests { ...@@ -393,7 +394,7 @@ mod tests {
]) ])
}); });
let global_context = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS_DESC }); let global_context = tests::setup(mock_db, &DB_TEST_BLOCKS_DESC);
tests::test_gql_query( tests::test_gql_query(
global_context, global_context,
...@@ -420,7 +421,7 @@ mod tests { ...@@ -420,7 +421,7 @@ mod tests {
); );
} }
static mut DB_TEST_BLOCKS: Option<BcDbRo> = None; static DB_TEST_BLOCKS: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_blocks() { fn test_graphql_blocks() {
...@@ -456,7 +457,7 @@ mod tests { ...@@ -456,7 +457,7 @@ mod tests {
]) ])
}); });
let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_BLOCKS }); let schema = tests::setup(mock_db, &DB_TEST_BLOCKS);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
......
...@@ -40,9 +40,10 @@ mod tests { ...@@ -40,9 +40,10 @@ mod tests {
use dup_crypto_tests_tools::mocks::{hash, pubkey}; use dup_crypto_tests_tools::mocks::{hash, pubkey};
use durs_bc_db_reader::blocks::BlockDb; use durs_bc_db_reader::blocks::BlockDb;
use mockall::predicate::eq; use mockall::predicate::eq;
use once_cell::sync::OnceCell;
use serde_json::json; use serde_json::json;
static mut DB_TEST_CURRENT_1: Option<BcDbRo> = None; static DB_TEST_CURRENT_1: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_current() { fn test_graphql_current() {
...@@ -70,7 +71,7 @@ mod tests { ...@@ -70,7 +71,7 @@ mod tests {
.with(eq(pubkey('B'))) .with(eq(pubkey('B')))
.returning(|_| Ok(Some("issuerName".to_owned()))); .returning(|_| Ok(Some("issuerName".to_owned())));
let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_CURRENT_1 }); let schema = tests::setup(mock_db, &DB_TEST_CURRENT_1);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
......
...@@ -31,9 +31,10 @@ mod tests { ...@@ -31,9 +31,10 @@ mod tests {
use crate::schema::queries::tests; use crate::schema::queries::tests;
use dubp_common_doc::BlockNumber; use dubp_common_doc::BlockNumber;
use durs_bc_db_reader::current_metadata::current_ud::CurrentUdDb; use durs_bc_db_reader::current_metadata::current_ud::CurrentUdDb;
use once_cell::sync::OnceCell;
use serde_json::json; use serde_json::json;
static mut DB_TEST_CURRENT_UD_1: Option<BcDbRo> = None; static DB_TEST_CURRENT_UD_1: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_current_ud() { fn test_graphql_current_ud() {
...@@ -52,7 +53,7 @@ mod tests { ...@@ -52,7 +53,7 @@ mod tests {
})) }))
}); });
let schema = tests::setup(mock_db, unsafe { &mut DB_TEST_CURRENT_UD_1 }); let schema = tests::setup(mock_db, &DB_TEST_CURRENT_UD_1);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
......
...@@ -36,13 +36,14 @@ pub(crate) fn execute( ...@@ -36,13 +36,14 @@ pub(crate) fn execute(
mod tests { mod tests {
use crate::db::BcDbRo; use crate::db::BcDbRo;
use crate::schema::queries::tests; use crate::schema::queries::tests;
use once_cell::sync::OnceCell;
use serde_json::json; use serde_json::json;
static mut DB_TEST_NODE_SUMMARY: Option<BcDbRo> = None; static DB_TEST_NODE_SUMMARY: OnceCell<BcDbRo> = OnceCell::new();
#[test] #[test]
fn test_graphql_node_summary() { fn test_graphql_node_summary() {
let schema = tests::setup(BcDbRo::new(), unsafe { &mut DB_TEST_NODE_SUMMARY }); let schema = tests::setup(BcDbRo::new(), &DB_TEST_NODE_SUMMARY);
tests::test_gql_query( tests::test_gql_query(
schema, schema,
......
...@@ -27,10 +27,11 @@ use durs_module::SoftwareMetaDatas; ...@@ -27,10 +27,11 @@ use durs_module::SoftwareMetaDatas;
use durs_network_documents::host::Host; use durs_network_documents::host::Host;
use durs_network_documents::url::Url; use durs_network_documents::url::Url;
use juniper::http::graphiql::graphiql_source; use juniper::http::graphiql::graphiql_source;
use once_cell::sync::OnceCell;
use std::net::SocketAddr; use std::net::SocketAddr;
/// Database readonly handler (access to database) /// Database readonly handler (access to database)
static mut DB_RO_HANDLER: Option<BcDbRo> = None; static DB_RO_HANDLER: OnceCell<BcDbRo> = OnceCell::new();
async fn graphiql() -> HttpResponse { async fn graphiql() -> HttpResponse {
let html = graphiql_source("/graphql"); let html = graphiql_source("/graphql");
...@@ -64,11 +65,13 @@ pub fn start_web_server( ...@@ -64,11 +65,13 @@ pub fn start_web_server(
let db = BcDbRo::new(); let db = BcDbRo::new();
// Give a static lifetime to the DB // Give a static lifetime to the DB
let db = durs_common_tools::fns::r#static::to_static_ref(db, unsafe { &mut DB_RO_HANDLER }); DB_RO_HANDLER
.set(db)
.expect("DB_RO_HANDLER already initialized !");
// Create global context // Create global context
let global_context = std::sync::Arc::new(GlobalContext::new( let global_context = std::sync::Arc::new(GlobalContext::new(
db, &DB_RO_HANDLER,
create_schema(), create_schema(),
soft_meta_datas.soft_name, soft_meta_datas.soft_name,
soft_meta_datas.soft_version, soft_meta_datas.soft_version,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment