use carbon_core::{
account::AccountMetadata,
postgres::{
metadata::AccountRowMetadata,
primitives::{Pubkey, U16, U64, U8},
},
};
#[derive(sqlx::FromRow, Debug, Clone)]
pub struct OrderRow {
#[sqlx(flatten)]
pub account_metadata: AccountRowMetadata,
pub closer: Pubkey,
pub output_token_account: Pubkey,
pub return_input_token_account: Pubkey,
pub return_rent_to: Pubkey,
pub id: U64,
pub quoted_out_amount: U64,
pub last_fillable_slot: U64,
pub slippage_bps: U16,
pub bump: U8,
pub vault_bump: U8,
pub flags: U8,
pub padding1: U8,
pub padding2: U8,
pub padding3: U8,
}
impl OrderRow {
pub fn from_parts(source: crate::accounts::order::Order, metadata: AccountMetadata) -> Self {
Self {
account_metadata: metadata.into(),
closer: source.closer.into(),
output_token_account: source.output_token_account.into(),
return_input_token_account: source.return_input_token_account.into(),
return_rent_to: source.return_rent_to.into(),
id: source.id.into(),
quoted_out_amount: source.quoted_out_amount.into(),
last_fillable_slot: source.last_fillable_slot.into(),
slippage_bps: source.slippage_bps.into(),
bump: source.bump.into(),
vault_bump: source.vault_bump.into(),
flags: source.flags.into(),
padding1: source.padding1.into(),
padding2: source.padding2.into(),
padding3: source.padding3.into(),
}
}
}
impl TryFrom<OrderRow> for crate::accounts::order::Order {
type Error = carbon_core::error::Error;
fn try_from(source: OrderRow) -> Result<Self, Self::Error> {
Ok(Self {
closer: *source.closer,
output_token_account: *source.output_token_account,
return_input_token_account: *source.return_input_token_account,
return_rent_to: *source.return_rent_to,
id: *source.id,
quoted_out_amount: *source.quoted_out_amount,
last_fillable_slot: *source.last_fillable_slot,
slippage_bps: source.slippage_bps.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
bump: source.bump.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
vault_bump: source.vault_bump.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
flags: source.flags.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
padding1: source.padding1.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
padding2: source.padding2.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
padding3: source.padding3.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
})
}
}
impl carbon_core::postgres::operations::Table for crate::accounts::order::Order {
fn table() -> &'static str {
"order_account"
}
fn columns() -> Vec<&'static str> {
vec![
"__pubkey",
"__slot",
"closer",
"output_token_account",
"return_input_token_account",
"return_rent_to",
"id",
"quoted_out_amount",
"last_fillable_slot",
"slippage_bps",
"bump",
"vault_bump",
"flags",
"padding1",
"padding2",
"padding3",
]
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Insert for OrderRow {
async fn insert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(
r#"
INSERT INTO order_account (
"closer",
"output_token_account",
"return_input_token_account",
"return_rent_to",
"id",
"quoted_out_amount",
"last_fillable_slot",
"slippage_bps",
"bump",
"vault_bump",
"flags",
"padding1",
"padding2",
"padding3",
__pubkey, __slot
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16
)"#,
)
.bind(self.closer)
.bind(self.output_token_account)
.bind(self.return_input_token_account)
.bind(self.return_rent_to)
.bind(&self.id)
.bind(&self.quoted_out_amount)
.bind(&self.last_fillable_slot)
.bind(self.slippage_bps)
.bind(self.bump)
.bind(self.vault_bump)
.bind(self.flags)
.bind(self.padding1)
.bind(self.padding2)
.bind(self.padding3)
.bind(self.account_metadata.pubkey)
.bind(&self.account_metadata.slot)
.execute(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Upsert for OrderRow {
async fn upsert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(
r#"INSERT INTO order_account (
"closer",
"output_token_account",
"return_input_token_account",
"return_rent_to",
"id",
"quoted_out_amount",
"last_fillable_slot",
"slippage_bps",
"bump",
"vault_bump",
"flags",
"padding1",
"padding2",
"padding3",
__pubkey, __slot
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16
) ON CONFLICT (
__pubkey
) DO UPDATE SET
"closer" = EXCLUDED."closer",
"output_token_account" = EXCLUDED."output_token_account",
"return_input_token_account" = EXCLUDED."return_input_token_account",
"return_rent_to" = EXCLUDED."return_rent_to",
"id" = EXCLUDED."id",
"quoted_out_amount" = EXCLUDED."quoted_out_amount",
"last_fillable_slot" = EXCLUDED."last_fillable_slot",
"slippage_bps" = EXCLUDED."slippage_bps",
"bump" = EXCLUDED."bump",
"vault_bump" = EXCLUDED."vault_bump",
"flags" = EXCLUDED."flags",
"padding1" = EXCLUDED."padding1",
"padding2" = EXCLUDED."padding2",
"padding3" = EXCLUDED."padding3",
__slot = EXCLUDED.__slot
"#,
)
.bind(self.closer)
.bind(self.output_token_account)
.bind(self.return_input_token_account)
.bind(self.return_rent_to)
.bind(&self.id)
.bind(&self.quoted_out_amount)
.bind(&self.last_fillable_slot)
.bind(self.slippage_bps)
.bind(self.bump)
.bind(self.vault_bump)
.bind(self.flags)
.bind(self.padding1)
.bind(self.padding2)
.bind(self.padding3)
.bind(self.account_metadata.pubkey)
.bind(&self.account_metadata.slot)
.execute(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Delete for OrderRow {
type Key = carbon_core::postgres::primitives::Pubkey;
async fn delete(key: Self::Key, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(
r#"DELETE FROM order_account WHERE
__pubkey = $1
"#,
)
.bind(key)
.execute(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Lookup for OrderRow {
type Key = carbon_core::postgres::primitives::Pubkey;
async fn lookup(
key: Self::Key,
pool: &sqlx::PgPool,
) -> carbon_core::error::CarbonResult<Option<Self>> {
let row = sqlx::query_as(
r#"SELECT * FROM order_account WHERE
__pubkey = $1
"#,
)
.bind(key)
.fetch_optional(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(row)
}
}
pub struct OrderMigrationOperation;
#[async_trait::async_trait]
impl sqlx_migrator::Operation<sqlx::Postgres> for OrderMigrationOperation {
async fn up(
&self,
connection: &mut sqlx::PgConnection,
) -> Result<(), sqlx_migrator::error::Error> {
sqlx::query(
r#"CREATE TABLE IF NOT EXISTS order_account (
-- Account data
"closer" BYTEA NOT NULL,
"output_token_account" BYTEA NOT NULL,
"return_input_token_account" BYTEA NOT NULL,
"return_rent_to" BYTEA NOT NULL,
"id" NUMERIC(20) NOT NULL,
"quoted_out_amount" NUMERIC(20) NOT NULL,
"last_fillable_slot" NUMERIC(20) NOT NULL,
"slippage_bps" INT4 NOT NULL,
"bump" INT2 NOT NULL,
"vault_bump" INT2 NOT NULL,
"flags" INT2 NOT NULL,
"padding1" INT2 NOT NULL,
"padding2" INT2 NOT NULL,
"padding3" INT2 NOT NULL,
-- Account metadata
__pubkey BYTEA NOT NULL,
__slot NUMERIC(20),
PRIMARY KEY (__pubkey)
)"#,
)
.execute(connection)
.await?;
Ok(())
}
async fn down(
&self,
connection: &mut sqlx::PgConnection,
) -> Result<(), sqlx_migrator::error::Error> {
sqlx::query(r#"DROP TABLE IF EXISTS order_account"#)
.execute(connection)
.await?;
Ok(())
}
}