File : oci-thick-string_var.adb


with OCI.Lib,OCI.Thread,OCI.Thick.Parameter_Pkg;
--with text_io;use text_io;
package body OCI.Thick.string_var is  
use lib,Parameter_Pkg;

  procedure Set_Length(Var : in out VString; Length : Natural) is
     Value : aliased OCIString := Get_Value_Internal(Var);
     rc : sword; 
  begin
     rc := OCIStringResize(
         env => thread.Environment,
         err => thread.Error,
         new_size => ub4(Length),
         str => Value'Access); 
     Check_Error(rc);
     Set_Value(Var,Value);
  end Set_Length;   

  procedure Initialize(Object : in out VString) is
  begin
     Initialize(Variable(Object));
     Set_Value(Object,OCIString(Empty_Handle));
  end;

  procedure Finalize  (Object : in out VString) is
  begin
     if Get_Value_Internal(Object)/=OCIString(Empty_Handle) then
       Set_Length(Object,0);
     end if; 
     Finalize(Variable(Object));
  end Finalize;

  function Allocated_Size(Value : in VString) return Natural is
     alsize : aliased ub4;
     rc : sword := OCIStringAllocSize(
                              env => Thread.Environment,
                              vs => Get_Value(Value),
                              allocsize => alsize'Access); 
                               
  begin
     Check_Error(rc);
     return Natural(alsize);
  end Allocated_Size;
  
  procedure Correct_Size(Stmt : Statement; Value : in out VString; Position : Positive) is
    Param : Parameter := Column(Stmt,Position);
    NSize : Natural;
    TCode : Typecode;
  begin
     tcode := Type_Code(Param);
     if TCode=TYPE_VARCHAR2
     or TCode=TYPE_CHAR
     or TCode=TYPE_VARCHAR then
       NSize := Data_Size(Param);
     else
       NSize := 128;  -- ot fanaria
     end if;  
     if Get_Value(Value)=OCIString(Empty_Handle) 
     or else Allocated_Size(Value)<nsize then 
       Set_Length(Value,NSize);
     end if;
  end Correct_Size;     

  
  procedure Define(Stmt : Statement; Value : in out VString; Position : Positive) is
  begin
     Define(Stmt,OCIString_Var.Variable(Value),Position);
     if Executed(Stmt) then
       Correct_Size(Stmt,Value,Position);
     end if;
  end Define;
  
  procedure Set_Value(Var : in out VString; Value : String) is
    str : aliased OCIString := Get_Value_Internal(Var);
    rc : sword := OCIStringAssignText (
         env => thread.Environment,
         err => thread.Error,
         rhs => C.To_C(Value), 
         rhs_len => Value'Length,
         lhs => str'Access);
  begin
    Check_Error(rc);
    Set_Value(Var,str); 
  end;
  
  function Get_Value(Var : VString) return String is
    Env : OCIEnv := Thread.Environment;
    Str : OCIString := Get_Value(Var);
  begin
     return C.To_Ada(CSTR.Value(
            OCIStringPtr(Env,Str), 
            C.Size_t(OCIStringSize(Env,Str))),
            False);
  end;

end OCI.Thick.string_var;