From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-0.9 required=3.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.5-pre1 Path: eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: =?UTF-8?Q?Bj=c3=b6rn_Lundin?= Newsgroups: comp.lang.ada Subject: [SOLVED] Re: converting pointer to value Date: Tue, 9 Mar 2021 13:07:46 +0100 Organization: A noiseless patient Spider Message-ID: References: <02709d96-50fe-4e87-bdb5-4f430fa2717an@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Tue, 9 Mar 2021 12:07:47 -0000 (UTC) Injection-Info: reader02.eternal-september.org; posting-host="24da4bf834975907eb3e04a1780c8e84"; logging-data="12405"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18RNH1ivj3AaRddrVFuW1YY" User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:78.0) Gecko/20100101 Thunderbird/78.6.1 Cancel-Lock: sha1:/70bpwyVcMBI/04fKuAIxbHVyyE= In-Reply-To: Content-Language: en-US Xref: reader02.eternal-september.org comp.lang.ada:61501 List-Id: Den 2021-03-04 kl. 18:35, skrev Dmitry A. Kazakov: Dmitry, this > > You need not to know that: > >    declare >       P : SQLPOINTER := ...; >       A : System.Address; >       pragma Import (Ada, A); >       for A'Address use P'Address; >       T : My_Fancy_Object; >       pragma Import (Ada, My_Fancy_Object); >       for T'Address use A; >    begin >       ... -- Use T at P > combined with > This looks wrong because SQLINTEGER is 32-bit. Why do not you use > Package System.Storage_Elements.Integer_Address instead, in order to > place an integer there? put me on the right track. The actual Ada question - rather than ODBC-API question - was how I get the value at a certain address. First - there has to be a pointer to a value - meaning I needed a new overload of SqlBindParameter that takes an integer pointer as argument, not the integer itself (here called value_pointer) declare L : SQLULEN := SQLULEN(Length(Tclob)); Rc : Sqlreturn := 0; Local_Length : Sqllen := Sqllen(Sql_Len_Data_At_Exec(Sqlinteger(L))); Length_Pointer : aliased PTR_SQLLEN := null; Value_Pointer : aliased PTR_SQLINTEGER := null; begin Length_Pointer := new Sqllen'(Local_Length); Value_Pointer := new SQLINTEGER'(1); Rc := Gnu.Db.Sqlcli.Sqlbindparameter (Statementhandle => Statement_Handle, Parameternumber => 1, Inputoutputtype => Sql_Param_Input, Valuetype => Sql_C_Char, Parametertype => Sql_Longvarchar, Columnsize => L, Decimaldigits => 0, Value => Value_Pointer, Bufferlength => 0, Strlen_Or_Indptr => Length_Pointer); Text_Io.Put_Line("bind clob rc" & Rc'Img); end; then I needed to understand that in call to Rc := SqlParamdata (Statement_Handle, pvalue'Access); pvalue itself contains the address of the value_pointer above, and that I can only tie that address to a variable once the value is known. declare Rc : Sqlreturn := Sqlexecute (Statement_Handle); Pvalue : aliased Sqlpointer; Sent : Integer := 0; Datalen : Integer := 0; Buffer_Len : Natural := 0; Chunk_Size : Natural := 1024*10; -- 10 k chunks S_Ptr : Ptr_String; N : Positive := 1; From,To : Positive := 1; begin Text_Io.Put_Line ("Exec: " & Rc'Img); -- get address of value_pointer Rc := Sqlparamdata (Statement_Handle,Pvalue'Access); declare Value : aliased Sqlinteger ; Add : System.Address := Gnu.Db.Sqlcli.To_Address(Pvalue); for Value'Address use Add; begin Text_Io.Put_Line ("SQLParamData1: " & Rc'Img ); --print it and use later on Text_Io.Put_Line ("SQLParamData1.2: '" & Value'Img & "'"); end; So now I can putData to clob - I tried 100Mb, and that is all I need. -- tclob is an unbounded string containg some Mb of text Datalen := Length(Tclob); while Sent < Datalen loop From := N; if Datalen - Sent >= Chunk_Size then To := N+ Chunk_Size -1; else To := N+ Datalen - Sent -1; end if; Buffer_Len := To - From +1; S_Ptr := new String'(Slice(Tclob, From, To)); N := N + Chunk_Size; Rc := Sqlputdata(Statementhandle => Statement_Handle, Data => To_Sqlpointer(S_Ptr), Strlen_Or_Ind => Sqllen(Buffer_Len)); Sent := Sent + S_Ptr.all'Length ; end loop; Rc := Sqlparamdata (Statement_Handle, Pvalue'Access); Text_Io.Put_Line ("SQLParamData2.sist: " & Rc'Img); end; I found some API error on my part. The code above does not use pvalue, but I will need it later on. Thanks for putting me on the right track -- Björn