You are not logged in.
Pages: 1
Basically, I'm using ORM with an external PostgreSQL database.
TOrmBuy = class(TOrm)
private
fcant: integer;
fprice: integer;
fdescrip: RawUtf8;
factive: Boolean;
fexpimp: Boolean;
published
property cant: integer read fcant write fcant;
property price: integer read fprice write fprice;
property descrip: RawUtf8 read fdescrip write fdescrip;
property active: Boolean read factive write factive;
property expimp: Boolean read fexpimp write fexpimp;
end;
myBuy := TOrmBuy.Create;
//This is filled in with the respective data
//Just to give one example (The values are actually filled in another function)
for i := 0 to 300 do
begin
myBuy.cant := 3;
myBuy.active := True;
ServerDB.Add(myBuy, True);
end;
It works perfectly well. But obviously it will take some time.
That's why I decided to use Batch.
myBatch := TRestBatch.Create(ServerDB.Orm,nil);
for i := 0 to 300 do
begin
myBuy.cant := 3;
myBuy.active := True;
myBatch.Add(myBuy,True);
end;
cresu := ServerDB.BatchSend(myBatch);
But there is an exception and it doesn't work:
TSqlDBPostgresLib Error "active" is type boolean but the expression is of type bigint
I understand that SQLite doesn't have a boolean type, but why does it work without Batch?
What do I need to do to make it work?
Thank you for any help you can provide.
@Javierus , Thank you very much for all that number of examples, in addition to all the SAD documentation that you have provided.
I'm using FPC 3.2.3 (fixes) with Windows 11 and wanted to learn about HTTP Basic Authentication.
So I took the "08-basicauth" example, but I ran into the following issues:
It was showing a related error that "RegisterInterfaces" was missing...
I fixed it by adding the following code to the "api.interfaces.pas" file:
initialization
TInterfaceFactory.RegisterInterfaces([TypeInfo(IBasicAuthApi)]);Inside the Log file, an error related to "useHttpApiRegisteringURI" is displayed.
"TRestHttpServer(06222840) Create: HttpSetServiceConfiguration() failed: ERROR_ACCESS_DENIED (5) for root - useHttpApiRegisteringURI may need admin rights"
"EXC ERestHttpServer {Message:"TRestHttpServer: http.sys URI registration error ERROR_ACCESS_DENIED for http://+:8080/root (you need to register the URI - try to use useHttpApiRegisteringURI)"}"
I solved it by changing from "HTTP_DEFAULT_MODE" to "useHttpAsync"
// Create HTTP server
fHttpServer := TRestHttpServer.Create(aPort, [fRestServer],
'+', useHttpAsync, {threaded=}32); It showed several memory leaks when exiting the program.
I solved it by adding a variable "fModel: TOrmModel;" and you don't need to free "fBasicAuthApi"
// Create in-memory REST server (no database needed)
fModel := TOrmModel.Create([]);
fRestServer := TRestServerFullMemory.Create(
fModel, 'root', {authentication=}true);
destructor TBasicAuthServer.Destroy;
begin
Stop;
fHttpServer.Free;
//fBasicAuthApi.Free;
fModel.Free;
fRestServer.Free;
inherited Destroy;
end;The program did not work correctly, with or without authentication it did not show the expected results.
After spending hours understanding how it worked, I found that the problem is with "methodName"
For some reason "Ctxt.UriMethodPath" always returns empty.
And within the code you have to:
methodName := Ctxt.UriMethodPath;
if methodName = '' then
begin
// Fallback to full URI
methodName := Ctxt.Call^.Url;
end;The problem is that it returns the entire Url.
For example, we obtain that:
methodName ="root/BasicAuthApi.PublicSection" , but it was expected that methodName ="PublicSection"
methodName ="root/BasicAuthApi.OnlyRole2" , but it was expected that methodName ="OnlyRole2"
methodName ="root/BasicAuthApi.OnlyRole1Json?par1=hello" , but it was expected that methodName ="OnlyRole1Json"
I solved it by doing the following code (maybe not the best solution, but it works)
methodName := Ctxt.UriMethodPath;
if methodName = '' then
begin
tmpUrl := Ctxt.Call^.Url;
mPosIni := PosI('.',tmpUrl) + 1;
mPosEnd := PosI('?',tmpUrl);
if mPosEnd >0 then
mLen := mPosEnd - mPosIni
else
mLen := length(tmpUrl);
methodName := Copy(tmpUrl,mPosIni,mLen);
end;Please try with
https://github.com/synopse/mORMot2/commit/5e6cc78f3
Thank you for including it.
Currently, the "DynArrayLoadCsv" function only allows csv file content to have a delimiter/separator ','.
IMHO, the function should have the option (not mandatory) to specify the delimiter/separator.
Respectfully, I propose changing the definition to: (It does not affect programs that have already been created.)
function TDynArrayLoadCsv(var Value: TDynArray; Csv: PUtf8Char;
Intern: TRawUtf8Interning = nil; CommaSep: AnsiChar=','): boolean;
function DynArrayLoadCsv(var Value; const Csv: RawUtf8; TypeInfo: PRttiInfo;
Intern: TRawUtf8Interning = nil; CommaSep: AnsiChar=','): boolean;And its respective implementation code: (I've only changed the constant ',' to a variable "CommaSep: AnsiChar")
An example of using a CSV file containing the semicolon ';' delimiter/separator:
if DynArrayLoadCsv(csvItems, csvContent, TypeInfo(TCsvItems), nil, ';') then
begin
end;initialization
// Register RTTI before any CSV parsing
Rtti.RegisterFromText([TypeInfo(TCsvItem), _TCsvItem]);
Thank you so much for your help and explanation, and the example you did with Claude is great.
One small detail I encountered with your example when opening it with FPC is that the executable path is in the "bin" folder, while the "test.csv" file is in the root directory.
And obviously, a message appears indicating that it can't be found.
The generated documentation is excellent: very concise and detailed in your example.
Thank you for taking the time to provide the solution and create an excellent example.
I have a "test.csv" file that only contains:
qty,price
4,50
12,100
I'm a beginner in mORMot2 and I'm trying to use the "DynArrayLoadCsv" function, but it always returns false:
type
TCsvItem = packed record
qty: integer;
price: integer;
end;
TCsvItems = array of TCsvItem;
var
csvItems: TCsvItems;
csvContent: RawUtf8;
csvContent := RawUtf8FromFile('test.csv');
if DynArrayLoadCsv(csvItems, csvContent, TypeInfo(TCsvItems)) then
writeln('DynArrayLoadCsv OK')
else
writeln('DynArrayLoadCsv Failed'); I tried changing the delimiter in the csv file from "," to ";" but it's still the same.
This is the complete code for the simple test program, including the CSV file.
I would appreciate any guidance you can provide.
The idea is basically the same as that used in the published example techempower-bench
After several tests, he concluded that to avoid this exception, a "GetPipelineResult" is required for each SQL statements sent.
And it's consistent with the operation of Pipeline mode.
This would be the corrected code for the one initially proposed.
I ran tests with several SQL statements sent to different tables in my database and it it works like a charm.
The goal/purpose is to use Pipeline mode for better PostgreSQL performance on slow networks.
Again, thank you very much for the excellent work done with mORMot2.
I had never worked with PostgreSQL's pipeline mode before.
After reading about it, For example this article.
I see that it has some advantages, and the best part is that mORMot2 has it implemented.
I implemented the following code , and it works! : the respective price values are updated in the database.
However, I'm getting the following exception when trying to release the connection, specifically with pConn.CheckPipelineSync.
TSqlDBPostgresConnection.CheckPipelineSync returned 1 instead of PGRES_PIPELINE_SYNC [] Any help you can provide would be greatly appreciated.
TWebSocketProtocolChat has the SendFrameJson function.
Is it possible to add this function to TWebSocketProcess?
Something like:
function TWebSocketProcess.SendFrameJson(const Json: RawUtf8): boolean;
var
frame: TWebSocketFrame;
begin
frame.opcode := focText;
frame.content := [];
frame.tix := 0;
FastSetRawByteString(frame.payload, pointer(Json), length(Json)); // temp copy
result := SendFrame(frame)
end;IMO, that kind of simple examples is prefect for anyone approaching mORMot2; what for an expert is "just ..." for a newcomer is "ah, that's what I was looking for"
IMHO, I agree with you.
Thanks.
Thanks for the feedback and interest.
I guess it is just
https://github.com/synopse/mORMot2/blob … server.dpr
but using THttpWebsocketAsyncServer class, isn't it?
Almost, it also has DoOnRequest which loads the file "restws_simpleechoserver.html"
I have done Example of an asynchronous HTTP WebSocket Echo Server with TWebSocketAsyncServer.
Point your browser to http://localhost:8888/ for initial page using the existing file "restws_simpleechserver.html"
What I've noticed is that when connecting for the first time, "Sender.Protocol.ConnectionID" starts at 2 or 3, not 1.
I hope this example is helpful and can be included in the official mORMot2 GitHub repository.
Thank you very much for such excellent work.
Pages: 1