got first query running
This commit is contained in:
parent
2ad9dd4f71
commit
a9476556b1
6 changed files with 76 additions and 6 deletions
|
@ -7,6 +7,8 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossterm = "0.26.1"
|
crossterm = "0.26.1"
|
||||||
|
futures = "0.3.28"
|
||||||
|
log = "0.4.19"
|
||||||
ratatui = "0.21.0"
|
ratatui = "0.21.0"
|
||||||
simplelog = "0.12.1"
|
simplelog = "0.12.1"
|
||||||
sqlx = { version = "0.6.3", features = ["postgres", "runtime-tokio-native-tls", "sqlite"] }
|
sqlx = { version = "0.6.3", features = ["postgres", "runtime-tokio-native-tls", "sqlite"] }
|
||||||
|
|
|
@ -59,6 +59,7 @@ CREATE TABLE rcnt.transactions (
|
||||||
trns_description varchar(250) NULL,
|
trns_description varchar(250) NULL,
|
||||||
trns_account int4 NOT NULL,
|
trns_account int4 NOT NULL,
|
||||||
trns_bucket int4 NULL,
|
trns_bucket int4 NULL,
|
||||||
|
trns_date Date not null,
|
||||||
CONSTRAINT transactions_pkey PRIMARY KEY (trns_id)
|
CONSTRAINT transactions_pkey PRIMARY KEY (trns_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
32
src/app.rs
32
src/app.rs
|
@ -1,10 +1,18 @@
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crossterm::event::{Event, self, KeyCode};
|
use crossterm::event::{Event, self, KeyCode};
|
||||||
|
use tokio;
|
||||||
use ratatui::widgets::ListState;
|
use ratatui::widgets::ListState;
|
||||||
|
|
||||||
|
use log::warn;
|
||||||
|
|
||||||
|
use crate::db::DB;
|
||||||
use crate::uis::history::HistoryState;
|
use crate::uis::history::HistoryState;
|
||||||
use crate::uis::new_transaction::NewTransactionTabState;
|
use crate::uis::new_transaction::NewTransactionTabState;
|
||||||
use crate::uis::navigation_frame::NavigationState;
|
use crate::uis::navigation_frame::NavigationState;
|
||||||
|
use crate::db::transaction::TransactionRecord;
|
||||||
|
|
||||||
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
|
@ -65,14 +73,19 @@ pub struct App<'a> {
|
||||||
pub states: States<'a>,
|
pub states: States<'a>,
|
||||||
|
|
||||||
pub input_mode: InputMode,
|
pub input_mode: InputMode,
|
||||||
|
|
||||||
|
pub db: Arc<tokio::sync::Mutex<DB>>,
|
||||||
|
pub records: Arc<Mutex<Vec<TransactionRecord>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> App<'a> {
|
impl<'a> App<'a> {
|
||||||
pub fn new() -> App<'a> {
|
pub fn new(db: DB, records: Arc<Mutex<Vec<TransactionRecord>>>) -> App<'a> {
|
||||||
App {
|
App {
|
||||||
running: true,
|
running: true,
|
||||||
states: States::new(),
|
states: States::new(),
|
||||||
input_mode: InputMode::Normal,
|
input_mode: InputMode::Normal,
|
||||||
|
db: Arc::new(tokio::sync::Mutex::new(db)),
|
||||||
|
records,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +114,9 @@ impl<'a> App<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let KeyCode::Char('r') = key.code {
|
||||||
|
self.refresh();
|
||||||
|
}
|
||||||
match self.states.active_frame {
|
match self.states.active_frame {
|
||||||
ActiveFrame::Navigation => {
|
ActiveFrame::Navigation => {
|
||||||
NavigationState::handle_event(key, self);
|
NavigationState::handle_event(key, self);
|
||||||
|
@ -115,6 +131,20 @@ impl<'a> App<'a> {
|
||||||
}
|
}
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh(&mut self) {
|
||||||
|
|
||||||
|
let fut = Arc::clone(&self.db);
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let res = fut.lock().await.get_all_records().await;
|
||||||
|
match res {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => warn!("{}", e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ActiveFrame {
|
pub enum ActiveFrame {
|
||||||
|
|
|
@ -1,20 +1,53 @@
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use futures::TryStreamExt;
|
||||||
|
|
||||||
|
use sqlx::Error;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
use sqlx::Row;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
|
|
||||||
|
use crate::db::transaction::TransactionRecord;
|
||||||
|
|
||||||
pub struct DB {
|
pub struct DB {
|
||||||
conn_pool: PgPool,
|
conn_pool: PgPool,
|
||||||
|
|
||||||
|
records: Arc<Mutex<Vec<TransactionRecord>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl DB {
|
impl DB {
|
||||||
pub async fn new() -> Result<DB, sqlx::Error> {
|
pub async fn new(records: Arc<Mutex<Vec<TransactionRecord>>>) -> Result<DB, sqlx::Error> {
|
||||||
let connection_pool = PgPoolOptions::new()
|
let connection_pool = PgPoolOptions::new()
|
||||||
.max_connections(3)
|
.max_connections(3)
|
||||||
.connect("postgres://rcntuser:Devel@pmentPa$$w0rd@10.0.0.183/Borealis").await?;
|
.connect("postgres://rcntuser:Devel@pmentPa$$w0rd@10.0.0.183/Borealis").await?;
|
||||||
Ok(DB {
|
Ok(DB {
|
||||||
conn_pool: connection_pool,
|
conn_pool: connection_pool,
|
||||||
|
records,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_all_records(&mut self) -> Result<(), Error> {
|
||||||
|
let mut rows = sqlx::query("SELECT trns_id, trns_amount, trns_description, trns_account, trns_bucket trns_date FROM rcnt.transactions")
|
||||||
|
.fetch(&self.conn_pool);
|
||||||
|
|
||||||
|
while let Some(row) = rows.try_next().await? {
|
||||||
|
let id: i64 = row.try_get("trns_id")?;
|
||||||
|
let amount: &str = row.try_get("trns_amount")?;
|
||||||
|
let date: &str = row.try_get("trns_date")?;
|
||||||
|
self.records.lock().unwrap().push(
|
||||||
|
TransactionRecord{
|
||||||
|
id: id.into(),
|
||||||
|
amount: amount.to_string(),
|
||||||
|
date: date.to_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
// cargo add crust_decimal
|
// cargo add crust_decimal
|
||||||
pub struct TransactionRecord {
|
pub struct TransactionRecord {
|
||||||
pub id: usize,
|
pub id: i64,
|
||||||
// pub amount: Decimal,
|
// pub amount: Decimal,
|
||||||
pub amount: String,
|
pub amount: String,
|
||||||
//pub record_date: Date,
|
//pub record_date: Date,
|
||||||
|
@ -11,7 +11,7 @@ pub struct TransactionRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionRecord {
|
impl TransactionRecord {
|
||||||
pub fn new(id: usize, amount: String, record_date: String) -> TransactionRecord {
|
pub fn new(id: i64, amount: String, record_date: String) -> TransactionRecord {
|
||||||
TransactionRecord {
|
TransactionRecord {
|
||||||
id,
|
id,
|
||||||
amount,
|
amount,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
|
@ -12,6 +14,7 @@ use ratatui::{
|
||||||
use recount::app::{App, AppResult};
|
use recount::app::{App, AppResult};
|
||||||
use recount::tui::Tui;
|
use recount::tui::Tui;
|
||||||
use recount::db::DB;
|
use recount::db::DB;
|
||||||
|
use recount::db::transaction::TransactionRecord;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> AppResult<()> {
|
async fn main() -> AppResult<()> {
|
||||||
|
@ -19,10 +22,11 @@ async fn main() -> AppResult<()> {
|
||||||
let log_file = "testing_log.txt".to_string();
|
let log_file = "testing_log.txt".to_string();
|
||||||
init_logger(log_file);
|
init_logger(log_file);
|
||||||
|
|
||||||
let db = DB::new().await?;
|
let records = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
let db = DB::new(Arc::clone(&records)).await?;
|
||||||
|
|
||||||
// Create an application.
|
// Create an application.
|
||||||
let mut app = App::new();
|
let mut app = App::new(db, records);
|
||||||
|
|
||||||
// Initialize the terminal user interface.
|
// Initialize the terminal user interface.
|
||||||
let backend = CrosstermBackend::new(io::stderr());
|
let backend = CrosstermBackend::new(io::stderr());
|
||||||
|
|
Loading…
Reference in a new issue