diff --git a/proto/api.proto b/proto/api.proto index 0ec6d99..6dc98d9 100644 --- a/proto/api.proto +++ b/proto/api.proto @@ -12,6 +12,8 @@ service Adresar { rpc GetAdresar (GetAdresarRequest) returns (AdresarResponse); rpc PutAdresar (PutAdresarRequest) returns (AdresarResponse); rpc DeleteAdresar (DeleteAdresarRequest) returns (DeleteAdresarResponse); + rpc GetAdresarCount (Empty) returns (CountResponse); // New endpoint + rpc GetAdresarByPosition (PositionRequest) returns (AdresarResponse); // New endpoint } message GetAdresarRequest { @@ -89,3 +91,14 @@ message DataResponse { message DeleteAdresarResponse { bool success = 1; // Indicates whether the deletion was successful } + +// New messages for the additional endpoints +message Empty {} // Empty request for count + +message CountResponse { + int64 count = 1; // Response with the count of items +} + +message PositionRequest { + int64 position = 1; // Request with the position of the item to retrieve +} diff --git a/src/adresar/docs/get_example.txt b/src/adresar/docs/get_example.txt new file mode 100644 index 0000000..5093a47 --- /dev/null +++ b/src/adresar/docs/get_example.txt @@ -0,0 +1,33 @@ +# TOTAL items in the adresar +❯ grpcurl -plaintext localhost:50051 multieko2.Adresar/GetAdresarCount +{ + "count": "43" +} + +# Item at this count. If there are 43 items, number 1 is the first item +❯ grpcurl -plaintext -d '{"position": 1}' localhost:50051 multieko2.Adresar/GetAdresarByPosition +{ + "id": "2", + "firma": "asdfasf", + "kz": " ", + "drc": " ", + "ulica": " ", + "psc": "sdfasdf", + "mesto": "asf", + "stat": "as", + "banka": "df", + "ucet": "asf", + "skladm": "f", + "ico": "f", + "kontakt": "f", + "telefon": "f", + "skladu": "f", + "fax": " " +} +# Item fetched by id. The first item was created and removed, therefore number 1 in ids doenst exists, since first to exist now has number 2 +❯ grpcurl -plaintext -d '{"id": 1}' localhost:50051 multieko2.Adresar/GetAdresar +ERROR: + Code: NotFound + Message: no rows returned by a query that expected to return at least one row +╭─    ~ ············································· 69 ✘ +╰─ diff --git a/src/adresar/handlers.rs b/src/adresar/handlers.rs index 294b352..72ae187 100644 --- a/src/adresar/handlers.rs +++ b/src/adresar/handlers.rs @@ -4,8 +4,12 @@ pub mod post_adresar; pub mod get_adresar; pub mod put_adresar; pub mod delete_adresar; +pub mod get_adresar_count; +pub mod get_adresar_by_position; pub use post_adresar::post_adresar; pub use get_adresar::get_adresar; pub use put_adresar::put_adresar; pub use delete_adresar::delete_adresar; +pub use get_adresar_count::get_adresar_count; +pub use get_adresar_by_position::get_adresar_by_position; diff --git a/src/adresar/handlers/get_adresar_by_position.rs b/src/adresar/handlers/get_adresar_by_position.rs new file mode 100644 index 0000000..17b73b5 --- /dev/null +++ b/src/adresar/handlers/get_adresar_by_position.rs @@ -0,0 +1,26 @@ +// src/adresar/handlers/get_by_position.rs +use tonic::{Status}; +use sqlx::PgPool; +use crate::proto::multieko2::{PositionRequest, AdresarResponse, GetAdresarRequest}; +use super::get_adresar; + +pub async fn get_adresar_by_position( + db_pool: &PgPool, + request: PositionRequest, +) -> Result { + if request.position < 1 { + return Err(Status::invalid_argument("Position must be at least 1")); + } + let offset = request.position - 1; + + let id: i64 = sqlx::query_scalar!( + "SELECT id FROM adresar ORDER BY id ASC OFFSET $1 LIMIT 1", + offset + ) + .fetch_optional(db_pool) + .await + .map_err(|e| Status::internal(e.to_string()))? + .ok_or_else(|| Status::not_found("Position out of bounds"))?; + + get_adresar(db_pool, GetAdresarRequest { id }).await +} diff --git a/src/adresar/handlers/get_adresar_count.rs b/src/adresar/handlers/get_adresar_count.rs new file mode 100644 index 0000000..ac5c943 --- /dev/null +++ b/src/adresar/handlers/get_adresar_count.rs @@ -0,0 +1,19 @@ +// src/adresar/handlers/get_adresar_count.rs +use tonic::{Status}; +use sqlx::PgPool; +use crate::proto::multieko2::{CountResponse, Empty}; + +pub async fn get_adresar_count( + db_pool: &PgPool, + _request: Empty, +) -> Result { + let count: i64 = sqlx::query_scalar!( + "SELECT COUNT(*) as count FROM adresar" + ) + .fetch_one(db_pool) + .await + .map_err(|e| Status::internal(e.to_string()))? + .unwrap_or(0); // Handle the case where the count is None + + Ok(CountResponse { count }) +} diff --git a/src/proto/descriptor.bin b/src/proto/descriptor.bin index de2945f..3d50045 100644 Binary files a/src/proto/descriptor.bin and b/src/proto/descriptor.bin differ diff --git a/src/server/mod.rs b/src/server/mod.rs index 07b20f5..7b172f7 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -2,10 +2,10 @@ use tonic::{Request, Response, Status}; use tonic_reflection::server::Builder as ReflectionBuilder; use crate::db; -use crate::adresar::handlers::{post_adresar, get_adresar, put_adresar, delete_adresar}; // Import the new handler +use crate::adresar::handlers::{post_adresar, get_adresar, put_adresar, delete_adresar, get_adresar_count, get_adresar_by_position}; use crate::proto::multieko2::{ PostAdresarRequest, AdresarResponse, GetAdresarRequest, PutAdresarRequest, - DeleteAdresarRequest, DeleteAdresarResponse, // Add these imports + DeleteAdresarRequest, DeleteAdresarResponse, PositionRequest, CountResponse, Empty, adresar_server::{Adresar, AdresarServer}, FILE_DESCRIPTOR_SET, }; @@ -47,6 +47,22 @@ impl Adresar for AdresarService { let response = delete_adresar(&self.db_pool, request.into_inner()).await?; Ok(Response::new(response)) } + + async fn get_adresar_count( + &self, + request: Request, + ) -> Result, Status> { + let response = get_adresar_count(&self.db_pool, request.into_inner()).await?; + Ok(Response::new(response)) + } + + async fn get_adresar_by_position( + &self, + request: Request, + ) -> Result, Status> { + let response = get_adresar_by_position(&self.db_pool, request.into_inner()).await?; + Ok(Response::new(response)) + } } pub async fn run_server(db_pool: sqlx::PgPool) -> Result<(), Box> {