-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sqlx #37
Sqlx #37
Changes from 7 commits
62b508f
df96bcb
3a3a0b5
8470831
6a89886
60e1cad
540397e
f26e794
4b0feb6
c24ab62
46e2ad2
8640ed8
174a929
e783af6
a987791
f1c7a3a
696dbdb
f36c2bc
bf84867
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DATABASE_URL=postgresql://postgres@localhost/postgres |
This file was deleted.
This file was deleted.
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
DROP TABLE bid; | ||
DROP TYPE bid_status; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
CREATE TYPE bid_status AS ENUM ('pending', 'lost', 'submitted'); | ||
|
||
CREATE TABLE bid | ||
( | ||
id UUID PRIMARY KEY, | ||
creation_time TIMESTAMP NOT NULL, | ||
permission_key BYTEA NOT NULL, | ||
chain_id TEXT NOT NULL, | ||
target_contract BYTEA NOT NULL, | ||
target_contract BYTEA NOT NULL CHECK (LENGTH(target_contract) = 20), | ||
target_calldata BYTEA NOT NULL, | ||
bid_amount NUMERIC(80, 0) NOT NULL, | ||
status TEXT NOT NULL, -- pending, lost, submitted | ||
auction_id UUID, -- TODO: should be linked to the auction table in the future | ||
bid_amount NUMERIC(78, 0) NOT NULL, | ||
status bid_status NOT NULL, | ||
auction_id UUID, -- TODO: should be linked to the auction table in the future | ||
removal_time TIMESTAMP -- TODO: should be removed and read from the auction table in the future | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,12 +29,18 @@ use { | |
Deserialize, | ||
Serialize, | ||
}, | ||
sqlx::types::{ | ||
time::{ | ||
OffsetDateTime, | ||
PrimitiveDateTime, | ||
sqlx::{ | ||
database::HasArguments, | ||
encode::IsNull, | ||
types::{ | ||
time::{ | ||
OffsetDateTime, | ||
PrimitiveDateTime, | ||
}, | ||
BigDecimal, | ||
}, | ||
BigDecimal, | ||
Postgres, | ||
TypeInfo, | ||
}, | ||
std::{ | ||
collections::HashMap, | ||
|
@@ -171,13 +177,24 @@ pub enum BidStatus { | |
Lost, | ||
} | ||
|
||
impl BidStatus { | ||
pub fn status_name(&self) -> String { | ||
match self { | ||
BidStatus::Pending => "pending".to_string(), | ||
BidStatus::Submitted(_) => "submitted".to_string(), | ||
BidStatus::Lost => "lost".to_string(), | ||
} | ||
impl sqlx::Encode<'_, sqlx::Postgres> for BidStatus { | ||
fn encode_by_ref(&self, buf: &mut <Postgres as HasArguments<'_>>::ArgumentBuffer) -> IsNull { | ||
let result = match self { | ||
BidStatus::Pending => "pending", | ||
BidStatus::Submitted(_) => "submitted", | ||
BidStatus::Lost => "lost", | ||
}; | ||
<&str as sqlx::Encode<sqlx::Postgres>>::encode(result, buf) | ||
} | ||
} | ||
|
||
impl sqlx::Type<sqlx::Postgres> for BidStatus { | ||
fn type_info() -> sqlx::postgres::PgTypeInfo { | ||
sqlx::postgres::PgTypeInfo::with_name("bid_status") | ||
} | ||
|
||
fn compatible(ty: &sqlx::postgres::PgTypeInfo) -> bool { | ||
ty.name() == "bid_status" | ||
} | ||
} | ||
|
||
|
@@ -246,12 +263,16 @@ impl Store { | |
let key = match &opportunity.params { | ||
OpportunityParams::V1(params) => params.permission_key.clone(), | ||
}; | ||
self.opportunity_store | ||
.opportunities | ||
.write() | ||
.await | ||
.entry(key) | ||
.and_modify(|opps| opps.retain(|o| o != opportunity)); | ||
let mut write_guard = self.opportunity_store.opportunities.write().await; | ||
let entry = write_guard.entry(key.clone()); | ||
if entry | ||
.and_modify(|opps| opps.retain(|o| o != opportunity)) | ||
.or_default() | ||
.is_empty() | ||
{ | ||
write_guard.remove(&key); | ||
} | ||
drop(write_guard); | ||
let now = OffsetDateTime::now_utc(); | ||
sqlx::query!( | ||
"UPDATE opportunity SET removal_time = $1 WHERE id = $2 AND removal_time IS NULL", | ||
|
@@ -274,7 +295,7 @@ impl Store { | |
&bid.target_contract.to_fixed_bytes(), | ||
bid.target_calldata.to_vec(), | ||
BigDecimal::from_str(&bid.bid_amount.to_string()).unwrap(), | ||
bid.status.status_name(), | ||
bid.status as _, | ||
) | ||
.execute(&self.db) | ||
.await.map_err(|e| { | ||
|
@@ -290,22 +311,25 @@ impl Store { | |
Ok(()) | ||
} | ||
|
||
pub async fn set_bid_status_and_broadcast( | ||
pub async fn finalize_bid_status_and_broadcast( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a clearer function name might be |
||
&self, | ||
update: BidStatusWithId, | ||
) -> anyhow::Result<()> { | ||
if update.bid_status == BidStatus::Pending { | ||
return Err(anyhow::anyhow!("Cannot finalize a pending bid")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this error msg is a bit awkward, maybe just "Bid is still pending" |
||
} | ||
|
||
let now = OffsetDateTime::now_utc(); | ||
sqlx::query!( | ||
"UPDATE bid SET status = $1 WHERE id = $2", | ||
update.bid_status.status_name(), | ||
"UPDATE bid SET status = $1, removal_time = $2 WHERE id = $3 AND removal_time IS NULL", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This field will be removed soon, when we add the auction table. Let's keep it as is for now. |
||
update.bid_status as _, | ||
PrimitiveDateTime::new(now.date(), now.time()), | ||
update.id | ||
) | ||
.execute(&self.db) | ||
.await?; | ||
|
||
|
||
self.bids.write().await.get_mut(&update.id).map(|bid| { | ||
bid.status = update.bid_status.clone(); | ||
}); | ||
self.bids.write().await.remove(&update.id); | ||
self.broadcast_status_update(update); | ||
Ok(()) | ||
} | ||
|
@@ -326,17 +350,4 @@ impl Store { | |
.cloned() | ||
.collect() | ||
} | ||
|
||
pub async fn remove_bid(&self, bid_id: &BidId) -> anyhow::Result<()> { | ||
let now = OffsetDateTime::now_utc(); | ||
sqlx::query!( | ||
"UPDATE bid SET removal_time = $1 WHERE id = $2 AND removal_time IS NULL", | ||
PrimitiveDateTime::new(now.date(), now.time()), | ||
bid_id | ||
) | ||
.execute(&self.db) | ||
.await?; | ||
self.bids.write().await.remove(bid_id); | ||
Ok(()) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind adding a note on which directory to run this from, just for clarity