You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
4.3 KiB
159 lines
4.3 KiB
use std::{fs, path::Path}; |
|
|
|
use rusqlite::{self, params, Connection}; |
|
|
|
use crate::{ |
|
error::{AppError, AppResult}, |
|
models::{Candle, Trade}, |
|
}; |
|
|
|
pub struct Repo { |
|
conn: Connection, |
|
} |
|
|
|
impl Repo { |
|
pub fn new_init(db_path: impl AsRef<Path>) -> AppResult<Self> { |
|
let path = db_path.as_ref(); |
|
|
|
// постоянно создаём новую бд для упрощения тестирования |
|
fs::remove_file(path).ok(); |
|
|
|
let conn = Connection::open(path)?; |
|
|
|
conn.execute( |
|
" |
|
CREATE TABLE IF NOT EXISTS trades( |
|
symbol TEXT NOT NULL, |
|
amount TEXT NOT NULL, |
|
taker_side TEXT NOT NULL, |
|
quantity TEXT NOT NULL, |
|
create_time INT NOT NULL, |
|
price TEXT NOT NULL, |
|
id TEXT NOT NULL, |
|
ts INT NOT NULL |
|
); |
|
", |
|
[], |
|
)?; |
|
conn.execute( |
|
" |
|
CREATE TABLE IF NOT EXISTS candles( |
|
low TEXT NOT NULL, |
|
high TEXT NOT NULL, |
|
open TEXT NOT NULL, |
|
close TEXT NOT NULL, |
|
amount TEXT NOT NULL, |
|
quantity TEXT NOT NULL, |
|
buy_taker_amount TEXT NOT NULL, |
|
buy_taker_quantity TEXT NOT NULL, |
|
trade_count INT NOT NULL, |
|
ts INT NOT NULL, |
|
weighted_average TEXT NOT NULL, |
|
interval TEXT NOT NULL, |
|
start_time INT NOT NULL, |
|
close_time INT NOT NULL |
|
); |
|
", |
|
[], |
|
)?; |
|
|
|
Ok(Self { conn }) |
|
} |
|
|
|
pub fn insert_candle(&self, candle: &Candle) -> AppResult<usize> { |
|
let q = " |
|
INSERT INTO candles( |
|
low, |
|
high, |
|
open, |
|
close, |
|
amount, |
|
quantity, |
|
buy_taker_amount, |
|
buy_taker_quantity, |
|
trade_count, |
|
ts, |
|
weighted_average, |
|
interval, |
|
start_time, |
|
close_time |
|
) VALUES ( |
|
?1, |
|
?2, |
|
?3, |
|
?4, |
|
?5, |
|
?6, |
|
?7, |
|
?8, |
|
?9, |
|
?10, |
|
?11, |
|
?12, |
|
?13, |
|
?14 |
|
) |
|
"; |
|
self.conn |
|
.execute( |
|
q, |
|
params![ |
|
&candle.low, |
|
&candle.high, |
|
&candle.open, |
|
&candle.close, |
|
&candle.amount, |
|
&candle.quantity, |
|
&candle.buy_taker_amount, |
|
&candle.buy_taker_quantity, |
|
&candle.trade_count, |
|
&candle.ts.and_utc().timestamp_millis(), |
|
&candle.weighted_average, |
|
&candle.interval, |
|
&candle.start_time.and_utc().timestamp_millis(), |
|
&candle.close_time.and_utc().timestamp_millis(), |
|
], |
|
) |
|
.map_err(AppError::from) |
|
} |
|
|
|
pub fn insert_trade(&self, trade: &Trade) -> AppResult<usize> { |
|
let q = " |
|
INSERT INTO trades( |
|
symbol, |
|
amount, |
|
taker_side, |
|
quantity, |
|
create_time, |
|
price, |
|
id, |
|
ts |
|
) VALUES ( |
|
?1, |
|
?2, |
|
?3, |
|
?4, |
|
?5, |
|
?6, |
|
?7, |
|
?8 |
|
); |
|
"; |
|
|
|
self.conn |
|
.execute( |
|
&q, |
|
params![ |
|
&trade.symbol, |
|
&trade.amount, |
|
&trade.taker_side, |
|
&trade.quantity, |
|
&trade.create_time.and_utc().timestamp_millis(), |
|
&trade.price, |
|
&trade.id, |
|
&trade.ts.and_utc().timestamp_millis() |
|
], |
|
) |
|
.map_err(AppError::from) |
|
} |
|
}
|
|
|