feat(transactions): add single-node transaction support with session-aware reads, commits, aborts, and transaction metrics
This commit is contained in:
@@ -2,8 +2,9 @@ use bson::{doc, Bson, Document};
|
||||
use rustdb_index::IndexEngine;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::context::{CommandContext, CursorState};
|
||||
use crate::context::{CommandContext, ConnectionState, CursorState};
|
||||
use crate::error::{CommandError, CommandResult};
|
||||
use crate::transactions;
|
||||
|
||||
/// Handle various admin / diagnostic / session / auth commands.
|
||||
pub async fn handle(
|
||||
@@ -11,6 +12,7 @@ pub async fn handle(
|
||||
db: &str,
|
||||
ctx: &CommandContext,
|
||||
command_name: &str,
|
||||
connection: &ConnectionState,
|
||||
) -> CommandResult<Document> {
|
||||
match command_name {
|
||||
"ping" => Ok(doc! { "ok": 1.0 }),
|
||||
@@ -24,13 +26,7 @@ pub async fn handle(
|
||||
"ok": 1.0,
|
||||
}),
|
||||
|
||||
"serverStatus" => Ok(doc! {
|
||||
"host": "localhost",
|
||||
"version": "7.0.0",
|
||||
"process": "rustdb",
|
||||
"uptime": ctx.start_time.elapsed().as_secs() as i64,
|
||||
"ok": 1.0,
|
||||
}),
|
||||
"serverStatus" => handle_server_status(ctx),
|
||||
|
||||
"hostInfo" => Ok(doc! {
|
||||
"system": {
|
||||
@@ -90,13 +86,7 @@ pub async fn handle(
|
||||
"codeName": "CommandNotFound",
|
||||
}),
|
||||
|
||||
"connectionStatus" => Ok(doc! {
|
||||
"authInfo": {
|
||||
"authenticatedUsers": [],
|
||||
"authenticatedUserRoles": [],
|
||||
},
|
||||
"ok": 1.0,
|
||||
}),
|
||||
"connectionStatus" => Ok(handle_connection_status(connection)),
|
||||
|
||||
"createUser" => handle_create_user(cmd, db, ctx).await,
|
||||
|
||||
@@ -156,9 +146,9 @@ pub async fn handle(
|
||||
Ok(doc! { "ok": 1.0 })
|
||||
}
|
||||
|
||||
"commitTransaction" | "abortTransaction" => Err(CommandError::IllegalOperation(
|
||||
"Transaction numbers are only allowed on a replica set member or mongos".into(),
|
||||
)),
|
||||
"commitTransaction" => transactions::commit_transaction_command(cmd, ctx).await,
|
||||
|
||||
"abortTransaction" => transactions::abort_transaction_command(cmd, ctx),
|
||||
|
||||
// Auth stubs - accept silently.
|
||||
"saslStart" => Ok(doc! {
|
||||
@@ -195,6 +185,72 @@ pub async fn handle(
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_server_status(ctx: &CommandContext) -> CommandResult<Document> {
|
||||
let oplog_stats = ctx.oplog.stats();
|
||||
Ok(doc! {
|
||||
"host": "localhost",
|
||||
"version": "7.0.0",
|
||||
"process": "rustdb",
|
||||
"uptime": ctx.start_time.elapsed().as_secs() as i64,
|
||||
"connections": {
|
||||
"current": 0_i32,
|
||||
"available": i32::MAX,
|
||||
},
|
||||
"logicalSessionRecordCache": {
|
||||
"activeSessionsCount": ctx.sessions.len() as i64,
|
||||
},
|
||||
"transactions": {
|
||||
"currentActive": ctx.transactions.len() as i64,
|
||||
},
|
||||
"oplog": {
|
||||
"currentSeq": oplog_stats.current_seq as i64,
|
||||
"totalEntries": oplog_stats.total_entries as i64,
|
||||
"oldestSeq": oplog_stats.oldest_seq as i64,
|
||||
"entriesByOp": {
|
||||
"insert": oplog_stats.inserts as i64,
|
||||
"update": oplog_stats.updates as i64,
|
||||
"delete": oplog_stats.deletes as i64,
|
||||
},
|
||||
},
|
||||
"security": {
|
||||
"authentication": ctx.auth.enabled(),
|
||||
"users": ctx.auth.user_count() as i64,
|
||||
},
|
||||
"ok": 1.0,
|
||||
})
|
||||
}
|
||||
|
||||
fn handle_connection_status(connection: &ConnectionState) -> Document {
|
||||
let authenticated_users: Vec<Bson> = connection
|
||||
.authenticated_users
|
||||
.iter()
|
||||
.map(|user| {
|
||||
Bson::Document(doc! {
|
||||
"user": user.username.clone(),
|
||||
"db": user.database.clone(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let authenticated_roles: Vec<Bson> = connection
|
||||
.authenticated_users
|
||||
.iter()
|
||||
.flat_map(|user| {
|
||||
user.roles
|
||||
.iter()
|
||||
.map(|role| Bson::Document(role_to_document(&user.database, role)))
|
||||
})
|
||||
.collect();
|
||||
|
||||
doc! {
|
||||
"authInfo": {
|
||||
"authenticatedUsers": authenticated_users,
|
||||
"authenticatedUserRoles": authenticated_roles,
|
||||
},
|
||||
"ok": 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_create_user(
|
||||
cmd: &Document,
|
||||
db: &str,
|
||||
|
||||
Reference in New Issue
Block a user