Skip to content

Commit

Permalink
moved mongo schema to new file
Browse files Browse the repository at this point in the history
  • Loading branch information
MyK00L committed Oct 13, 2021
1 parent 2f4ecd3 commit 30ba04c
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 124 deletions.
128 changes: 4 additions & 124 deletions contest_service/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ use std::convert::TryFrom;
use mappings::chat::Message;
use mongodb::{
bson::{doc, Document},
options::{
ClientOptions, CreateCollectionOptions, UpdateOptions, ValidationAction, ValidationLevel,
},
Client, Database,
options::{ClientOptions, UpdateOptions},
Client,
};
use protos::service::contest::{contest_server::*, *};
use protos::utils::*;
use tonic::{transport::*, Request, Response, Status};

mod mappings;

mod mongo_schema;
#[cfg(test)]
mod tests;

Expand All @@ -29,125 +28,6 @@ where
Status::internal(format!("{:?}", e))
}

async fn init_contest_service_db(db: Database) -> Result<(), Box<dyn std::error::Error>> {
// TODO: consider using this validator syntax (might be slightly nicer):
// https://docs.mongodb.com/v5.0/core/schema-validation/#other-query-expressions
db.create_collection(
"contest_metadata",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["name", "description"],
"properties": {
"name": { "bsonType": "string" },
"description": { "bsonType": "string" },
"startTime": { "bsonType": "timestamp" }, // missing means there is no start time
"endTime": { "bsonType": "timestamp" } // missing means there is no end time
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.capped(true)
.max(1)
// Size must be set if we want to used capped. SWe set it to an unreachable value (1 MB) so
// it will never be reached by our singleton document (enforced by max(1)).
.size(2_u64.pow(20))
.build(),
)
.await?;

db.create_collection(
"problems",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "name", "longName", "statement"],
"properties": {
"_id": { "bsonType": "int" }, // problem id
"name": { "bsonType": "string" },
"longName": { "bsonType": "string" },
"statement": { "bsonType": "binData" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"users",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "fullname", "password"],
"properties": {
"_id": { "bsonType": "string" }, // username
"fullname": { "bsonType": "string" },
"password": { "bsonType": "string" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"announcements",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "subject", "text", "created"],
"properties": {
"_id": { "bsonType": "int" }, // announcement id
"subject": { "bsonType": "string" },
"problemId": { "bsonType": "int" },
"text": { "bsonType": "string" },
"to": { "bsonType": "string" },
"created": { "bsonType": "timestamp" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"questions",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "subject", "text", "created"],
"properties": {
"_id": { "bsonType": "int" }, // question id
"subject": { "bsonType": "string" },
"problemId": { "bsonType": "int" },
"text": { "bsonType": "string" },
"from": { "bsonType": "string" },
"created": { "bsonType": "timestamp" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

Ok(())
}

#[derive(Debug)]
pub struct ContestService {
db_client: Client,
Expand All @@ -156,7 +36,7 @@ pub struct ContestService {
impl ContestService {
async fn new() -> Result<Self, Box<dyn std::error::Error>> {
let db_client = Client::with_options(ClientOptions::parse(CONNECTION_STRING).await?)?;
init_contest_service_db(db_client.database("contestdb")).await?;
mongo_schema::init_contest_service_db(db_client.database("contestdb")).await?;
Ok(Self { db_client })
}

Expand Down
124 changes: 124 additions & 0 deletions contest_service/src/mongo_schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use mongodb::{
bson::doc,
options::{CreateCollectionOptions, ValidationAction, ValidationLevel},
Database,
};

pub async fn init_contest_service_db(db: Database) -> Result<(), Box<dyn std::error::Error>> {
// TODO: consider using this validator syntax (might be slightly nicer):
// https://docs.mongodb.com/v5.0/core/schema-validation/#other-query-expressions
db.create_collection(
"contest_metadata",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["name", "description"],
"properties": {
"name": { "bsonType": "string" },
"description": { "bsonType": "string" },
"startTime": { "bsonType": "timestamp" }, // missing means there is no start time
"endTime": { "bsonType": "timestamp" } // missing means there is no end time
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.capped(true)
.max(1)
// Size must be set if we want to used capped. SWe set it to an unreachable value (1 MB) so
// it will never be reached by our singleton document (enforced by max(1)).
.size(2_u64.pow(20))
.build(),
)
.await?;

db.create_collection(
"problems",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "name", "longName", "statement"],
"properties": {
"_id": { "bsonType": "int" }, // problem id
"name": { "bsonType": "string" },
"longName": { "bsonType": "string" },
"statement": { "bsonType": "binData" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"users",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "fullname", "password"],
"properties": {
"_id": { "bsonType": "string" }, // username
"fullname": { "bsonType": "string" },
"password": { "bsonType": "string" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"announcements",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "subject", "text", "created"],
"properties": {
"_id": { "bsonType": "int" }, // announcement id
"subject": { "bsonType": "string" },
"problemId": { "bsonType": "int" },
"text": { "bsonType": "string" },
"to": { "bsonType": "string" },
"created": { "bsonType": "timestamp" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

db.create_collection(
"questions",
CreateCollectionOptions::builder()
.validator(doc! {
"$jsonSchema": {
"bsonType": "object",
"required": ["_id", "subject", "text", "created"],
"properties": {
"_id": { "bsonType": "int" }, // question id
"subject": { "bsonType": "string" },
"problemId": { "bsonType": "int" },
"text": { "bsonType": "string" },
"from": { "bsonType": "string" },
"created": { "bsonType": "timestamp" }
}
}
})
.validation_action(ValidationAction::Error)
.validation_level(ValidationLevel::Strict)
.build(),
)
.await?;

Ok(())
}

0 comments on commit 30ba04c

Please sign in to comment.