Skip to content

Commit e7f1366

Browse files
ldanilekConvex, Inc.
authored and
Convex, Inc.
committed
thread ComponentId through UserFacingModel (#25818)
UserFacingModel always deals with user tables, so it's scoped to a component. the main benefit of this is in tests we can use `new_root_for_tests`, and this will be passed down to the transaction methods underneath, when converting table name and number to tablet. this can also fetch the component ID when we remove the `Root` shortcut. GitOrigin-RevId: 97222d63b48dea7511c5ef6447a88ec26f693826
1 parent 6bff364 commit e7f1366

22 files changed

+177
-115
lines changed

crates/application/src/export_worker.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ mod tests {
920920
for i in 0..2 {
921921
let table: TableName = str::parse(format!("table_{i}").as_str())?;
922922
let mut tx = db.begin(Identity::system()).await?;
923-
UserFacingModel::new(&mut tx)
923+
UserFacingModel::new_root_for_test(&mut tx)
924924
.insert(table, ConvexObject::empty())
925925
.await?;
926926
db.commit(tx).await?;
@@ -972,22 +972,25 @@ mod tests {
972972
let mut tx = db.begin(Identity::system()).await?;
973973
let id = match i {
974974
0 => {
975-
UserFacingModel::new(&mut tx)
975+
UserFacingModel::new_root_for_test(&mut tx)
976976
.insert(table, assert_obj!("foo" => 1))
977977
.await?
978978
},
979979
1 => {
980-
UserFacingModel::new(&mut tx)
980+
UserFacingModel::new_root_for_test(&mut tx)
981981
.insert(table, assert_obj!("foo" => [1, "1"]))
982982
.await?
983983
},
984984
_ => {
985-
UserFacingModel::new(&mut tx)
985+
UserFacingModel::new_root_for_test(&mut tx)
986986
.insert(table, assert_obj!("foo" => "1"))
987987
.await?
988988
},
989989
};
990-
let doc = UserFacingModel::new(&mut tx).get(id, None).await?.unwrap();
990+
let doc = UserFacingModel::new_root_for_test(&mut tx)
991+
.get(id, None)
992+
.await?
993+
.unwrap();
991994
let tablet_id = tx.table_mapping().inject_table_id()(doc.table())?.tablet_id;
992995
let doc = doc.to_resolved(tablet_id);
993996
let id_v6 = doc.developer_id().encode();
@@ -1163,12 +1166,12 @@ mod tests {
11631166

11641167
// Write to two tables and delete one.
11651168
let mut tx = db.begin(Identity::system()).await?;
1166-
UserFacingModel::new(&mut tx)
1169+
UserFacingModel::new_root_for_test(&mut tx)
11671170
.insert("table_0".parse()?, ConvexObject::empty())
11681171
.await?;
11691172
db.commit(tx).await?;
11701173
let mut tx = db.begin(Identity::system()).await?;
1171-
UserFacingModel::new(&mut tx)
1174+
UserFacingModel::new_root_for_test(&mut tx)
11721175
.insert("table_1".parse()?, ConvexObject::empty())
11731176
.await?;
11741177
db.commit(tx).await?;

crates/application/src/schema_worker/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ mod tests {
241241
};
242242
let (id, _) = SchemaModel::new(&mut tx).submit_pending(db_schema).await?;
243243
// Insert a document that matches the schema
244-
UserFacingModel::new(&mut tx)
244+
UserFacingModel::new_root_for_test(&mut tx)
245245
.insert(table_name.clone(), assert_obj!())
246246
.await?;
247247
db.commit(tx).await?;

crates/application/src/snapshot_import.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,10 +2856,10 @@ a
28562856

28572857
{
28582858
let mut tx = app.begin(identity).await?;
2859-
let validated_id = UserFacingModel::new(&mut tx)
2859+
let validated_id = UserFacingModel::new_root_for_test(&mut tx)
28602860
.insert(table_name.parse()?, assert_obj!())
28612861
.await?;
2862-
UserFacingModel::new(&mut tx)
2862+
UserFacingModel::new_root_for_test(&mut tx)
28632863
.insert(
28642864
table_with_foreign_key.parse()?,
28652865
assert_obj!(
@@ -2910,7 +2910,7 @@ _id,a
29102910

29112911
{
29122912
let mut tx = app.begin(identity).await?;
2913-
UserFacingModel::new(&mut tx)
2913+
UserFacingModel::new_root_for_test(&mut tx)
29142914
.insert(table_name.parse()?, assert_obj!())
29152915
.await?;
29162916
app.commit_test(tx).await?;

crates/application/src/tests/occ_retries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async fn test_replace_tx(
3030
id: ResolvedDocumentId,
3131
value: ConvexValue,
3232
) -> anyhow::Result<((), Vec<DeploymentAuditLogEvent>)> {
33-
UserFacingModel::new(tx)
33+
UserFacingModel::new_root_for_test(tx)
3434
.replace(id.into(), obj!("name" => value)?)
3535
.await?;
3636
Ok(((), vec![]))

crates/database/src/bootstrap_model/schema/tests.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -351,37 +351,39 @@ async fn test_schema_enforced_on_write(rt: TestRuntime) -> anyhow::Result<()> {
351351

352352
// Inserting a document that matches the schema should succeed
353353
let object = assert_obj!("name" => "emma", "age" => 24);
354-
let id = UserFacingModel::new(&mut tx)
354+
let id = UserFacingModel::new_root_for_test(&mut tx)
355355
.insert(table.clone(), object)
356356
.await?;
357357

358358
// Replacing a document that matches the schema should succeed
359359
let object = assert_obj!("name" => "lee", "age" => 24);
360-
UserFacingModel::new(&mut tx).replace(id, object).await?;
360+
UserFacingModel::new_root_for_test(&mut tx)
361+
.replace(id, object)
362+
.await?;
361363

362364
// Updating a document that matches the schema should succeed
363365
let object = assert_obj!("name" => "alex", "age" => 24);
364-
UserFacingModel::new(&mut tx)
366+
UserFacingModel::new_root_for_test(&mut tx)
365367
.patch(id, object.into())
366368
.await?;
367369

368370
// Inserting a document that does not match the schema should fail
369371
let bad_object = assert_obj!("name" => "emma", "age" => "24");
370-
let err = UserFacingModel::new(&mut tx)
372+
let err = UserFacingModel::new_root_for_test(&mut tx)
371373
.insert(table, bad_object.clone())
372374
.await
373375
.unwrap_err();
374376
assert_eq!(err.short_msg(), "SchemaEnforcementError");
375377

376378
// Replacing a document that does not match the schema should fail
377-
let err = UserFacingModel::new(&mut tx)
379+
let err = UserFacingModel::new_root_for_test(&mut tx)
378380
.replace(id, bad_object.clone())
379381
.await
380382
.unwrap_err();
381383
assert_eq!(err.short_msg(), "SchemaEnforcementError");
382384

383385
// Updating a document that does not match the schema should fail
384-
let err = UserFacingModel::new(&mut tx)
386+
let err = UserFacingModel::new_root_for_test(&mut tx)
385387
.patch(id, bad_object.into())
386388
.await
387389
.unwrap_err();
@@ -403,23 +405,25 @@ async fn test_schema_failed_after_bad_insert(rt: TestRuntime) -> anyhow::Result<
403405

404406
// Inserting a document that matches the schema should succeed
405407
let object = assert_obj!("name" => "emma", "age" => 24);
406-
let id = UserFacingModel::new(&mut tx)
408+
let id = UserFacingModel::new_root_for_test(&mut tx)
407409
.insert(table.clone(), object)
408410
.await?;
409411

410412
// Replacing a document that matches the schema should succeed
411413
let object = assert_obj!("name" => "lee", "age" => 24);
412-
UserFacingModel::new(&mut tx).replace(id, object).await?;
414+
UserFacingModel::new_root_for_test(&mut tx)
415+
.replace(id, object)
416+
.await?;
413417

414418
// Updating a document that matches the schema should succeed
415419
let object = assert_obj!("name" => "alex", "age" => 24);
416-
UserFacingModel::new(&mut tx)
420+
UserFacingModel::new_root_for_test(&mut tx)
417421
.patch(id, object.into())
418422
.await?;
419423

420424
// Inserting a document that does not match the schema should fail
421425
let bad_object = assert_obj!("name" => "emma", "age" => "24");
422-
UserFacingModel::new(&mut tx)
426+
UserFacingModel::new_root_for_test(&mut tx)
423427
.insert(table.clone(), bad_object.clone())
424428
.await?;
425429
let SchemaMetadata { state, schema: _ } = tx
@@ -435,7 +439,7 @@ async fn test_schema_failed_after_bad_insert(rt: TestRuntime) -> anyhow::Result<
435439
// failed and succeed
436440
let mut model = SchemaModel::new(&mut tx);
437441
let (schema_id, _state) = model.submit_pending(db_schema.clone()).await?;
438-
UserFacingModel::new(&mut tx)
442+
UserFacingModel::new_root_for_test(&mut tx)
439443
.replace(id, bad_object.clone())
440444
.await?;
441445
let SchemaMetadata { state, schema: _ } = tx
@@ -451,7 +455,7 @@ async fn test_schema_failed_after_bad_insert(rt: TestRuntime) -> anyhow::Result<
451455
// failed and succeed
452456
let mut model = SchemaModel::new(&mut tx);
453457
let (schema_id, _state) = model.submit_pending(db_schema.clone()).await?;
454-
UserFacingModel::new(&mut tx)
458+
UserFacingModel::new_root_for_test(&mut tx)
455459
.patch(id, bad_object.into())
456460
.await?;
457461
let SchemaMetadata { state, schema: _ } = tx

crates/database/src/bootstrap_model/user_facing.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55

66
use anyhow::Context;
77
use common::{
8+
components::ComponentId,
89
document::{
910
DeveloperDocument,
1011
ResolvedDocument,
@@ -64,11 +65,24 @@ use crate::{
6465
// 5. We support branching on the `convex` NPM package's version.
6566
pub struct UserFacingModel<'a, RT: Runtime> {
6667
tx: &'a mut Transaction<RT>,
68+
// TODO(lee) pass component to transaction methods.
69+
_component: ComponentId,
6770
}
6871

6972
impl<'a, RT: Runtime> UserFacingModel<'a, RT> {
70-
pub fn new(tx: &'a mut Transaction<RT>) -> Self {
71-
Self { tx }
73+
pub fn new(tx: &'a mut Transaction<RT>, component: ComponentId) -> Self {
74+
Self {
75+
tx,
76+
_component: component,
77+
}
78+
}
79+
80+
#[cfg(any(test, feature = "testing"))]
81+
pub fn new_root_for_test(tx: &'a mut Transaction<RT>) -> Self {
82+
Self {
83+
tx,
84+
_component: ComponentId::Root,
85+
}
7286
}
7387

7488
#[convex_macro::instrument_future]

crates/database/src/query/index_range.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55

66
use async_trait::async_trait;
77
use common::{
8+
components::ComponentId,
89
document::DeveloperDocument,
910
index::IndexKeyBytes,
1011
interval::Interval,
@@ -169,7 +170,8 @@ impl IndexRange {
169170
}
170171
self.cursor_interval.curr_exclusive = Some(CursorPosition::After(index_position));
171172
self.returned_results += 1;
172-
UserFacingModel::new(tx).record_read_document(&v, self.printable_index_name.table())?;
173+
UserFacingModel::new(tx, ComponentId::Root)
174+
.record_read_document(&v, self.printable_index_name.table())?;
173175
// Database bandwidth for index reads
174176
tx.usage_tracker.track_database_egress_size(
175177
self.printable_index_name.table().to_string(),

crates/database/src/query/search_query.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use async_trait::async_trait;
22
use common::{
3+
components::ComponentId,
34
document::DeveloperDocument,
45
index::IndexKeyBytes,
56
knobs::TRANSACTION_MAX_READ_SIZE_BYTES,
@@ -227,7 +228,7 @@ impl SearchResultIterator {
227228
self.next_index += 1;
228229

229230
let id = self.table_number.id(candidate.id);
230-
let (document, existing_doc_ts) = UserFacingModel::new(tx)
231+
let (document, existing_doc_ts) = UserFacingModel::new(tx, ComponentId::Root)
231232
.get_with_ts(id, self.version.clone())
232233
.await?
233234
.ok_or_else(|| {

crates/database/src/search_and_vector_bootstrap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ mod tests {
882882
"vector" => values,
883883
"channel" => ConvexValue::String("#general".try_into()?),
884884
);
885-
let document_id = UserFacingModel::new(&mut tx)
885+
let document_id = UserFacingModel::new_root_for_test(&mut tx)
886886
.insert(table_name, document)
887887
.await?;
888888
db.commit(tx).await?;

crates/database/src/table_iteration.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ mod tests {
742742
continue;
743743
}
744744
let id = *(objects.keys().nth(index % objects.len()).unwrap());
745-
let replaced = UserFacingModel::new(&mut tx)
745+
let replaced = UserFacingModel::new_root_for_test(&mut tx)
746746
.replace(id.into(), object)
747747
.await?;
748748
objects.insert(id, replaced);
@@ -752,7 +752,9 @@ mod tests {
752752
continue;
753753
}
754754
let id = *(objects.keys().nth(index % objects.len()).unwrap());
755-
UserFacingModel::new(&mut tx).delete(id.into()).await?;
755+
UserFacingModel::new_root_for_test(&mut tx)
756+
.delete(id.into())
757+
.await?;
756758
objects.remove(&id).unwrap();
757759
},
758760
}
@@ -850,7 +852,7 @@ mod tests {
850852
let snapshot_ts = unchecked_repeatable_ts(database.commit(tx).await?);
851853

852854
let mut tx = database.begin(Identity::system()).await?;
853-
UserFacingModel::new(&mut tx)
855+
UserFacingModel::new_root_for_test(&mut tx)
854856
.replace(id.into(), assert_obj!("k" => "a"))
855857
.await?;
856858
database.commit(tx).await?;

crates/database/src/tests/apply_function_runner_tx.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async fn test_apply_function_runner_tx_new_table(rt: TestRuntime) -> anyhow::Res
6666
.await?;
6767

6868
// Insert a document into a new table
69-
UserFacingModel::new(&mut function_runner_tx)
69+
UserFacingModel::new_root_for_test(&mut function_runner_tx)
7070
.insert("table".parse()?, obj!("field" => "value")?)
7171
.await?;
7272

@@ -106,7 +106,7 @@ async fn test_apply_function_runner_tx_new_table(rt: TestRuntime) -> anyhow::Res
106106
async fn test_apply_function_runner_tx_read_only(rt: TestRuntime) -> anyhow::Result<()> {
107107
let db = new_test_database(rt).await;
108108
let mut setup_tx = db.begin_system().await?;
109-
let id = UserFacingModel::new(&mut setup_tx)
109+
let id = UserFacingModel::new_root_for_test(&mut setup_tx)
110110
.insert("table".parse()?, obj!("field" => "value")?)
111111
.await?;
112112
db.commit(setup_tx).await?;
@@ -123,7 +123,7 @@ async fn test_apply_function_runner_tx_read_only(rt: TestRuntime) -> anyhow::Res
123123
)
124124
.await?;
125125

126-
UserFacingModel::new(&mut function_runner_tx)
126+
UserFacingModel::new_root_for_test(&mut function_runner_tx)
127127
.get_with_ts(id, None)
128128
.await?;
129129

@@ -160,7 +160,7 @@ async fn test_apply_function_runner_tx_read_only(rt: TestRuntime) -> anyhow::Res
160160
async fn test_apply_function_runner_tx_replace(rt: TestRuntime) -> anyhow::Result<()> {
161161
let db = new_test_database(rt).await;
162162
let mut setup_tx = db.begin_system().await?;
163-
let id = UserFacingModel::new(&mut setup_tx)
163+
let id = UserFacingModel::new_root_for_test(&mut setup_tx)
164164
.insert("table".parse()?, obj!("field" => "value")?)
165165
.await?;
166166
db.commit(setup_tx).await?;
@@ -177,7 +177,7 @@ async fn test_apply_function_runner_tx_replace(rt: TestRuntime) -> anyhow::Resul
177177
)
178178
.await?;
179179

180-
UserFacingModel::new(&mut function_runner_tx)
180+
UserFacingModel::new_root_for_test(&mut function_runner_tx)
181181
.replace(id, obj!("field" => "value2")?)
182182
.await?;
183183

@@ -217,7 +217,7 @@ async fn test_apply_function_runner_tx_merge_existing_writes(
217217
let db = new_test_database(rt).await;
218218
let mut backend_tx = db.begin_system().await?;
219219
// Make writes before initializing funrun transaction
220-
UserFacingModel::new(&mut backend_tx)
220+
UserFacingModel::new_root_for_test(&mut backend_tx)
221221
.insert("table".parse()?, obj!("field" => "value")?)
222222
.await?;
223223
let begin_timestamp = backend_tx.begin_timestamp();
@@ -234,7 +234,7 @@ async fn test_apply_function_runner_tx_merge_existing_writes(
234234
function_runner_tx.merge_writes(updates, generated_ids)?;
235235

236236
// Perform writes as if in funrun
237-
UserFacingModel::new(&mut function_runner_tx)
237+
UserFacingModel::new_root_for_test(&mut function_runner_tx)
238238
.insert("table2".parse()?, obj!("foo" => "bla")?)
239239
.await?;
240240

@@ -274,7 +274,7 @@ async fn test_apply_function_runner_tx_merge_existing_writes_bad(
274274
let db = new_test_database(rt).await;
275275
let mut backend_tx = db.begin_system().await?;
276276
// Make writes before initializing funrun transaction
277-
UserFacingModel::new(&mut backend_tx)
277+
UserFacingModel::new_root_for_test(&mut backend_tx)
278278
.insert("table".parse()?, obj!("field" => "value")?)
279279
.await?;
280280
let begin_timestamp = backend_tx.begin_timestamp();
@@ -290,7 +290,7 @@ async fn test_apply_function_runner_tx_merge_existing_writes_bad(
290290
.await?;
291291

292292
// Perform writes as if in funrun
293-
UserFacingModel::new(&mut function_runner_tx)
293+
UserFacingModel::new_root_for_test(&mut function_runner_tx)
294294
.insert("table2".parse()?, obj!("foo" => "bla")?)
295295
.await?;
296296

0 commit comments

Comments
 (0)