github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/database/lmdb_ffi.rs (about) 1 /* 2 * Copyright 2018 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ------------------------------------------------------------------------------ 16 */ 17 use cpython::{PyList, PyObject, Python}; 18 use database::lmdb::*; 19 use py_ffi; 20 use std::ffi::CStr; 21 use std::os::raw::{c_char, c_void}; 22 use std::path::Path; 23 24 #[repr(u32)] 25 #[derive(Debug)] 26 pub enum ErrorCode { 27 Success = 0, 28 NullPointerProvided = 0x01, 29 InvalidFilePath = 0x02, 30 InvalidIndexString = 0x03, 31 32 InitializeContextError = 0x11, 33 InitializeDatabaseError = 0x12, 34 } 35 36 #[no_mangle] 37 pub extern "C" fn lmdb_database_new( 38 path: *const c_char, 39 file_size: usize, 40 indexes_ptr: *mut py_ffi::PyObject, 41 db_ptr: *mut *const c_void, 42 ) -> ErrorCode { 43 if path.is_null() { 44 return ErrorCode::NullPointerProvided; 45 } 46 47 let indexes: Vec<String> = unsafe { 48 let py = Python::assume_gil_acquired(); 49 let py_obj = PyObject::from_borrowed_ptr(py, indexes_ptr); 50 let py_list: PyList = py_obj.extract(py).unwrap(); 51 py_list 52 .iter(py) 53 .map(|pyobj| pyobj.extract::<String>(py).unwrap()) 54 .collect() 55 }; 56 57 let db_path = unsafe { 58 match CStr::from_ptr(path).to_str() { 59 Ok(s) => s, 60 Err(_) => return ErrorCode::InvalidFilePath, 61 } 62 }; 63 64 let ctx = match LmdbContext::new(Path::new(&db_path), indexes.len(), Some(file_size)) { 65 Ok(ctx) => ctx, 66 Err(err) => { 67 error!( 68 "Unable to create LMDB context for db at {}: {:?}", 69 db_path, err 70 ); 71 return ErrorCode::InitializeContextError; 72 } 73 }; 74 75 match LmdbDatabase::new(ctx, &indexes) { 76 Ok(db) => { 77 unsafe { 78 *db_ptr = Box::into_raw(Box::new(db)) as *const c_void; 79 } 80 ErrorCode::Success 81 } 82 Err(err) => { 83 error!("Unable to create Database at {}: {:?}", db_path, err); 84 ErrorCode::InitializeDatabaseError 85 } 86 } 87 } 88 89 #[no_mangle] 90 pub extern "C" fn lmdb_database_drop(lmdb_database: *mut c_void) -> ErrorCode { 91 if lmdb_database.is_null() { 92 return ErrorCode::NullPointerProvided; 93 } 94 95 unsafe { Box::from_raw(lmdb_database as *mut LmdbDatabase) }; 96 ErrorCode::Success 97 }