pub struct Session<C: Connection> { /* private fields */ }Expand description
The Session is the central unit-of-work manager.
It tracks objects loaded from or added to the database and coordinates flushing changes back to the database.
Implementations§
Source§impl<C: Connection> Session<C>
impl<C: Connection> Session<C>
Sourcepub fn with_config(connection: C, config: SessionConfig) -> Self
pub fn with_config(connection: C, config: SessionConfig) -> Self
Create a new session with custom configuration.
Sourcepub fn connection(&self) -> &C
pub fn connection(&self) -> &C
Get a reference to the underlying connection.
Sourcepub fn config(&self) -> &SessionConfig
pub fn config(&self) -> &SessionConfig
Get the session configuration.
Sourcepub fn on_before_flush(
&mut self,
f: impl FnMut() -> Result<(), Error> + Send + 'static,
)
pub fn on_before_flush( &mut self, f: impl FnMut() -> Result<(), Error> + Send + 'static, )
Register a callback to run before flush.
The callback can abort the flush by returning Err.
Sourcepub fn on_after_flush(
&mut self,
f: impl FnMut() -> Result<(), Error> + Send + 'static,
)
pub fn on_after_flush( &mut self, f: impl FnMut() -> Result<(), Error> + Send + 'static, )
Register a callback to run after a successful flush.
Sourcepub fn on_before_commit(
&mut self,
f: impl FnMut() -> Result<(), Error> + Send + 'static,
)
pub fn on_before_commit( &mut self, f: impl FnMut() -> Result<(), Error> + Send + 'static, )
Register a callback to run before commit (after flush).
The callback can abort the commit by returning Err.
Sourcepub fn on_after_commit(
&mut self,
f: impl FnMut() -> Result<(), Error> + Send + 'static,
)
pub fn on_after_commit( &mut self, f: impl FnMut() -> Result<(), Error> + Send + 'static, )
Register a callback to run after a successful commit.
Sourcepub fn on_after_rollback(
&mut self,
f: impl FnMut() -> Result<(), Error> + Send + 'static,
)
pub fn on_after_rollback( &mut self, f: impl FnMut() -> Result<(), Error> + Send + 'static, )
Register a callback to run after rollback.
Sourcepub fn add<M: Model + Clone + Send + Sync + Serialize + 'static>(
&mut self,
obj: &M,
)
pub fn add<M: Model + Clone + Send + Sync + Serialize + 'static>( &mut self, obj: &M, )
Add a new object to the session.
The object will be INSERTed on the next flush() call.
Sourcepub fn add_all<'a, M, I>(&mut self, objects: I)
pub fn add_all<'a, M, I>(&mut self, objects: I)
Add multiple objects to the session at once.
This is equivalent to calling add() for each object, but provides a more
convenient API for bulk operations.
§Example
let users = vec![user1, user2, user3];
session.add_all(&users);
// Or with an iterator
session.add_all(users.iter());All objects will be INSERTed on the next flush() call.
Sourcepub fn delete<M: Model + 'static>(&mut self, obj: &M)
pub fn delete<M: Model + 'static>(&mut self, obj: &M)
Delete an object from the session.
The object will be DELETEd on the next flush() call.
Sourcepub fn mark_dirty<M: Model + Clone + Send + Sync + Serialize + 'static>(
&mut self,
obj: &M,
)
pub fn mark_dirty<M: Model + Clone + Send + Sync + Serialize + 'static>( &mut self, obj: &M, )
Mark an object as dirty (modified) so it will be UPDATEd on flush.
This updates the stored values from the object and schedules an UPDATE. Only works for objects that are already tracked as Persistent.
§Example
let mut hero = session.get::<Hero>(1).await?.unwrap();
hero.name = "New Name".to_string();
session.mark_dirty(&hero); // Schedule for UPDATE
session.flush(cx).await?; // Execute the UPDATESourcepub async fn get<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
pk: impl Into<Value>,
) -> Outcome<Option<M>, Error>
pub async fn get<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, pk: impl Into<Value>, ) -> Outcome<Option<M>, Error>
Get an object by primary key.
First checks the identity map, then queries the database if not found.
Sourcepub async fn get_by_pk<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
pk_values: &[Value],
) -> Outcome<Option<M>, Error>
pub async fn get_by_pk<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, pk_values: &[Value], ) -> Outcome<Option<M>, Error>
Sourcepub async fn get_with_options<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
pk_values: &[Value],
options: &GetOptions,
) -> Outcome<Option<M>, Error>
pub async fn get_with_options<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, pk_values: &[Value], options: &GetOptions, ) -> Outcome<Option<M>, Error>
Get an object by primary key with options.
This is the most flexible form of get() supporting:
- Composite primary keys via
&[Value] with_for_updatefor row locking
§Example
let options = GetOptions::default().with_for_update(true);
let user = session.get_with_options::<User>(&[Value::BigInt(1)], &options).await?;Sourcepub fn contains<M: Model + 'static>(&self, obj: &M) -> bool
pub fn contains<M: Model + 'static>(&self, obj: &M) -> bool
Check if an object is tracked by this session.
Sourcepub fn expunge_all(&mut self)
pub fn expunge_all(&mut self)
Detach all objects from the session.
Sourcepub fn is_modified<M: Model + Serialize + 'static>(&self, obj: &M) -> bool
pub fn is_modified<M: Model + Serialize + 'static>(&self, obj: &M) -> bool
Check if an object has pending changes.
Returns true if:
- Object is new (pending INSERT)
- Object has been modified since load (pending UPDATE)
- Object is marked for deletion (pending DELETE)
Returns false if:
- Object is not tracked
- Object is clean (unchanged since load)
- Object is detached or expired
§Example
let user = session.get::<User>(1).await?.unwrap();
assert!(!session.is_modified(&user)); // Fresh from DB
// Modify and re-check
let mut user_mut = user.clone();
user_mut.name = "New Name".to_string();
session.mark_dirty(&user_mut);
assert!(session.is_modified(&user_mut)); // Now dirtySourcepub fn modified_attributes<M: Model + Serialize + 'static>(
&self,
obj: &M,
) -> Vec<&'static str>
pub fn modified_attributes<M: Model + Serialize + 'static>( &self, obj: &M, ) -> Vec<&'static str>
Get the list of modified attribute names for an object.
Returns the column names that have changed since the object was loaded. Returns an empty vector if:
- Object is not tracked
- Object is new (all fields are “modified”)
- Object is clean (no changes)
§Example
let mut user = session.get::<User>(1).await?.unwrap();
user.name = "New Name".to_string();
session.mark_dirty(&user);
let changed = session.modified_attributes(&user);
assert!(changed.contains(&"name"));Sourcepub fn object_state<M: Model + 'static>(&self, obj: &M) -> Option<ObjectState>
pub fn object_state<M: Model + 'static>(&self, obj: &M) -> Option<ObjectState>
Get the state of a tracked object.
Returns None if the object is not tracked by this session.
Sourcepub fn expire<M: Model + 'static>(
&mut self,
obj: &M,
attributes: Option<&[&str]>,
)
pub fn expire<M: Model + 'static>( &mut self, obj: &M, attributes: Option<&[&str]>, )
Expire an object’s cached attributes, forcing reload on next access.
After calling this method, the next get() call for this object will reload
from the database instead of returning the cached version.
§Arguments
obj- The object to expire.attributes- Optional list of attribute names to expire. IfNone, all attributes are expired.
§Example
// Expire all attributes
session.expire(&user, None);
// Expire specific attributes
session.expire(&user, Some(&["name", "email"]));
// Next get() will reload from database
let refreshed = session.get::<User>(cx, user.id).await?;§Notes
- Expiring an object does not discard pending changes. If the object has been modified but not flushed, those changes remain pending.
- Expiring a detached or new object has no effect.
Sourcepub fn expire_all(&mut self)
pub fn expire_all(&mut self)
Expire all objects in the session.
After calling this method, all tracked objects will be marked as expired. The next access to any object will reload from the database.
§Example
// Expire everything in the session
session.expire_all();
// All subsequent get() calls will reload from database
let user = session.get::<User>(cx, 1).await?; // Reloads from DB
let team = session.get::<Team>(cx, 1).await?; // Reloads from DB§Notes
- This does not affect new or deleted objects.
- Pending changes are not discarded.
Sourcepub fn is_expired<M: Model + 'static>(&self, obj: &M) -> bool
pub fn is_expired<M: Model + 'static>(&self, obj: &M) -> bool
Check if an object is expired (needs reload from database).
Returns true if the object is marked as expired and will be reloaded
on the next access.
Sourcepub fn expired_attributes<M: Model + 'static>(
&self,
obj: &M,
) -> Option<Option<&HashSet<String>>>
pub fn expired_attributes<M: Model + 'static>( &self, obj: &M, ) -> Option<Option<&HashSet<String>>>
Get the list of expired attribute names for an object.
Returns:
Noneif the object is not tracked or not expiredSome(None)if all attributes are expiredSome(Some(set))if only specific attributes are expired
Sourcepub async fn refresh<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
obj: &M,
) -> Outcome<Option<M>, Error>
pub async fn refresh<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, obj: &M, ) -> Outcome<Option<M>, Error>
Refresh an object by reloading it from the database.
This method immediately reloads the object from the database, updating
the cached copy in the session. Unlike expire(), which defers the reload
until the next access, refresh() performs the reload immediately.
§Arguments
cx- The async context for database operations.obj- The object to refresh.
§Returns
Returns Ok(Some(refreshed)) if the object was found in the database,
Ok(None) if the object no longer exists in the database, or an error.
§Example
// Immediately reload from database
let refreshed = session.refresh(&cx, &user).await?;
if let Some(user) = refreshed {
println!("Refreshed: {}", user.name);
} else {
println!("User was deleted from database");
}§Notes
- This discards any changes in the session’s cached copy.
- If the object has pending changes, they will be lost.
- If the object no longer exists in the database, it is removed from the session.
Sourcepub async fn flush(&mut self, cx: &Cx) -> Outcome<(), Error>
pub async fn flush(&mut self, cx: &Cx) -> Outcome<(), Error>
Flush pending changes to the database.
This executes INSERT, UPDATE, and DELETE statements but does NOT commit.
Sourcepub async fn rollback(&mut self, cx: &Cx) -> Outcome<(), Error>
pub async fn rollback(&mut self, cx: &Cx) -> Outcome<(), Error>
Rollback the current transaction.
Sourcepub async fn load_lazy<T: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
lazy: &Lazy<T>,
cx: &Cx,
) -> Outcome<bool, Error>
pub async fn load_lazy<T: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, lazy: &Lazy<T>, cx: &Cx, ) -> Outcome<bool, Error>
Sourcepub async fn load_many<P, T, F>(
&mut self,
cx: &Cx,
objects: &[P],
accessor: F,
) -> Outcome<usize, Error>
pub async fn load_many<P, T, F>( &mut self, cx: &Cx, objects: &[P], accessor: F, ) -> Outcome<usize, Error>
Batch load lazy relationships for multiple objects.
This method collects all FK values, executes a single query, and populates each Lazy field. This prevents the N+1 query problem when iterating over a collection and accessing lazy relationships.
§Example
// Load 100 heroes
let mut heroes = session.query::<Hero>().all().await?;
// Without batch loading: 100 queries (N+1 problem)
// With batch loading: 1 query
session.load_many(&cx, &mut heroes, |h| &h.team).await?;
// All teams now loaded
for hero in &heroes {
if let Some(team) = hero.team.get() {
println!("{} is on {}", hero.name, team.name);
}
}Sourcepub async fn load_many_to_many<P, Child, FA, FP>(
&mut self,
cx: &Cx,
objects: &mut [P],
accessor: FA,
parent_pk: FP,
link_table: &LinkTableInfo,
) -> Outcome<usize, Error>
pub async fn load_many_to_many<P, Child, FA, FP>( &mut self, cx: &Cx, objects: &mut [P], accessor: FA, parent_pk: FP, link_table: &LinkTableInfo, ) -> Outcome<usize, Error>
Batch load many-to-many relationships for multiple parent objects.
This method loads related objects via a link table in a single query, avoiding the N+1 problem for many-to-many relationships.
§Example
// Load 100 heroes
let mut heroes = session.query::<Hero>().all().await?;
// Without batch loading: 100 queries (N+1 problem)
// With batch loading: 1 query via JOIN
let link_info = LinkTableInfo::new("hero_powers", "hero_id", "power_id");
session.load_many_to_many(&cx, &mut heroes, |h| &mut h.powers, |h| h.id.unwrap(), &link_info).await?;
// All powers now loaded
for hero in &heroes {
if let Some(powers) = hero.powers.get() {
println!("{} has {} powers", hero.name, powers.len());
}
}Sourcepub async fn load_many_to_many_pk<P, Child, FA, FP>(
&mut self,
cx: &Cx,
objects: &mut [P],
accessor: FA,
parent_pk: FP,
link_table: &LinkTableInfo,
) -> Outcome<usize, Error>
pub async fn load_many_to_many_pk<P, Child, FA, FP>( &mut self, cx: &Cx, objects: &mut [P], accessor: FA, parent_pk: FP, link_table: &LinkTableInfo, ) -> Outcome<usize, Error>
Batch load many-to-many relationships for multiple parent objects using composite keys.
This is the generalized form of load_many_to_many that supports composite parent and/or
child primary keys via LinkTableInfo::composite(...).
Sourcepub async fn load_one_to_many<P, Child, FA, FP>(
&mut self,
cx: &Cx,
objects: &mut [P],
accessor: FA,
parent_pk: FP,
) -> Outcome<usize, Error>
pub async fn load_one_to_many<P, Child, FA, FP>( &mut self, cx: &Cx, objects: &mut [P], accessor: FA, parent_pk: FP, ) -> Outcome<usize, Error>
Batch load one-to-many relationships for multiple parent objects.
This populates RelatedMany<Child> where the child table has a foreign key column pointing
back to the parent. It runs a single query:
SELECT *, <fk_col> AS __parent_pk FROM <child_table> WHERE <fk_col> IN (...)
and then groups results per parent PK to populate each RelatedMany.
Flush pending link/unlink operations for many-to-many relationships.
This method persists pending link and unlink operations that were tracked
via RelatedMany::link() and RelatedMany::unlink() calls.
§Example
// Add a power to a hero
hero.powers.link(&fly_power);
// Remove a power from a hero
hero.powers.unlink(&x_ray_vision);
// Flush the link table operations
let link_info = LinkTableInfo::new("hero_powers", "hero_id", "power_id");
session.flush_related_many(&cx, &mut [hero], |h| &mut h.powers, |h| h.id.unwrap(), &link_info).await?;Flush pending link/unlink operations for many-to-many relationships (composite keys).
Sourcepub fn relate_to_one<Child, Parent, FC, FP, FK>(
&self,
child: &mut Child,
child_accessor: FC,
set_fk: FK,
parent: &mut Parent,
parent_accessor: FP,
)where
Child: Model + Clone + 'static,
Parent: Model + Clone + 'static,
FC: FnOnce(&mut Child) -> &mut Related<Parent>,
FP: FnOnce(&mut Parent) -> &mut RelatedMany<Child>,
FK: FnOnce(&mut Child),
pub fn relate_to_one<Child, Parent, FC, FP, FK>(
&self,
child: &mut Child,
child_accessor: FC,
set_fk: FK,
parent: &mut Parent,
parent_accessor: FP,
)where
Child: Model + Clone + 'static,
Parent: Model + Clone + 'static,
FC: FnOnce(&mut Child) -> &mut Related<Parent>,
FP: FnOnce(&mut Parent) -> &mut RelatedMany<Child>,
FK: FnOnce(&mut Child),
Relate a child to a parent with bidirectional sync.
Sets the parent on the child (ManyToOne side) and adds the child to the
parent’s collection (OneToMany side) if back_populates is defined.
§Example
// Hero has a ManyToOne relationship to Team (hero.team)
// Team has a OneToMany relationship to Hero (team.heroes) with back_populates
session.relate_to_one(
&mut hero,
|h| &mut h.team,
|h| h.team_id = team.id, // Set FK
&mut team,
|t| &mut t.heroes,
);
// Now hero.team is set AND team.heroes includes heroSourcepub fn unrelate_from_one<Child, Parent, FC, FP, FK>(
&self,
child: &mut Child,
child_accessor: FC,
clear_fk: FK,
parent: &mut Parent,
parent_accessor: FP,
)where
Child: Model + Clone + 'static,
Parent: Model + Clone + 'static,
FC: FnOnce(&mut Child) -> &mut Related<Parent>,
FP: FnOnce(&mut Parent) -> &mut RelatedMany<Child>,
FK: FnOnce(&mut Child),
pub fn unrelate_from_one<Child, Parent, FC, FP, FK>(
&self,
child: &mut Child,
child_accessor: FC,
clear_fk: FK,
parent: &mut Parent,
parent_accessor: FP,
)where
Child: Model + Clone + 'static,
Parent: Model + Clone + 'static,
FC: FnOnce(&mut Child) -> &mut Related<Parent>,
FP: FnOnce(&mut Parent) -> &mut RelatedMany<Child>,
FK: FnOnce(&mut Child),
Sourcepub fn relate_many_to_many<Left, Right, FL, FR>(
&self,
left: &mut Left,
left_accessor: FL,
right: &mut Right,
right_accessor: FR,
)where
Left: Model + Clone + 'static,
Right: Model + Clone + 'static,
FL: FnOnce(&mut Left) -> &mut RelatedMany<Right>,
FR: FnOnce(&mut Right) -> &mut RelatedMany<Left>,
pub fn relate_many_to_many<Left, Right, FL, FR>(
&self,
left: &mut Left,
left_accessor: FL,
right: &mut Right,
right_accessor: FR,
)where
Left: Model + Clone + 'static,
Right: Model + Clone + 'static,
FL: FnOnce(&mut Left) -> &mut RelatedMany<Right>,
FR: FnOnce(&mut Right) -> &mut RelatedMany<Left>,
Relate two objects in a many-to-many relationship with bidirectional sync.
Adds each object to the other’s collection.
§Example
// Hero has ManyToMany to Power via hero_powers link table
// Power has ManyToMany to Hero via hero_powers link table (back_populates)
session.relate_many_to_many(
&mut hero,
|h| &mut h.powers,
&mut power,
|p| &mut p.heroes,
);
// Now hero.powers includes power AND power.heroes includes heroSourcepub fn unrelate_many_to_many<Left, Right, FL, FR>(
&self,
left: &mut Left,
left_accessor: FL,
right: &mut Right,
right_accessor: FR,
)where
Left: Model + Clone + 'static,
Right: Model + Clone + 'static,
FL: FnOnce(&mut Left) -> &mut RelatedMany<Right>,
FR: FnOnce(&mut Right) -> &mut RelatedMany<Left>,
pub fn unrelate_many_to_many<Left, Right, FL, FR>(
&self,
left: &mut Left,
left_accessor: FL,
right: &mut Right,
right_accessor: FR,
)where
Left: Model + Clone + 'static,
Right: Model + Clone + 'static,
FL: FnOnce(&mut Left) -> &mut RelatedMany<Right>,
FR: FnOnce(&mut Right) -> &mut RelatedMany<Left>,
Unrelate two objects in a many-to-many relationship with bidirectional sync.
Removes each object from the other’s collection.
Sourcepub fn enable_n1_detection(&mut self, threshold: usize)
pub fn enable_n1_detection(&mut self, threshold: usize)
Enable N+1 query detection with the specified threshold.
When the number of lazy loads for a single relationship reaches the threshold, a warning is emitted suggesting batch loading.
§Example
session.enable_n1_detection(3); // Warn after 3 lazy loads
// This will trigger a warning:
for hero in &mut heroes {
hero.team.load(&mut session).await?;
}
// Check stats
if let Some(stats) = session.n1_stats() {
println!("Potential N+1 issues: {}", stats.potential_n1);
}Sourcepub fn disable_n1_detection(&mut self)
pub fn disable_n1_detection(&mut self)
Disable N+1 query detection and clear the tracker.
Sourcepub fn n1_detection_enabled(&self) -> bool
pub fn n1_detection_enabled(&self) -> bool
Check if N+1 detection is enabled.
Sourcepub fn n1_tracker_mut(&mut self) -> Option<&mut N1QueryTracker>
pub fn n1_tracker_mut(&mut self) -> Option<&mut N1QueryTracker>
Get mutable access to the N+1 tracker (for recording loads).
Sourcepub fn reset_n1_tracking(&mut self)
pub fn reset_n1_tracking(&mut self)
Reset N+1 detection counts (call at start of new request/transaction).
Sourcepub fn record_lazy_load(
&mut self,
parent_type: &'static str,
relationship: &'static str,
)
pub fn record_lazy_load( &mut self, parent_type: &'static str, relationship: &'static str, )
Record a lazy load for N+1 detection.
This is called automatically by lazy loading methods.
Sourcepub async fn merge<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
model: M,
load: bool,
) -> Outcome<M, Error>
pub async fn merge<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, model: M, load: bool, ) -> Outcome<M, Error>
Merge a detached object back into the session.
This method reattaches a detached or externally-created object to the session, copying its state to the session-tracked instance if one exists.
§Behavior
-
If object with same PK exists in session: Updates the tracked object with values from the provided object and returns a clone of the tracked version.
-
If
loadis true and object not in session: Queries the database for an existing row, merges the provided values onto it, and tracks it. -
If object not in session or DB: Treats it as new (will INSERT on flush).
§Example
// Object from previous session or external source
let mut detached_user = User { id: Some(1), name: "Updated Name".into(), .. };
// Merge into current session
let attached_user = session.merge(&cx, detached_user, true).await?;
// attached_user is now tracked, changes will be persisted on flush
session.flush(&cx).await?;§Parameters
cx: The async context for database operations.model: The detached model instance to merge.load: If true, load from database when not in identity map.
§Returns
The session-attached version of the object. If the object was already tracked, returns a clone of the updated tracked object. Otherwise, returns a clone of the newly tracked object.
Sourcepub async fn merge_without_load<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>(
&mut self,
cx: &Cx,
model: M,
) -> Outcome<M, Error>
pub async fn merge_without_load<M: Model + Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static>( &mut self, cx: &Cx, model: M, ) -> Outcome<M, Error>
Merge a detached object without loading from database.
This is a convenience method equivalent to merge(cx, model, false).
Use this when you know the object doesn’t exist in the database or
you don’t want to query the database.
§Example
let attached = session.merge_without_load(&cx, detached_user).await?;Sourcepub fn pending_new_count(&self) -> usize
pub fn pending_new_count(&self) -> usize
Get count of objects pending INSERT.
Sourcepub fn pending_delete_count(&self) -> usize
pub fn pending_delete_count(&self) -> usize
Get count of objects pending DELETE.
Sourcepub fn pending_dirty_count(&self) -> usize
pub fn pending_dirty_count(&self) -> usize
Get count of dirty objects pending UPDATE.
Sourcepub fn tracked_count(&self) -> usize
pub fn tracked_count(&self) -> usize
Get total tracked object count.
Sourcepub fn in_transaction(&self) -> bool
pub fn in_transaction(&self) -> bool
Whether we’re in a transaction.
Sourcepub fn debug_state(&self) -> SessionDebugInfo
pub fn debug_state(&self) -> SessionDebugInfo
Dump session state for debugging.
Sourcepub async fn bulk_insert<M: Model + Clone + Send + Sync + 'static>(
&mut self,
cx: &Cx,
models: &[M],
) -> Outcome<u64, Error>
pub async fn bulk_insert<M: Model + Clone + Send + Sync + 'static>( &mut self, cx: &Cx, models: &[M], ) -> Outcome<u64, Error>
Bulk insert multiple model instances without object tracking.
This generates a single multi-row INSERT statement and bypasses the identity map entirely, making it much faster for large batches.
Models are inserted in chunks of batch_size to avoid excessively
large SQL statements. The default batch size is 1000.
Returns the total number of rows inserted.
Sourcepub async fn bulk_insert_with_batch_size<M: Model + Clone + Send + Sync + 'static>(
&mut self,
cx: &Cx,
models: &[M],
batch_size: usize,
) -> Outcome<u64, Error>
pub async fn bulk_insert_with_batch_size<M: Model + Clone + Send + Sync + 'static>( &mut self, cx: &Cx, models: &[M], batch_size: usize, ) -> Outcome<u64, Error>
Bulk insert with a custom batch size.
Sourcepub async fn bulk_update<M: Model + Clone + Send + Sync + 'static>(
&mut self,
cx: &Cx,
models: &[M],
) -> Outcome<u64, Error>
pub async fn bulk_update<M: Model + Clone + Send + Sync + 'static>( &mut self, cx: &Cx, models: &[M], ) -> Outcome<u64, Error>
Bulk update multiple model instances without individual tracking.
Each model is updated individually using its primary key, but all updates are executed in a single transaction without going through the identity map or change tracking.
Returns the total number of rows updated.