Repository: diesel-rs/diesel
File: diesel/src/sqlite/connection/stmt.rs (Rust)

Code before:

    pub fn bind(&mut self, tpe: SqliteType, value: Option<Vec<u8>>) -> QueryResult<()> {
        self.bind_index += 1;
        let value = SerializedValue {
            ty: tpe,
            data: value,
        };
        let result = value.bind_to(self.inner_statement, self.bind_index);

        ensure_sqlite_ok(result, self.raw_connection())
    }

    fn num_fields(&self) -> usize {
        unsafe { ffi::sqlite3_column_count(self.inner_statement.as_ptr()) as usize }
    }

    /// The lifetime of the returned CStr is shorter than self.
    ///
    /// > The returned string pointer is valid until either the prepared statement
    /// > is destroyed by sqlite3_finalize() or until the statement is automatically
    /// > reprepared by the first call to sqlite3_step() for a particular
    /// > run or until the next call to sqlite3_column_name()
    /// > or sqlite3_column_name16() on the same column.
    /// 
    /// https://www.sqlite.org/c3ref/column_name.html
    unsafe fn field_name<'a>(&self, idx: usize) -> Option<&'a CStr> {
        let ptr = ffi::sqlite3_column_name(self.inner_statement.as_ptr(), idx as libc::c_int);
        if ptr.is_null() {
            None
        } else {
            Some(CStr::from_ptr(ptr))
        }
    }

    fn step(&mut self) -> QueryResult<Option<SqliteRow>> {
        match unsafe { ffi::sqlite3_step(self.inner_statement.as_ptr()) } {
            ffi::SQLITE_DONE => Ok(None),
            ffi::SQLITE_ROW => Ok(Some(SqliteRow::new(self.inner_statement))),
            _ => Err(last_error(self.raw_connection())),
        }
    }

    fn reset(&mut self) {
        self.bind_index = 0;
        unsafe { ffi::sqlite3_reset(self.inner_statement.as_ptr()) };
    }

    fn raw_connection(&self) -> *mut ffi::sqlite3 {
        unsafe { ffi::sqlite3_db_handle(self.inner_statement.as_ptr()) }
    }
}

Review comment (suggestion):
The doc states that "The lifetime of the returned `CStr` is shorter than self.", but it looks like this signature actually allows *extending* the lifetime.
```rust
fn field_name(&self, idx: usize) -> Option<&CStr>;
```
or (if we want to be more explicit)
```rust
fn field_name<'a, 'b: 'a>(&'a self, idx: usize) -> Option<&'b CStr>;
```
would solve part of the issue.

Code after:

    pub fn bind(&mut self, tpe: SqliteType, value: Option<Vec<u8>>) -> QueryResult<()> {
        self.bind_index += 1;
        let value = SerializedValue {
            ty: tpe,
            data: value,
        };
        let result = value.bind_to(self.inner_statement, self.bind_index);

        ensure_sqlite_ok(result, self.raw_connection())
    }

    fn num_fields(&self) -> usize {
        unsafe { ffi::sqlite3_column_count(self.inner_statement.as_ptr()) as usize }
    }

    /// The lifetime of the returned CStr is shorter than self.
    ///
    /// > The returned string pointer is valid until either the prepared statement
    /// > is destroyed by sqlite3_finalize() or until the statement is automatically
    /// > reprepared by the first call to sqlite3_step() for a particular
    /// > run or until the next call to sqlite3_column_name()
    /// > or sqlite3_column_name16() on the same column.
    ///
    /// https://www.sqlite.org/c3ref/column_name.html
    unsafe fn field_name<'a, 'b: 'a>(&'a self, idx: usize) -> Option<&'b CStr> {
        let ptr = ffi::sqlite3_column_name(self.inner_statement.as_ptr(), idx as libc::c_int);
        if ptr.is_null() {
            None
        } else {
            Some(CStr::from_ptr(ptr))
        }
    }

    fn step(&mut self) -> QueryResult<Option<SqliteRow>> {
        match unsafe { ffi::sqlite3_step(self.inner_statement.as_ptr()) } {
            ffi::SQLITE_DONE => Ok(None),
            ffi::SQLITE_ROW => Ok(Some(SqliteRow::new(self.inner_statement))),
            _ => Err(last_error(self.raw_connection())),
        }
    }

    fn reset(&mut self) {
        self.bind_index = 0;
        unsafe { ffi::sqlite3_reset(self.inner_statement.as_ptr()) };
    }

    fn raw_connection(&self) -> *mut ffi::sqlite3 {
        unsafe { ffi::sqlite3_db_handle(self.inner_statement.as_ptr()) }
    }
}