| 1285 | |
| 1286 | #[pymethod] |
| 1287 | fn create_collation( |
| 1288 | &self, |
| 1289 | name: PyUtf8StrRef, |
| 1290 | callable: PyObjectRef, |
| 1291 | vm: &VirtualMachine, |
| 1292 | ) -> PyResult<()> { |
| 1293 | let name = name.to_cstring(vm)?; |
| 1294 | let db = self.db_lock(vm)?; |
| 1295 | let Some(data) = CallbackData::new(callable.clone(), vm) else { |
| 1296 | unsafe { |
| 1297 | sqlite3_create_collation_v2( |
| 1298 | db.db, |
| 1299 | name.as_ptr(), |
| 1300 | SQLITE_UTF8, |
| 1301 | null_mut(), |
| 1302 | None, |
| 1303 | None, |
| 1304 | ); |
| 1305 | } |
| 1306 | return Ok(()); |
| 1307 | }; |
| 1308 | let data = Box::into_raw(Box::new(data)); |
| 1309 | |
| 1310 | if !callable.is_callable() { |
| 1311 | return Err(vm.new_type_error("parameter must be callable")); |
| 1312 | } |
| 1313 | |
| 1314 | let ret = unsafe { |
| 1315 | sqlite3_create_collation_v2( |
| 1316 | db.db, |
| 1317 | name.as_ptr(), |
| 1318 | SQLITE_UTF8, |
| 1319 | data.cast(), |
| 1320 | Some(CallbackData::collation_callback), |
| 1321 | Some(CallbackData::destructor), |
| 1322 | ) |
| 1323 | }; |
| 1324 | |
| 1325 | db.check(ret, vm).inspect_err(|_| { |
| 1326 | // create_collation do not call destructor if error occur |
| 1327 | let _ = unsafe { Box::from_raw(data) }; |
| 1328 | }) |
| 1329 | } |
| 1330 | |
| 1331 | #[pymethod] |
| 1332 | fn create_window_function( |