* Insert a row and return Result-like type instead of throwing on error. * * This method provides the same functionality as insert() but returns * an InsertResult that contains either the successfully inserted row * (with auto-generated fields populated) or an InsertError with details * about what went wrong. * * @param row_data The row to insert * @retur
| 414 | * } |
| 415 | */ |
| 416 | InsertResult<T> try_insert(const T& row_data) { |
| 417 | SpacetimeDB::bsatn::Writer writer; |
| 418 | SpacetimeDB::bsatn::serialize(writer, row_data); |
| 419 | auto buffer_vec = writer.get_buffer(); |
| 420 | |
| 421 | // Prepare buffer with extra space for auto-increment writeback |
| 422 | const size_t original_len = buffer_vec.size(); |
| 423 | const size_t extra_space = detail::AUTO_INCREMENT_BUFFER_SPACE; |
| 424 | std::vector<uint8_t> buffer(buffer_vec.begin(), buffer_vec.end()); |
| 425 | buffer.resize(original_len + extra_space); |
| 426 | |
| 427 | size_t buffer_len = original_len; |
| 428 | Status status = ::datastore_insert_bsatn(table_id_, buffer.data(), &buffer_len); |
| 429 | |
| 430 | // Instead of calling detail::handle_ffi_error (which LOG_FATALs), |
| 431 | // handle errors and return appropriate InsertError |
| 432 | if (is_error(status)) { |
| 433 | InsertErrorType error_type; |
| 434 | std::string message; |
| 435 | |
| 436 | // Map status codes to our error types |
| 437 | if (status == StatusCode::UNIQUE_ALREADY_EXISTS) { |
| 438 | error_type = InsertErrorType::UniqueConstraintViolation; |
| 439 | message = "Unique constraint violation"; |
| 440 | } else if (status == StatusCode::AUTO_INC_OVERFLOW) { |
| 441 | error_type = InsertErrorType::AutoIncOverflow; |
| 442 | message = "Auto increment overflow"; |
| 443 | } else { |
| 444 | error_type = InsertErrorType::Other; |
| 445 | message = "Insert failed with status: " + std::string(StatusCode::to_string(status)); |
| 446 | } |
| 447 | |
| 448 | return InsertResult<T>(InsertError(error_type, status, message)); |
| 449 | } |
| 450 | |
| 451 | // Success path - same as current insert() |
| 452 | if (buffer_len == 0) { |
| 453 | // No auto-generated fields, return the original row |
| 454 | return InsertResult<T>(T(row_data)); |
| 455 | } |
| 456 | |
| 457 | // The buffer contains ONLY the generated column values in BSATN format |
| 458 | T updated_row = row_data; |
| 459 | SpacetimeDB::bsatn::Reader reader(buffer.data(), buffer_len); |
| 460 | detail::integrate_autoinc(updated_row, reader); |
| 461 | |
| 462 | return InsertResult<T>(std::move(updated_row)); |
| 463 | } |
| 464 | |
| 465 | |
| 466 | /** |
no test coverage detected