Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
52 linesCodeBlameRaw
1//! Allowances and the usage entry that consumes them commit together.
2use worker::Result;
3use crate::{Billing, credits::Eligible};
4
5pub(crate) const PLAN: &str = "INSERT INTO allowance_use (kind, scope, month, used)
6 SELECT 'plan_credit', workspace, ?2, credit_micros FROM ledger WHERE id=?1 AND credit_micros > 0
7 ON CONFLICT(kind, scope, month) DO UPDATE SET used=used+excluded.used";
8pub(crate) const TRIAL: &str = "UPDATE trial_grants SET used_micros=used_micros+
9 (SELECT trial_micros FROM ledger WHERE id=?1) WHERE workspace=(SELECT workspace FROM ledger WHERE id=?1)";
10pub(crate) const GIFT: &str = "INSERT INTO allowance_use (kind, scope, month, used)
11 SELECT 'complimentary', workspace, ?2, gift_micros FROM ledger WHERE id=?1 AND gift_micros > 0
12 ON CONFLICT(kind, scope, month) DO UPDATE SET used=used+excluded.used";
13pub(crate) const OSS_POOL: &str = "INSERT INTO allowance_use (kind, scope, month, used)
14 SELECT 'oss_pool', '', ?2, oss_micros FROM ledger WHERE id=?1 AND oss_micros > 0
15 ON CONFLICT(kind, scope, month) DO UPDATE SET used=used+excluded.used";
16pub(crate) const OSS_REPO: &str = "INSERT INTO allowance_use (kind, scope, month, used)
17 SELECT 'oss_repo', ?3, ?2, oss_micros FROM ledger WHERE id=?1 AND oss_micros > 0
18 ON CONFLICT(kind, scope, month) DO UPDATE SET used=used+excluded.used";
19
20impl Billing {
21 pub(crate) async fn posted_allocation(&self, reference: &str) -> Result<(i64, crate::credits::Drawn)> {
22 #[derive(serde::Deserialize)]
23 struct Row { amount_micros: i64, credit_micros: i64, gift_micros: i64, trial_micros: i64, oss_micros: i64, given_micros: i64 }
24 let row = self.db.prepare("SELECT amount_micros, credit_micros, gift_micros, trial_micros, oss_micros, given_micros FROM ledger WHERE reference = ?")
25 .bind(&[reference.into()])?.first::<Row>(None).await?
26 .ok_or_else(|| worker::Error::RustError("Posted usage is missing".into()))?;
27 Ok((-row.amount_micros, crate::credits::Drawn {
28 credit: row.credit_micros, gift: row.gift_micros, trial: row.trial_micros, oss: row.oss_micros, given: row.given_micros,
29 }))
30 }
31
32 pub(crate) async fn allocation_statements(&self, id: &str, workspace: &str, month: &str, eligible: &Eligible, plan: bool)
33 -> Result<Vec<worker::D1PreparedStatement>> {
34 let repo = eligible.repo.as_deref().unwrap_or("").to_lowercase();
35 let public = !repo.is_empty() && self.is_public(&repo).await;
36 let repo_cap = if public { self.oss_repo_cap(workspace).await? } else { 0 };
37 Ok(vec![
38 self.db.prepare(include_str!("allocate_usage.sql")).bind(&[
39 id.into(), workspace.into(), month.into(),
40 (if plan { self.plans.plan_included_micros } else { 0 } as f64).into(),
41 i32::from(eligible.trial).into(), repo.as_str().into(),
42 (if public { self.plans.oss_pool_micros } else { 0 } as f64).into(), (repo_cap as f64).into(),
43 i32::from(eligible.cover_rest && !plan).into(),
44 ])?,
45 self.db.prepare(PLAN).bind(&[id.into(), month.into()])?,
46 self.db.prepare(GIFT).bind(&[id.into(), month.into()])?,
47 self.db.prepare(TRIAL).bind(&[id.into()])?,
48 self.db.prepare(OSS_POOL).bind(&[id.into(), month.into()])?,
49 self.db.prepare(OSS_REPO).bind(&[id.into(), month.into(), repo.into()])?,
50 ])
51 }
52}