1515
1616use crate :: chkerr;
1717use crate :: connection:: Conn ;
18+ use crate :: sql_type:: vector:: VecFmt ;
1819use crate :: sql_type:: vector:: VecRef ;
1920use crate :: sql_type:: Bfile ;
2021use crate :: sql_type:: Blob ;
@@ -52,6 +53,7 @@ use odpic_sys::*;
5253use std:: borrow:: Cow ;
5354use std:: convert:: TryInto ;
5455use std:: fmt;
56+ use std:: mem:: MaybeUninit ;
5557use std:: os:: raw:: c_char;
5658use std:: ptr;
5759use std:: rc:: Rc ;
@@ -154,6 +156,7 @@ pub struct SqlValue<'a> {
154156 keep_dpiobj : DpiObject ,
155157 pub ( crate ) lob_bind_type : LobBindType ,
156158 pub ( crate ) query_params : QueryParams ,
159+ vector_format : VecFmt ,
157160}
158161
159162impl SqlValue < ' _ > {
@@ -174,6 +177,7 @@ impl SqlValue<'_> {
174177 keep_dpiobj : DpiObject :: null ( ) ,
175178 lob_bind_type,
176179 query_params,
180+ vector_format : VecFmt :: Flexible ,
177181 }
178182 }
179183
@@ -228,6 +232,7 @@ impl SqlValue<'_> {
228232 keep_dpiobj : DpiObject :: null ( ) ,
229233 lob_bind_type : LobBindType :: Locator ,
230234 query_params : QueryParams :: new ( ) ,
235+ vector_format : param. vector_format ,
231236 } )
232237 }
233238
@@ -728,6 +733,20 @@ impl SqlValue<'_> {
728733 unsafe { Ok ( dpiData_getStmt ( self . data ( ) ?) ) }
729734 }
730735
736+ /// # Safety
737+ ///
738+ /// The actual lifetime of VecRef isn't 'static.
739+ /// It is same with that of DpiVar.
740+ unsafe fn get_vec_ref_unchecked ( & self ) -> Result < VecRef < ' static > > {
741+ self . check_not_null ( ) ?;
742+ let mut info = MaybeUninit :: uninit ( ) ;
743+ chkerr ! (
744+ self . ctxt( ) ,
745+ dpiVector_getValue( self . data( ) ?. value. asVector, info. as_mut_ptr( ) )
746+ ) ;
747+ VecRef :: from_dpi ( info. assume_init ( ) )
748+ }
749+
731750 //
732751 // set_TYPE_unchecked methods
733752 //
@@ -923,6 +942,7 @@ impl SqlValue<'_> {
923942 keep_dpiobj : DpiObject :: null ( ) ,
924943 lob_bind_type : self . lob_bind_type ,
925944 query_params : self . query_params . clone ( ) ,
945+ vector_format : self . vector_format ,
926946 } )
927947 } else {
928948 Err ( Error :: internal_error ( "dpVar handle isn't initialized" ) )
@@ -1064,7 +1084,12 @@ impl SqlValue<'_> {
10641084 } ) ,
10651085 NativeType :: Rowid => self . get_rowid_as_string_unchecked ( ) ,
10661086 NativeType :: Stmt => self . invalid_conversion_to_rust_type ( "string" ) ,
1067- NativeType :: Vector => todo ! ( ) ,
1087+ NativeType :: Vector => Ok ( match unsafe { self . get_vec_ref_unchecked ( ) ? } {
1088+ VecRef :: Float32 ( slice) => format ! ( "{:?}" , slice) ,
1089+ VecRef :: Float64 ( slice) => format ! ( "{:?}" , slice) ,
1090+ VecRef :: Int8 ( slice) => format ! ( "{:?}" , slice) ,
1091+ VecRef :: Binary ( slice) => format ! ( "{:?}" , slice) ,
1092+ } ) ,
10681093 }
10691094 }
10701095
@@ -1075,10 +1100,79 @@ impl SqlValue<'_> {
10751100 NativeType :: Blob => self . get_blob_unchecked ( ) ,
10761101 NativeType :: Char => Ok ( parse_str_into_raw ( & self . get_cow_str_unchecked ( ) ?) ?) ,
10771102 NativeType :: Clob => Ok ( parse_str_into_raw ( & self . get_clob_as_string_unchecked ( ) ?) ?) ,
1103+ NativeType :: Vector
1104+ if self . vector_format == VecFmt :: Binary
1105+ || self . vector_format == VecFmt :: Flexible =>
1106+ unsafe {
1107+ let vec_ref = self . get_vec_ref_unchecked ( ) ?;
1108+ match vec_ref {
1109+ VecRef :: Binary ( slice) => Ok ( slice. to_vec ( ) ) ,
1110+ _ => Err ( Error :: invalid_type_conversion (
1111+ vec_ref. oracle_type ( ) . to_string ( ) ,
1112+ "Vec<u8>" ,
1113+ ) ) ,
1114+ }
1115+ } ,
10781116 _ => self . invalid_conversion_to_rust_type ( "raw" ) ,
10791117 }
10801118 }
10811119
1120+ pub ( crate ) fn to_f32_vec ( & self ) -> Result < Vec < f32 > > {
1121+ match self . native_type {
1122+ NativeType :: Vector
1123+ if self . vector_format == VecFmt :: Float32
1124+ || self . vector_format == VecFmt :: Flexible =>
1125+ unsafe {
1126+ let vec_ref = self . get_vec_ref_unchecked ( ) ?;
1127+ match vec_ref {
1128+ VecRef :: Float32 ( slice) => Ok ( slice. to_vec ( ) ) ,
1129+ _ => Err ( Error :: invalid_type_conversion (
1130+ vec_ref. oracle_type ( ) . to_string ( ) ,
1131+ "Vec<f32>" ,
1132+ ) ) ,
1133+ }
1134+ } ,
1135+ _ => self . invalid_conversion_to_rust_type ( "Vec<f32>" ) ,
1136+ }
1137+ }
1138+
1139+ pub ( crate ) fn to_f64_vec ( & self ) -> Result < Vec < f64 > > {
1140+ match self . native_type {
1141+ NativeType :: Vector
1142+ if self . vector_format == VecFmt :: Float64
1143+ || self . vector_format == VecFmt :: Flexible =>
1144+ unsafe {
1145+ let vec_ref = self . get_vec_ref_unchecked ( ) ?;
1146+ match vec_ref {
1147+ VecRef :: Float64 ( slice) => Ok ( slice. to_vec ( ) ) ,
1148+ _ => Err ( Error :: invalid_type_conversion (
1149+ vec_ref. oracle_type ( ) . to_string ( ) ,
1150+ "Vec<f64>" ,
1151+ ) ) ,
1152+ }
1153+ } ,
1154+ _ => self . invalid_conversion_to_rust_type ( "Vec<f64>" ) ,
1155+ }
1156+ }
1157+
1158+ pub ( crate ) fn to_i8_vec ( & self ) -> Result < Vec < i8 > > {
1159+ match self . native_type {
1160+ NativeType :: Vector
1161+ if self . vector_format == VecFmt :: Int8 || self . vector_format == VecFmt :: Flexible =>
1162+ unsafe {
1163+ let vec_ref = self . get_vec_ref_unchecked ( ) ?;
1164+ match vec_ref {
1165+ VecRef :: Int8 ( slice) => Ok ( slice. to_vec ( ) ) ,
1166+ _ => Err ( Error :: invalid_type_conversion (
1167+ vec_ref. oracle_type ( ) . to_string ( ) ,
1168+ "Vec<i8>" ,
1169+ ) ) ,
1170+ }
1171+ } ,
1172+ _ => self . invalid_conversion_to_rust_type ( "Vec<i8>" ) ,
1173+ }
1174+ }
1175+
10821176 /// Gets the SQL value as Timestamp. The Oracle type must be
10831177 /// `DATE`, `TIMESTAMP`, or `TIMESTAMP WITH TIME ZONE`.
10841178 pub ( crate ) fn to_timestamp ( & self ) -> Result < Timestamp > {
@@ -1401,6 +1495,7 @@ impl SqlValue<'_> {
14011495 keep_dpiobj : DpiObject :: null ( ) ,
14021496 lob_bind_type : self . lob_bind_type ,
14031497 query_params : self . query_params . clone ( ) ,
1498+ vector_format : self . vector_format ,
14041499 } )
14051500 }
14061501}
0 commit comments