You are not logged in.
Pages: 1
That´s OK, and yes, it is very specific. Thank you any way, we will explore TJSONObjectDecoder and the Batch process and try to avoid GetSQLValues.
Thank you
Nothing is wrong with current methods.
The legacy system only has read access and only allows inserts by sending the sql text to an intermediate service.
That is why we need to generate the sql text.
We will analyze your recommendation.
Hello AB,
I found the GetSQLValues function very useful for generating the insert statement necessary to add records to an inherited table.
However, when the table has a blob field, the syntax is different than what is needed, limiting its usefulness.
Based on what I found in mORMot.pas:
/// return the UTF-8 encoded SQL source to INSERT the values contained
// in the current published fields of a TSQLRecord child
// - only simple fields name (i.e. not TSQLRawBlob/TSQLRecordMany) are updated:
// BLOB fields are ignored (use direct update via dedicated methods instead)
// - format is '(COL1, COL2) VALUES ('VAL1', 'VAL2')' if some column was ignored
// (BLOB e.g.)
// - format is 'VALUES ('VAL1', 'VAL2')' if all columns values are available
// - is not used by the ORM (do not use prepared statements) - only here
// for conveniency
function GetSQLValues: RawUTF8;
function TSQLRecord.GetSQLValues: RawUTF8;
var i: integer;
V: RawUTF8;
wasString: boolean;
begin
result := '';
if self<>nil then
with RecordProps do
if SimpleFields=nil then
exit else begin
if HasNotSimpleFields then // get 'COL1,COL2': no 'ID,' for INSERT (false below)
result := SQLTableSimpleFieldsNoRowID; // always <> '*'
result := result+' VALUES (';
for i := 0 to length(SimpleFields)-1 do
with SimpleFields[i] do begin
GetValueVar(self,true,V,@wasString);
if wasString then
V := QuotedStr(V);
result := result+V+',';
end;
result[length(result)] := ')';
end;
end;
Since the SQLTableSimpleFieldsNoRowID function returns the list of column names, the result is:
'COL1, COL2 VALUES (' VAL1 ',' VAL2 ')' if some column was ignored
which differs from the definition.
For the correct syntax, as the definition of the GetSQLValues function indicates, it is necessary to enclose this list in parentheses:
if HasNotSimpleFields then // get 'COL1,COL2': no 'ID,' for INSERT (false below)
result := '(' + SQLTableSimpleFieldsNoRowID + ')'; // always <> '*'
So the function GetSQLValues could be used in all cases
Regards.
We had a similar problem, trying to replicate the master over an empty slave first time.
We solved adding a call to this function at the initialization of the slave server:
function TMyRestServer.RecordVersionSynchronizeSlaveIni(Master: TSQLRest;
ChunkRowLimit: integer; OnWrite: TOnBatchWrite): integer;
var
Table: TSQLRecordClass;
RecordVersionIni,Tvers,Tprev: TRecordVersion;
field: TSQLPropInfoRTTIRecordVersion;
tx: integer;
begin
Result := 1;
RecordVersionIni := Self.RecordVersionCurrent();
if RecordVersionIni=0 then
RecordVersionIni := -1;
for tx := 0 to Self.Model.TablesMax do begin
Table := Self.Model.Tables[tx];
field := Table.RecordProps.RecordVersionField;
if field<>nil then begin
Tvers := 0;
Self.fRecordVersionMax := RecordVersionIni;
repeat
Tprev := Tvers;
Tvers := inherited RecordVersionSynchronizeSlave(Table, Master, ChunkRowLimit, OnWrite);
if Tvers<0 then begin
InternalLog('%.RecordVersionSynchronizeSlaveStart(%): REST failure',[self,Table],sllError);
Result := 0;
break;
end;
until Tprev = Tvers;
end;
end;
Self.fRecordVersionMax := 0;
end;
Regards
With pleasure:
procedure TCurlHTTP.InternalSendRequest(const aData: SockString);
begin // see [url]http://curl.haxx.se/libcurl/c/CURLOPT_CUSTOMREQUEST.html[/url]
// libcurl has dedicated options for GET,HEAD verbs
if (fIn.Method='') or (fIn.Method='GET') then begin
curl.easy_setopt(fHandle,coHTTPGet,1);
if (aData<>'') and (fIn.Method='GET') then begin // e.g. GET with body
curl.easy_setopt(fHandle,coCustomRequest,pointer(fIn.Method));
curl.easy_setopt(fHandle,coNoBody,0);
curl.easy_setopt(fHandle,coUpload,1);
fIn.Data := aData;
fIn.DataOffset := 0;
curl.easy_setopt(fHandle,coInFile,pointer(self));
curl.easy_setopt(fHandle,coReadFunction,@CurlReadData);
curl.easy_setopt(fHandle,coInFileSize,length(aData));
end;
end else
if fIn.Method='HEAD' then
curl.easy_setopt(fHandle,coNoBody,1) else begin
// handle other HTTP verbs
curl.easy_setopt(fHandle,coCustomRequest,pointer(fIn.Method));
if aData='' then begin // e.g. DELETE or LOCK
curl.easy_setopt(fHandle,coNoBody,1);
curl.easy_setopt(fHandle,coUpload,0);
end else begin // e.g. POST or PUT
curl.easy_setopt(fHandle,coNoBody,0);
curl.easy_setopt(fHandle,coUpload,1);
fIn.Data := aData;
fIn.DataOffset := 0;
curl.easy_setopt(fHandle,coInFile,pointer(self));
curl.easy_setopt(fHandle,coReadFunction,@CurlReadData);
curl.easy_setopt(fHandle,coInFileSize,length(aData));
end;
InternalAddHeader('Expect:'); // disable 'Expect: 100 Continue'
end;
curl.easy_setopt(fHandle,coWriteFunction,@CurlWriteRawByteString);
curl.easy_setopt(fHandle,coFile,@fOut.Data);
curl.easy_setopt(fHandle,coHeaderFunction,@CurlWriteRawByteString);
curl.easy_setopt(fHandle,coWriteHeader,@fOut.Header);
end;
Regards
We developed an application to manage queues of people needing care at a public hospital, for its various services, using mORMot framework and Delphi 7.
Last week we compiled the project done in Delphi 7 in a virtual machine with Xubuntu, FPC 3.1.1 and Lazarus 1.5. The compilation was successful and we have not encountered problems running the program until now. We had to make a small adjustment in the unit SynCrtSock.pas, class TCurlHTTP, function InternalSendRequest, as the GET method to obtain an array of records needs the parameters in the body and curl does not allow it unless the option coCustomRequest is used.
Congratulations on a great job. Regards
This is my 1st post, congratulations for all this job for you and your team,
and thank you for publishing it. Nice to join you.
I'm studying the framework to apply it in a new development.
Concerning LVCL and GUI I got an error trying to compile mysecnotepad example:
SynCommons.pas(18344) Undeclared Identifier: CheckSynchronize
Apparently missing from LVCL\SysUtis.pas
Regards.
Pages: 1