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:
271
update_codebase.txt
Normal file
271
update_codebase.txt
Normal 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.
|
||||
|
||||
Reference in New Issue
Block a user