You are not logged in.
some help?
AB,
I have a application client/server. On the client side, I send the data to be updated on the server. On the server side, get the information and update the database.
My question is how I can get the update error to send to the customer?
Server:
function TServiceRemoteSQL.fn_UpdateRecord(AData: RawUTF8): RawUTF8;
var
v_sqlrc: TSQLRecord;
begin
....
v_sqlrc := TSQLRecordClass(MyClass).CreateAndFillPrepare(AData);
frmDMServer.fProps.ThreadSafeConnection.StartTransaction;
while v_sqlrc.FillOne do
begin
if not frmDMServer.aServerDB.Update(v_sqlrc) then
begin
Result := 'Not Update';
v_sqlrc.Free;
frmDMServer.fProps.ThreadSafeConnection.Rollback;
Exit;
end;
end;
....
end;
Thanks for the feedback.
so I used and it worked:
Interface:
ILongWorkCallback = interface(IInvokable)
['{C443AF11-E137-43D3-AB75-1CEC17FE30B2}']
procedure WorkFinished(const worktype : Integer;
timeTaken: integer;
const AResult: RawByteString);
Server:
AStream: TRawByteStringStream
frxPDFExport.Stream := AStream;
frxPDFExport.ShowDialog := False;
frxReport.PrepareReport(True);
frxReport.Export(AfrxPDFExport);
AStream.seek(0,soBeginning);
fCallback.WorkFinished(fWorktype,GetTickCount64 - ftix,AStream.DataString);
Client:
v_Stream : TMemoryStream;
v_Stream := TMemoryStream.Create;
WriteStringToStream(v_Stream,AResult);
v_Stream.Position := 0;
v_Stream.SaveToFile(v_filename);
v_Stream.Free;
Hi,
I am generating a report on the server side with FastReport. How do I send the generated report to the client through the following function:
ILongWorkCallback = interface(IInvokable)
['{C443AF11-E137-43D3-AB75-1CEC17FE30B2}']
procedure WorkFinished(const worktype : Integer;
timeTaken: integer;
const AResult: ??????);
Array81, good afternoon.
I'm trying to extamente this. Can you give me a hint how you are doing.
Thanks.
Ab,
I'm not getting it.
Please help me give way as I do. I need a routine that, from time to time, check if there are updates on records that users are accessing
Thanks
My application is client / server.
On the side of the client I use TClientDataSet.
I'm trying to do a routine check for updates to the database.
so do:
procedure TForm1.Timer1Timer(Sender: TObject);
var
v: TSQLTableJSON;
v1: boolean;
v2: Rawutf8;
begin
v1: = True;
v2: = DataSetToJSON (MyClientDataSet);
v: = TSQLTableJSON.Create ('',pointer (v2), length (v2));
if frmDM.fRestClient.UpdateFromServer ([v], v1) then
// change records;
end;
Always informs that there was no update, even if another client update a record.
What am I doing wrong?
Thanks for your return.
But what happens is that my file has 42GB. When calling the "v_synfile := TSynMemoryStreamMapped.Create(OpenDialog1.FileName);", gives error.
In the function "function TMemoryMap.Map(aFile: THandle; aCustomSize: cardinal; aCustomOffset: Int64): boolean;" has
if (fFileSize <= 0) or (fFileSize> maxint) then
/// Maxint = $ 7FFFFFFF = 1,999 GB (2GB would induce errors PtrInt)
Hello ab.
I need to develop a routine to read huge files (47GB).
This routine must process line by line.
I made using ReadLn. But it was very slow and moreover can not read special characters on the line
So I am trying to make such a routine:
const
BUFF_SIZE = $8000;
var
datafile : array [0..BUFF_SIZE-1] of ansichar;
myEOF : Boolean;
v_string,
v_result : string;
hFile : THandle;
dwread :LongWord;
I : Integer;
if OpenDialog1.Execute then
begin
hFile := CreateFile(PChar(OpenDialog1.FileName),
GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
0);
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
while (dwread > 0) and (not myEOF) do
begin
Readfile(hFile, datafile, BUFF_SIZE, dwread, nil);
if dwread <> BUFF_SIZE then
myEOF := true;
v_string := datafile;
SetLength(v_result,length(v_string));
asm
MOV EDI,v_string
MOV EAX,13
MOV ECX,dwread
CLD
@again:
REPNE SCASB
OR ECX,ECX
JZ @done
INC I
JMP @again
@done:
end;}
end;
end;
end;
closehandle(hFile);
This code is working well and is fast. It is counting the number of lines that the file has.
Now I need a help to change the routine in assembler. The idea is to separate the rows to be
processsas individually. Like that:
asm
MOV EDI,v_result
MOV ESI,v_string
MOV EAX,13
MOV ECX,dwread
CLD
@again:
MOV AL, [ESI]
INC ESI
CMP AL,13
JL @process
OR ECX,ECX
JZ @done
MOV [EDI],AL
INC EDI
JMP @again
@process:
......
JMP @again
@done:
end;
This code is not working.
Can you help me?
ab, good morning.
Wonder. I managed to save. I did so and it worked:
v_sqlrc := TSQLMyRecord.Create;
for v_count := 0 to v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldCount - 1 do
begin
if v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].DataType <> TFieldType.ftBlob then
begin
v_value := v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].AsString;
v_sqlrc.SetFieldValue(v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].FullName,
PUTF8Char(v_value));
end;
end;
v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldByName('ID').Value := frmDM.fRestClient.Add(v_sqlrc,True,False);
for v_count := 0 to v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldCount - 1 do
begin
if v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].DataType = TFieldType.ftBlob then
begin
v_ms := TMemoryStream.Create;
TGraphicField(v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count]).SaveToStream(v_ms);
v_ms.Position := 0;
frmDM.fRestClient.UpdateBlob(v_sqlrc.RecordClass,
v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldByName('ID').AsInteger,
S2U(v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].FullName),
v_ms);
v_ms.free;
end;
Now I have another problem. To consult, do this:
v_ressql := AProps.ExecuteInlined('SELECT * FROM MYTABLE',True);
v_table := v_ressql.FetchAllAsJSON(False);
JSONToClientDataSet(v_CadastroCDS[v_count],v_table,nil,cdsReplace);
In variable v_table, the blob is Base64. But when running JSONToClientDataSet, he is transforming the blob field to RawUTF8, giving error.
v_table variable:
'{"fieldCount":9,"values":["ID","IDPRODUCT","PRODUCT_PHOTO","INC_DATE","MOD_DATE","INC_USER","INC_NAME","MOD_USER","MOD_NAME",5,1,"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'...
ab, I am using the following code to update my data:
v_sqlrc := TSQLMyRecord.Create;
for v_count := 0 to v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldCount - 1 do
begin
v_value := v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].AsString;
v_sqlrc.SetFieldValue(v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].Fields[v_count].FullName,
PUTF8Char(v_value));
end;
v_CadastroCDS[tbc_Cadastro.ActiveTab.Index].FieldByName('ID').Value := frmDM.fRestClient.Add(v_sqlrc,True,False);
But I have a blob field (picture). How do I save this field correctly?
ab, I have two tables in my database. Country and states. A country can have multiple states.
I have the following TSQLRecord:
TSQLCPU_COUNTRY = class(TSQLRecord)
private
fIDCOUNTRY : Integer;
fNAME : RawUTF8;
published
property IDCOUNTRY : Integer read fIDCOUNTRY write fIDCOUNTRY;
property NAME : RawUTF8 read fNAME write fNAME;
end;
TSQLCPU_STATE = class(TSQLRecord)
private
fIDCOUNTRY : TSQLCPU_COUNTRY;
//fIDCOUNTRY : Integer;
fIDUF : RawUTF8;
fNAME : RawUTF8;
fCODUF : Integer;
published
property IDCOUNTRY : TSQLCPU_COUNTRY read fIDCOUNTRY write fIDCOUNTRY;
property IDUF : RawUTF8 read fIDUF write fIDUF;
property NAME : RawUTF8 read fNAME write fNAME;
property CODUF : Integer read fCODUF write fCODUF;
end;
I used CreateAndFillPrepareJoined:
v_cpucountry := TSQLCPU_STATE.CreateAndFillPrepareJoined(frmDM.fRestClient,'',[],[]);
dsCountry.DataSet := TSynSQLTableDataSet.Create(Self,v_cpucountry.FillTable);
It's working. All information is in a single dataset.
How can I have two dataset's? In my form first I present only the countries. Then each selected country, shows the states.
It I downloaded and worked.
Thank you very much.
This is the JSON content:
'{"fieldCount":13,"values":["ID","IDUSER","USER_CODEXT","NAME","IDGROUP","EMAIL","INC_DATE","MOD_DATE","INC_USER","MOD_USER","INC_NAME","MOD_NAME","IDGROUP_NAME",1,1,"","USER 1",1,"","2015-02-17T09:53:36","2015-04-03T19:36:50",0,0,"SUPER USUÁRIO","SUPER USUÁRIO","USUÁRIOS",2,2,"","USER 2",1,"","2015-02-17T09:53:36","2015-04-03T19:36:50",0,0,"SUPER USUÁRIO","SUPER USUÁRIO","USUÁRIOS",3,3,"","USER 3",1,"3","2015-02-17T09:54:00","2015-05-12T20:56:40",0,0,"SUPER USUÁRIO","SUPER USUÁRIO","USUÁRIOS",4,4,"","USER 4",1,"","2015-02-25T19:36:19","2015-05-12T20:56:40",0,0,"SUPER USUÁRIO","SUPER USUÁRIO","USUÁRIOS"],"rowCount":4}
In clientdataset the INC_DATE and MOD_DATE fields are timestamp.
The introduction of TSQLTable.FieldTypeIntegerDetectionOnAllRows function generated a problem in JSONToClientDataSet command. I already have clientdataset created and this has a Timestamp field. When the JSONToClientDataSet command and executed generates an error with the message "not parse string to timestamp".
Would you help me?
I'll try to explain.
I have to read a csv file.
In the first line of this file I have to get some information and write to a master table. I next lines of this file, I have to write to a detail table. This is why I need the ID of the master table.
But I need a transaction of all, because it fails at some point, have to give RollBak at all.
We clear?
Thanks for the feedback.
I changed my code looked like this:
procedure TLongWorkServiceThread.Execute;
var
v_count,
v_ID : Integer;
v_batchibpt,
v_batchibptdet: TSQLRestBatch;
v_cpuibpt : TSQLCPU_IBPT;
v_cpuibptdet : TSQLCPU_IBPTDET;
v_cputipi : TSQLCPU_TIPI;
begin
inherited;
try
for v_count := 0 to ffile.Count - 1 do
begin
case v_count of
0: ;
1: begin
v_cpuibpt := TSQLCPU_IBPT.Create;
v_batchibpt := TSQLRestBatch.Create(frmDMServer.aServerDB,TSQLCPU_IBPT);
v_cpuibptdet := TSQLCPU_IBPTDET.Create;
v_batchibptdet := TSQLRestBatch.Create(frmDMServer.aServerDB,TSQLCPU_IBPTDET);
v_cpuibpt.IBPTVERSION := fn_getposstring(ffile[v_count],';',12);
v_cpuibpt.IBPT_START := StrToDate(fn_getposstring(ffile[v_count],';',9));
v_cpuibpt.IBPT_FINISH := StrToDate(fn_getposstring(ffile[v_count],';',10));
v_cpuibpt.IBPTSOURCE := fn_getposstring(ffile[v_count],';',13);
v_cpuibpt.IBPTKEY := fn_getposstring(ffile[v_count],';',11);
v_cpuibpt.INC_DATE := now;
v_cpuibpt.INC_USER := fuser;
v_ID := v_batchibpt.Add(v_cpuibpt,True,False);
if v_ID = 0 then
begin
v_batchibpt.Free;
v_batchibptdet.Free;
v_cpuibpt.Free;
v_cpuibptdet.Free;
fCallback.WorkFailed(fWorkType,
frmServAppRM.OLANG.fn_lerini('Mens','cpuMMensNotInsert','cpuMMensNotInsert'));
exit;
end;
end;
else
begin
v_cputipi := TSQLCPU_TIPI.Create(frmDMServer.aServerDB,
'TIPINCM=? AND TIPIEXT=?',
[fn_getposstring(ffile[v_count],';',1),
fn_getposstring(ffile[v_count],';',2)]);
if (v_cputipi.TIPINCM = fn_getposstring(ffile[v_count],';',1)) and
(v_cputipi.TIPIEXT = fn_getposstring(ffile[v_count],';',2)) then
begin
v_cpuibptdet.IDIBPT := v_ID;
v_cpuibptdet.IDTIPI := v_cputipi.ID;
v_cpuibptdet.IBPTALIQ_NATION := StrToFloat(fn_getposstring(ffile[v_count],';',5));
v_cpuibptdet.IBPTALIQ_INTERN := StrToFloat(fn_getposstring(ffile[v_count],';',6));
v_cpuibptdet.IBPTALIQ_STATE := StrToFloat(fn_getposstring(ffile[v_count],';',7));
v_cpuibptdet.IBPTALIQ_CITY := StrToFloat(fn_getposstring(ffile[v_count],';',8));
v_cpuibptdet.INC_DATE := now;
v_cpuibptdet.INC_USER := fuser;
v_cpuibptdet.MOD_USER := fuser;
if v_batchibptdet.Add(v_cpuibptdet,True,False) = 0 then
begin
v_batchibpt.Free;
v_batchibptdet.Free;
v_cpuibpt.Free;
v_cpuibptdet.Free;
fCallback.WorkFailed(fWorkType,
frmServAppRM.OLANG.fn_lerini('Mens','cpuMMensNotInsert','cpuMMensNotInsert'));
exit;
end;
end;
v_cputipi.Free;
end;
end;
end;
frmDMServer.aServerDB.BatchSend(v_batchibpt);
frmDMServer.aServerDB.BatchSend(v_batchibptdet);
v_batchibpt.Free;
v_batchibptdet.Free;
v_cpuibpt.Free;
v_cpuibptdet.Free;
fCallback.WorkFinished(fWorktype,GetTickCount64 - ftix)
except
on E: Exception do
begin
if not (E is EAbort) then
begin
v_batchibpt.Free;
v_batchibptdet.Free;
fCallback.WorkFailed(fWorkType,E.Message);
end;
end;
end;
end;
end;
But it is not working. The add the line "v_ID := v_batchibpt.Add(v_cpuibpt,True,False);" always returns zero.
What could be wrong?
I have a client/server application.
On the server side, I have a thread that inserts records in the database. But I'm not getting the transaction to be respected. When a rollback is performed, the permance record in the database. My code looks like this:
TLongWorkServiceThread = class(TThread)
protected
fCallback: ILongWorkCallback;
fWorkType: Integer;
ffile : TStringList;
fuser : Integer;
ftix : Int64;
fConn : TSQLDBConnection;
procedure Execute; override;
public
constructor Create(const worktype: Integer;
const callback: ILongWorkCallback;
const Afile : TStringList;
const Auser : Integer);
....
{ TLongWorkServiceThread }
constructor TLongWorkServiceThread.Create(const worktype: Integer;
const callback: ILongWorkCallback;
const Afile : TStringList;
const Auser : Integer);
begin
inherited Create(false);
fCallback := Callback;
fWorkType := worktype;
fuser := Auser;
ftix := GetTickCount64;
ffile := TStringList.Create;
ffile.Assign(Afile);
FreeOnTerminate := true;
end;
procedure TLongWorkServiceThread.Execute;
var
v_count,
v_ID : Integer;
v_cpuibpt : TSQLCPU_IBPT;
v_cpuibptdet: TSQLCPU_IBPTDET;
v_cputipi : TSQLCPU_TIPI;
begin
inherited;
case fWorkType of
0: //Processar arquivo IBPT
begin
try
fConn := frmDMServer.fProps.NewConnection;
fConn.Connect;
fConn.StartTransaction;
for v_count := 0 to ffile.Count - 1 do
begin
case v_count of
0: ;
1: begin
v_cpuibpt := TSQLCPU_IBPT.Create;
v_cpuibptdet := TSQLCPU_IBPTDET.Create;
v_cpuibpt.IBPTVERSION := fn_getposstring(ffile[v_count],';',12);
v_cpuibpt.IBPT_START := StrToDate(fn_getposstring(ffile[v_count],';',9));
v_cpuibpt.IBPT_FINISH := StrToDate(fn_getposstring(ffile[v_count],';',10));
v_cpuibpt.IBPTSOURCE := fn_getposstring(ffile[v_count],';',13);
v_cpuibpt.IBPTKEY := fn_getposstring(ffile[v_count],';',11);
v_cpuibpt.INC_DATE := now;
v_cpuibpt.INC_USER := fuser;
v_ID := frmDMServer.aServerDB.Add(v_cpuibpt,True,False);
......
if (condiction) then
begin
fConn.Rollback;
v_cpuibpt.Free;
v_cpuibptdet.Free;
fCallback.WorkFailed(fWorkType,
frmServAppRM.OLANG.fn_lerini('Mens','cpuMMensNotInsert','cpuMMensNotInsert'));
exit;
end
else
fConn.Commit;
end;
........
What am I doing wrong?
Exemple:
Rows, Rows2: ISQLDBRows;
fJSONBuffer: RawUTF8;
Rows := Props.Execute(SQL,[],nil,True);
fJSONBuffer := Rows.FetchAllAsJSON(false);
Rows.free;
----> How do I to fJSONBuffer to Rows again?
----> like this -> Rows2 := JSONToRows(fJSONBuffer);
Thank you for your assistance.
My last question. As I transform my JSON in a ISQLDBRows?
Thank you by return.
In my case, the data are sent by the server and comes in JSON.
I would like to use the functions ready for ORM. JSON for TSQLTable I have no problems in doing so. Can You give me an example of how I export for SQLite3?
Good night.
I saw that there is a function RowsToSQLite3.
How do I export JSON or ClientDataset for SQLite3?
I can't use the CreateAndFillPrepareJoined. You would have an example?
Thanks.
Do I need to do a search in the database, on the client side.
I am using as well:
frmDM.fRestClient.ExecuteList([TSQLCPU_USER,TSQLCPU_GROUP],
'SELECT CPU_USER.ROWID,CPU_USER.*,' +
'CPU_GROUP.NAME AS GROUP_NAME ' +
'FROM CPU_USER ' +
'INNER JOIN CPU_GROUP ON (CPU_USER.IDGROUP = CPU_GROUP.ROWID) ' +
'WHERE CPU_USER.IDUSER <> 9999 ORDER BY CPU_USER.IDUSER');
This is the best way or is there another way?
I am with this doubt because, in some other questioning, I have read that the ExecutList command should not be used on the client side.
thanks
I am using TSQLRestClientURI with ExecuteList and Tclientdataset. Everything is working well, but I am facing a problem. When I delete a record by command TSQLRestClientURI.Delete , works perfectly when I give the command UpdateFromServer. The record does not appear in my grid. However when I exclude the registry directly from database, the record does not come out of my grid, even giving the command UpdateFromServer.
How do I that records are what really are in the database, regardless of whether form excluded by application or directly in the database?
Thank's for return.
I was avoiding to use the TClientDataSet, but if no other way ...
My application is in Delphi XE6-FireMonkey Metropolis IU.
I am using TSynSQLTableDataSet. I'm TStringGrid with TBindSourceDB and TBindingsList.
The problem is that the scroll does not work. When I use TClientDataSet, instead of TSynSQLTableDataSet, works perfectly.
I need a help at this point. Thank you.
thanks
Another issue.
How do I that are not created index in my tables?
When I connect to my database, the system is creating some index's automatically, for example:
CREATE UNIQUE INDEX DESCENDING "NDXCPU_PROCESSIDPROCESS" ON "CPU_PROCESS Nord IDPROCESS" );
I did so:
Server side:
TDBServerList = class
private
FDBServers : TRawUTF8List;
FPropsList : TRawUTF8List;
public
constructor Create;
destructor Destroy;override;
procedure AddServer(const ASessionID: Cardinal;
const AServerDB: TSQLRestServerDB);
procedure RemoveServer(const ASessionID: Cardinal);
function GetServer(const ASessionID: Cardinal): TSQLRestServerDB;
procedure AddProps(const ASessionID: Cardinal;
const AProps: TSQLDBConnectionProperties);
procedure RemoveProps(const ASessionID: Cardinal);
function GetProps(const ASessionID: Cardinal): TSQLDBConnectionProperties;
end;
{ TDBServerList }
procedure TDBServerList.AddProps(const ASessionID: Cardinal;
const AProps: TSQLDBConnectionProperties);
begin
FPropsList.AddObject(IntToStr(ASessionId), AProps);
end;
procedure TDBServerList.AddServer(const ASessionID: Cardinal;
const AServerDB: TSQLRestServerDB);
begin
FDBServers.AddObject(IntToStr(ASessionId), AServerDB);
end;
constructor TDBServerList.Create;
begin
FDBServers := TRawUTF8List.Create(True);
FPropsList := TRawUTF8List.Create(True);
end;
destructor TDBServerList.Destroy;
var
v_count: Integer;
begin
{for v_count := 0 to FDBServers.Count-1 do
TSQLRestServerDB(FDBServers.Objects[v_count]).Free;}
FDBServers.Free;
{for v_count := 0 to FPropsList.Count-1 do
TSQLDBConnectionProperties(FPropsList.Objects[v_count]).Free;}
FPropsList.Free;
inherited;
end;
function TDBServerList.GetProps(const ASessionID: Cardinal): TSQLDBConnectionProperties;
begin
Result := TSQLDBConnectionProperties(FPropsList.Objects[FPropsList.IndexOf(IntToStr(ASessionId))]);
end;
function TDBServerList.GetServer(const ASessionID: Cardinal): TSQLRestServerDB;
begin
Result := TSQLRestServerDB(FDBServers.Objects[FDBServers.IndexOf(IntToStr(ASessionId))]);
end;
procedure TDBServerList.RemoveProps(const ASessionID: Cardinal);
var
v_pt: PtrInt;
begin
v_pt := FPropsList.IndexOf(IntToStr(ASessionId));
if v_pt >= 0 then
FPropsList.Delete(v_pt);
end;
procedure TDBServerList.RemoveServer(const ASessionID: Cardinal);
var
v_pt: PtrInt;
begin
v_pt := FDBServers.IndexOf(IntToStr(ASessionId));
if v_pt >= 0 then
FDBServers.Delete(v_pt);
end;
function TServiceRemoteSQL.fn_connectdb(const AServer,
AUserName,
APassword,
AServerName,
ADataBase: RawUTF8;
const AEngine: TRemoteSQLEngine;
const ASessionID: Cardinal): RawUTF8;
const // rseOleDB, rseODBC, rseOracle, rseSQlite3, rseJet, rseMSSQL, rseFirebird
TYPES: array[TRemoteSQLEngine] of TSQLDBConnectionPropertiesClass = (
TOleDBConnectionProperties,
TODBCConnectionProperties,
TSQLDBOracleConnectionProperties,
TSQLDBSQLite3ConnectionProperties,
{$ifdef WIN64}nil{$else}TOleDBJetConnectionProperties{$endif},
TOleDBMSSQL2008ConnectionProperties,
TSQLDBFireDACConnectionProperties);
var
fProps : TSQLDBConnectionProperties;
aServerDB : TSQLRestServerDB;
fModel : TSQLModel;
begin
Result := '';
if TYPES[aEngine] = nil then
begin
Result := StringToUTF8(Format(frmServAppRM.OLANG.fn_lerini('Mens',
'cpuMMensEngineNotSup',
'cpuMMensEngineNotSup') +
' ',
[GetEnumName(TypeInfo(TRemoteSQLEngine),
ord(aEngine))^]));
FreeAndNil(fProps);
end
else
begin
// Conectando Firebird
fProps := TYPES[aEngine].Create(aServerName,
aServer +
':' +
ADataBase,
AUserName,
aPassWord);
try
fProps.MainConnection.Connect;
// clonando model
fModel := TSQLModel(frmServAppRM.aModel);
// registrar tabelas do banco
VirtualTableExternalRegister(fModel,
TSQLCPU_COMPANY,
fProps,
'CPU_COMPANY');
fModel.Props[TSQLCPU_COMPANY].ExternalDB.MapField('ID','IDCOMPANY');
VirtualTableExternalRegister(fModel,
TSQLCPU_USER,
fProps,
'CPU_USER');
fModel.Props[TSQLCPU_USER].ExternalDB.MapField('ID','IDUSER');
VirtualTableExternalRegister(fModel,
TSQLCPU_PROCESS,
fProps,
'CPU_PROCESS');
fModel.Props[TSQLCPU_PROCESS].ExternalDB.MapField('ID','IDPROCESS');
VirtualTableExternalRegister(fModel,
TSQLCPU_SYSTEM,
fProps,
'CPU_SYSTEM');
fModel.Props[TSQLCPU_SYSTEM].ExternalDB.MapField('ID','IDSYSTEM');
VirtualTableExternalRegister(fModel,
TSQLCPU_SYSTEMS,
fProps,
'CPU_SYSTEMS');
fModel.Props[TSQLCPU_SYSTEMS].ExternalDB.MapField('ID','IDSYSTEMS');
VirtualTableExternalRegister(fModel,
TSQLCPU_PROGRAM,
fProps,
'CPU_PROGRAM');
fModel.Props[TSQLCPU_PROGRAM].ExternalDB.MapField('ID','IDSYSTEM');
VirtualTableExternalRegister(fModel,
TSQLCPU_FORM,
fProps,
'CPU_FORM');
fModel.Props[TSQLCPU_FORM].ExternalDB.MapField('ID','IDFORM');
VirtualTableExternalRegister(fModel,
TSQLCPU_FORMFILTER,
fProps,
'CPU_FORMFILTER');
fModel.Props[TSQLCPU_FORMFILTER].ExternalDB.MapField('ID','IDFORM').
MapField('IDFILTER','IDFILTER');
VirtualTableExternalRegister(fModel,
TSQLCPU_FORMTABSHEET,
fProps,
'CPU_FORMTABSHEET');
fModel.Props[TSQLCPU_FORMTABSHEET].ExternalDB.MapField('ID','IDFORM').
MapField('IDTABSHEET','IDTABSHEET');
VirtualTableExternalRegister(fModel,
TSQLCPU_FTSSOURCE,
fProps,
'CPU_FTSSOURCE');
fModel.Props[TSQLCPU_FTSSOURCE].ExternalDB.MapField('ID','IDFORM').
MapField('IDTABSHEET','IDTABSHEET');
VirtualTableExternalRegister(fModel,
TSQLCPU_FORMSECCION,
fProps,
'CPU_FORMSECCION');
fModel.Props[TSQLCPU_FORMSECCION].ExternalDB.MapField('ID','IDFORM').
MapField('IDTABSHEET','IDTABSHEET').
MapField('IDSECCION','IDSECCION');
VirtualTableExternalRegister(fModel,
TSQLCPU_FORMSECFIELD,
fProps,
'CPU_FORMSECFIELD');
fModel.Props[TSQLCPU_FORMSECFIELD].ExternalDB.MapField('ID','IDFORM').
MapField('IDTABSHEET','IDTABSHEET').
MapField('IDSECCION','IDSECCION').
MapField('IDFIELD','IDFIELD');
aServerDB := TSQLRestServerDB.Create(fModel, ':memory:',false); // authentication=false
aServerDB.CreateMissingTables;
// iniciar o HTTP server
frmServAppRM.aHTTPServer := TSQLHttpServer.Create(frmDMServer.fSettings.Port,
[aServerDB],
'+',
useHttpApiRegisteringURI);
frmServAppRM. aHTTPServer.AccessControlAllowOrigin := '*'; // for AJAX requests to work
// adicionando a lista
frmDMServer.fDBServerList.AddServer(ASessionID,aServerDB);
frmDMServer.fDBServerList.AddProps(ASessionID,fProps);
//aServerDB.Free;
//fModel.Free;
//fProps.Free;
except
on E: Exception do
begin
FreeAndNil(fProps);
Result := StringToUTF8(Format(frmServAppRM.OLANG.fn_lerini('Mens',
'cpuMMensConerr',
'cpuMMensConerr') +
E.Message,
[#13]));
end;
end;
end;
end;
Works.
Thanks.
I have mapped field:
VirtualTableExternalRegister(aModel,
TSQLCPU_USER,
fProps,
'CPU_USER');
aModel.Props[TSQLCPU_USER].ExternalDB.MapField('ID','IDUSER');
When I try to update a record, shows an error that the IDUSER field does not exist.
v_user := TSQLCPU_USER.Create(frmDMServer.aServerDB,'IDUSER=?',[1]);
v_user.NAME := 'USER 2';
v_user.MOD_DATE := now;
v_user.MOD_USER := 9999;
frmDMServer.aServerDB.Update(v_user);
I need help to solve this
I need a help. I'm converting my ERP to mormot. In my ERP, the user can choose the database to connect. I use a Service Interface.
In Service Interface, I have this code:
type
TRemoteSQLEngine = (rseOleDB, rseODBC, rseOracle, rseSQlite3, rseJet, rseMSSQL, rseFirebird);
TSQLCPU_USER = class(TSQLRecordVirtual)
private
fIDUSER : Double;
fUSER_CODEXT: RawUTF8;
fNAME : RawUTF8;
fIDGROUP : Double;
fEMAIL : RawUTF8;
fINC_DATE : TDateTime;
fMOD_DATE : TDateTime;
fINC_USER : Double;
fMOD_USER : Double;
published
property IDUSER : Double read fIDUSER write fIDUSER;
property USER_CODEXT: RawUTF8 read fUSER_CODEXT write fUSER_CODEXT;
property NAME : RawUTF8 read fNAME write fNAME;
property IDGROUP : Double read fIDGROUP write fIDGROUP;
property EMAIL : RawUTF8 read fEMAIL write fEMAIL;
property INC_DATE : TDateTime read fINC_DATE write fINC_DATE;
property MOD_DATE : TDateTime read fMOD_DATE write fMOD_DATE;
property INC_USER : Double read fINC_USER write fINC_USER;
property MOD_USER : Double read fMOD_USER write fMOD_USER;
end;
IRemoteSQL = interface(IInvokable)
['{7392E8F4-02AE-4054-8DB7-56A8B95B795B}']
// Função para conectar ao banco de dados - Thread
function fn_connectdb(const AServer,
AUserName,
APassword,
AServerName,
ADataBase: RawUTF8;
const AEngine: TRemoteSQLEngine): RawUTF8;
end;
var
fProps : TSQLDBConnectionProperties;
fServerDB : TSQLRestServerDB;
fModel : TSQLModel;
fRestClient : TSQLRestClientURI;
fRestClientDB: TSQLRestClientDB;
fRestServer : TSQLRestServer;
fHTTPServer : TSQLHttpServer;
implementation
function DataModel(v_serverroot:RawUTF8): TSQLModel;
begin
Result := TSQLModel.Create([TSQLCPU_COMPANY,
TSQLCPU_USER,
TSQLCPU_PROCESS,
TSQLCPU_SYSTEM,
TSQLCPU_SYSTEMS,
TSQLCPU_PROGRAM,
TSQLCPU_FORM,
TSQLCPU_FORMFILTER,
TSQLCPU_FORMTABSHEET,
TSQLCPU_FTSSOURCE,
TSQLCPU_FORMSECCION,
TSQLCPU_FORMSECFIELD],
v_serverroot);
end;
In server side, i have this code:
procedure TfrmServAppRM.FormCreate(Sender: TObject);
begin
fService := TServiceRemoteSQL.Create;
fModel := DataModel(frmDMServer.fSettings.RootName);
try
fRestServer := TSQLRestServerFullMemory.Create(fModel,'users.json',false,True);
try
// registrar o servico IRemoteSQL do lado do servidor (metodos ServerInterface)
fRestServer.ServiceRegister(TServiceRemoteSQL,
[TypeInfo(IRemoteSQL)],
sicClientDriven).SetOptions([],
[optExecInMainThread,
optFreeInMainThread]);
//aServer.AuthenticationRegister(TSQLRestServerAuthenticationNone);
fRestServer.OnSessionCreate := fn_notifysessionC;
fRestServer.OnSessionClosed := fn_notifysessionD;
fHTTPServer := TSQLHttpServer.Create(frmDMServer.fSettings.Port,
[fRestServer],
'+',
useHttpApiRegisteringURI);
fHTTPServer.AccessControlAllowOrigin := '*'; // for AJAX requests to work
except
//
end;
except
//
end;
fService.Free;
end;
function TServiceRemoteSQL.fn_connectdb(const AServer,
AUserName,
APassword,
AServerName,
ADataBase: RawUTF8;
const AEngine: TRemoteSQLEngine): RawUTF8;
const // rseOleDB, rseODBC, rseOracle, rseSQlite3, rseJet, rseMSSQL, rseFirebird
TYPES: array[TRemoteSQLEngine] of TSQLDBConnectionPropertiesClass = (
TOleDBConnectionProperties,
TODBCConnectionProperties,
TSQLDBOracleConnectionProperties,
TSQLDBSQLite3ConnectionProperties,
{$ifdef WIN64}nil{$else}TOleDBJetConnectionProperties{$endif},
TOleDBMSSQL2008ConnectionProperties,
TSQLDBFireDACConnectionProperties);
begin
Result := '';
if fProps <> nil then
begin
Result := StringToUTF8(frmServAppRM.OLANG.fn_lerini('Mens',
'cpuMMensExistCon',
'cpuMMensExistCon'));
FreeAndNil(fProps);
end
else
begin
if TYPES[aEngine] = nil then
begin
Result := 'Error';
FreeAndNil(fProps);
end
else
begin
fProps := TYPES[aEngine].Create(aServerName,
aServer +
':' +
ADataBase,
AUserName,
aPassWord);
try
fProps.MainConnection.Connect;
VirtualTableExternalRegister(fModel,
TSQLCPU_USER,
fProps,
'CPU_USER');
fModel.Props[TSQLCPU_USER].ExternalDB.MapField('ID','IDUSER');
fServerDB := TSQLRestServerDB.Create(fModel, ':memory:',false); // authentication=false
fServerDB.CreateMissingTables;
except
on E: Exception do
begin
FreeAndNil(fProps);
Result :='Error';
end;
end;
end;
end;
end;
In client side, I have this code:
procedure TfrmMain.FormShow(Sender: TObject);
begin
fModel := DataModel(frmDM.fsettings.fRootName);
// Criar SQL client e conectar ao servidor
fRestClient := TSQLHttpClientWinHTTP.Create(frmDM.fsettings.fHost,
frmDM.fsettings.fPort,
fModel);
if not fRestClient.ServerTimeStampSynchronize then
begin
MessageDlg(Format(OLANG.fn_lerini('Mens',
'cpuMMensErrorSocket',
'cpuMMensErrorSocket'),
[#13,#13,#13,#13]),
TMsgDlgType.mtError,
[TMsgDlgBtn.mbOK],0);
Close;
exit;
end;
if (not fRestClient.SetUser('User','synopse')) or
(not fRestClient.ServiceRegisterClientDriven(TypeInfo(IRemoteSQL),frmDM.fService)) then
begin
MessageDlg(Format(OLANG.fn_lerini('Mens',
'cpuMMensErrorService',
'cpuMMensErrorService'),
[#13,#13]),
TMsgDlgType.mtError,
[TMsgDlgBtn.mbOK],0);
Close;
exit;
end;
procedure TfrmMain.btnLoginClick(Sender: TObject);
begin
fService.fn_connectdb(frmDM.fsettings.fDBs[cbDB.ItemIndex].fServer,
frmDM.fsettings.fDBs[cbDB.ItemIndex].fUserID,
frmDM.fsettings.fDBs[cbDB.ItemIndex].fPassword,
frmDM.fsettings.fDBs[cbDB.ItemIndex].fServerName,
frmDM.fsettings.fDBs[cbDB.ItemIndex].fDatabaseName,
TRemoteSQLEngine(frmDM.fsettings.fDBs[cbDB.ItemIndex].fEngine));
end;
In service side, when I call this code, work and I access the register from the table:
v_cpuuser:= TSQLCPU_USER.Create(fServerDB,'IDUSER>=?',[1]);
But, in client side, when i call this code, don't work and I can't access the register's from the table:
v_cpuuser:= TSQLCPU_USER.Create(fRestClient,'IDUSER>=?',[1]);
PLEASE, WHAT AM I DOING WRONG OR WHAT IS MISSING IN MY CODE?
thanks.
An information, this file was entered by notepad
Please, how do I do so that the file is in utf-8?
this is the content, part of my JSON file:
{
"fPrograms":
[
{
"fGroup": "CONFIGURAÇÃO",
"fIDProgram": 1,
"fName": "Program",
"fDescription": "Programas"
},
{
"fGroup": "CONFIGURAÇÃO",
"fIDProgram": 3,
"fName": "Form",
"fDescription": "Configurações"
},
]
}
ello
I have a settings file with Portuguese characters (eg: configuração).
How do I function RecordLoadJSON recognize these characters?
Follow my code:
TPrograms = packed record
fPrograms: array of record
FGROUP: RawUTF8;
fIDProgram: integer;
fName: RawUTF8;
fDescription: RawUTF8;
end;
end;
const
__TPrograms = 'FPrograms [FGROUP RawUTF8 fIDProgram integer fName RawUTF8 fDescription RawUTF8]';
TTextWriter.RegisterCustomJSONSerializerFromText (TypeInfo (TPrograms), __TPrograms);
v_FileName: = 'FilePrograms.settings';
v_tmp: = StringFromFile (v_FileName);
RemoveCommentsFromJSON (pointer (v_tmp));
RecordLoadJSON (v_programs, pointer (v_tmp), TypeInfo (TPrograms));
I am making a simple application. I have data in a ClientDataSet. How do I convert my data from ClientDataSet to JSON?
Thanks for the feedback.
I will use the ORM methods. About DB'll continue using RDBMS
I have some crucial questions to convert my DataSnap project in ORM.
Today my application (client-server) already have a database where the application runs. Today use a DataSnap server.
My questions are:
1) To convert to mORMot I use the application accessing this external database with SQL (same as example 16) or should I switch to TSQRecord create and use virtual tables?
2) The database should remain as it is or would be interesting I change a field to store using JSON instead of having individual fields. example:
Today CREATE TABLE "CPU_COMPANY"
("CNPJCPF" VARCHAR (18) NOT NULL,
"NAME" VARCHAR (60) NOT NULL,
"FANTASY VARCHAR (60) NOT NULL,
"INSC_EST VARCHAR (18),
"INSC_MUN VARCHAR (18),
PRIMARY KEY ("CNPJCPF")
);
tomorrow:
CREATE TABLE "CPU_COMPANY"
(
"CNPJCPF" VARCHAR (18) NOT NULL,
"COMPANY_DATA" SUB_TYPE BLOB TEXT SEGMENT SIZE 80 NOT NULL,
PRIMARY KEY ("CNPJCPF")
);
In my application I generate PDF with TPdfDocumentGDI. Must be saved in a BLOB field in my database.
I used like this:
v_pdf: TPdfDocumentGDI;
v_pdfstream: = TMemoryStream.Create;
v_pdf.SaveToStream (v_pdfstream);
v_pdfstream.Position: = 0;
fdQuery.ParamByName ('REQUESTPAGE_PAGES') LoadFromStream (apages, Data.DB.ftBlob).;
How can I do this with mORMot?
I'm trying so, but does not work:
v_pdf: TPdfDocumentGDI;
v_pdfstream: = TMemoryStream.Create;
v_pdf.SaveToStream (v_pdfstream);
v_pdfstream.Position: = 0;
v_prep: Props.NewThreadSafeStatementPrepared = ('INSERT INTO CPU_REQUESTPAGE' +
'(REQUESTPAGE_PAGES)' +
'VALUES (?)'
False);
v_prep.BindBlob (1, pointer (v_pdfstream), v_pdfstream.Size);
v_prep.ExecutePrepared;
Delphi XE5 Version 19.0.13476.4176
I'll do a test by changing the connection to ODBC
In my database, the blob field value is a compress (Zlib.ZCompress) and looks like this:
xÚ•“[nà Eÿ+uw®=<üàsbHD•˜œ¨û_I‰ó¨¢¸qr‘Ð ÝÃŒ˜üèbð¸‰V_BÇmRWŠÓïo€ì*j*IB!ñÖðïó!bV²$m
©í'QQ[e¸µ&B…R:ûE):S¨®¿¿ê'!M¹„olC.àêªk*ˆì2.•@ÿ…»4Æpµégpi„ÒfïžÁ‘‘³Ù[ùž³Ë9\š¢^Äͱ©ÖÊÏ}éÏÖ袩ŸnÒ„û°¾ñåFK{écKu!Õ©ïÇD7ð°qqœW4á8øÔ‡Áºœ~äUˆì¡ò<ƒKMŠ>ÈÔ~À|)16{#Ã!×1怱;W.ãkîiÏ°!G'ðÆ
½Ïeôìøüòl_>Ó ÿŸ#ª4
When I use the process that you showed me, the recovered data looks like this:
'x'#0'•'#6'ýÿ['#0'n'#0'ýÿ '#0#$10#0'E'#0'ýÿ+'#0'u'#0#$F#0'w'#0#1#0'ýÿ='#0'<'#0'ýÿýÿs'#0'b'#0'H'#0'D'#0'ýÿýÿ'#$16#0'ýÿýÿýÿ_'#0'I'#0'ýÿbÛ¸Üq'#0'r'#0'ýÿýÿ '#0'ýÿÌ'#0'ýÿ'#1#0#$18#0'ýÿýÿb'#0'ýÿ'#$17#0'ýÿV'#0'_'#0'B'#0#$12#0'ýÿm'#0'R'#0'W'#0'ýÿýÿ'#$19#0'ýÿo'#0'ýÿýÿ*'#0'j'#0'*'#0'I'#0'B'#0'!'#0'ýÿýÿ'#6#0'ýÿýÿýÿ!'#0'b'#0'V'#0'ýÿ$'#0'm'#0#$A#0'ýÿýÿ'#$19#0''''#0'Q'#0'Q'#0'['#0'e'#0'ýÿ'#$11#0'ýÿ&'#0'B'#0#$1F#0'ýÿýÿ'#$1F#0'R'#0':'#0'ýÿE'#0')'#0':'#0'S'#0'ýÿýÿýÿýÿýÿ'#6#0''''#0'!'#0#$1A#0'M'#0'ýÿýÿo'#0'l'#0'C'#0'.'#0'ýÿýÿk'#0'*'#0'ýÿýÿ2'#0'.'#0'ýÿ@'#0'ýÿýÿ'#$1D#0'ýÿ4'#0'ýÿp'#0'ýÿýÿg'#0'p'#0'i'#0'ýÿýÿf'#0#$E#0'ýÿýÿ'#$15#0'ýÿýÿýÿýÿ['#0'ýÿ'#$14#0'ýÿýÿýÿ9'#0'\'#0'ýÿýÿ^'#0'ýÿq'#3'ýÿ'#2#0#$AD#5'ýÿýÿ}'#0#$C#0'ýÿýÿýÿ©ˆ'#$17#0'ýÿn'#0'„'#4'ýÿýÿýÿýÿýÿF'#0'K'#0'{'#0'ýÿc'#0'K'#0'u'#0'!'#0'i'#5'ýÿýÿ'#5#0'D'#0'7'#0'ýÿ'#$18#0'ýÿq'#0'q'#0#$1A#0'ýÿW'#0'4'#0'ýÿ8'#0'ýÿ'#7#5'ýÿýÿýÿ'#$1C#0'~'#0'ýÿU'#0'ýÿýÿýÿ'#$18#0'<'#0'ýÿK'#0'M'#0'ýÿ>'#0'ýÿýÿ'#$F#0'~'#0'ýÿ'#3#0'|'#0#8#0')'#0'1'#0'6'#0'{'#0#$17#0'#'#0'ýÿ!'#0'ýÿ1'#0'1`'#$E#0';'#0'W'#0'.'#0'ýÿk'#0'ýÿ'#$19#0'i'#0'ð'#3'!'#0'G'#0#1#0#3#0''''#0'ýÿýÿ'#$D#0'ýÿÁ'#3'e'#0'ýÿýÿ'#$7F#0'ýÿ'#$7F#0'ýÿ'#5#0#$1D#0'ýÿl'#0'_'#0'>'#0'ýÿ'#9#0'ýÿ'#5#0'ýÿ#'#0'ýÿ4'#0
and thus can not do the uncompress
Thanks for the feedback.
But it did not work. My Blob field is not string. Is there another way?
About your tip "Props instance and the Rows interface in the same function / method", I'll follow and appreciate.
About your question TSQLDBFireDACConnectionProperties, for this example, I'm using the Firebird database. And from what I saw, it was the only way of connection. If you have other tips, let me know.
Before I used this:
sqlPage: TFDQuery;
myconnection :TFDConnection;
v_ms : TMemoryStream;
sqlPage.Connection := myconnection;
sqlPage.SQL.Add('SELECT BLOBFIELD FROM MYTABLE');
sqlPage.Open;
v_ms := TMemoryStream.Create;
(sqlPage.FieldByName('BLOBFIELD') as TBlobField).SaveToStream(v_ms);
Today i use:
Props: TSQLDBConnectionProperties;
v_SQL : RawUTF8;
Rows : ISQLDBRows;
Props :=TSQLDBFireDACConnectionProperties.Create(Server,Database,UserName,Password);
v_SQL := trim(StringToUTF8('SELECT BLOBFIELD FROM MYTABLE'));
Rows := Props.Execute(v_SQL,[]);
My question: How do I get the field and save to a TMemoryStream, as I did before?
Thank you very much.
Now, one more question. In my webservice (dll) I can use, or has the logs?
If yes, tell me how to do.