Repository: launchbadge/sqlx
File: sqlx-core/src/query_builder.rs (Rust)

Code before:
            variable_count: 0,
        }
    }

    pub fn push(&mut self, sql: impl Display) -> &mut Self {
        self.query.push_str(&format!(" {}", sql));

        self
    }

    pub fn push_bind<A>(&mut self, value: A) -> &mut Self
    where
        A: 'a + Encode<'a, DB> + Send + Type<DB>,
    {
        match self.arguments {
            Some(ref mut arguments) => {
                arguments.add(value);
                self.variable_count += 1;
                self.query
                    .push_str(&arguments.place_holder(self.variable_count));
            }
            None => panic!("Arguments taken already"),
        }

        self
    }

    pub fn build(&mut self) -> Query<'_, DB, <DB as HasArguments<'a>>::Arguments> {
        Query {
            statement: Either::Left(&self.query),
            arguments: match self.arguments.take() {
                Some(arguments) => Some(arguments),
                None => None,
            },
            database: PhantomData,
            persistent: true,
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::postgres::Postgres;

    #[test]
    fn test_new() {
        let qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users");
        assert_eq!(qb.query, "SELECT * FROM users");
    }


Review comment (suggestion):
I could potentially see someone wanting to reuse the same `QueryBuilder` multiple times, maybe to amortize the allocation of the query string.

In that case, we should provide a `.clear()` or `.reset()` (bikeshedding?) method to clear the query string and replace `arguments` with `Some(Default::default())`. We could use `self.arguments.is_none()` in `.push()` as a sanity check to remind the user to call `.reset()` after `.build()` if they want to build a new query with the same builder.

Code after:
        }
    }

    pub fn push(&mut self, sql: impl Display) -> &mut Self {
        if self.arguments.is_none() {
            panic!("QueryBuilder must be reset before reuse")
        }

        write!(self.query, "{}", sql).expect("error formatting `sql`");

        self
    }

    pub fn push_bind<A>(&mut self, value: A) -> &mut Self
    where
        A: 'a + Encode<'a, DB> + Send + Type<DB>,
    {
        match self.arguments {
            Some(ref mut arguments) => {
                arguments.add(value);

                arguments
                    .format_placeholder(&mut self.query)
                    .expect("error in format_placeholder");
            }
            None => panic!("Arguments taken already"),
        }

        self
    }

    pub fn build(&mut self) -> Query<'_, DB, <DB as HasArguments<'a>>::Arguments> {
        Query {
            statement: Either::Left(&self.query),
            arguments: match self.arguments.take() {
                Some(arguments) => Some(arguments),
                None => None,
            },
            database: PhantomData,
            persistent: true,
        }
    }

    pub fn reset(&mut self) -> &mut Self {
        self.query.clear();
        self.arguments = Some(Default::default());

        self
    }
}