@@ -4,7 +4,6 @@ use std::ffi::{CStr, CString};
44use std:: io:: { stderr, Write } ;
55use std:: os:: raw as libc;
66use std:: ptr;
7- use std:: rc:: Rc ;
87
98use sqlite:: SqliteType ;
109use result:: * ;
@@ -14,13 +13,12 @@ use super::sqlite_value::SqliteRow;
1413use util:: NonNull ;
1514
1615pub struct Statement {
17- raw_connection : Rc < RawConnection > ,
1816 inner_statement : NonNull < ffi:: sqlite3_stmt > ,
1917 bind_index : libc:: c_int ,
2018}
2119
2220impl Statement {
23- pub fn prepare ( raw_connection : & Rc < RawConnection > , sql : & str ) -> QueryResult < Self > {
21+ pub fn prepare ( raw_connection : & RawConnection , sql : & str ) -> QueryResult < Self > {
2422 let mut stmt = ptr:: null_mut ( ) ;
2523 let mut unused_portion = ptr:: null ( ) ;
2624 let prepare_result = unsafe {
@@ -33,10 +31,11 @@ impl Statement {
3331 )
3432 } ;
3533
36- ensure_sqlite_ok ( prepare_result, raw_connection) . map ( |_| Statement {
37- raw_connection : Rc :: clone ( raw_connection) ,
38- inner_statement : unsafe { NonNull :: new_unchecked ( stmt) } ,
39- bind_index : 0 ,
34+ ensure_sqlite_ok ( prepare_result, raw_connection. internal_connection . as_ptr ( ) ) . map ( |_| {
35+ Statement {
36+ inner_statement : unsafe { NonNull :: new_unchecked ( stmt) } ,
37+ bind_index : 0 ,
38+ }
4039 } )
4140 }
4241
@@ -111,7 +110,7 @@ impl Statement {
111110 }
112111 } ;
113112
114- ensure_sqlite_ok ( result, & self . raw_connection )
113+ ensure_sqlite_ok ( result, self . raw_connection ( ) )
115114 }
116115
117116 fn num_fields ( & self ) -> usize {
@@ -133,28 +132,32 @@ impl Statement {
133132 match unsafe { ffi:: sqlite3_step ( self . inner_statement . as_ptr ( ) ) } {
134133 ffi:: SQLITE_DONE => Ok ( None ) ,
135134 ffi:: SQLITE_ROW => Ok ( Some ( SqliteRow :: new ( self . inner_statement ) ) ) ,
136- _ => Err ( last_error ( & self . raw_connection ) ) ,
135+ _ => Err ( last_error ( self . raw_connection ( ) ) ) ,
137136 }
138137 }
139138
140139 fn reset ( & mut self ) {
141140 self . bind_index = 0 ;
142141 unsafe { ffi:: sqlite3_reset ( self . inner_statement . as_ptr ( ) ) } ;
143142 }
143+
144+ fn raw_connection ( & self ) -> * mut ffi:: sqlite3 {
145+ unsafe { ffi:: sqlite3_db_handle ( self . inner_statement . as_ptr ( ) ) }
146+ }
144147}
145148
146- fn ensure_sqlite_ok ( code : libc:: c_int , raw_connection : & RawConnection ) -> QueryResult < ( ) > {
149+ fn ensure_sqlite_ok ( code : libc:: c_int , raw_connection : * mut ffi :: sqlite3 ) -> QueryResult < ( ) > {
147150 if code == ffi:: SQLITE_OK {
148151 Ok ( ( ) )
149152 } else {
150153 Err ( last_error ( raw_connection) )
151154 }
152155}
153156
154- fn last_error ( raw_connection : & RawConnection ) -> Error {
155- let error_message = raw_connection . last_error_message ( ) ;
157+ fn last_error ( raw_connection : * mut ffi :: sqlite3 ) -> Error {
158+ let error_message = last_error_message ( raw_connection ) ;
156159 let error_information = Box :: new ( error_message) ;
157- let error_kind = match raw_connection . last_error_code ( ) {
160+ let error_kind = match last_error_code ( raw_connection ) {
158161 ffi:: SQLITE_CONSTRAINT_UNIQUE | ffi:: SQLITE_CONSTRAINT_PRIMARYKEY => {
159162 DatabaseErrorKind :: UniqueViolation
160163 }
@@ -164,12 +167,21 @@ fn last_error(raw_connection: &RawConnection) -> Error {
164167 DatabaseError ( error_kind, error_information)
165168}
166169
170+ fn last_error_message ( conn : * mut ffi:: sqlite3 ) -> String {
171+ let c_str = unsafe { CStr :: from_ptr ( ffi:: sqlite3_errmsg ( conn) ) } ;
172+ c_str. to_string_lossy ( ) . into_owned ( )
173+ }
174+
175+ fn last_error_code ( conn : * mut ffi:: sqlite3 ) -> libc:: c_int {
176+ unsafe { ffi:: sqlite3_extended_errcode ( conn) }
177+ }
178+
167179impl Drop for Statement {
168180 fn drop ( & mut self ) {
169181 use std:: thread:: panicking;
170182
171183 let finalize_result = unsafe { ffi:: sqlite3_finalize ( self . inner_statement . as_ptr ( ) ) } ;
172- if let Err ( e) = ensure_sqlite_ok ( finalize_result, & self . raw_connection ) {
184+ if let Err ( e) = ensure_sqlite_ok ( finalize_result, self . raw_connection ( ) ) {
173185 if panicking ( ) {
174186 write ! (
175187 stderr( ) ,
0 commit comments