fn take_token(
        &self,
        uploader: i32,
        now: NaiveDateTime,
        conn: &PgConnection,
    ) -> QueryResult<Bucket> {
        use self::publish_limit_buckets::dsl::*;
        use diesel::sql_types::{Double, Interval, Text, Timestamp};

        sql_function!(fn date_part(x: Text, y: Timestamp) -> Double);
        sql_function! {
            #[sql_name = "date_part"]
            fn interval_part(x: Text, y: Interval) -> Double;
        }
        sql_function!(fn floor(x: Double) -> Integer);
        sql_function!(fn greatest<T>(x: T, y: T) -> T);
        sql_function!(fn least<T>(x: T, y: T) -> T);

        let burst = publish_rate_overrides::table
            .find(uploader)
            .select(publish_rate_overrides::burst)
            .first::<i32>(conn)
            .optional()?
            .unwrap_or(self.burst);

        // Interval division is poorly defined in general (what is 1 month / 30 days?)
        // However, for the intervals we're dealing with, it is always well
        // defined, so we convert to an f64 of seconds to represent this.
        let tokens_to_add = floor(
            (date_part("epoch", now) - date_part("epoch", last_refill))
                / interval_part("epoch", self.refill_rate()),
        );

        diesel::insert_into(publish_limit_buckets)
            .values((user_id.eq(uploader), tokens.eq(burst), last_refill.eq(now)))
            .on_conflict(user_id)
            .do_update()
            .set((
                tokens.eq(least(burst, greatest(0, tokens - 1) + tokens_to_add)),
                last_refill
                    .eq(last_refill + self.refill_rate().into_sql::<Interval>() * tokens_to_add),
            ))
            .get_result(conn)
    }
/// Refill a user's bucket as needed, take a token from it,
/// and returns the result.
///
/// The number of tokens remaining will always be between 0 and self.burst.
/// If the number is 0, the request should be rejected, as the user doesn't
/// have a token to take. Technically a "full" bucket would have
/// `self.burst + 1` tokens in it, but that value would never be returned
/// since we only refill buckets when trying to take a token from it.
Refill a user's bucket as needed, take a token from it,
and returns the result.

The number of tokens remaining will always be between 0 and self.burst.
If the number is 0, the request should be rejected, as the user doesn't
have a token to take. Technically a "full" bucket would have
`self.burst + 1` tokens in it, but that value would never be returned
since we only refill buckets when trying to take a token from it.
Refill a user ' s bucket as needed take a token from it and returns the result . The number of tokens remaining will always be between 0 and self . burst . If the number is 0 the request should be rejected as the user doesn ' t have a token to take . Technically a " full " bucket would have ` self . burst + 1 ` tokens in it but that value would never be returned since we only refill buckets when trying to take a token from it .
fn take_token(
        &self,
        uploader: i32,
        now: NaiveDateTime,
        conn: &PgConnection,
    ) -> QueryResult<Bucket> {
        use self::publish_limit_buckets::dsl::*;
        use diesel::sql_types::{Double, Interval, Text, Timestamp};
        sql_function!(fn date_part(x: Text, y: Timestamp) -> Double);
        sql_function! {
            #[sql_name = "date_part"]
            fn interval_part(x: Text, y: Interval) -> Double;
        }
        sql_function!(fn floor(x: Double) -> Integer);
        sql_function!(fn greatest<T>(x: T, y: T) -> T);
        sql_function!(fn least<T>(x: T, y: T) -> T);
        let burst = publish_rate_overrides::table
            .find(uploader)
            .select(publish_rate_overrides::burst)
            .first::<i32>(conn)
            .optional()?
            .unwrap_or(self.burst);
        // Interval division is poorly defined in general (what is 1 month / 30 days?)
        // However, for the intervals we're dealing with, it is always well
        // defined, so we convert to an f64 of seconds to represent this.
        let tokens_to_add = floor(
            (date_part("epoch", now) - date_part("epoch", last_refill))
                / interval_part("epoch", self.refill_rate()),
        );
        diesel::insert_into(publish_limit_buckets)
            .values((user_id.eq(uploader), tokens.eq(burst), last_refill.eq(now)))
            .on_conflict(user_id)
            .do_update()
            .set((
                tokens.eq(least(burst, greatest(0, tokens - 1) + tokens_to_add)),
                last_refill
                    .eq(last_refill + self.refill_rate().into_sql::<Interval>() * tokens_to_add),
            ))
            .get_result(conn)
    }
fn take_token ( & self , uploader : i32 , now : NaiveDateTime , conn : & PgConnection , ) -> QueryResult < Bucket > { use self :: publish_limit_buckets :: dsl :: * ; use diesel :: sql_types :: { Double , Interval , Text , Timestamp } ; sql_function ! ( fn date_part ( x Text y Timestamp ) Double ) ; sql_function ! { [ sql_name " " ] fn interval_part ( x Text y Interval ) Double } sql_function ! ( fn floor ( x Double ) Integer ) ; sql_function ! ( fn greatest T ( x T y T ) T ) ; sql_function ! ( fn least T ( x T y T ) T ) ; let burst = publish_rate_overrides :: table . find ( uploader ) . select ( publish_rate_overrides :: burst ) . first :: < i32 > ( conn ) . optional ( ) ? . unwrap_or ( self . burst ) ; // Interval division is poorly defined in general (what is 1 month / 30 days?) // However, for the intervals we're dealing with, it is always well // defined, so we convert to an f64 of seconds to represent this. let tokens_to_add = floor ( ( date_part ( " " , now ) - date_part ( " " , last_refill ) ) / interval_part ( " " , self . refill_rate ( ) ) , ) ; diesel :: insert_into ( publish_limit_buckets ) . values ( ( user_id . eq ( uploader ) , tokens . eq ( burst ) , last_refill . eq ( now ) ) ) . on_conflict ( user_id ) . do_update ( ) . set ( ( tokens . eq ( least ( burst , greatest ( 0 , tokens - 1 ) + tokens_to_add ) ) , last_refill . eq ( last_refill + self . refill_rate ( ) . into_sql :: < Interval > ( ) * tokens_to_add ) , ) ) . get_result ( conn ) }
Refill a user's bucket as needed, take a token from it,
and returns the result.
Refill a user ' s bucket as needed take a token from it and returns the result .
&self
uploader
i32
now
NaiveDateTime
conn
&PgConnection