1
- // TODO(factors): Code left for reference; remove after migration to factors
2
- // mod host_component;
3
-
4
- use spin_app:: MetadataKey ;
5
- use spin_core:: wasmtime:: component:: Resource ;
6
- use spin_world:: async_trait;
7
- use spin_world:: v1:: sqlite:: Error as V1SqliteError ;
1
+ use spin_core:: async_trait;
8
2
use spin_world:: v2:: sqlite;
9
- use std:: { collections:: HashSet , sync:: Arc } ;
10
-
11
- pub const DATABASES_KEY : MetadataKey < HashSet < String > > = MetadataKey :: new ( "databases" ) ;
12
-
13
- /// A store of connections for all accessible databases for an application
14
- #[ async_trait]
15
- pub trait ConnectionsStore : Send + Sync {
16
- /// Get a `Connection` for a specific database
17
- async fn get_connection (
18
- & self ,
19
- database : & str ,
20
- ) -> Result < Option < Arc < dyn Connection + ' static > > , sqlite:: Error > ;
21
-
22
- fn has_connection_for ( & self , database : & str ) -> bool ;
23
- }
24
3
25
4
/// A trait abstracting over operations to a SQLite database
26
5
#[ async_trait]
@@ -33,163 +12,3 @@ pub trait Connection: Send + Sync {
33
12
34
13
async fn execute_batch ( & self , statements : & str ) -> anyhow:: Result < ( ) > ;
35
14
}
36
-
37
- /// An implementation of the SQLite host
38
- pub struct SqliteDispatch {
39
- allowed_databases : HashSet < String > ,
40
- connections : table:: Table < Arc < dyn Connection > > ,
41
- connections_store : Arc < dyn ConnectionsStore > ,
42
- }
43
-
44
- impl SqliteDispatch {
45
- pub fn new ( connections_store : Arc < dyn ConnectionsStore > ) -> Self {
46
- Self {
47
- connections : table:: Table :: new ( 256 ) ,
48
- allowed_databases : HashSet :: new ( ) ,
49
- connections_store,
50
- }
51
- }
52
-
53
- /// (Re-)initialize dispatch for a give app
54
- pub fn component_init (
55
- & mut self ,
56
- allowed_databases : HashSet < String > ,
57
- connections_store : Arc < dyn ConnectionsStore > ,
58
- ) {
59
- self . allowed_databases = allowed_databases;
60
- self . connections_store = connections_store;
61
- }
62
-
63
- fn get_connection (
64
- & self ,
65
- connection : Resource < sqlite:: Connection > ,
66
- ) -> Result < & Arc < dyn Connection > , sqlite:: Error > {
67
- self . connections
68
- . get ( connection. rep ( ) )
69
- . ok_or ( sqlite:: Error :: InvalidConnection )
70
- }
71
- }
72
-
73
- #[ async_trait]
74
- impl sqlite:: Host for SqliteDispatch {
75
- fn convert_error ( & mut self , error : sqlite:: Error ) -> anyhow:: Result < sqlite:: Error > {
76
- Ok ( error)
77
- }
78
- }
79
-
80
- #[ async_trait]
81
- impl sqlite:: HostConnection for SqliteDispatch {
82
- async fn open (
83
- & mut self ,
84
- database : String ,
85
- ) -> Result < Resource < sqlite:: Connection > , sqlite:: Error > {
86
- if !self . allowed_databases . contains ( & database) {
87
- return Err ( sqlite:: Error :: AccessDenied ) ;
88
- }
89
- self . connections_store
90
- . get_connection ( & database)
91
- . await
92
- . and_then ( |conn| conn. ok_or ( sqlite:: Error :: NoSuchDatabase ) )
93
- . and_then ( |conn| {
94
- self . connections
95
- . push ( conn)
96
- . map_err ( |( ) | sqlite:: Error :: Io ( "too many connections opened" . to_string ( ) ) )
97
- } )
98
- . map ( Resource :: new_own)
99
- }
100
-
101
- async fn execute (
102
- & mut self ,
103
- connection : Resource < sqlite:: Connection > ,
104
- query : String ,
105
- parameters : Vec < sqlite:: Value > ,
106
- ) -> Result < sqlite:: QueryResult , sqlite:: Error > {
107
- let conn = match self . get_connection ( connection) {
108
- Ok ( c) => c,
109
- Err ( err) => return Err ( err) ,
110
- } ;
111
- conn. query ( & query, parameters) . await
112
- }
113
-
114
- fn drop ( & mut self , connection : Resource < sqlite:: Connection > ) -> anyhow:: Result < ( ) > {
115
- let _ = self . connections . remove ( connection. rep ( ) ) ;
116
- Ok ( ( ) )
117
- }
118
- }
119
-
120
- #[ async_trait]
121
- impl spin_world:: v1:: sqlite:: Host for SqliteDispatch {
122
- async fn open ( & mut self , database : String ) -> Result < u32 , V1SqliteError > {
123
- let result = <Self as sqlite:: HostConnection >:: open ( self , database) . await ;
124
- result. map_err ( to_legacy_error) . map ( |s| s. rep ( ) )
125
- }
126
-
127
- async fn execute (
128
- & mut self ,
129
- connection : u32 ,
130
- query : String ,
131
- parameters : Vec < spin_world:: v1:: sqlite:: Value > ,
132
- ) -> Result < spin_world:: v1:: sqlite:: QueryResult , V1SqliteError > {
133
- let this = Resource :: new_borrow ( connection) ;
134
- let result = <Self as sqlite:: HostConnection >:: execute (
135
- self ,
136
- this,
137
- query,
138
- parameters. into_iter ( ) . map ( from_legacy_value) . collect ( ) ,
139
- )
140
- . await ;
141
- result. map_err ( to_legacy_error) . map ( to_legacy_query_result)
142
- }
143
-
144
- async fn close ( & mut self , connection : u32 ) -> anyhow:: Result < ( ) > {
145
- <Self as sqlite:: HostConnection >:: drop ( self , Resource :: new_own ( connection) )
146
- }
147
-
148
- fn convert_error ( & mut self , error : V1SqliteError ) -> anyhow:: Result < V1SqliteError > {
149
- Ok ( error)
150
- }
151
- }
152
- use spin_world:: v1:: sqlite as v1;
153
-
154
- fn to_legacy_error ( error : sqlite:: Error ) -> v1:: Error {
155
- match error {
156
- sqlite:: Error :: NoSuchDatabase => v1:: Error :: NoSuchDatabase ,
157
- sqlite:: Error :: AccessDenied => v1:: Error :: AccessDenied ,
158
- sqlite:: Error :: InvalidConnection => v1:: Error :: InvalidConnection ,
159
- sqlite:: Error :: DatabaseFull => v1:: Error :: DatabaseFull ,
160
- sqlite:: Error :: Io ( s) => v1:: Error :: Io ( s) ,
161
- }
162
- }
163
-
164
- fn to_legacy_query_result ( result : sqlite:: QueryResult ) -> v1:: QueryResult {
165
- v1:: QueryResult {
166
- columns : result. columns ,
167
- rows : result. rows . into_iter ( ) . map ( to_legacy_row_result) . collect ( ) ,
168
- }
169
- }
170
-
171
- fn to_legacy_row_result ( result : sqlite:: RowResult ) -> v1:: RowResult {
172
- v1:: RowResult {
173
- values : result. values . into_iter ( ) . map ( to_legacy_value) . collect ( ) ,
174
- }
175
- }
176
-
177
- fn to_legacy_value ( value : sqlite:: Value ) -> v1:: Value {
178
- match value {
179
- sqlite:: Value :: Integer ( i) => v1:: Value :: Integer ( i) ,
180
- sqlite:: Value :: Real ( r) => v1:: Value :: Real ( r) ,
181
- sqlite:: Value :: Text ( t) => v1:: Value :: Text ( t) ,
182
- sqlite:: Value :: Blob ( b) => v1:: Value :: Blob ( b) ,
183
- sqlite:: Value :: Null => v1:: Value :: Null ,
184
- }
185
- }
186
-
187
- fn from_legacy_value ( value : v1:: Value ) -> sqlite:: Value {
188
- match value {
189
- v1:: Value :: Integer ( i) => sqlite:: Value :: Integer ( i) ,
190
- v1:: Value :: Real ( r) => sqlite:: Value :: Real ( r) ,
191
- v1:: Value :: Text ( t) => sqlite:: Value :: Text ( t) ,
192
- v1:: Value :: Blob ( b) => sqlite:: Value :: Blob ( b) ,
193
- v1:: Value :: Null => sqlite:: Value :: Null ,
194
- }
195
- }
0 commit comments