1
1
use anyhow:: Context as _;
2
+ use spin_core:: async_trait;
2
3
use spin_factor_sqlite:: SqliteFactor ;
3
4
use spin_factors:: RuntimeFactors ;
4
5
use spin_factors_executor:: ExecutorHooks ;
@@ -21,68 +22,65 @@ impl SqlStatementExecutorHook {
21
22
pub fn new ( sql_statements : Vec < String > ) -> Self {
22
23
Self { sql_statements }
23
24
}
24
- }
25
25
26
- impl < F : RuntimeFactors , U > ExecutorHooks < F , U > for SqlStatementExecutorHook {
27
- fn configure_app (
28
- & mut self ,
29
- configured_app : & spin_factors:: ConfiguredApp < F > ,
30
- ) -> anyhow:: Result < ( ) > {
26
+ /// Executes the sql statements.
27
+ pub async fn execute ( & self , sqlite : & spin_factor_sqlite:: AppState ) -> anyhow:: Result < ( ) > {
31
28
if self . sql_statements . is_empty ( ) {
32
29
return Ok ( ( ) ) ;
33
30
}
34
- let Some ( sqlite) = configured_app. app_state :: < SqliteFactor > ( ) . ok ( ) else {
35
- return Ok ( ( ) ) ;
36
- } ;
37
- if let Ok ( current) = tokio:: runtime:: Handle :: try_current ( ) {
38
- let _ = current. spawn ( execute ( sqlite. clone ( ) , self . sql_statements . clone ( ) ) ) ;
39
- }
40
- Ok ( ( ) )
41
- }
42
- }
43
-
44
- /// Executes the sql statements.
45
- pub async fn execute (
46
- sqlite : spin_factor_sqlite:: AppState ,
47
- sql_statements : Vec < String > ,
48
- ) -> anyhow:: Result < ( ) > {
49
- let get_database = |label| {
50
- let sqlite = & sqlite;
51
- async move {
31
+ let get_database = |label| async move {
52
32
sqlite
53
33
. get_connection ( label)
54
34
. await
55
35
. transpose ( )
56
36
. with_context ( || format ! ( "failed connect to database with label '{label}'" ) )
57
- }
58
- } ;
37
+ } ;
59
38
60
- for statement in & sql_statements {
61
- if let Some ( config) = statement. strip_prefix ( '@' ) {
62
- let ( file, label) = parse_file_and_label ( config) ?;
63
- let database = get_database ( label) . await ?. with_context ( || {
39
+ for statement in & self . sql_statements {
40
+ if let Some ( config) = statement. strip_prefix ( '@' ) {
41
+ let ( file, label) = parse_file_and_label ( config) ?;
42
+ let database = get_database ( label) . await ?. with_context ( || {
64
43
format ! (
65
44
"based on the '@{config}' a registered database named '{label}' was expected but not found."
66
45
)
67
46
} ) ?;
68
- let sql = std:: fs:: read_to_string ( file) . with_context ( || {
69
- format ! ( "could not read file '{file}' containing sql statements" )
70
- } ) ?;
71
- database. execute_batch ( & sql) . await . with_context ( || {
72
- format ! ( "failed to execute sql against database '{label}' from file '{file}'" )
73
- } ) ?;
74
- } else {
75
- let Some ( default) = get_database ( DEFAULT_SQLITE_LABEL ) . await ? else {
76
- debug_assert ! ( false , "the '{DEFAULT_SQLITE_LABEL}' sqlite database should always be available but for some reason was not" ) ;
77
- return Ok ( ( ) ) ;
78
- } ;
79
- default
47
+ let sql = std:: fs:: read_to_string ( file) . with_context ( || {
48
+ format ! ( "could not read file '{file}' containing sql statements" )
49
+ } ) ?;
50
+ database. execute_batch ( & sql) . await . with_context ( || {
51
+ format ! ( "failed to execute sql against database '{label}' from file '{file}'" )
52
+ } ) ?;
53
+ } else {
54
+ let Some ( default) = get_database ( DEFAULT_SQLITE_LABEL ) . await ? else {
55
+ debug_assert ! ( false , "the '{DEFAULT_SQLITE_LABEL}' sqlite database should always be available but for some reason was not" ) ;
56
+ return Ok ( ( ) ) ;
57
+ } ;
58
+ default
80
59
. query ( statement, Vec :: new ( ) )
81
60
. await
82
61
. with_context ( || format ! ( "failed to execute following sql statement against default database: '{statement}'" ) ) ?;
62
+ }
83
63
}
64
+ Ok ( ( ) )
65
+ }
66
+ }
67
+
68
+ #[ async_trait]
69
+ impl < F , U > ExecutorHooks < F , U > for SqlStatementExecutorHook
70
+ where
71
+ F : RuntimeFactors ,
72
+ F :: AppState : Sync ,
73
+ {
74
+ async fn configure_app (
75
+ & mut self ,
76
+ configured_app : & spin_factors:: ConfiguredApp < F > ,
77
+ ) -> anyhow:: Result < ( ) > {
78
+ let Some ( sqlite) = configured_app. app_state :: < SqliteFactor > ( ) . ok ( ) else {
79
+ return Ok ( ( ) ) ;
80
+ } ;
81
+ self . execute ( & sqlite) . await ?;
82
+ Ok ( ( ) )
84
83
}
85
- Ok ( ( ) )
86
84
}
87
85
88
86
/// Parses a @{file:label} sqlite statement
0 commit comments