Browse Source

Implement sqlx::Type for more datatypes

This maker our DB code slightly simpler because we can directly use
our newtypes in the query and they are also constructed right away
by sqlx.
debug-collab-settlement
Thomas Eizinger 3 years ago
committed by Daniel Karzel
parent
commit
1e0bf3de72
No known key found for this signature in database GPG Key ID: 30C3FC2E438ADB6E
  1. 138
      daemon/sqlx-data.json
  2. 117
      daemon/src/db.rs
  3. 2
      daemon/src/lib.rs
  4. 11
      daemon/src/model.rs
  5. 2
      daemon/src/model/cfd.rs
  6. 30
      daemon/src/sqlx_ext.rs

138
daemon/sqlx-data.json

@ -1,7 +1,25 @@
{ {
"db": "SQLite", "db": "SQLite",
"04399897350d026ee0830ccaba3638f8aa8f4ef9694d59286f32b9e2449a99fa": { "221a6283db798bacaba99e7e85130f9a8bbea1299d8cb99d272b1d478dc19775": {
"query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price,\n ord.min_quantity,\n ord.max_quantity,\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price,\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id,\n state.quantity_usd,\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.uuid = $1\n ", "query": "\n select\n state\n from cfd_states\n where cfd_id = $1\n order by id desc\n limit 1;\n ",
"describe": {
"columns": [
{
"name": "state",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
}
},
"3d41b8a81df84252dae228d8512b7491416520a6ad89561f67cdfb673f864a5a": {
"query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n ",
"describe": { "describe": {
"columns": [ "columns": [
{ {
@ -20,17 +38,17 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "initial_price", "name": "initial_price: crate::model::Price",
"ordinal": 3, "ordinal": 3,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "min_quantity", "name": "min_quantity: crate::model::Usd",
"ordinal": 4, "ordinal": 4,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "max_quantity", "name": "max_quantity: crate::model::Usd",
"ordinal": 5, "ordinal": 5,
"type_info": "Text" "type_info": "Text"
}, },
@ -40,7 +58,7 @@
"type_info": "Int64" "type_info": "Int64"
}, },
{ {
"name": "liquidation_price", "name": "liquidation_price: crate::model::Price",
"ordinal": 7, "ordinal": 7,
"type_info": "Text" "type_info": "Text"
}, },
@ -60,12 +78,12 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "oracle_event_id", "name": "oracle_event_id: crate::model::BitMexPriceEventId",
"ordinal": 11, "ordinal": 11,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "quantity_usd", "name": "quantity_usd: crate::model::Usd",
"ordinal": 12, "ordinal": 12,
"type_info": "Text" "type_info": "Text"
}, },
@ -76,7 +94,7 @@
} }
], ],
"parameters": { "parameters": {
"Right": 1 "Right": 0
}, },
"nullable": [ "nullable": [
false, false,
@ -96,26 +114,8 @@
] ]
} }
}, },
"221a6283db798bacaba99e7e85130f9a8bbea1299d8cb99d272b1d478dc19775": { "414ecf7f0cfce0a1a482b1b430d960867df835aae7fe1b306aa7f22353795dcf": {
"query": "\n select\n state\n from cfd_states\n where cfd_id = $1\n order by id desc\n limit 1;\n ", "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.uuid = $1\n ",
"describe": {
"columns": [
{
"name": "state",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
}
},
"22aae04782d6d9d6fa025e7606e3dcce91bfb9aca4aef9089a9ff9407c9f2715": {
"query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price,\n ord.min_quantity,\n ord.max_quantity,\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price,\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id,\n state.quantity_usd,\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n ",
"describe": { "describe": {
"columns": [ "columns": [
{ {
@ -134,17 +134,17 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "initial_price", "name": "initial_price: crate::model::Price",
"ordinal": 3, "ordinal": 3,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "min_quantity", "name": "min_quantity: crate::model::Usd",
"ordinal": 4, "ordinal": 4,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "max_quantity", "name": "max_quantity: crate::model::Usd",
"ordinal": 5, "ordinal": 5,
"type_info": "Text" "type_info": "Text"
}, },
@ -154,7 +154,7 @@
"type_info": "Int64" "type_info": "Int64"
}, },
{ {
"name": "liquidation_price", "name": "liquidation_price: crate::model::Price",
"ordinal": 7, "ordinal": 7,
"type_info": "Text" "type_info": "Text"
}, },
@ -174,12 +174,12 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "oracle_event_id", "name": "oracle_event_id: crate::model::BitMexPriceEventId",
"ordinal": 11, "ordinal": 11,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "quantity_usd", "name": "quantity_usd: crate::model::Usd",
"ordinal": 12, "ordinal": 12,
"type_info": "Text" "type_info": "Text"
}, },
@ -190,7 +190,7 @@
} }
], ],
"parameters": { "parameters": {
"Right": 0 "Right": 1
}, },
"nullable": [ "nullable": [
false, false,
@ -210,8 +210,8 @@
] ]
} }
}, },
"4bb5424ebcd683a149f15df5560fdea6727174f4cd6e0709e526ac3a690e2e5e": { "5569292de42c8ce5cff83beb43af1f8e6c3c12b17e740550c1303a1a6d151100": {
"query": "\n select\n uuid as \"uuid: crate::model::cfd::OrderId\",\n trading_pair as \"trading_pair: crate::model::TradingPair\",\n position as \"position: crate::model::Position\",\n initial_price,\n min_quantity,\n max_quantity,\n leverage as \"leverage: crate::model::Leverage\",\n liquidation_price,\n creation_timestamp_seconds as \"ts_secs: crate::model::Timestamp\",\n settlement_time_interval_seconds as \"settlement_time_interval_secs: i64\",\n origin as \"origin: crate::model::cfd::Origin\",\n oracle_event_id\n\n from orders\n where uuid = $1\n ", "query": "\n select\n uuid as \"uuid: crate::model::cfd::OrderId\",\n trading_pair as \"trading_pair: crate::model::TradingPair\",\n position as \"position: crate::model::Position\",\n initial_price as \"initial_price: crate::model::Price\",\n min_quantity as \"min_quantity: crate::model::Usd\",\n max_quantity as \"max_quantity: crate::model::Usd\",\n leverage as \"leverage: crate::model::Leverage\",\n liquidation_price as \"liquidation_price: crate::model::Price\",\n creation_timestamp_seconds as \"ts_secs: crate::model::Timestamp\",\n settlement_time_interval_seconds as \"settlement_time_interval_secs: i64\",\n origin as \"origin: crate::model::cfd::Origin\",\n oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\"\n from\n orders\n where\n uuid = $1\n ",
"describe": { "describe": {
"columns": [ "columns": [
{ {
@ -230,17 +230,17 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "initial_price", "name": "initial_price: crate::model::Price",
"ordinal": 3, "ordinal": 3,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "min_quantity", "name": "min_quantity: crate::model::Usd",
"ordinal": 4, "ordinal": 4,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "max_quantity", "name": "max_quantity: crate::model::Usd",
"ordinal": 5, "ordinal": 5,
"type_info": "Text" "type_info": "Text"
}, },
@ -250,7 +250,7 @@
"type_info": "Int64" "type_info": "Int64"
}, },
{ {
"name": "liquidation_price", "name": "liquidation_price: crate::model::Price",
"ordinal": 7, "ordinal": 7,
"type_info": "Text" "type_info": "Text"
}, },
@ -270,7 +270,7 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "oracle_event_id", "name": "oracle_event_id: crate::model::BitMexPriceEventId",
"ordinal": 11, "ordinal": 11,
"type_info": "Text" "type_info": "Text"
} }
@ -294,8 +294,26 @@
] ]
} }
}, },
"6dbd14a613a982521b4cc9179fd6f6b0298c0a4475508536379e9b82c9f2d0a0": { "8cbe349911b35d8e79763d64b4f5813b4bd98f12e0bba5ada84d2cae8b08ef4f": {
"query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price,\n ord.min_quantity,\n ord.max_quantity,\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price,\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id,\n state.quantity_usd,\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.oracle_event_id = $1\n ", "query": "\n select\n id\n from cfds\n where order_uuid = $1;\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
}
},
"f822252e3d3eb70a03300529d8de8f553e8d97b1aac72fb964cbde49d65fe153": {
"query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.oracle_event_id = $1\n ",
"describe": { "describe": {
"columns": [ "columns": [
{ {
@ -314,17 +332,17 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "initial_price", "name": "initial_price: crate::model::Price",
"ordinal": 3, "ordinal": 3,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "min_quantity", "name": "min_quantity: crate::model::Usd",
"ordinal": 4, "ordinal": 4,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "max_quantity", "name": "max_quantity: crate::model::Usd",
"ordinal": 5, "ordinal": 5,
"type_info": "Text" "type_info": "Text"
}, },
@ -334,7 +352,7 @@
"type_info": "Int64" "type_info": "Int64"
}, },
{ {
"name": "liquidation_price", "name": "liquidation_price: crate::model::Price",
"ordinal": 7, "ordinal": 7,
"type_info": "Text" "type_info": "Text"
}, },
@ -354,12 +372,12 @@
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "oracle_event_id", "name": "oracle_event_id: crate::model::BitMexPriceEventId",
"ordinal": 11, "ordinal": 11,
"type_info": "Text" "type_info": "Text"
}, },
{ {
"name": "quantity_usd", "name": "quantity_usd: crate::model::Usd",
"ordinal": 12, "ordinal": 12,
"type_info": "Text" "type_info": "Text"
}, },
@ -389,23 +407,5 @@
false false
] ]
} }
},
"8cbe349911b35d8e79763d64b4f5813b4bd98f12e0bba5ada84d2cae8b08ef4f": {
"query": "\n select\n id\n from cfds\n where order_uuid = $1;\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
}
} }
} }

117
daemon/src/db.rs

@ -1,11 +1,9 @@
use crate::model::cfd::{Cfd, CfdState, Order, OrderId}; use crate::model::cfd::{Cfd, CfdState, Order, OrderId};
use crate::model::{BitMexPriceEventId, Usd}; use crate::model::BitMexPriceEventId;
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use rust_decimal::Decimal;
use sqlx::pool::PoolConnection; use sqlx::pool::PoolConnection;
use sqlx::{Sqlite, SqlitePool}; use sqlx::{Sqlite, SqlitePool};
use std::mem; use std::mem;
use std::str::FromStr;
use time::Duration; use time::Duration;
pub async fn run_migrations(pool: &SqlitePool) -> anyhow::Result<()> { pub async fn run_migrations(pool: &SqlitePool) -> anyhow::Result<()> {
@ -33,15 +31,15 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection<Sqlite>) -> a
.bind(&order.id) .bind(&order.id)
.bind(&order.trading_pair) .bind(&order.trading_pair)
.bind(&order.position) .bind(&order.position)
.bind(&order.price.to_string()) .bind(&order.price)
.bind(&order.min_quantity.to_string()) .bind(&order.min_quantity)
.bind(&order.max_quantity.to_string()) .bind(&order.max_quantity)
.bind(order.leverage.get()) .bind(&order.leverage)
.bind(&order.liquidation_price.to_string()) .bind(&order.liquidation_price)
.bind(&order.creation_timestamp.seconds()) .bind(&order.creation_timestamp.seconds())
.bind(&order.settlement_interval.whole_seconds()) .bind(&order.settlement_interval.whole_seconds())
.bind(&order.origin) .bind(&order.origin)
.bind(&order.oracle_event_id.to_string()) .bind(&order.oracle_event_id)
.execute(conn) .execute(conn)
.await?; .await?;
@ -62,18 +60,19 @@ pub async fn load_order_by_id(
uuid as "uuid: crate::model::cfd::OrderId", uuid as "uuid: crate::model::cfd::OrderId",
trading_pair as "trading_pair: crate::model::TradingPair", trading_pair as "trading_pair: crate::model::TradingPair",
position as "position: crate::model::Position", position as "position: crate::model::Position",
initial_price, initial_price as "initial_price: crate::model::Price",
min_quantity, min_quantity as "min_quantity: crate::model::Usd",
max_quantity, max_quantity as "max_quantity: crate::model::Usd",
leverage as "leverage: crate::model::Leverage", leverage as "leverage: crate::model::Leverage",
liquidation_price, liquidation_price as "liquidation_price: crate::model::Price",
creation_timestamp_seconds as "ts_secs: crate::model::Timestamp", creation_timestamp_seconds as "ts_secs: crate::model::Timestamp",
settlement_time_interval_seconds as "settlement_time_interval_secs: i64", settlement_time_interval_seconds as "settlement_time_interval_secs: i64",
origin as "origin: crate::model::cfd::Origin", origin as "origin: crate::model::cfd::Origin",
oracle_event_id oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId"
from
from orders orders
where uuid = $1 where
uuid = $1
"#, "#,
id id
) )
@ -84,15 +83,15 @@ pub async fn load_order_by_id(
id: row.uuid, id: row.uuid,
trading_pair: row.trading_pair, trading_pair: row.trading_pair,
position: row.position, position: row.position,
price: row.initial_price.parse()?, price: row.initial_price,
min_quantity: row.min_quantity.parse()?, min_quantity: row.min_quantity,
max_quantity: row.max_quantity.parse()?, max_quantity: row.max_quantity,
leverage: row.leverage, leverage: row.leverage,
liquidation_price: row.liquidation_price.parse()?, liquidation_price: row.liquidation_price,
creation_timestamp: row.ts_secs, creation_timestamp: row.ts_secs,
settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), settlement_interval: Duration::new(row.settlement_time_interval_secs, 0),
origin: row.origin, origin: row.origin,
oracle_event_id: row.oracle_event_id.parse()?, oracle_event_id: row.oracle_event_id,
}) })
} }
@ -131,7 +130,7 @@ pub async fn insert_cfd(cfd: &Cfd, conn: &mut PoolConnection<Sqlite>) -> anyhow:
"#, "#,
) )
.bind(&cfd.order.id) .bind(&cfd.order.id)
.bind(&cfd.quantity_usd.to_string()) .bind(&cfd.quantity_usd)
.bind(state) .bind(state)
.execute(conn) .execute(conn)
.await?; .await?;
@ -275,16 +274,16 @@ pub async fn load_cfd_by_order_id(
ord.uuid as "uuid: crate::model::cfd::OrderId", ord.uuid as "uuid: crate::model::cfd::OrderId",
ord.trading_pair as "trading_pair: crate::model::TradingPair", ord.trading_pair as "trading_pair: crate::model::TradingPair",
ord.position as "position: crate::model::Position", ord.position as "position: crate::model::Position",
ord.initial_price, ord.initial_price as "initial_price: crate::model::Price",
ord.min_quantity, ord.min_quantity as "min_quantity: crate::model::Usd",
ord.max_quantity, ord.max_quantity as "max_quantity: crate::model::Usd",
ord.leverage as "leverage: crate::model::Leverage", ord.leverage as "leverage: crate::model::Leverage",
ord.liquidation_price, ord.liquidation_price as "liquidation_price: crate::model::Price",
ord.ts_secs as "ts_secs: crate::model::Timestamp", ord.ts_secs as "ts_secs: crate::model::Timestamp",
ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64",
ord.origin as "origin: crate::model::cfd::Origin", ord.origin as "origin: crate::model::cfd::Origin",
ord.oracle_event_id, ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId",
state.quantity_usd, state.quantity_usd as "quantity_usd: crate::model::Usd",
state.state state.state
from ord from ord
@ -301,15 +300,15 @@ pub async fn load_cfd_by_order_id(
id: row.uuid, id: row.uuid,
trading_pair: row.trading_pair, trading_pair: row.trading_pair,
position: row.position, position: row.position,
price: row.initial_price.parse()?, price: row.initial_price,
min_quantity: row.min_quantity.parse()?, min_quantity: row.min_quantity,
max_quantity: row.max_quantity.parse()?, max_quantity: row.max_quantity,
leverage: row.leverage, leverage: row.leverage,
liquidation_price: row.liquidation_price.parse()?, liquidation_price: row.liquidation_price,
creation_timestamp: row.ts_secs, creation_timestamp: row.ts_secs,
settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), settlement_interval: Duration::new(row.settlement_time_interval_secs, 0),
origin: row.origin, origin: row.origin,
oracle_event_id: row.oracle_event_id.parse()?, oracle_event_id: row.oracle_event_id,
}; };
// TODO: // TODO:
@ -317,7 +316,7 @@ pub async fn load_cfd_by_order_id(
// via https://github.com/comit-network/hermes/issues/290 // via https://github.com/comit-network/hermes/issues/290
Ok(Cfd { Ok(Cfd {
order, order,
quantity_usd: Usd::new(Decimal::from_str(&row.quantity_usd)?), quantity_usd: row.quantity_usd,
state: serde_json::from_str(row.state.as_str())?, state: serde_json::from_str(row.state.as_str())?,
}) })
} }
@ -373,16 +372,16 @@ pub async fn load_all_cfds(conn: &mut PoolConnection<Sqlite>) -> anyhow::Result<
ord.uuid as "uuid: crate::model::cfd::OrderId", ord.uuid as "uuid: crate::model::cfd::OrderId",
ord.trading_pair as "trading_pair: crate::model::TradingPair", ord.trading_pair as "trading_pair: crate::model::TradingPair",
ord.position as "position: crate::model::Position", ord.position as "position: crate::model::Position",
ord.initial_price, ord.initial_price as "initial_price: crate::model::Price",
ord.min_quantity, ord.min_quantity as "min_quantity: crate::model::Usd",
ord.max_quantity, ord.max_quantity as "max_quantity: crate::model::Usd",
ord.leverage as "leverage: crate::model::Leverage", ord.leverage as "leverage: crate::model::Leverage",
ord.liquidation_price, ord.liquidation_price as "liquidation_price: crate::model::Price",
ord.ts_secs as "ts_secs: crate::model::Timestamp", ord.ts_secs as "ts_secs: crate::model::Timestamp",
ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64",
ord.origin as "origin: crate::model::cfd::Origin", ord.origin as "origin: crate::model::cfd::Origin",
ord.oracle_event_id, ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId",
state.quantity_usd, state.quantity_usd as "quantity_usd: crate::model::Usd",
state.state state.state
from ord from ord
@ -399,20 +398,20 @@ pub async fn load_all_cfds(conn: &mut PoolConnection<Sqlite>) -> anyhow::Result<
id: row.uuid, id: row.uuid,
trading_pair: row.trading_pair, trading_pair: row.trading_pair,
position: row.position, position: row.position,
price: row.initial_price.parse()?, price: row.initial_price,
min_quantity: row.min_quantity.parse()?, min_quantity: row.min_quantity,
max_quantity: row.max_quantity.parse()?, max_quantity: row.max_quantity,
leverage: row.leverage, leverage: row.leverage,
liquidation_price: row.liquidation_price.parse()?, liquidation_price: row.liquidation_price,
creation_timestamp: row.ts_secs, creation_timestamp: row.ts_secs,
settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), settlement_interval: Duration::new(row.settlement_time_interval_secs, 0),
origin: row.origin, origin: row.origin,
oracle_event_id: row.oracle_event_id.parse()?, oracle_event_id: row.oracle_event_id,
}; };
Ok(Cfd { Ok(Cfd {
order, order,
quantity_usd: Usd::new(Decimal::from_str(&row.quantity_usd)?), quantity_usd: row.quantity_usd,
state: serde_json::from_str(row.state.as_str())?, state: serde_json::from_str(row.state.as_str())?,
}) })
}) })
@ -476,16 +475,16 @@ pub async fn load_cfds_by_oracle_event_id(
ord.uuid as "uuid: crate::model::cfd::OrderId", ord.uuid as "uuid: crate::model::cfd::OrderId",
ord.trading_pair as "trading_pair: crate::model::TradingPair", ord.trading_pair as "trading_pair: crate::model::TradingPair",
ord.position as "position: crate::model::Position", ord.position as "position: crate::model::Position",
ord.initial_price, ord.initial_price as "initial_price: crate::model::Price",
ord.min_quantity, ord.min_quantity as "min_quantity: crate::model::Usd",
ord.max_quantity, ord.max_quantity as "max_quantity: crate::model::Usd",
ord.leverage as "leverage: crate::model::Leverage", ord.leverage as "leverage: crate::model::Leverage",
ord.liquidation_price, ord.liquidation_price as "liquidation_price: crate::model::Price",
ord.ts_secs as "ts_secs: crate::model::Timestamp", ord.ts_secs as "ts_secs: crate::model::Timestamp",
ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64",
ord.origin as "origin: crate::model::cfd::Origin", ord.origin as "origin: crate::model::cfd::Origin",
ord.oracle_event_id, ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId",
state.quantity_usd, state.quantity_usd as "quantity_usd: crate::model::Usd",
state.state state.state
from ord from ord
@ -505,20 +504,20 @@ pub async fn load_cfds_by_oracle_event_id(
id: row.uuid, id: row.uuid,
trading_pair: row.trading_pair, trading_pair: row.trading_pair,
position: row.position, position: row.position,
price: row.initial_price.parse()?, price: row.initial_price,
min_quantity: row.min_quantity.parse()?, min_quantity: row.min_quantity,
max_quantity: row.max_quantity.parse()?, max_quantity: row.max_quantity,
leverage: row.leverage, leverage: row.leverage,
liquidation_price: row.liquidation_price.parse()?, liquidation_price: row.liquidation_price,
creation_timestamp: row.ts_secs, creation_timestamp: row.ts_secs,
settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), settlement_interval: Duration::new(row.settlement_time_interval_secs, 0),
origin: row.origin, origin: row.origin,
oracle_event_id: row.oracle_event_id.parse()?, oracle_event_id: row.oracle_event_id,
}; };
Ok(Cfd { Ok(Cfd {
order, order,
quantity_usd: row.quantity_usd.parse()?, quantity_usd: row.quantity_usd,
state: serde_json::from_str(row.state.as_str())?, state: serde_json::from_str(row.state.as_str())?,
}) })
}) })

2
daemon/src/lib.rs

@ -16,6 +16,8 @@ use tokio::sync::watch;
use xtra::message_channel::{MessageChannel, StrongMessageChannel}; use xtra::message_channel::{MessageChannel, StrongMessageChannel};
use xtra::{Actor, Address}; use xtra::{Actor, Address};
pub mod sqlx_ext; // Must come first because it is a macro.
pub mod actors; pub mod actors;
pub mod auth; pub mod auth;
pub mod bitmex_price_feed; pub mod bitmex_price_feed;

11
daemon/src/model.rs

@ -1,4 +1,4 @@
use crate::olivia; use crate::{impl_sqlx_type_display_from_str, olivia};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use bdk::bitcoin::{Address, Amount, Denomination}; use bdk::bitcoin::{Address, Amount, Denomination};
use chrono::DateTime; use chrono::DateTime;
@ -62,9 +62,13 @@ impl str::FromStr for Usd {
} }
} }
impl_sqlx_type_display_from_str!(Usd);
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Price(Decimal); pub struct Price(Decimal);
impl_sqlx_type_display_from_str!(Price);
impl Price { impl Price {
pub fn new(value: Decimal) -> Result<Self, Error> { pub fn new(value: Decimal) -> Result<Self, Error> {
if value == Decimal::ZERO { if value == Decimal::ZERO {
@ -133,6 +137,7 @@ impl InversePrice {
} }
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)] #[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(transparent)]
pub struct Leverage(u8); pub struct Leverage(u8);
impl Leverage { impl Leverage {
@ -377,7 +382,7 @@ pub enum TradingPair {
BtcUsd, BtcUsd,
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, sqlx::Type)]
pub enum Position { pub enum Position {
Long, Long,
Short, Short,
@ -507,6 +512,8 @@ impl str::FromStr for BitMexPriceEventId {
} }
} }
impl_sqlx_type_display_from_str!(BitMexPriceEventId);
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)] #[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)]
pub struct Timestamp(i64); pub struct Timestamp(i64);

2
daemon/src/model/cfd.rs

@ -660,7 +660,7 @@ impl Cfd {
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self.order.origin { match self.order.origin {
Origin::Ours => self.order.position.clone(), Origin::Ours => self.order.position,
// If the order is not our own we take the counter-position in the CFD // If the order is not our own we take the counter-position in the CFD
Origin::Theirs => match self.order.position { Origin::Theirs => match self.order.position {

30
daemon/src/sqlx_ext.rs

@ -0,0 +1,30 @@
#[macro_export]
macro_rules! impl_sqlx_type_display_from_str {
($ty:ty) => {
impl sqlx::Type<sqlx::Sqlite> for $ty {
fn type_info() -> sqlx::sqlite::SqliteTypeInfo {
String::type_info()
}
}
impl<'q> sqlx::Encode<'q, sqlx::Sqlite> for $ty {
fn encode_by_ref(
&self,
args: &mut Vec<sqlx::sqlite::SqliteArgumentValue<'q>>,
) -> sqlx::encode::IsNull {
self.to_string().encode_by_ref(args)
}
}
impl<'r> sqlx::Decode<'r, sqlx::Sqlite> for $ty {
fn decode(
value: sqlx::sqlite::SqliteValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let string = String::decode(value)?;
let value = string.parse()?;
Ok(value)
}
}
};
}
Loading…
Cancel
Save