From cee2bff94b2b7bf66bdd3992e9c66dc0a848a546 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 16 Jun 2026 14:32:32 +0200 Subject: [PATCH] implement methods and adjust grpc --- Cargo.lock | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++- grpc.proto | 4 +-- src/main.rs | 80 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 174 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b71c2ed..5d2b1a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,6 +251,12 @@ dependencies = [ "cmov", ] +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + [[package]] name = "digest" version = "0.10.7" @@ -907,7 +913,9 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" name = "nex-account" version = "0.1.0" dependencies = [ + "log", "prost", + "simplelog", "sqlx", "tokio", "tonic", @@ -915,6 +923,12 @@ dependencies = [ "tonic-prost-build", ] +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-traits" version = "0.2.19" @@ -924,6 +938,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1017,6 +1040,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.37" @@ -1280,6 +1309,17 @@ dependencies = [ "digest 0.11.3", ] +[[package]] +name = "simplelog" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" +dependencies = [ + "log", + "termcolor", + "time", +] + [[package]] name = "slab" version = "0.4.12" @@ -1355,6 +1395,8 @@ dependencies = [ "sha2 0.10.9", "smallvec", "thiserror", + "tokio", + "tokio-stream", "tracing", "url", ] @@ -1394,6 +1436,7 @@ dependencies = [ "sqlx-sqlite", "syn", "thiserror", + "tokio", "url", ] @@ -1540,6 +1583,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "2.0.18" @@ -1560,6 +1612,38 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.3" @@ -1920,6 +2004,15 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + [[package]] name = "windows-link" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index a903566..21ab909 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,9 @@ prost = "0.14.3" tonic-prost = "*" tonic = "0.14.6" tokio = { version = "1.52.3", features = ["macros", "rt-multi-thread"] } -sqlx = { version = "0.9.0", features = ["postgres"] } +sqlx = { version = "0.9.0", features = ["postgres", "runtime-tokio"] } +log = "0.4.32" +simplelog = "0.12.2" [build-dependencies] tonic-prost-build = "0.14.6" diff --git a/grpc.proto b/grpc.proto index 94978ec..ea379d4 100644 --- a/grpc.proto +++ b/grpc.proto @@ -4,7 +4,7 @@ package nex_account; message ActCreateInfoNoPid { string principal_name = 1; - string key = 2; + bytes key = 2; string email = 3; } @@ -13,7 +13,7 @@ message PID { } message NexKey { - string key = 1; + bytes key = 1; } service NexAccountService { diff --git a/src/main.rs b/src/main.rs index b000277..c58e929 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,10 @@ use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, }; -use sqlx::PgPool; -use tonic::transport::Server; +use log::error; +use simplelog::{Config, TerminalMode}; +use sqlx::{PgPool, query}; +use tonic::{Response, transport::Server}; use crate::grpc::{ ActCreateInfoNoPid, NexKey, Pid, @@ -17,25 +19,95 @@ pub struct NexAccountServer { pool: PgPool, } +pub async fn next_pid(pool: &PgPool) -> i32 { + loop { + let next_pid = sqlx::query!("SELECT nextval('pid_seq') as pid") + .fetch_one(pool) + .await + .expect("unable to get next pid") + .pid + .expect("unable to get next pid") as i32; + + let already_exists = sqlx::query!( + "SELECT EXISTS(select 1 from nex_accounts where pid = $1)", + next_pid + ) + .fetch_one(pool) + .await + .ok() + .map(|v| v.exists) + .flatten() + .unwrap_or(true); + + if !already_exists { + break next_pid; + } + } +} + +/// use this on the sqlx error to print the error message and return a status indicating its not availible currently to the caller +fn db_neverfail(sql_err: sqlx::Error) -> tonic::Status { + error!("sqlx error occurred: {}", sql_err); + tonic::Status::aborted("error in database") +} + #[tonic::async_trait] impl NexAccountService for NexAccountServer { async fn create_new_sequential_or_update_and_get_account( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status> { - todo!() + let request = request.into_inner(); + + let next_pid = next_pid(&self.pool).await; + query!( + "insert into nex_accounts ( + pid, principal_name, email, nex_key + ) values ( + $1, $2, $3, $4 + )", + next_pid, + request.principal_name, + request.email, + &request.key[..] + ) + .execute(&self.pool) + .await + .map_err(db_neverfail)?; + Ok(Response::new(Pid { pid: next_pid })) } async fn get_nex_key_by_pid( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status> { - todo!() + let pid = request.into_inner().pid; + + let sql_res = query!("select nex_key from nex_accounts where pid = $1", pid) + .fetch_optional(&self.pool) + .await + .map_err(db_neverfail)?; + + if let Some(res) = sql_res { + Ok(Response::new(NexKey { key: res.nex_key })) + } else { + Err(tonic::Status::not_found( + "nex account with provided pid does not exist", + )) + } } } #[tokio::main] async fn main() { + simplelog::TermLogger::init( + log::LevelFilter::Debug, + Config::default(), + TerminalMode::Mixed, + simplelog::ColorChoice::Auto, + ) + .expect("unable to set logger"); + let db_url = env::var("DATABASE_URL").expect("database url not specified"); let pool = PgPool::connect(&db_url) .await