Skip to main content

InsertBuilder

Type Alias InsertBuilder 

Source
pub type InsertBuilder<'a, Schema, State, Table, Marker = (), Row = ()> = QueryBuilder<'a, Schema, State, Table, Marker, Row>;
Expand description

A PostgreSQL INSERT being built: a QueryBuilder in one of the Insert* states.

Rows come from .values(...) (the table’s generated Insert* model) or from .select(...). Then add ON CONFLICT handling and RETURNING as needed. State allows only these steps, in this order.

§Examples

let query = db
    .insert(user)
    .values([InsertUser::new("Alice"), InsertUser::new("Bob")])
    .on_conflict_do_nothing()
    .returning(user.id);
assert_eq!(
    query.to_sql().sql(),
    r#"INSERT INTO "users" ("name") VALUES ($1), ($2) ON CONFLICT DO NOTHING RETURNING "users"."id""#
);

Aliased Type§

pub struct InsertBuilder<'a, Schema, State, Table, Marker = (), Row = ()> {
    pub sql: SQL<'a, PostgresValue<'a>>,
    /* private fields */
}

Fields§

§sql: SQL<'a, PostgresValue<'a>>

The SQL built so far.

Implementations§

Source§

impl<'a, Schema, Table> InsertBuilder<'a, Schema, InsertInitial, Table>
where Table: PostgresTable<'a>,

Source

pub fn value<T>( self, value: Table::Insert<T>, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>

Inserts one row. Shorthand for .values([row]).

§Examples
let query = db.insert(user).value(InsertUser::new("Alice"));
assert_eq!(query.to_sql().sql(), r#"INSERT INTO "users" ("name") VALUES ($1)"#);
Source

pub fn values<I, T>( self, values: I, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where I: IntoIterator<Item = Table::Insert<T>>,

Inserts the given rows, built with the table’s Insert* model.

Every row has the same model type. A column a row leaves unset gets its database default; when rows set different columns, every row lists the union of the columns, with DEFAULT where it sets none.

§Examples
let query = db
    .insert(user)
    .values([InsertUser::new("Alice"), InsertUser::new("Bob")]);
assert_eq!(
    query.to_sql().sql(),
    r#"INSERT INTO "users" ("name") VALUES ($1), ($2)"#
);
Source

pub fn columns<Columns>( self, columns: Columns, ) -> InsertBuilder<'a, Schema, InsertColumnsSet<Columns::Columns>, Table>
where Columns: InsertTargetColumns<'a, PostgresValue<'a>, Table>,

Sets the target columns, in order, for INSERT ... SELECT.

The list must include every required column (non-null without a default). Continue with select, whose columns must match these in number, order and type.

§Examples
let query = db
    .insert(post)
    .columns((post.author_id, post.title))
    .select(db.select((user.id, user.name)).from(user));
assert_eq!(
    query.to_sql().sql(),
    r#"INSERT INTO "posts" ("author_id", "title") SELECT "users"."id", "users"."name" FROM "users""#
);
Source

pub fn select<Q, R, ScopeProof, AggProof>( self, query: Q, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where Table: InsertSelectTable, Q: IntoSelectQuery<'a, Schema, R>, Q::Marker: InsertSelectCompatible<'a, PostgresValue<'a>, Table, R> + MarkerScopeValidFor<ScopeProof> + MarkerAggValidFor<Q::Grouped, AggProof>,

Inserts the rows of a SELECT into every insertable column of the table.

The query’s columns must match the table’s insertable columns in number, order, type and nullability, and the query must pass the usual scope and GROUP BY checks; all of this is checked at compile time. To fill only some columns, call columns first.

Source

pub fn select_raw<Q>( self, query: Q, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where Q: ToSQL<'a, PostgresValue<'a>>,

Inserts the rows of a raw SELECT, with no target column list.

Nothing about the query is checked: not its column count, types, nullability, sources or aggregates. Prefer select.

Source§

impl<'a, Schema, Table, Targets> InsertBuilder<'a, Schema, InsertColumnsSet<Targets>, Table>
where Table: PostgresTable<'a> + InsertSelectTable,

Source

pub fn select<Q, R, RequiredProof, ScopeProof, AggProof>( self, query: Q, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where Targets: IncludesRequired<Table::RequiredColumns, RequiredProof>, Q: IntoSelectQuery<'a, Schema, R>, Q::Marker: PartialInsertSelectCompatible<'a, PostgresValue<'a>, Targets> + MarkerScopeValidFor<ScopeProof> + MarkerAggValidFor<Q::Grouped, AggProof>,

Inserts the rows of a SELECT into the columns chosen with .columns(...).

The query’s columns must match the target columns in number, order, type and nullability, and the query must pass the usual scope and GROUP BY checks; all of this is checked at compile time.

Source

pub fn select_raw<Q, RequiredProof>( self, query: Q, ) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where Targets: IncludesRequired<Table::RequiredColumns, RequiredProof>, Q: ToSQL<'a, PostgresValue<'a>>,

Inserts the rows of a raw SELECT into the chosen target columns.

Only the target list is checked (it must include every required column); the query itself is not. Prefer select.

Source§

impl<'a, S, T> InsertBuilder<'a, S, InsertValuesSet, T>

Source

pub fn on_conflict<C: ConflictTarget<T>>( self, target: C, ) -> OnConflictBuilder<'a, S, T>

Starts ON CONFLICT (columns), handling rows that would violate a unique constraint on the target.

The target is a primary-key column, a unique column, or a unique index (anything implementing ConflictTarget<T>, which the macros generate). Finish with .do_nothing() or .do_update(update_model).

§Examples
fn main() {
use drizzle::postgres::prelude::*;
use drizzle::postgres::builder::QueryBuilder;

#[PostgresTable(name = "users")]
struct User {
    #[column(serial, primary)]
    id: i32,
    name: String,
    #[column(unique)]
    email: Option<String>,
}

#[PostgresIndex(unique)]
struct UserEmailIdx(User::email);

#[derive(PostgresSchema)]
struct Schema {
    user: User,
    user_email_idx: UserEmailIdx,
}

let builder = QueryBuilder::new::<Schema>();
let schema = Schema::new();
let user = schema.user;

// Target a specific column
builder.insert(user).values([InsertUser::new("Alice")])
    .on_conflict(user.id).do_nothing();

// DO UPDATE with new values
let query = builder.insert(user).values([InsertUser::new("Alice")])
    .on_conflict(user.email).do_update(UpdateUser::default().with_name("updated"));
assert_eq!(
    query.to_sql().sql(),
    r#"INSERT INTO "users" ("name") VALUES ($1) ON CONFLICT ("email") DO UPDATE SET "name" = $2"#
);

// Target a unique index
builder.insert(user).values([InsertUser::new("Alice")])
    .on_conflict(schema.user_email_idx).do_nothing();
}
Source

pub fn on_conflict_on_constraint<C: NamedConstraint<T>>( self, target: C, ) -> OnConflictBuilder<'a, S, T>

Starts ON CONFLICT ON CONSTRAINT name, naming the unique constraint to handle.

The target is a unique column or a named unique constraint (anything implementing NamedConstraint<T>, which the macros generate). A standalone unique index is not a constraint, so PostgreSQL rejects it here; use on_conflict for indexes. Finish with .do_nothing() or .do_update(update_model).

§Examples
fn main() {
use drizzle::postgres::prelude::*;
use drizzle::postgres::builder::QueryBuilder;

#[PostgresTable(name = "users")]
struct User {
    #[column(serial, primary)]
    id: i32,
    name: String,
    #[column(unique)]
    email: Option<String>,
}

#[derive(PostgresSchema)]
struct Schema {
    user: User,
}

let builder = QueryBuilder::new::<Schema>();
let schema = Schema::new();

let user = schema.user;
builder.insert(user).values([InsertUser::new("Alice")])
    .on_conflict_on_constraint(user.email).do_nothing();
}
Source

pub fn on_conflict_do_nothing( self, ) -> InsertBuilder<'a, S, InsertOnConflictSet, T>

Adds ON CONFLICT DO NOTHING with no target: rows that violate any unique or exclusion constraint are skipped.

Source

pub fn returning<Columns, ScopeProof>( self, columns: Columns, ) -> InsertBuilder<'a, S, InsertReturningSet, T, Scoped<<Columns as IntoSelectTarget>::Marker, Cons<T, Nil>>, <<Columns as IntoSelectTarget>::Marker as ResolveRow<T>>::Row>
where Columns: ExprSources + ToSQL<'a, PostgresValue<'a>> + IntoSelectTarget, Columns::Sources: SourcesIn<Cons<T, Nil>, ScopeProof>, Columns::Marker: ResolveRow<T>,

Adds RETURNING columns, so the statement returns the inserted rows.

Pass a column, a tuple of columns, or () for all columns. Only columns of the target table are allowed.

§Examples
let query = db
    .insert(user)
    .values([InsertUser::new("Alice")])
    .returning((user.id, user.name));
assert_eq!(
    query.to_sql().sql(),
    r#"INSERT INTO "users" ("name") VALUES ($1) RETURNING "users"."id", "users"."name""#
);
Source§

impl<'a, S, T> InsertBuilder<'a, S, InsertOnConflictSet, T>

Source

pub fn returning<Columns, ScopeProof>( self, columns: Columns, ) -> InsertBuilder<'a, S, InsertReturningSet, T, Scoped<<Columns as IntoSelectTarget>::Marker, Cons<T, Nil>>, <<Columns as IntoSelectTarget>::Marker as ResolveRow<T>>::Row>
where Columns: ExprSources + ToSQL<'a, PostgresValue<'a>> + IntoSelectTarget, Columns::Sources: SourcesIn<Cons<T, Nil>, ScopeProof>, Columns::Marker: ResolveRow<T>,

Adds RETURNING columns after the ON CONFLICT clause.

Rows skipped by DO NOTHING are not returned.

Source§

impl<'a, S, T> InsertBuilder<'a, S, InsertDoUpdateSet, T>

Source

pub fn where<E, ScopeProof>( self, condition: E, ) -> InsertBuilder<'a, S, InsertOnConflictSet, T>
where E: ExprSources + Expr<'a, PostgresValue<'a>>, E::Sources: SourcesIn<Cons<T, Nil>, ScopeProof>, E::SQLType: BooleanLike,

Adds a WHERE condition to DO UPDATE: conflicting rows are updated only when it holds.

Renders ON CONFLICT (...) DO UPDATE SET ... WHERE condition. The condition may only use columns of the target table.

Source

pub fn returning<Columns, ScopeProof>( self, columns: Columns, ) -> InsertBuilder<'a, S, InsertReturningSet, T, Scoped<<Columns as IntoSelectTarget>::Marker, Cons<T, Nil>>, <<Columns as IntoSelectTarget>::Marker as ResolveRow<T>>::Row>
where Columns: ExprSources + ToSQL<'a, PostgresValue<'a>> + IntoSelectTarget, Columns::Sources: SourcesIn<Cons<T, Nil>, ScopeProof>, Columns::Marker: ResolveRow<T>,

Adds RETURNING columns after DO UPDATE SET.