#1 Re: mORMot 2 » Feature request — let a handler opt out of server-side Range handling » Yesterday 12:38:29

vs

Update — closing this from our side.

After pulling current master (2.4.15081) and testing through our Main reverse proxy with no local patch, video plays cleanly with smooth seek across the whole length. You were right: STATICFILE built-in range support works exactly as you described.

Our diagnosis was misled by an ERR_CONTENT_LENGTH_MISMATCH browser console message that happened to appear at the same time as several unrelated symptoms in our stack (a CSS bug clipping the player controls, a separate log-file ACL issue causing a shutdown hang, a canvas cross-origin error on our scrub-preview thumbnails). We kept mentally correlating that "mismatch" with each new symptom and convinced ourselves the buffered proxy was re-slicing OutContent. It was not — the mismatch is benign console noise that does not affect playback.

So no upstream change is needed on your end.
Thanks for the patient pointer, and sorry for the noise.

#2 Re: mORMot 2 » Feature request — let a handler opt out of server-side Range handling » 2026-05-26 18:30:02

vs

Thanks, Arnaud!

Yes — the local-file STATICFILE path is exactly what we use on the backend side, and it works flawlessly (verified on a 1.2 GB MP4: seek across the whole length is fast, no issues). So we don't need anything for STATICFILE.

Our concrete case is exactly the "other case" you mention: a reverse-proxy handler in front of the backend. The handler has no local file — it forwards the browser's Range to an upstream HTTP server, gets back a partial 206 + Content-Range + bytes, and tries to ship that response verbatim through Ctxt.OutContent + OutCustomHeaders + RespStatus=206. Because the server then runs ValidateRange on OutContent by the absolute RangeOffset, the already-correct partial body gets re-sliced to empty.

A per-response opt-out (e.g. a response flag the handler can set to say "I have produced the correct 206 + Content-Range + body — ship verbatim, skip ValidateRange") would unblock this without affecting STATICFILE semantics. Any preference on the API shape would let us prototype against your tree.

Thanks again for the great work!

#3 mORMot 2 » Feature request — let a handler opt out of server-side Range handling » 2026-05-26 10:07:44

vs
Replies: 3

Hi Arnaud,

  I'm building a small reverse proxy in front of several mORMot HTTP servers — a
  single gateway that forwards /<prefix>/... to internal backends (one public URL,
  one TLS cert). Normal requests work fine, but I cannot transparently pass through
  HTTP Range responses for media (e.g. a large MP4 a backend serves via STATICFILE).

  The blocker is that the server applies its OWN Range handling to my handler's
  response:

  * Input side: the incoming `Range:` header is filtered out of Ctxt.InHeaders, so
    my proxy handler can't see/forward it. I can solve this with hsoHeadersUnfiltered.

  * Output side (the real blocker): when rfWantRange is set,
    THttpRequestContext.CompressContentAndFinalizeHead calls ValidateRange, which
    re-slices my OutContent by the absolute RangeOffset. So when my handler already
    returns a correct partial 206 + Content-Range (the bytes I fetched from the
    backend for `bytes=N-`), the server applies the offset a SECOND time:
    RangeOffset >= length(OutContent) -> ContentLength := 0 -> empty body. The
    client gets a 206 with ~0 bytes.

  I couldn't find a THttpServerOption to disable this output-side re-processing —
  hsoHeadersUnfiltered keeps the header on input, but rfWantRange is still set, so
  ValidateRange still runs.

  Minimal repro (useHttpSocket):
    - Handler: on a request whose Range is `bytes=N-` (N>0), set RespStatus := 206,
      add `Content-Range: bytes N-(N+chunk-1)/total` to OutCustomHeaders, and set
      OutContent to the `chunk` bytes for that range.
    - Client: GET with `Range: bytes=N-`.
    - Expected: 206 with `chunk` bytes. Actual: 206 with 0 bytes (the server
      re-ranges OutContent by the absolute N).

  Request: a per-response way for a handler to say "this response is final / I
  manage the range myself — ship my status + headers + OutContent verbatim; do not
  set rfWantRange, do not run ValidateRange, do not re-slice OutContent." For
  example, a response flag the handler can set.

  I'm aware the usual recommendation here is nginx in front + X-Accel-Redirect
  (OnSendFile / NginxSendFileFrom). In this project I specifically want mORMot
  itself to be the single gateway binary (one URL, one TLS cert, no nginx), so I'm
  not looking for an external proxy — only for the minimal primitive that lets
  mORMot's own HTTP server pass a Range/206 response through transparently from a
  handler. This looks like the concrete missing piece under the "reverse proxy"
  scope of #387 / #389.

  With that primitive I can implement a lightweight transparent reverse proxy and
  cap the forwarded range myself to keep memory bounded — no full streaming wrapper
  needed.

  Version: mORMot 2.4, FPC Win64.

  Thanks for the great work!

#4 Re: mORMot 2 » PostgreSQL ORM behavior: Reusing deleted record IDs after insert » 2026-05-03 22:47:35

vs

Look towards TSynUniqueIdentifier from mormot.crypt.secure
- 64-bit TSynUniqueIdentifier and its efficient Generator

type
  /// 64-bit integer unique identifier, as computed by TSynUniqueIdentifierGenerator
  // - they are increasing over time (so are much easier to store/shard/balance
  // than UUID/GUID), and contain generation time and a 16-bit process ID
  // - mapped by TSynUniqueIdentifierBits memory structure
  // - bits 0..14 map a 15-bit increasing counter (collision-free)
  // - bits 15..30 map a 16-bit process identifier
  // - bits 31..63 map a 33-bit UTC time, encoded as seconds since Unix epoch
  // - may be used on client side for something similar to a MongoDB ObjectID,
  // but compatible with TOrm.ID: TID properties
  TSynUniqueIdentifier = type TID

and TOrmModel function SetIDGenerator from mormot.orm.core

#5 Re: mORMot 2 » new samples for mormot2, any rules? » 2026-04-11 12:25:05

vs

@flydev — noticed your mention of the mormot.ext.os extension here.

We discussed the stdin pipe need in
https://synopse.info/forum/viewtopic.php?id=7304
and your implementation is spot-on for our multi-FFmpeg scenario.

Really impressed by the mormot2-extensions repo — it's not just a quick patch but a proper library with tests and four demo projects covering different real-world use cases (interactive processes, concurrent FFmpeg, even Claude Code orchestration).

Thanks for the effort!

#6 Re: mORMot 2 » RunRedirect feature request(stdin) » 2026-04-11 12:06:07

vs

@flydev — thank you, this is exactly what we needed!

Our use case: up to 8 concurrent FFmpeg capture processes (SDI decks via DeckLink), where we need to stop individual recordings gracefully while the others keep running. The current GenerateConsoleCtrlEvent approach kills the entire console group — all 8 decks go down.
Your TExternalProcess with proc.Write('q'#10) + WaitFor solves this cleanly. I tested the FFmpegDemo — the sibling isolation works perfectly (stopping Deck2 while Deck1 and Deck3 continue encoding).

The design as a standalone extension (mormot.ext.os) with zero patches to core is very practical — we can start using it right away.

And hopefully @ab considers including this into the main mORMot2 repository — IMHO it feels like a natural fit for mormot.core.os wink

We'll integrate this into our FeedIngest product and report back with results.
Great work on both Windows and Linux support!

#7 Re: mORMot 2 » SessionsLoadFromFile breaks all session after restart » 2026-03-27 11:25:23

vs

Thank you Arnaud for the explanation.

That makes perfect sense — GroupRights stored as pointer(IDValue) limits IDs to PtrInt size.

We were assigning TSynUniqueIdentifierGenerator to all tables including TAuthUser/TAuthGroup, which produced 63-bit IDs
incompatible with this design.

Our fix: skip auth tables in SetIDGenerator loop:
if vClass.InheritsFrom(TAuthUser) or vClass.InheritsFrom(TAuthGroup) then
  continue;

Auth tables now use default auto-increment, domain tables keep TSynUniqueIdentifier. Problem solved.

Perhaps worth a note in the SetIDGenerator documentation that it should not be used with TAuthUser/TAuthGroup descendants?

#8 Re: mORMot 2 » SessionsLoadFromFile breaks all session after restart » 2026-03-26 09:24:02

vs

Hi Arnaud, back in this thread.

Another issue found on another production implementation.

SessionsSaveToFile/LoadFromFile truncates 64-bit User.IDValue to 32-bit

TAuthSession.SaveTo and CreateFrom use WriteVarUInt32/VarUInt32 for fUser.IDValue and fUser.GroupRights.IDValue:

// SaveTo (line 5066-5068):
W.WriteVarUInt32(fUser.IDValue);
W.WriteVarUInt32(fUser.GroupRights.IDValue);

// CreateFrom (line 5083, 5086):
fUser.IDValue := Read.VarUInt32;
fUser.GroupRights.IDValue := Read.VarUInt32;

IDValue is TID = Int64, but VarUInt32 handles only 32-bit values. When using TSynUniqueIdentifierGenerator (63-bit IDs), the upper
bits are silently lost.

Reproduction:
1. Use TSynUniqueIdentifierGenerator for TAuthUser/TAuthGroup tables
2. Login → session created with 63-bit User.ID (e.g. 3810583231573688321)
3. Stop server → SessionsSaveToFile truncates to low 32 bits (2164424705)
4. Start server → SessionsLoadFromFile restores truncated ID → user not found in DB → session is useless

Fix: replace WriteVarUInt32/VarUInt32 with WriteVarUInt64/VarUInt64 for both IDValue fields. This changes the .ses binary format
(old files would need to be discarded on upgrade).

#9 Re: mORMot 2 » RunRedirect feature request(stdin) » 2026-03-22 14:18:22

vs

Arnaud, let me bother you again this Sunday! roll

What's the best way to handle this issue?

#10 Re: mORMot 2 » SessionsLoadFromFile breaks all session after restart » 2026-03-22 14:11:19

vs

Arnaud, you're amazing as always.

I barely finished my coffee before we received the fix.

My sincere respect and gratitude!

Added...
Checked, fix works!

#11 mORMot 2 » SessionsLoadFromFile breaks all session after restart » 2026-03-22 13:16:11

vs
Replies: 6

SessionsLoadFromFile breaks all session lookups due to fSessionCounterMin mismatch after restart

When using SessionsSaveToFile/SessionsLoadFromFile (or Shutdown with a state file) for session persistence across restarts, all session lookups via LockedSessionFind fail after the server restarts.

  Root cause:
  - In TRestServer.Create, fSessionCounterMin := Random32(1 shl 20) + 10 (a new random value on every startup, up to ~1,048,585)
  - SessionsLoadFromFile restores fSessionCounter from the file, but fSessionCounterMin stays at the new random value
  - LockedSessionFind checks: if (aSessionID <= fSessionCounterMin) or (aSessionID > cardinal(fSessionCounter)) then exit;
  - For any small deployment where saved fSessionCounter < new fSessionCounterMin, ALL sessions (loaded and newly created) are silently rejected

  This makes SessionsSaveToFile/SessionsLoadFromFile effectively broken for any server with fewer than ~1 million total logins (which is most deployments).

  Proposed fix in SessionsLoadFromFile, after restoring fSessionCounter:
      fSessionCounter := PCardinal(R.P)^;
      fSessionCounterMin := 0; // allow all loaded session IDs to pass bounds check

  Setting fSessionCounterMin=0 is safe because session IDs 0 and 1 (CONST_AUTHENTICATION_NOT_USED/NOT_STARTED) are rejected by the caller before LockedSessionFind is ever reached.

  Regression from mORMot1: the old TSQLRestServerDB.Shutdown(filename) + SessionsLoadFromFile pattern worked reliably in mORMot1 because fSessionCounterMin was not randomized.

#12 Re: mORMot 2 » RunRedirect feature request(stdin) » 2026-03-12 18:45:29

vs

Re: RunRedirect feature request (stdin)

Adding another strong use-case for roKeepStdinPipe (or similar): graceful per-process stop of multiple FFmpeg instances.

We run N FFmpeg capture processes (one per deck, up to 8) via RunRedirect. When the operator stops one deck, we need to send q\n to that specific FFmpeg — the standard graceful shutdown signal. FFmpeg then flushes its buffers, closes the output file cleanly, and exits with code 0.

The current workaround — returning true from TOnRedirect — triggers GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0), which sends the signal to the entire console group. With 8 active FFmpeg processes this would kill all of them simultaneously. So we currently rely on TerminateProcess (hard kill after 5s), which risks incomplete/corrupted output files.

A roKeepStdinPipe flag that keeps the stdin write-handle accessible would allow writing q\n to the specific process and solve this cleanly. Alternatively, a roNewProcessGroup flag (CREATE_NEW_PROCESS_GROUP) would allow targeted GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid).

Either approach would make RunRedirect suitable for production multi-process management.

---

#13 Re: mORMot 2 » About Multi-Device Authentication » 2025-12-02 21:43:50

vs

Hi, Arnaud.

When you have time and opportunity, please commit steps 7 and 8 to fully understand mORMot2's "Clean Architecture" principle.

I would like to say a special thank you for your teaching, mentoring, and evangelism in modern Pascal.
Respect.

#14 Re: mORMot 2 » mORMot: CreateMissingTables adds default ID despite existing varchar » 2025-10-08 15:49:20

vs

Please try

MyModel.Props[TMyTable].ExternalDB.MapField('ID', 'MY_TABLE_ID');

#15 Re: mORMot 2 » Accessing this URL using TWinHttp will report an error » 2025-10-01 17:45:27

vs

Hello, dear community!

I use IHttpClient/TSimpleHttpClient to access a third-party REST server.
Authentication is performed via a POST request. The request and response are as follows:

C:\Users>curl -i -X POST "http://localhost:8080/j_spring_security_check" -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie: JSESSIONID=F6E4DEBE5FFA22C694907C6AB93B4880" --data "j_username=ODA&password=&j_password=a7f59c966023f1234fe41d69be3a7d43e2e50046&cnonce=09f0cd58db639de3092c1c74f3aa72207f38afa2&_csrf=58ad7adb-fc25-452d-8cad-bad841f619be"
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Location: /
Content-Length: 0
Date: Wed, 01 Oct 2025 17:17:28 GMT

And if I understand correctly, TSimpleHttpClient perform a redirect occurs followed by a new POST request, to which the server responds with status code 500 — most likely because a POST request to Location: / is not implemented.
I resolved this issue using a workaround.

type
  TSimpleHttpClientAcc = class(TSimpleHttpClient);
...
  HttpClient := TSimpleHttpClientAcc.Create;
...
  HttpClient.fHttp.RedirectMax := 0;

Maybe there's a more elegant way to solve this issue?
On the other hand, it might help someone avoid wasting a ton of time figuring out the cause of a 500 error from third-party REST servers with 30* response wink

#16 Re: mORMot 2 » Executable.Version is empty? » 2025-09-02 23:04:27

vs

Allow me to expand on this topic a bit more )).
I decided to ask Copilot how it would respond to this question.
Below is the result. The link in Copilot's answer refers exact to this thread on the forum.

https://ibb.co/fRbBnLb
https://ibb.co/fRbBnLb

It’s a kind of loop — Copilot teaches us, we teach Copilot, and then Copilot teaches us again. smile
But it was Arnaud who taught us all first — with that excellent documentation!

#17 Re: mORMot 2 » Executable.Version is empty? » 2025-09-01 15:58:43

vs

Don't worry.
You're welcome!

#18 Re: mORMot 2 » Executable.Version is empty? » 2025-09-01 12:50:38

vs

As described in the documentation - you need to call GetExecutableVersion to initialize its Version fields

https://github.com/synopse/mORMot2/blob … 1492-L1498

#19 Re: mORMot 2 » About ReturnFileFromFolder in mORMot2 » 2025-08-07 11:30:03

vs

Hi!
Two questions:

1. In THttpProxyUrl, there's a property:
/// CSV list of GLOB file or directly names to be rejected as not found
// - e.g. '*.secret'
property RejectCsv: RawUtf8;

If I try to get the content of a file like *.secret, I correctly get:

HTTP 404 Not Found
Wrong route

Which is great!
However, in the folder listing, files matching *.secret are still visible — because the FolderHtmlIndex procedure from mormot.core.search doesn't seem to respect RejectCsv.
Is there a way to override FolderHtmlIndex with a custom version, or hook into the existing one to take into account RejectCsv?


2. What's the best way to reject all files except, say, *.pdf?

Thanks in advance!

#21 Re: mORMot 2 » Performance of Mormot Collections vs. Spring v2 Collections » 2025-03-02 22:14:16

vs

Arnaud, please understand me correctly, this is not a call to action, but rather a reflections on this FREE Sunday evening on your thoughts number 28 and 26 in this "Think free as in free speech, not free beer" very inspiring post.
51XpdusUVoL._SL400_.jpg
The citation of this article most likely will increased and sooner or later it will be useful for someone in conjunction with mORMot )))
And as always, thank you for your sharing of your knowledge and experience and incredible daily productivity.
Thank you from the bottom of my heart.

#22 Re: mORMot 2 » Performance of Mormot Collections vs. Spring v2 Collections » 2025-03-02 17:08:29

vs

Maybe this article will be useful - Optimal Bounds for Open Addressing Without Reordering.

Along the way, we disprove the central conjecture left by Yao in his seminal paper “Uniform Hashing is Optimal”. Uniform Hashing is Optimal

#23 Re: mORMot 2 » Using the FindFiles function » 2024-11-26 22:23:54

vs

Thanks ab, as always!
With this commit, all hidden files and files from hidden subfolders are listed. Checked both Delphi and Lazarus on Windows.
Files with the system attribute are not in the list.

#24 Re: mORMot 2 » Using the FindFiles function » 2024-11-26 17:15:19

vs

1. Unfortunately, the result is the same as yesterday.
I guess that in the call

(FindFirst(fold + '*', faDirectory, F) = 0) then //line 1695 mormot.core.search 

it is necessary to set the faHidden parameter when ffoIncludeHiddenFiles in Options, something like this

(FindFirst(fold + '*', faDirectory or Integer(ffoIncludeHiddenFiles in Options) shl 1 {faHidden = $00000002}, F) = 0) then 

Of course, there is still the question of listing system files that are not currently on the list, but I am not sure if this is really necessary.


2. I probably expressed my thought incorrectly, it was not a request to include this check in the FindFiles function, but rather a question whether such an approach might work, and implement it in my extended function.

Thanks!

#25 Re: mORMot 2 » Using the FindFiles function » 2024-11-25 22:56:27

vs

Thanks, ab!
1. Partially. Hidden files in the list. But files from the hidden folders is out, unfortunately.

2. As an option, maybe after executing FindFiles try to check the last file in the list by the FileExists function. And if FileExists returns false, we can assume that the connection was broken.
Of course we should take the last file from the unsorted list and understand that there is a possibility that this last file could have been deleted during the time FindFiles ended and FileExists was called.
But at least it's something, than nothing )))

#26 mORMot 2 » Using the FindFiles function » 2024-11-25 15:57:41

vs
Replies: 6

Hello!

Using the FindFiles function from mormot.core.search I have two questions.

1. How, without changing the source code, namely the constants faInvalidFile and faDirectoryMask, can I also get hidden files and files from hidden folders, as a result.
    For example, the *__history* directory from the folder with the source codes for Delphi IDE.

2. Is there any mechanism to determine that the function has stopped scanning the directory due to, for example, a broken VPN connection to the remote server. Now, in this case, the function returns the number of records that it successfully scanned before the connection was broken and without notification that the connection was lost during its execution.
   Probably it is worth analyzing GetLastError() <> ERROR_NO_MORE_FILES?
   https://learn.microsoft.com/en-us/windo … -directory

Maybe someone has encountered such cases and you already have solutions or solution options.

Thank you!

#27 Re: mORMot 2 » The Big Divide » 2024-10-19 17:38:19

vs

Let me add my two cents.
For me, there are three things that greatly help in understanding the framework, first two of which I try to do daily:

1. Follow the commits. Honestly, I'm just amazed by Arnaud's productivity throughout the day, especially day after day. Arnaud, please share your secret to such work efficiency! smile
2. Keep an eye on the discussions  forum.
3. When necessary, look at the test units for examples of how to use various functions, approaches, and usage scenarios, as they cover the entire framework.

#28 Re: mORMot 2 » MGet fails silently if Content-Length unknown » 2024-02-08 18:56:23

vs

Incredible. Thank you!
I'll try to do some tests.

#29 Re: mORMot 2 » MGet fails silently if Content-Length unknown » 2024-02-07 22:50:12

vs

Great as always, ab!
Thank you!

Generally speaking also plus FTP, FTPS, and SFTP wink

ftp://[user[:password]@]server[:port]/path/to/remote/resource.mpeg
sftp://[user[:password]@]server[:port]/path/to/remote/resource.mpeg

From
https://ffmpeg.org/ffmpeg-protocols.html#ftp

#30 Re: mORMot 2 » MGet fails silently if Content-Length unknown » 2024-02-07 18:45:38

vs

I'm afraid to be wrong, but maybe it makes sense to add the ability to download files over SMB to MGet.
Or move this feature into a separate utility, something like

smbget - wget-like utility for download files over SMB

https://manpages.ubuntu.com/manpages/tr … get.1.html

#31 Re: mORMot 2 » RunRedirect and TOnRedirect small confusion of descriptions » 2024-02-07 17:56:10

vs

Humm, you are rigth. Testing with "ping" works fine.
But with small test program like

 
begin
  for i := 10 to 80 do
    begin
      write(IntToStr(i) + ',');
      sleep(200);
    end;
end. 

I get this log

Start at: 07.02.2024 19:54:58
OnRedirect at: 07.02.2024 19:55:06
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52
OnRedirect at: 07.02.2024 19:55:12
,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
Exit Code: 0
function TFoo.OnRedirect(const text: RawByteString; pid: cardinal): boolean;
begin
  Result := False;
//  Writeln(pid);
  if text <> '' then
    begin
      Writeln('OnRedirect at: ' + DateTimeToStr(Now));
      Writeln(text);
    end;
end;

#33 Re: mORMot 2 » RunRedirect and TOnRedirect small confusion of descriptions » 2024-02-06 19:55:52

vs

As always, thanks for the lightning-fast response, ab! ))


Add.

Is it possible to add RedirectOutput execution after a certain timeout rather than after the buffer is full?
For long processes with percentage progress, a lot of time passes until the buffer is filled out and the data is transferred to TOnRedirect.
Thanks!

#34 mORMot 2 » RunRedirect and TOnRedirect small confusion of descriptions » 2024-02-06 18:55:22

vs
Replies: 6

Hi!

mormot.core.os

  // - should return true to stop the execution, or false to continue
  .....
  // - the raw process ID (dword on Windows, cint on POSIX) is also supplied
  TOnRedirect = function(const text: RawByteString; pid: cardinal): boolean of object;


  // - will optionally call onoutput() to notify the new output state
  // - can abort if onoutput() callback returns false, or waitfordelayms expires
  ....
  function RunRedirect(const cmd: TFileName; exitcode: PInteger = nil;


Actually, it works fine as described for TOnRedirect. i.e. when the result is false then execution continue.

#35 Re: mORMot 2 » IDocList/IDocDict JSON for Delphi and FPC » 2024-02-02 23:51:05

vs

Thank you Arnaud for your daily work and for sharing your knowledge and experience with us!
Great job!

Regarding your question in the blog article about the magic number 1.0594631 is the twelfth root of 2, if I'm not mistaken.
And your hint about programming music suggests that there are 12 semitones in an octave and each semitone differs from its neighbors by 1.0594631 (the twelfth root of 2).
I guessed? )))))

#36 Re: Free Pascal Compiler » VsCode as editor » 2024-01-21 22:33:26

vs
macfly wrote:

Yes, I can create a tutorial.

With some examples of Tasks to do the builds, compilation, etc. This part was where I invested the most time, but it wasn't complicated.

Maybe I missed something. Is there a link to your tutorial? Thank you!

#37 Re: mORMot 1 » Firebird transactions » 2024-01-21 17:10:37

vs

Do you change line 616 cMaxStm = 50 in mormot.db.sql.ibx.

Yes, 48 and below working fine ))). I added the numbers for Ibx firebird 25 to my previous post.

Previous test on 2.5 pass without problem.

Because, as I wrote earlier, embedded version of fbclient.dll from firebird 5 installation was used instead of connecting to 2.5 firebird server

Edited: Or execute statement size exceeded  64K  limit on Fb2.5, Fb3 and above have limit of 10MB.

Yes, that's right, https://www.firebirdfaq.org/faq197/

Do you try to add define LEGACYFIREBIRDAPIONLY to force using of legacy api with Fb4/5?

Yes, but without success.

! EXC   EIBInterBaseError {Message:"Engine Code: 335544351\r\nunsuccessful metadata update"} [Main] at 0100375a46 client/include/wloadlibrary.inc tfbclientapi.ibdatabaseerror (209)

#38 Re: mORMot 1 » Firebird transactions » 2024-01-20 18:41:03

vs

More accurate test results.

Running tests using Synopse mORMot framework 2.2.6792, compiled with Free Pascal 3.2.2 64 bit, against SQLite 3.44.2, on Windows 11 64bit (10.0.22631), at 2024-01-20 20:02:16.

Insertion speed (rows/second)                                           Read speed (rows/second)
                  Direct      Batch       Trans       Batch Trans   |                     By one      All Virtual All Direct
Zeos firebird 25  2739        76921       5911        58403         |   Zeos firebird 25  7811        407398      427313
Zeos firebird 4   2471        57124       7942        41158         |   Zeos firebird 4   7868        391282      412609
Zeos firebird 5   1960        70443       7295        49310         |   Zeos firebird 5   8212        413479      498529
Ibx firebird 25   756         43030       6628        40509         |   Ibx firebird 25   1356        100883      117096
Ibx firebird 4    1824        33112       7650        42821         |   Ibx firebird 4    1617        138475      104979
Ibx firebird 5    1367        60364       6479        40248         |   Ibx firebird 5    1791        235510      211555

A separate test was run for each driver and each firebird server version.

Ibx firebird 25 did not pass the test due to an error: Solved by changing line 616 cMaxStm = 50 in mormot.db.sql.ibx at cMaxStm = 45

Project PerfTestConsole raised exception class 'EIBInterBaseError' with message:
Engine Code: 335544569
Dynamic SQL Error
-SQL error code = -204
-Implementation limit exceeded
-block size exceeds implementation restriction

 In file 'FBClientAPI.pas' at line 412:

#39 Re: mORMot 1 » Firebird transactions » 2024-01-20 01:43:00

vs
ttomas wrote:

2. Correct, this is the reason I create ibx mormot driver. Main goal is to have 0 active transaction if nobody is connected to app/server.

Great, thanks for sharing your experience!

ttomas wrote:

{$define ZEOSTRANS} is only for testing, not recomended for production.

Ок, thanks. Yes, it is clear!

tomas wrote:

@vs, do you success build with delphi, if yes delphi version please. @ab alearedy commit changes in trunk.

Yes, with my local edits MVCServerFirebirdIbx compiling successful for both (Lazarus and Delphi 12) and working as expected, except FTS.
Tomorrow I'll try to play with ..\ex\extdb-bench\PerfTestConsole.dpr for both (Lazarus and Delphi 12) with the latest ab's commit.

I suspect that the performance figures that I gave a little earlier are not entirely correct.
Most likely the embedded version of fbclient.dll server from firebird 5 installation was used instead of connecting to a particular version of firebird server.
But this is just a guess, I'll try to figure it out tomorrow.

Add.
By the way. Thanks madorin, there is a pretty good library with precise transaction controls for Firebird. Separate for reading and writing transactions, at least.
Maybe this could be a starting point for the next Firebird driver for mORMot 2
https://github.com/madorin/fibplus/
https://github.com/madorin/fibplus/commits/master

#40 Re: mORMot 1 » Firebird transactions » 2024-01-19 21:43:32

vs

ab, thanks for the tip.
Still, there may be a small typo, line 10 in ..\ex\extdb-bench\PerfTestConsole.dpr

  {../../src/$R mormot.win.default.manifest.res} 

ttomas, thank you for the clarification!

1 and 3 - clear.

2. A few words about this. As I wrote earlier in this thread, this long transaction leads to an increase records versioning for frequently updated tables, which for systems running 24/7 after some time, leads to a dramatically decrease performance for both reading and writing. Firebird 4 solved this problem at some point, but still, a long transaction that opens when the server starts, in my opinion, is not a very correct configuration. Therefore fbintf seems more suitable.

#41 Re: mORMot 1 » Firebird transactions » 2024-01-19 12:27:54

vs

Some test results

Running tests using Synopse mORMot framework 2.2.6749, compiled with Free Pascal 3.2.2 64 bit, against SQLite 3.44.2, on Windows 8 64bit (6.2.9200), at 2024-01-19 13:28:17.

Insertion speed								|	Read speed
 			Direct	Batch	Trans	Batch Trans		| 				By one	All Virtual	All Direct
Zeos firebird 25	2265	60781	16408	65852			|	Zeos firebird 25	10884	366770		399840
Zeos firebird 4		2187	55836	6949	63136			|	Zeos firebird 4		6944	373538		412864
Zeos firebird 5		2473	65590	8084	52379			|	Zeos firebird 5		8154	403177		490196
Ibx firebird 25		2366	43955	15503	40030			|	Ibx firebird 25		3850	164076		120290
Ibx firebird 4		1296	37603	3675	49165			|	Ibx firebird 4		1798	106503		99975
Ibx firebird 5		1275	30746	4452	40146			|	Ibx firebird 5		1967	221028		214850

For some reason log shows Windows 8 64bit, but in fact Windows 11 64bit.

#42 Re: mORMot 1 » Firebird transactions » 2024-01-19 02:05:37

vs
ttomas wrote:

Yes need to be changed to string. I will try to create push request.

Thank you so much.

Fixing these two issues
for Lazarus:

MVCServerFirebirdIbx.dpr(54,17) Error: identifier idents no member "CreateDescendingPK"
MVCServerFirebirdIbx.dpr(95,1) Error: Can't open resource file "D:\Projects\Delphi\Components\Synopse\mORMot2-2.0.stable\ex\mvc-blog\mormot.win.default.manifest.res"

and
for Delphi:

[dcc32 Error] mormot.db.sql.ibx.pas(120): E2010 Incompatible types: 'UTF8String' and 'string'
[dcc32 Error] MVCServerFirebirdIbx.dpr(54): E2003 Undeclared identifier: 'CreateDescendingPK'

MVCServerFirebirdIbx compiling successful for both and working as expected, except FTS

#43 Re: mORMot 1 » Firebird transactions » 2024-01-18 14:51:12

vs

fbintf1.4-0 already installed on Delphi.

For Lazarus:
MVCServerFirebirdIbx.dpr(54,17) Error: identifier idents no member "CreateDescendingPK"
MVCServerFirebirdIbx.dpr(95,1) Error: Can't open resource file "D:\Projects\Delphi\Components\Synopse\mORMot2-2.0.stable\ex\mvc-blog\mormot.win.default.manifest.res"

mormot.db.sql.ibx.pas(119):
property FirebirdLibraryPathName: RawUtf8
but
mormot.db.sql.ibx.pas(87):
fFirebirdLibraryPathName: string;

#44 Re: mORMot 1 » Firebird transactions » 2024-01-18 00:22:27

vs

Two small inaccuracies

commit 2.2.6749

[dcc32 Error] mormot.db.sql.ibx.pas(120): E2010 Incompatible types: 'UTF8String' and 'string'
[dcc32 Error] MVCServerFirebirdIbx.dpr(54): E2003 Undeclared identifier: 'CreateDescendingPK'

#45 Re: mORMot 2 » LDAP Active Directory list users » 2024-01-05 17:30:24

vs

For today's commit, "2.2.6617" works fine. Thank you!
But strangely, I followed https://github.com/synopse/mORMot2/commits/master every day and did not see any changes regarding this issue.
Probably I was inattentive and missed it))))
That's why I decided to bother you today.

#46 Re: mORMot 2 » LDAP Active Directory list users » 2024-01-05 14:50:51

vs

Hi Ab.
Was the log I sent useful?

#47 Re: mORMot 2 » LDAP Active Directory list users » 2023-11-20 21:14:11

vs
ab wrote:

Did you try both OU=1\+2 MEDIA and OU=1+2 MEDIA content?

Yes. Same results.

ab wrote:

Can you enable the application console, and define a ASNDEBUG conditional and report the output to the console during the search?

Sorry. I do not have permission to publish the log of communication with the corporate AD server. Can I send the log to your email address?

#48 Re: mORMot 2 » LDAP Active Directory list users » 2023-11-20 20:12:13

vs

It is MS.
I tried it, but unfortunately parameter passes, but TLdapClient.GetUserInfo returns false.
I.e. Search returns true but SearchResult.Count = 0.

#49 Re: mORMot 2 » LDAP Active Directory list users » 2023-11-19 12:59:49

vs

Hi Ab.

The call

TLdapClient.GetGroupInfo('', vBaseDN, vLdapGroup, '', True);

Successfully returns the corresponding group (vLdapGroup) with N members.
One of the member from this group has DN returned by vLdapGroup.member[k] kind of 'CN=Super User,OU=1\+2 MEDIA,OU=Domain Users,DC=1plus2,DC=corp';

To determine sAMAccountName for this user, the next call

TLdapClient.GetUserInfo('', vLdapGroup.member[k], '', vLdapUser);

returns an error
Invalid input name: CN=Super User,OU=1\+2 MEDIA,OU=Domain Users,DC=1plus2,DC=corp

If I remove \ before +, then such a user does not exist.
The actual name of this OU is "1+2 Media" without quotes.

How to correctly call a TLdapClient.GetUserInfo with such a parameter?

In continuation of our conversation, this is not a problem of non ASCII characters, rather this is a problem of special characters for AD.

Thanks a lot.

#50 Re: mORMot 1 » Firebird transactions » 2021-08-08 00:01:02

vs

It looks like firebird 4 solves that issue of commit retaining transaction

Board footer

Powered by FluxBB