(
executor: E,
query: &str,
bindings: Vec<Value<'_>>,
)
| 101 | } |
| 102 | |
| 103 | fn execute_query<'a, E>( |
| 104 | executor: E, |
| 105 | query: &str, |
| 106 | bindings: Vec<Value<'_>>, |
| 107 | ) -> Result<Vec<sqlx::sqlite::SqliteRow>, VmError> |
| 108 | where |
| 109 | E: sqlx::Executor<'a, Database = sqlx::Sqlite>, |
| 110 | { |
| 111 | Handle::current() |
| 112 | .block_on(async { |
| 113 | let mut query_builder = sqlx::query(query); |
| 114 | |
| 115 | // Bind parameters |
| 116 | for value in bindings { |
| 117 | match value { |
| 118 | Value::Number(n) => { |
| 119 | query_builder = query_builder.bind(n); |
| 120 | } |
| 121 | Value::String(s) => { |
| 122 | query_builder = query_builder.bind(s.to_str().unwrap()); |
| 123 | } |
| 124 | Value::Boolean(b) => { |
| 125 | query_builder = query_builder.bind(b); |
| 126 | } |
| 127 | Value::Nil => { |
| 128 | query_builder = query_builder.bind(Option::<String>::None); |
| 129 | } |
| 130 | Value::List(list) => { |
| 131 | let vec = &list.borrow().data; |
| 132 | // SQLite doesn't have native array types, so convert to string representation |
| 133 | let json = serde_json::to_string( |
| 134 | &vec.iter().map(Value::to_serde_value).collect::<Vec<_>>(), |
| 135 | ) |
| 136 | .map_err(|e| sqlx::Error::Protocol(e.to_string()))?; |
| 137 | query_builder = query_builder.bind(json); |
| 138 | } |
| 139 | _ => return Err(sqlx::Error::Protocol("Unsupported parameter type".into())), |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | query_builder.fetch_all(executor).await |
| 144 | }) |
| 145 | .map_err(|e| VmError::RuntimeError(format!("Database query error: {}", e))) |
| 146 | } |
| 147 | |
| 148 | fn execute_typed_query<'gc, 'a, E>( |
| 149 | ctx: Context<'gc>, |
no test coverage detected