#1 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » Today 03:28:11

Both findings confirmed and fixed in e005b09e - test-first: the new suite
cases reproduced exactly your matrix (400 on async, no status at all on
sync, and the 0 vs -1 event length) before the fix.

- A chunked body over MaximumAllowedContentLength now gets a clean 413 on
  both families before the connection closes. As a side effect this also
  fixes a pre-existing quirk where the async server reported its 1GB
  in-memory overflow as 400.
- OnBodyDownload now receives aContentLength = -1 for chunked bodies on
  both families, and the doc says so.

The ~12s deferred cleanup you measured is the async connection GC, as
documented. Thanks for the Int64/4.5GB datapoint - good to have that
confirmed on real hardware rather than just by arithmetic.

#3 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-08-01 16:04:37

Great report, thanks.

Your ENOSPC observation is implemented in fcd6afed: when writing to the
spool stream fails, both server families now answer 507 Insufficient
Storage before closing, instead of the raw reset (new
HTTP_INSUFFICIENTSTORAGE constant + StatusCodeToText entry). One caveat:
on THttpServer the 507 is deterministic (the body is fully read before
the failing write), on THttpAsyncServer it is best effort - the failure
happens mid-transfer, so if the client is still blasting the body, the
reset may still win the race. A full lingering-close would be the next
step if that turns out to matter in practice - your curl test would tell.
Covered in the regression tests with a stream that fails after 64KB.

The 7-22s cleanup delay after a hard disconnect is the async connection
instance GC - expected, and now documented in the event comment.

https://github.com/landrix/mORMot2/tree … put-stream

#4 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-08-01 08:12:43

* Done in 92470c90 https://github.com/landrix/mORMot2/comm … 54d9abce28 :
  both hooks now live in virtual sub-methods
  (THttpAsyncServerConnection.DoBodyDownload and
  THttpServerSocket.DoBodyDownload), and the managed locals are out of the
  OnRead / GetRequest hot paths.

* Regarding THttpSocket.Destroy calling Http.ProcessDone: I checked every
  place that sets rfContentStreamNeedFree.

  In the THttpSocket hierarchy, the flag is only set for streams created by
  the server:

  * ContentFromFile responses
  * the progressive static-file path
  * the new OnBodyDownload spool

  The first two are released through ProcessDone in the
  THttpServer.Process finally block. The body-download spool is released in
  DownloadBody.

  THttpClientSocket never assigns Http.ContentStream; client downloads use
  the GetBody(DestStream) parameter, and ownership stays with the caller.

  So the new call should be a no-op everywhere except for the case it is meant
  to cover: a connection being closed after the event in GetRequest, but
  before deferred body retrieval by the thread pool or THttpServerResp.

  I would still appreciate a second check in case I missed an ownership path.

* On stream lifetime, nginx as a reverse proxy spools request bodies to a
  temporary file under client_body_temp_path. proxy_request_buffering is
  enabled by default.

  client_body_in_file_only has two relevant modes:

  * clean: nginx deletes the file when the request is complete
  * on: nginx leaves the file in place, and the application becomes
    responsible for it

  In the latter case, the application receives the path through
  $request_body_file.

  The current branch effectively implements clean while exposing the file
  name through InContent, similar to $request_body_file.

  For customizable lifetime handling, I prefer the
  TFileStreamEventuallyDelete approach because it would remove the need for
  ContentInputName entirely.

  TFileStreamEventuallyDelete = class(TFileStreamEx)

  It would delete the file on destruction unless DeleteFileOnDestroy is set
  to false.

  The event would return this stream, or any other TStream as it does today.
  The server would free it through the existing rfContentStreamNeedFree paths,
  while the deletion policy would stay with the stream class.

  The default behavior would match nginx's clean mode. A handler that wants
  to keep the file could set DeleteFileOnDestroy to false or rename the file
  first, which would correspond to nginx's on mode.

  It would also be useful to let the handler reuse the already-open stream
  instead of reopening the file by name. Once the body is complete, the
  server could rewind the stream and expose it on the request, for example
  through a new property on THttpServerRequestAbstract:

  InContentStream: TStream

  The connection would remain responsible for freeing it after the request.
  InContent could still contain the file name with the STATICFILE marker,
  serving as the $request_body_file equivalent.

  This would also remove the current free-before-Prepare sequence in
  DoRequest, because the input stream would move from Http.ContentStream to
  the request instance before response processing begins.

If this design looks right, I will implement it this way. You can choose the
class name and location; mormot.core.os, next to TFileStreamEx, seems like the
natural place.

#5 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-08-01 04:10:49

The server side is ready for testing:

https://github.com/landrix/mORMot2/tree … put-stream

I added a new THttpServerGeneric.OnBodyDownload event for both THttpServer and THttpAsyncServer. The event returns a TStream, for example a TFileStreamEx pointing to a temporary file, and the request body is written there without keeping it in memory.

The request then reaches the callbacks with InContentType = STATICFILE_CONTENT_TYPE and InContent containing the file name, similar to how file-based responses are handled. The temporary file is deleted after the request unless the handler renames or moves it.

Compressed request bodies currently return 415 with Accept-Encoding: identity. Chunked bodies are limited by MaximumAllowedContentLength, since their final size is not known in advance. The previous 1 GB in-memory limit does not apply to streamed bodies.

While testing this, I found two existing bugs in the asynchronous request parser and fixed them in the same branch:

* THttpRequestContext.ProcessRead did not consume the actual chunk data from the input buffer. As a result, chunked uploads to THttpAsyncServer could stall or be rejected.
* DoProcessParseLine could read one byte beyond the buffer when a network packet ended exactly on the #13 of a CRLF sequence.

There is also a new TNetworkProtocols.BodyDownload test with 98 assertions. It covers an 8 MB spooled upload, chunked uploads through a raw socket, multipart decoding directly from the spooled file using THttpMultiPartDecoder, rejected compressed bodies, cleanup after aborted uploads, and both server implementations.

The tests are green with FPC on aarch64-linux and Delphi Win32/Win64.

@zen010101: this is the branch to try on your machines. Disk-full situations, slow connections and interrupted uploads are the cases I would especially like to see tested.

I will open the PR after getting some real-world feedback here.

#6 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-07-30 06:10:47

Thanks for the quick review and merge.

I can take the server-side implementation next, based on the approach outlined earlier in this thread:

* Add a `THttpServerGeneric` callback that is invoked after the request headers have been parsed, but before the body is read. The callback would return the destination `TStream` for the request body; returning `nil` would preserve the existing in-memory behavior. Most of the required plumbing is already in place, since `THttpRequestContext.ProcessRead` writes to `ContentStream` when one is assigned.
* Use a spooled temporary file as the default stream implementation. This should also work safely with `THttpAsyncServer` and its relatively small worker pool. `TPipeStream` could remain available for blocking server implementations.
* Expose the uploaded body to the handler using `InContentType = STATICFILE_CONTENT_TYPE` and `InContent` set to the temporary file path, mirroring the existing response-side mechanism.
* Wrap this at the REST layer through a `TRestUriContext.InStream` property.
* Extend SOA method handling so that an interface method with a single `TStream` parameter can consume the request body directly.
* In streaming mode, reject compressed request bodies with HTTP `415 Unsupported Media Type` and return `Accept-Encoding: identity`.
* Feed the resulting stream into `THttpMultiPartDecoder`, allowing multipart/form-data uploads of arbitrary size with constant memory usage. This should also address issue #292.

Does this match the architecture you had in mind?

I would follow the same workflow as before: agree on the public interface here first, then implement it on a branch together with the relevant tests.

#9 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-07-29 05:32:51

Thanks @flydev for posting this; I’ll consolidate everything, and then we’ll see what the next steps are.

#10 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-07-27 19:50:07

Done as suggested: I added a new TTestCoreBase.MultiPartDecoder method and moved the multipart tests there from MimeTypes. MimeTypes now only covers MIME recognition, while the MIM test data array is shared by both.

The existing encoder round-trips are now also decoded incrementally by THttpMultiPartDecoder. This includes Rfc2388NestedFiles=true, where a second decoder reads the nested multipart/mixed directly from the outer Current.Content stream.

I also added decoder-specific tests for a 300 KB section containing many CRLF--boundary near-matches, several work-buffer sizes, a source returning only 1–7 bytes per Read(), delimiters split at every buffer position, token and quoted-pair parameters, padding, preamble and epilogue, the header-line limit, truncated input raising EHttpMultiPart, and edge cases for MultiPartFormDataBoundary().

1,310 assertions, green with FPC aarch64-linux and Delphi Win32/Win64.
the whole TTestCoreBase suite still passes on both.

One issue I ran into: Current.Content.Size reports the number of bytes read so far because the section length is not known in advance. Therefore Delphi's CopyFrom(src, 0) silently copies nothing. The documentation recommends StreamCopyUntilEnd() or a normal Read() loop instead, as already done in mormot.crypt.core and mormot.core.zip.

Two questions before I open the PR:

* Current is a record property, so each access copies its four RawUtf8 fields. The documentation recommends caching Current.Content in a local variable. Would a pointer-returning getter, similar to PHttpMultiPartStreamSection, be preferable?

* MultiPartFormDataBoundary() currently sits in mormot.net.client next to the decoder. Would it fit better in mormot.core.buffers next to the other MultiPartFormData* functions, so it could also be reused by MultiPartFormDataDecode?

https://github.com/landrix/mORMot2/tree … rt-decoder

#11 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-07-27 13:02:21

Quick update: the first `THttpMultiPartDecoder` version is working and passes the round-trip tests.

Before opening the PR: where should the decoder tests go?

Extend the existing multipart tests in test.core.base.pas or add them to test.net.proto.pas, next to the implementation?

#12 Re: mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-07-17 11:10:52

Thanks for the detailed analysis.

A few thoughts:

  • Dedicated event:  If it receives the parsed headers and Content-Length and returns the destination TStream (or nil for the current in-memory behavior), the application can choose between a temporary TFileStreamEx and a TPipeStream per request. The main DoS consideration could then be documented: pipes should be fine with THttpServer, where each connection has its own thread, or with non-blocking/Pending-style consumption; a temporary file would be the safer default for THttpAsyncServer.

  • Using STATICFILE_CONTENT_TYPE for the input side makes sense and mirrors the existing output logic. Exposing it through TRestUriContext.InStream, together with detecting a single TStream parameter at the SOA level, should also avoid exposing two competing content types to users.

  • 415 with "Accept-Encoding: identity" for compressed input sounds good. Explicit gzip support through TSynZipDecompressor could always be added later if there is actual demand.

The server-side foundation still depends on the event and stream design, but THttpMultiPartDecoder seems fairly self-contained. I could prepare a PR for an incremental boundary scanner operating on any TStream, processing one part at a time, roughly like Go's mime/multipart.Reader. This would let handlers consume a spooled or piped request body without loading the whole multipart payload into memory.

I would include round-trip tests against THttpMultiPartStream, covering preamble and epilogue handling, CRLF edge cases, nested content-type parameters, and boundaries split across read buffers.

Would you prefer it in mormot.net.http, or in mormot.core.buffers next to MultiPartFormDataDecode?

For the server part, I can then adapt to whichever event/stream design you choose.

#13 mORMot 2 » Server-side large file upload (issue #292) — proposal » 2026-07-17 07:41:42

sh17
Replies: 21

Hi ab,

I'd like to pick up GitHub issue #292 and ask whether a PR in this direction would be welcome before I start coding.

The goal is to support server-side uploads larger than 2 GB without buffering the complete request body in RAM.

Current situation

As far as I can see:

  • THttpRequestContext.ProcessRead already supports writing the request body to ContentStream, for both Content-Length and chunked transfer encoding.

  • However, neither THttpServer nor THttpAsyncServer assigns ContentStream for incoming requests. Request bodies therefore end up in the Content buffer and are limited by MaxHttpInMemSize.

  • MultiPartFormDataDecode also expects the complete multipart body in memory.

We currently work around this with application-level chunking: create an upload, send multiple smaller PUT requests, then finalize it. This works well, but it is a custom protocol and cannot be used by normal multipart clients such as HTML forms, curl -F, or third-party applications.

Possible implementation

Because THttpAsyncServer calls the request handler only after the body has been received, a Go-style pull parser cannot be used directly. My suggestion would be to split the work into two steps.

1. Allow incoming bodies to be written to a stream

Add a hook or option to THttpServerSocketGeneric that assigns Ctxt.ContentStream after the headers have been parsed and before the body is read.

Possible variants:

  • An event similar to OnBeforeBody, where the application may assign a stream such as TFileStreamEx, together with rfContentStreamNeedFree.

  • Automatic spooling based on a configurable memory threshold and temporary directory.

I would personally prefer the event first, since it is small and leaves storage policy to the application. A threshold-based default could be added later.

Since both server implementations use ProcessRead, the same mechanism should work for THttpServer and THttpAsyncServer. The request handler would receive either Content or ContentStream, depending on how the body was stored.

2. Add a streaming multipart reader

As a follow-up, a TMultiPartReader could parse multipart data incrementally from any TStream. The handler could then process one part at a time and copy file parts directly to their final destination.

Open questions
  • How should this interact with Content-Encoding, since decompression currently operates on the in-memory buffer?

  • Is freeing ContentStream through ProcessDone sufficient for aborted connections?

  • Would you prefer an application-provided stream, automatic threshold-based spooling, or both?

Would a PR starting with step 1 be welcome?

#14 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-07-05 16:07:20

@flydev Have you been able to publish the code on GitHub yet? I’d share mine with you after that.

#15 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-06-18 19:23:51

OK, then maybe we should try to merge that somehow after your vacation smile

#16 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-06-18 18:49:18

By the way, I also developed a sqlite-vec extension using lembed, available at https://github.com/landrix/sqlite-vec-for-Delphi. It builds upon two extensions.
I'm exclusively using FreePascal now—no more Delphi. It's just because of the repo names.

#17 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-06-18 18:42:52

If it’s okay with flydev, I’d like to propose some code that builds upon his—specifically, a `mormot.ai` namespace. I’m also willing to maintain it. I’ve implemented the current MCP specification, and right now, I’m working on LLM clients and agents.

Flydev's mormot-os is definitely required. The TLimitedStreamWriter you added today is already being put to use as well.

Sven

#18 Re: mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-06-18 11:00:30

Hi flydev,

thanks a lot — I didn't know about mormot2-extensions, and your
mormot-mcp-server is genuinely the closest thing to "MCP done the mORMot way"
I've seen. I went through it in detail;

- It reads like a mORMot core unit, not a Delphi port: IInvokable tools,
  RTTI-based schema generation, TDocVariant envelopes, the tri-license header
  and * section style.
- The transport layer is excellent — stdio, HTTP, SSE and a real Streamable
  HTTP with token-by-token streaming (incl. the Claude CLI demo). That directly
  answers the streaming question from my post.
- The TSynTestCase coverage for the transports (origin validation, sessions,
  batching, notifications, bad-JSON, 405 paths) is exactly the rigor I'd want.

Where my use case still diverges — and why I think there's room for both:

1. Spec revision. Our agents target the current MCP revision
   (2025-11-25); your server is on 2024-11-05 + Streamable HTTP 2025-03-26.
   For us the newer revision isn't optional.
2. Auth is our product core. We're a SaaS backend with JWT, HttpOnly refresh
   cookies, __Host-csrf double-submit, a role/permission model and owner-capped
   scopes. MCP tool execution has to run *inside* that context on our existing
   mORMot host (TUriRouter + guards), not as a separate server. Your
   TMcpAuthContext is a nice foundation, but the wiring is fairly specific to us.

So I'll keep building our mormot.ai.* clean-room layer (current spec + auth bound
to our context), but I'd love to align the Streamable HTTP transport with your
approach rather than reinvent it.

Which loops back to my question for Arnaud: with community MCP servers now existing,
is there appetite to converge any of this under an official namespace, or do you
prefer it stays as companion packages? Happy either way.

Thanks again for pointing me to it.

Best,
Sven

#19 mORMot 2 » Proposing a `mormot.ai.*` extension — Model Context Protocol (MCP) » 2026-06-17 21:03:11

sh17
Replies: 19

Hi Arnaud, hi all,

We run mORMot 2 in production (FPC on Linux, native, no Indy/Wine) as the backend
of a SaaS for the trades. We now need an **MCP server** so our backend can expose
tools/resources to AI agents (e.g. Claude Desktop and our own agent), and ideally
LLM client drivers later on.

Before writing much code I'd like to check interest and get your guidance, because
I think this belongs **in the mORMot world**, not as yet another standalone lib.

## The gap

As far as I can see, mORMot has no AI/LLM/MCP module today. Meanwhile mORMot
already ships everything such a module needs and would do it better than the
Delphi-only options out there (which lean on Indy and `System.JSON`/`System.Rtti`):

- `mormot.net.server` / `mormot.net.async` — HTTP server for the *Streamable HTTP*
  MCP transport
- `mormot.net.ws.*` — WebSockets for streaming
- `mormot.core.json` / `mormot.core.variants` — JSON-RPC 2.0 envelopes with
  `TDocVariant`
- `mormot.core.rtti` — generating JSON-Schema for tool input from typed records
- cross-compiler (FPC + Delphi), cross-platform, no extra dependencies

## What I'm proposing

A small, **clean-room** extension under a new `mormot.ai.*` namespace, built
against the official **MCP specification (revision 2025-11-25)** and JSON-RPC 2.0
— not derived from any third-party MCP code. Initial, transport-neutral layout:

```
mormot.ai.mcp.types            JSON-RPC/MCP types + envelope build/parse
mormot.ai.mcp.server           engine: tool/resource registry + JSON-RPC dispatch
                               (initialize, tools/list, tools/call) — JSON in/out
mormot.ai.mcp.transport.stdio  stdin/stdout (local subprocess transport)
mormot.ai.mcp.transport.http   Streamable HTTP on mormot.net.server
```

The engine takes JSON in and returns JSON out, so it is fully unit-testable
without a socket; transports are thin adapters. Tools implement a small
`IMcpTool` interface (`GetName`/`GetDescription`/`GetInputSchema`/`Execute`).

I already have the first unit (`mormot.ai.mcp.types`) and FPCUnit tests for the
JSON-RPC envelopes; the rest is staged behind it.

## Questions

1. **Interest & home** — would you welcome such an extension under the
   `mormot.ai.*` namespace (eventual upstream into mORMot), or would you prefer
   it lives as an external companion package? Either is fine for us; I'd just
   like to build it the way that has the best chance of being useful to others.
2. **Namespace & conventions** — if upstream is on the table, is `mormot.ai.*`
   the naming you'd want (e.g. `mormot.ai.mcp.server`)? Any coding-style or CLA
   requirements I should follow from the start?
3. **Transport** — for Streamable HTTP, what's your recommended building block:
   plain `THttpServer`/`THttpAsyncServer` with manual chunked writes, or is there
   a pattern you'd point me at for long-lived streaming responses + an optional
   WebSocket upgrade?
4. **JSON-RPC API shape** — for a framework-grade API, would you prefer the
   envelopes/dispatch built on `TDocVariant` (what I have now) or on typed records
   with `mormot.core.rtti` serialization? Happy to follow your taste here.

I'm willing to maintain this and contribute it back. Thanks for mORMot — it has
been a joy to build a native FPC backend on it.

Best regards,
Sven

#20 Re: mORMot 1 » ICU extension for SQLite » 2024-09-14 06:44:44

Well, I just can't call the function sqlite3.db_config(sql.DB, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1);
under Delphi Win64. There is an access violation directly in the sqlite library.
Both in the static version and in the DLL. I can't provide a more detailed analysis because I can't debug sqlite.

It works with Delphi Win32. But the extension is only Win64.

(I have tested the extension with DiSQLite3, there they works)

#22 Re: mORMot 1 » ICU extension for SQLite » 2024-08-13 14:17:20

ab wrote:

Please define "code crash".

---------------------------
GExperts Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0000000000D1EE5F. Read of address FFFFFFFFFFFFFFFF'.
---------------------------
[&Filter ...] [Ignore &All this Session] [&Break] [Additional &Info] [&Continue]
---------------------------
ThreadId=24592
ProcessId=1
ThreadName="Main"
ExceptionMessage="Access violation at address 0000000000D1EE5F. Read of address FFFFFFFFFFFFFFFF"
ExceptionName="EAccessViolation"
ExceptionDisplayName="$C0000005"
ExceptionAddress=00D1EE5F
FileName=<not available>
LineNumber=<not available>

---------------------------

#23 Re: mORMot 1 » ICU extension for SQLite » 2024-08-13 14:00:07

i have downloaded

https://github.com/asg017/sqlite-vec/re … _64.tar.gz

created a win64 vcl application

and

uses
  ...
  ,mormot.core.os,mormot.db.sql,mormot.db.raw.sqlite3,mormot.core.unicode
  ,mormot.core.base,mormot.db.raw.sqlite3.static,mormot.db.sql.sqlite3
  ,mormot.db.core,mormot.core.datetime

procedure TForm1.FormCreate(Sender: TObject);
var
  sql : TSQLDatabase;
  lLoad : Integer;
  lMsg : PUtf8Char;
begin
  sql := TSQLDatabase.Create(ExtractFilePath(Application.ExeName)+'sample.sql','');
  try
    sqlite3.db_config(sql.DB, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1);
    lLoad:= sql.SQLite3Library.load_extension(sql.DB, PUtf8Char(ExtractFilePath(Application.ExeName)+'vec0.dll'), 0, lMsg);
    if not (lLoad= SQLITE_OK) then
      raise Exception.Create('Error Message');
    sql.Free;
  except
    on E:Exception do
      begin
      end;
  end;

end;

code crash at sqlite3.db_config(....

#24 Re: mORMot 1 » ICU extension for SQLite » 2024-08-13 07:38:13

Somehow none of it works. Or it doesn't work with my extension. Does anyone know more about this? I want to download the following extension.

https://github.com/asg017/sqlite-vec/re … .2-alpha.6

Can anyone help?

#25 Re: PDF Engine » SynPDF and PDF/3-A standard » 2023-11-01 09:57:19

ab wrote:

Any help is welcome to follow PDF/3-A support.

What help is needed? What is still to be done?

#26 Re: mORMot 1 » Embed SQLite C object files into application » 2018-08-16 08:46:48

with wxsqlite it works smile but i need a DB Explorer

Thanks

#27 Re: mORMot 1 » Embed SQLite C object files into application » 2018-08-16 07:09:22

i need encryption in Delphi Win64, so i need the external DLL.

#28 Re: mORMot 1 » Embed SQLite C object files into application » 2018-08-15 13:01:48

For the 64bit variant I have to take the SQLite DLL from https://github.com/utelle/wxsqlite3/releases, right?

Is there a database viewer that supports this encryption?

#29 Re: Other components » Hyphenation in Delphi » 2017-10-25 12:19:25

Is it included in main repository?

#30 Re: mORMot 1 » How to save a File to MongoDB with mORMot Framework? » 2016-02-17 17:43:31

thank you @ab, for your explanations. I would have to check that again. But I think we exceed the 16 MB limit also not. And the files are rarely changed.

#31 Re: mORMot 1 » How to save a File to MongoDB with mORMot Framework? » 2016-02-17 07:30:51

What are the difficults to support GridFS? Aside from that, who programmed it.

#32 Re: SyNode » Adding JavaScript support for mORMot framework » 2015-10-07 07:50:44

Any news on this project? Win64 Support,...Does it make sense to update to the latest version of SpiderMonkey?

#34 Re: mORMot 1 » Can't obtain Blob from SQLite » 2015-09-18 13:18:23

according to my first post,

This code should work, but it does not.
Can someone take a look on this, please.
thanks

var
  sql : TSQLDatabase;
  blob : TSQLBlobStream;
  memory : TMemoryStream;
begin
  sql := TSQLDatabase.Create('d:\temp\test.db');
  try                
     sql.Execute('CREATE TABLE IF NOT EXISTS "files" ("UID"    INTEGER PRIMARY KEY AUTOINCREMENT, "Filename"    TEXT NOT NULL, "File"    BLOB);');
    memory := TMemoryStream.Create;
    memory.LoadFromFile('d:\temp\v\DOCUMENT_2013-20280_2013_05_14_11_14_31.XML');
    memory.Position := 0;
  
    sql.Execute('INSERT INTO files (Filename) VALUES ("'+StringToUTF8('DOCUMENT_2013-20280_2013_05_14_11_14_31.XML')+'")');
    blob := sql.Blob('main','files','File',0,true);     <------------ cannot open value of type null extended_errcode=1
    blob.CopyFrom(memory,memory.Size);
    memory.Free;
    blob.Free;
  finally
    sql.Destroy;
  end;

#35 Re: mORMot 1 » Can't obtain Blob from SQLite » 2015-09-18 07:29:34

ab wrote:

Your path is not correct.
Try 'd:\temp\test.db' instead of 'test.db'.

dosn't work.

https://www.sqlite.org/c3ref/blob_open.html say the dbname is called 'main', but it also does not work


ab wrote:

But why do you use sql.Blob() ?
Use a regular SELECT statement with ColumnBlob() on the TSQLDatabase.
It would be much faster and safer.

sorry, i can't find some example or documentation to read / write binary blobs

#36 mORMot 1 » Can't obtain Blob from SQLite » 2015-09-17 21:51:06

sh17
Replies: 6

Can't obtain Blob direct from SQLite

Which DBName is correct?

var
  sql : TSQLDatabase;
  blob : TSQLBlobStream;
  memory : TMemoryStream;
begin
  sql := TSQLDatabase.Create('d:\temp\test.db');
  try               
     sql.Execute('CREATE TABLE IF NOT EXISTS "files" ("UID"    INTEGER PRIMARY KEY AUTOINCREMENT, "Filename"    TEXT NOT NULL, "File"    BLOB);');

    memory := TMemoryStream.Create;
    memory.LoadFromFile('d:\temp\v\DOCUMENT_2013-20280_2013_05_14_11_14_31.XML');
    memory.Position := 0;
 
    sql.Execute('INSERT INTO files (Filename) VALUES ("'+UTF8Encode('DOCUMENT_2013-20280_2013_05_14_11_14_31.XML')+'")');
    blob := sql.Blob('test.db','files','File',0,true);     <------------ no such table test.db.files extended_errcode=1
    blob.CopyFrom(memory,memory.Size);
    memory.Free;
    blob.Free;
  finally
    sql.Destroy;
  end;

#38 Re: PDF Engine » XMP Support » 2014-06-24 05:25:40

ab wrote:

Any contribution is welcome!
:-)

i do my best.

I have to look also for PDF/A-3 support.

#39 PDF Engine » XMP Support » 2014-06-23 08:14:52

sh17
Replies: 3

Could it be difficult to integrate the full XMP support?

http://en.wikipedia.org/wiki/Extensible … a_Platform

Board footer

Powered by FluxBB