fix: resolve PostgreSQL type mismatches and add willexecutor debug logging

- Fix get_next_address_index: use try_get::<i32> for PG SERIAL/INTEGER columns
- Fix search_tx: use try_get::<i32> for PG status column
- Fix execute_insert: parse locktime (String→i64) and in_vout (String→i32)
  before binding to PG INTEGER columns
- Fix execute_insert: bind tbl_out vout as i32, amount as String for PG
- Fix save_new_address: cast xpub i64 to i32 for PG INTEGER column
- Fix get_pending_txs: cast i64 bind params to i32, use try_get::<i32> for reads
- Fix get_stats: use try_get::<i32> for all numeric PG INTEGER columns
- Add trace logging in parse_request_transactions for xpub address matching
- Add trace logging in get_all_addresses_by_xpub for query debugging
This commit is contained in:
2026-08-18 03:14:03 -04:00
parent 8dc344cbd1
commit 8f764f06b2
65 changed files with 4879 additions and 1188 deletions

271
update Normal file
View File

@@ -0,0 +1,271 @@
Per creare un Webservice in Rust che utilizza Axis (un framework per la definizione di servizi web basato su XML Schema) e Diesel (un ORM per database SQLite), dobbiamo seguire alcuni passaggi. Tuttavia, è
importante notare che l'uso diretto di Axis con Diesel non è il modo più comune o consigliato per creare servizi web in Rust. Più spesso si usa Axum o Rocket come framework principale.
Tuttavia, posso mostrarti un esempio molto simplificato di come potresti iniziare a strutturare il tuo progetto utilizzando Diesel con SQLite3 e una libreria esterna per la definizione dei servizi web. Per
brevità, utilizzeremo `axum`, che è uno dei framework più popolari per creare servizi web in Rust.
### Prerequisiti
1. Installa Rust: https://www.rust-lang.org/tools/install
2. Crea un nuovo progetto con Cargo:
```sh
cargo new rust_sqlite_webserver
cd rust_sqlite_webserver
```
3. Aggiungi le dipendenze al file `Cargo.toml`:
```toml
[dependencies]
axum = "0.6"
tokio = { version = "1", features = ["full"] }
diesel = { version = "2.0", features = ["sqlite"] }
dotenv = "0.15"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[build-dependencies]
diesel_cli = { version = "2.0", features = ["sqlite"] }
[[bin]]
name = "main"
path = "src/main.rs"
```
### Schema di Database
Creiamo un semplice schema per un database SQLite3 con Diesel.
1. Crea il file `schema.rs` in una nuova directory `src/schema/`.
```rust
// src/schema/users.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email TEXT NOT NULL UNIQUE
);
```
2. Genera i modelli Diesel:
```sh
cargo run --bin diesel_cli setup
cargo run --bin diesel_cli migrate
```
### Creazione del Servizio Web con Axum
1. Crea un file `main.rs` nella directory `src/`.
```rust
use axum::{
routing::get,
Router,
};
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use std::env;
mod schema;
mod models;
// Importiamo i modelli generati da Diesel
use self::schema::users::dsl::*;
#[derive(Serialize)]
struct User {
id: i32,
name: String,
email: String,
}
impl From<models::User> for User {
fn from(user: models::User) -> Self {
User {
id: user.id,
name: user.name,
email: user.email,
}
}
}
#[derive(Deserialize, Insertable)]
#[diesel(table_name = users)]
struct NewUser {
name: String,
email: String,
}
async fn get_users() -> impl axum::response::IntoResponse {
let conn = establish_connection();
let results = users.load::<models::User>(&conn).expect("Error loading users");
(axum::http::StatusCode::OK, axum::Json(results.into_iter().map(User::from).collect()))
}
async fn create_user(user: axum::Json<NewUser>) -> impl axum::response::IntoResponse {
let conn = establish_connection();
let new_user = user.0;
diesel::insert_into(users)
.values(&new_user)
.get_result::<models::User>(&conn)
.expect("Error creating new user");
(axum::http::StatusCode::CREATED, axum::Json(User::from(new_user)))
}
fn establish_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}
#[tokio::main]
async fn main() {
// Set the `RUST_LOG` environment variable if you want to see logs
env_logger::init();
let app = Router::new()
.route("/users", get(get_users).post(create_user));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
```
### Esecuzione del Progetto
1. Crea un file `.env` nella directory root con la seguente riga:
```sh
DATABASE_URL=sqlite://db.sqlite3
```
2. Esegui il progetto:
```sh
cargo run
```
Ora, puoi accedere al tuo servizio web:
- Per ottenere tutti gli utenti: `GET http://localhost:3000/users`
- Per creare un nuovo utente: `POST http://localhost:3000/users` con il corpo JSON:
```json
{
"name": "John Doe",
"email": "john.doe@example.com"
}
```
Questo esempio mostra come iniziare a strutturare un servizio web in Rust utilizzando Axum, Diesel con SQLite3. Ricorda che questo è solo un punto di partenza e potrebbe essere esteso o modificato per
soddisfare le tue specifiche esigenze.
>>> il mio progetto prevede vari file binari, oltre al webservice come posso gestire piu' binari?
Se il tuo progetto in Rust contiene diversi file binari (ad esempio, un client e un server separati), puoi organizzarli in moduli all'interno del tuo progetto. Ogni modulo può essere compilato come un file
binario separato.
Ecco come farlo:
1. **Struttura del Progetto**:
Organizza il tuo progetto in una directory `src` con sottodirectory per i vari binari e moduli. Ad esempio:
```
rust_project/
├── src/
│ ├── main.rs
│ ├── client/
│ │ └── main.rs
│ ├── server/
│ │ └── main.rs
│ └── common/
│ └── lib.rs
├── Cargo.toml
└── .env
```
2. **Creazione dei Binari**:
Ogni sottodirectory con un file `main.rs` può essere considerata un binario separato.
3. **Cargo.toml**:
Configura il tuo `Cargo.toml` per gestire i vari binari.
```toml
[package]
name = "rust_project"
version = "0.1.0"
edition = "2018"
[dependencies]
axum = "0.6"
tokio = { version = "1", features = ["full"] }
diesel = { version = "2.0", features = ["sqlite"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[build-dependencies]
diesel_cli = { version = "2.0", features = ["sqlite"] }
[[bin]]
name = "server"
path = "src/server/main.rs"
[[bin]]
name = "client"
path = "src/client/main.rs"
```
4. **Esecuzione dei Binari**:
Puoi ora compilare e eseguire i binari separati.
```sh
cargo build --release
./target/release/server
./target/release/client
```
5. **Moduli Comuni**:
Se hai moduli comuni che vengono utilizzati da più binari, puoi organizzarli in una directory `common` e importarli nei vari binari.
```rust
// src/common/lib.rs
pub mod common_module {
pub fn common_function() {
println!("This is a common function");
}
}
```
Allora, puoi importare questo modulo in altri binari:
```rust
// src/server/main.rs
extern crate rust_project;
use rust_project::common::lib as common;
fn main() {
common::common_function();
}
```
6. **File `.env`**:
Puoi avere un file `.env` nella directory root del progetto per gestire le variabili d'ambiente comuni, e poi specificare variabili d'ambiente separate per ogni binario in sottodirectory.
```sh
# .env
DATABASE_URL=sqlite://db.sqlite3
# src/server/.env
SERVER_PORT=3000
# src/client/.env
CLIENT_IP=localhost
```
Questo approccio ti permette di mantenere una struttura organizzata per i tuoi progetti multi-binari in Rust, facilitando la gestione e il sviluppo di diverse parti del tuo progetto.