Skip to content

Commit

Permalink
feat: add count route
Browse files Browse the repository at this point in the history
  • Loading branch information
marvin-j97 committed Feb 2, 2024
1 parent eccff6e commit 6e45e71
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 12 deletions.
80 changes: 80 additions & 0 deletions server/src/api/count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::app_state::AppState;
use crate::error::CustomRouteResult;
use crate::identifier::is_valid_table_identifier;
use crate::response::build_response;
use actix_web::http::StatusCode;
use actix_web::{
post,
web::{self, Path},
HttpResponse,
};
use serde_json::json;

#[post("/v1/table/{name}/count")]
pub async fn handler(
path: Path<String>,
app_state: web::Data<AppState>,
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let table_name = path.into_inner();

if table_name.starts_with('_') {
return Ok(build_response(
before.elapsed(),
StatusCode::BAD_REQUEST,
"Invalid table name",
&json!(null),
));
}

if !is_valid_table_identifier(&table_name) {
return Ok(build_response(
before.elapsed(),
StatusCode::BAD_REQUEST,
"Invalid table name",
&json!(null),
));
}

let tables = app_state.tables.read().await;

if let Some(table) = tables.get(&table_name) {
let (row_count, cell_count) = {
let table = table.clone();

tokio::task::spawn_blocking(move || table.count())
.await
.expect("should join")
}?;

let dur = before.elapsed();

let micros_total = dur.as_micros();

let micros_per_row = if row_count == 0 {
None
} else {
Some(micros_total / row_count as u128)
};

Ok(build_response(
dur,
StatusCode::OK,
"Count successful",
&json!({
"row_count": row_count,
"cell_count": cell_count,
"micros": micros_total,
"micros_per_row": micros_per_row,
}),
))
} else {
Ok(build_response(
before.elapsed(),
StatusCode::NOT_FOUND,
"Table not found",
&json!(null),
))
}
}
4 changes: 2 additions & 2 deletions server/src/api/delete_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ pub async fn handler(
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let tables = app_state.tables.read().await;

let table_name = path.into_inner();

if table_name.starts_with('_') {
Expand All @@ -53,6 +51,8 @@ pub async fn handler(

let req_body = req_body.into_inner();

let tables = app_state.tables.read().await;

if let Some(table) = tables.get(&table_name) {
let count = {
let table = table.clone();
Expand Down
4 changes: 2 additions & 2 deletions server/src/api/delete_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ pub async fn handler(
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let mut tables = app_state.tables.write().await;

let table_name = path.into_inner();

if table_name.starts_with('_') {
Expand All @@ -39,6 +37,8 @@ pub async fn handler(
));
}

let mut tables = app_state.tables.write().await;

if let Some(table) = tables.get(&table_name).cloned() {
app_state.manifest_table.delete_user_table(&table_name)?;
tables.remove(&table_name);
Expand Down
4 changes: 2 additions & 2 deletions server/src/api/get_rows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ pub async fn handler(
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let tables = app_state.tables.read().await;

let table_name = path.into_inner();

if table_name.starts_with('_') {
Expand All @@ -48,6 +46,8 @@ pub async fn handler(
));
}

let tables = app_state.tables.read().await;

if let Some(table) = tables.get(&table_name) {
let result = {
let table = table.clone();
Expand Down
4 changes: 2 additions & 2 deletions server/src/api/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ pub async fn handler(
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let tables = app_state.tables.write().await;

let table_name = path.into_inner();

let actual_name = format!("usr_{table_name}");

let tables = app_state.tables.write().await;

if tables.get(&actual_name).is_some() {
/* let rows = app_state
.metrics_table
Expand Down
1 change: 1 addition & 0 deletions server/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod count;
pub mod create_column_family;
pub mod create_table;
pub mod delete_row;
Expand Down
4 changes: 2 additions & 2 deletions server/src/api/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pub async fn handler(
) -> CustomRouteResult<HttpResponse> {
let before = std::time::Instant::now();

let tables = app_state.tables.read().await;

let table_name = path.into_inner();

if table_name.starts_with('_') {
Expand All @@ -42,6 +40,8 @@ pub async fn handler(
));
}

let tables = app_state.tables.read().await;

if let Some(table) = tables.get(&table_name) {
let result = {
let table = table.clone();
Expand Down
4 changes: 2 additions & 2 deletions server/src/api/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ pub async fn handler(
return bad_request(before, "Items array should not be empty");
}

let tables = app_state.tables.read().await;

let table_name = path.into_inner();

if table_name.starts_with('_') {
Expand All @@ -54,6 +52,8 @@ pub async fn handler(
));
}

let tables = app_state.tables.read().await;

if let Some(table) = tables.get(&table_name).cloned() {
// TODO: use spawn_blocking

Expand Down
1 change: 1 addition & 0 deletions server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ async fn main() -> smoltable::Result<()> {
.service(api::list_tables::handler)
.service(api::create_table::handler)
.service(api::write::handler)
.service(api::count::handler)
.service(api::get_rows::handler)
.service(api::delete_row::handler)
.service(api::scan::handler)
Expand Down

0 comments on commit 6e45e71

Please sign in to comment.