@@ -7,14 +7,15 @@ use http::StatusCode;
7
7
8
8
use spacetimedb:: client:: ClientActorIndex ;
9
9
use spacetimedb:: energy:: { EnergyBalance , EnergyQuanta } ;
10
- use spacetimedb:: host:: { HostController , ModuleHost , NoSuchModule , UpdateDatabaseResult } ;
10
+ use spacetimedb:: host:: { HostController , MigratePlanResult , ModuleHost , NoSuchModule , UpdateDatabaseResult } ;
11
11
use spacetimedb:: identity:: { AuthCtx , Identity } ;
12
12
use spacetimedb:: messages:: control_db:: { Database , HostType , Node , Replica } ;
13
13
use spacetimedb:: sql;
14
14
use spacetimedb_client_api_messages:: http:: { SqlStmtResult , SqlStmtStats } ;
15
15
use spacetimedb_client_api_messages:: name:: { DomainName , InsertDomainResult , RegisterTldResult , SetDomainsResult , Tld } ;
16
16
use spacetimedb_lib:: { ProductTypeElement , ProductValue } ;
17
17
use spacetimedb_paths:: server:: ModuleLogsDir ;
18
+ use spacetimedb_schema:: auto_migrate:: { MigrationPolicy , PrettyPrintStyle } ;
18
19
use tokio:: sync:: watch;
19
20
20
21
pub mod auth;
@@ -67,14 +68,15 @@ impl Host {
67
68
& self ,
68
69
auth : AuthCtx ,
69
70
database : Database ,
71
+ confirmed_read : bool ,
70
72
body : String ,
71
73
) -> axum:: response:: Result < Vec < SqlStmtResult < ProductValue > > > {
72
74
let module_host = self
73
75
. module ( )
74
76
. await
75
77
. map_err ( |_| ( StatusCode :: NOT_FOUND , "module not found" . to_string ( ) ) ) ?;
76
78
77
- let json = self
79
+ let ( tx_offset , durable_offset , json) = self
78
80
. host_controller
79
81
. using_database (
80
82
database,
@@ -115,17 +117,28 @@ impl Host {
115
117
. map ( |( col_name, col_type) | ProductTypeElement :: new ( col_type, Some ( col_name) ) )
116
118
. collect ( ) ;
117
119
118
- Ok ( vec ! [ SqlStmtResult {
119
- schema,
120
- rows: result. rows,
121
- total_duration_micros: total_duration. as_micros( ) as u64 ,
122
- stats: SqlStmtStats :: from_metrics( & result. metrics) ,
123
- } ] )
120
+ Ok ( (
121
+ result. tx_offset ,
122
+ db. durable_tx_offset ( ) ,
123
+ vec ! [ SqlStmtResult {
124
+ schema,
125
+ rows: result. rows,
126
+ total_duration_micros: total_duration. as_micros( ) as u64 ,
127
+ stats: SqlStmtStats :: from_metrics( & result. metrics) ,
128
+ } ] ,
129
+ ) )
124
130
} ,
125
131
)
126
132
. await
127
133
. map_err ( log_and_500) ??;
128
134
135
+ if confirmed_read {
136
+ if let Some ( mut durable_offset) = durable_offset {
137
+ let tx_offset = tx_offset. await . map_err ( |_| log_and_500 ( "transaction aborted" ) ) ?;
138
+ durable_offset. wait_for ( tx_offset) . await . map_err ( log_and_500) ?;
139
+ }
140
+ }
141
+
129
142
Ok ( json)
130
143
}
131
144
@@ -134,9 +147,10 @@ impl Host {
134
147
database : Database ,
135
148
host_type : HostType ,
136
149
program_bytes : Box < [ u8 ] > ,
150
+ policy : MigrationPolicy ,
137
151
) -> anyhow:: Result < UpdateDatabaseResult > {
138
152
self . host_controller
139
- . update_module_host ( database, host_type, self . replica_id , program_bytes)
153
+ . update_module_host ( database, host_type, self . replica_id , program_bytes, policy )
140
154
. await
141
155
}
142
156
}
@@ -219,8 +233,11 @@ pub trait ControlStateWriteAccess: Send + Sync {
219
233
& self ,
220
234
publisher : & Identity ,
221
235
spec : DatabaseDef ,
236
+ policy : MigrationPolicy ,
222
237
) -> anyhow:: Result < Option < UpdateDatabaseResult > > ;
223
238
239
+ async fn migrate_plan ( & self , spec : DatabaseDef , style : PrettyPrintStyle ) -> anyhow:: Result < MigratePlanResult > ;
240
+
224
241
async fn delete_database ( & self , caller_identity : & Identity , database_identity : & Identity ) -> anyhow:: Result < ( ) > ;
225
242
226
243
// Energy
@@ -309,8 +326,13 @@ impl<T: ControlStateWriteAccess + ?Sized> ControlStateWriteAccess for Arc<T> {
309
326
& self ,
310
327
identity : & Identity ,
311
328
spec : DatabaseDef ,
329
+ policy : MigrationPolicy ,
312
330
) -> anyhow:: Result < Option < UpdateDatabaseResult > > {
313
- ( * * self ) . publish_database ( identity, spec) . await
331
+ ( * * self ) . publish_database ( identity, spec, policy) . await
332
+ }
333
+
334
+ async fn migrate_plan ( & self , spec : DatabaseDef , style : PrettyPrintStyle ) -> anyhow:: Result < MigratePlanResult > {
335
+ ( * * self ) . migrate_plan ( spec, style) . await
314
336
}
315
337
316
338
async fn delete_database ( & self , caller_identity : & Identity , database_identity : & Identity ) -> anyhow:: Result < ( ) > {
0 commit comments