#1 Re: mORMot Framework » mORMot 2 Generics and Collections » 2021-12-20 10:26:21

zed

What is the minimum supported Delphi version for this? Is it 2009?

#2 Re: mORMot Framework » Will mORMOT/Delphi work together on Linux? » 2021-11-15 15:01:55

zed
ab wrote:

Tip: ensure you use fpdebug +gdb as debugger in Lazarus.

Can you give more details? I can choose only FpDebug or GDB as backend - how can I choose "fpdebug +gdb"?
4e86e5b39096947cf8a3acc520a550f7.jpeg

#3 Re: mORMot Framework » Support for http 2.0 » 2021-08-31 05:51:11

zed

libcurl backend supports http2.

#6 Re: mORMot Framework » No support for trigram FTS5 tokenizer added in SQLit3.34.0(2020-12-01) » 2020-12-24 12:09:07

zed

It works for me with SynSQLite3Static and sqlite3.dll (both tested only for Win32). I used precompiled dll https://www.sqlite.org/download.html

mORMot 1.18.6192, Delphi 10.3.3 CE, test code:

program SynFTS5Test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  SynCommons,
  SynSQLite3,
  SynSQLite3Static,
  mORMot,
  mORMotSQLite3;

type
  TSQLRecordFTS5Trigram = class(TSQLRecordFTS5);

  TSQLTextRecord = class(TSQLRecordFTS5Trigram)
  protected
    FText: RawUTF8;
  published
    property Text: RawUTF8 read FText write FText;
  end;

var
  VModel: TSQLModel;
  VClient: TSQLRestClientDB;
begin
  //sqlite3 := TSQLite3LibraryDynamic.Create;

  Writeln(SYNOPSE_FRAMEWORK_FULLVERSION);
  try
    VModel := TSQLModel.Create([TSQLTextRecord]);
    VClient := TSQLRestClientDB.Create(VModel, nil, 'fts5.db3', TSQLRestServerDB);
    try
      VClient.Server.CreateMissingTables;
      // ...
    finally
      VClient.Free;
      VModel.Free;
    end;
  except
    on E: Exception do begin
      Writeln(E.ClassName, ': ', E.Message);
    end;
  end;

  Writeln('Press ENTER to exit...');
  Readln;
end.

#8 mORMot Framework » FTS5 rises error: no such tokenizer: simple » 2020-11-24 14:56:36

zed
Replies: 1

mORMot version: 1.18.6171

Test code:

uses
  System.SysUtils,
  SynCommons,
  SynSQLite3Static,
  mORMot,
  mORMotSQLite3;

type
  TSQLTextRecord = class(TSQLRecordFTS5)
  protected
    FText: RawUTF8;
  published
    property Text: RawUTF8 read FText write FText;
  end;

var
  VModel: TSQLModel;
  VClient: TSQLRestClientDB;
begin
  Writeln(SYNOPSE_FRAMEWORK_FULLVERSION);
  try
    VModel := TSQLModel.Create([TSQLTextRecord]);
    VClient := TSQLRestClientDB.Create(VModel, nil, 'fts5.db3', TSQLRestServerDB);
    try
      VClient.Server.CreateMissingTables;
      // ...
    finally
      VClient.Free;
      VModel.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

rises exception:

ESQLite3Exception: Error SQLITE_ERROR (1) [Step] using 3.33.0 - no such tokenizer: simple, extended_errcode=1

Same code works fine with FTS3 and FTS4.

FTS5 have three built in tokenizers:

- The unicode61 tokenizer, based on the Unicode 6.1 standard. This is the default.
- The ascii tokenizer, which assumes all characters outside of the ASCII codepoint range (0-127) are to be treated as token characters.
- The porter tokenizer, which implements the porter stemming algorithm.

It seems, that default "simple" tokenizer was renamed to "ascii" in FTS5 and it isn't a default anymore.

#9 Re: mORMot Framework » Renaming TSQLRecord to TORM » 2020-11-09 17:10:13

zed

For some functions, like Trim() the easiest is to create an overload

Yea, it easy, but wait: [DCC Error] SynCommons.pas(24041): E2251 Ambiguous overloaded call to 'Trim'

SynTrim is a good name for this function that will fix all troubles.

#10 Re: mORMot Framework » Renaming TSQLRecord to TORM » 2020-10-30 15:08:46

zed
edwinsn wrote:

We can just use fully qualified names for procedures and functions. for example: `unit1.procedure1`

Your example is not relevant because mORMot 2 uses long units names. In my opinion, using prefixes is preferable.

mormot.core.base.TrimU()
SynTrim()

#11 Re: mORMot Framework » Does RecordSave and RecordLoad work with packed records only? » 2020-07-04 09:13:24

zed

In this blog-post you wrote:

It is also mandatory that you declare the record as packed.
Otherwise, you may have unexpected access violation issues, since alignement may vary, depending on local setting, and compiler revision.

So, if I will use fixed alignment {$A8} and the same compiler to Save/Load records, can I not use "packed"?

I'm asking because in my simple test it works fine without "packed". Tested on Delphi 10.3.3 (x32/x64).

#12 mORMot Framework » Does RecordSave and RecordLoad work with packed records only? » 2020-07-03 16:01:07

zed
Replies: 2

Documentation says:

- will handle packed records, with binaries (byte, word, integer...) and
string types properties (but not with internal raw pointers, of course)

so is it mean that only packed records supported?

And the same question about RecordSaveJson - does it work with all records or packed only (documentation says nothing)?

#13 Re: mORMot Framework » Fast MM5 » 2020-05-05 18:21:20

zed

Is this topic still about FastMM5?

#14 Re: mORMot Framework » cannot build sqlite.c » 2020-01-27 17:45:21

zed

Embarcadero C++ 10.2 "Tokyo" Compiler and Command-line Tools (Win32 only) direct link:
http://altd.embarcadero.com/download/bc … BCC102.zip (45.2Mb)

The Embarcadero 10.2 Tokyo C++ compiler is a free, Clang-based compiler for 32-bit Windows. The download includes a number of other tools, as well as the Dinkumware STL and headers and import libraries required to build both command-line and GUI Windows applications.

#15 Re: htm2pdf » htm2pdf dll » 2020-01-24 06:54:51

zed
erick wrote:

But the DLL idea probably wouldn't work because I have a feeling the graphical code cannot run in anything but the main thread.

You can call functions from the main thread, no matter where they are. So, the dll idea should work.

#17 Re: mORMot Framework » Store PDF as Blobs in SQlite - performance issues? » 2019-12-17 19:39:27

zed

At first, you should answer the question: what is the "large blob" means in your case? Is it 1k, 100k, 1M, 100M?

After this you can go here: https://www.sqlite.org/intern-v-extern-blob.html and check if your case is "green" (than you can use blobs) or "red" (then use file system).

#18 Re: mORMot Framework » cannot build sqlite.c » 2019-11-23 10:47:02

zed

mpv
Problem with linking sqlite3.obj compiled with modern Free C++ compiler (Clang based) under Win32. At that moment mORMot uses classic compiler from Community Edition which ships with commercial use limitations: https://www.embarcadero.com/free-tools/ccompiler

#19 Re: mORMot Framework » cannot build sqlite.c » 2019-11-22 20:47:24

zed

This errors says that you should continue refactoring SynSQLite3Static.pas if you want to get it work.

#20 Re: mORMot Framework » cannot build sqlite.c » 2019-11-22 07:00:34

zed

Open SynSQLite3Static.pas and add constant prefix:

  {$ifdef MSWINDOWS}
    {$ifdef CPU64}
      {$L sqlite3.o}  // compiled with C++ Builder 10.3 Community Edition bcc64
    {$else}
      {$L sqlite3.obj}  // compiled with free Borland C++ Compiler 5.5
       const _PREFIX = '_';  // compiled with modern C++ Builder Free compiler (Clang based)   <------ add this
    {$endif}
  {$else}

This will fix name underscore problem and than maybe compilation will be successful.

#21 Re: mORMot Framework » cannot build sqlite.c » 2019-11-21 07:20:49

zed

In your obj file this functions named as _CodecGetReadKey, _CodecGetWriteKey etc. so this is naming convention problem. Maybe there is missing some compiler switches?

#22 Re: mORMot Framework » cannot build sqlite.c » 2019-11-19 17:28:10

zed

Explain, what is not working for you?

#23 Re: mORMot Framework » cannot build sqlite.c » 2019-11-14 18:58:10

zed

Did you try to use this bat file: https://github.com/synopse/mORMot/blob/ … ite3/c.bat

@echo off

attrib -r sqlite3.obj
del sqlite3.obj

rem set bcc=\dev\bccXE7
set bcc=d:\dev\bcc

%bcc%\bin\bcc32 -6 -Oi -O2 -c -d -u- sqlite3.c

attrib +r sqlite3.obj

pause

or take this (for win64) and adopt it for win32.

#24 Re: mORMot Framework » SynCurl: some minor improvements » 2019-10-27 08:15:25

zed

And now, Delphi (2007, 10.3.2) can't compile this unit because of missing initialization section.

Fix:

initialization
  // empty

finalization
  if PtrInt(curl.Module)>0 then begin
    curl.global_cleanup;
    FreeLibrary(curl.Module);
  end;

#25 mORMot Framework » SynCurl: some minor improvements » 2019-10-22 11:39:26

zed
Replies: 5

1. Add some missing/renamed constants to the TCurlOption: https://github.com/synopse/mORMot/pull/243
Main issue of this constants is to be able to use modern progress callback function (CURLOPT_XFERINFOFUNCTION) as recommended in documentation https://curl.haxx.se/libcurl/c/CURLOPT_ … CTION.html 

2. Let pass libcurl dll name as a parameter: https://github.com/synopse/mORMot/pull/245
I would prefer to use the same library name for Win32 and Win64 versions with my application.

#27 Re: mORMot Framework » CurlIsAvailable: possible bug with multi-thread function call » 2019-10-20 19:16:11

zed

LibCurlInitialize can be refactored with additional variable wich solves the problem. I will create pull request with fix tomorrow.

#28 mORMot Framework » CurlIsAvailable: possible bug with multi-thread function call » 2019-10-20 15:01:57

zed
Replies: 3

I'm talking about this function:

function CurlIsAvailable: boolean;
begin
 try
   if curl.Module=0 then
     LibCurlInitialize;
   result := PtrInt(curl.Module)>0;
 except
   result := false;
 end;
end;

Now, consider situation when thread A and B calls it at same time (library is not initialized yet).

1. Thread A compares  curl.Module with zero and call LibCurlInitialize.
2. Thread A enters into critical section inside LibCurlInitialize and load dll into memory (call LoadLibrary), now curl.Module <> 0
3. Thread A interrupted halfway (no any GetProcAddress called yet) and Thread B start its work
4. Thread B compares curl.Module with zero and return True
5. Thread B try access to the any function (for example, curl.easy_init) and fails with AV!

To fix this bug we need to use temporary variable for library handle instead immediately writing to curl.Module.
curl.Module should be written only at the exit from LibCurlInitialize when initialization is fully complete.

#29 Re: mORMot Framework » TCurlHttp access to curl.easy_setopt » 2019-09-03 12:53:23

zed
  /// low-level libcurl library file name, depending on the running OS
  LIBCURL_DLL = {$ifdef Darwin} 'libcurl.dylib' {$else}
    {$ifdef Linux} 'libcurl.so' {$else} 'libcurl-x64.dll' {$endif}{$endif};

What about Win32 platform? Is it no longer supported?

#31 mORMot Framework » TDynArray.Sort bug » 2019-02-06 08:16:09

zed
Replies: 2

This test case fails on version 1.18.5015:

uses
  mORMot,
  SynCommons;

procedure Test_ArraySorted;
var
  VCount: Integer;
  VArr, VIntArr: TIntegerDynArray;
  VDynArr: TDynArray;
begin
  VDynArr.InitSpecific(TypeInfo(TIntegerDynArray), VIntArr, djInteger, @VCount);

  SetLength(VArr, 1);
  VArr[0] := 1;

  VDynArr.AddArray(VArr);
  VDynArr.Sort;

  Assert(VDynArr.Sorted, 'TDynArray.Sort failed!');
end;

Possible fix (SynCommons.pas):

procedure TDynArray.Sort(aCompare: TDynArraySortCompare);
begin
  if Count <= 1 then
    fSorted := true // array with 0 or 1 element is always sorted
  else
    SortRange(0,Count-1,aCompare);  
end;

#33 Re: mORMot Framework » Created ZIP file is not valid » 2018-07-19 15:56:16

zed

I make some tests and here is 4 Gb file size limitation, not 2. When mORMot needed to write more then 4 Gb data to output file, LongWord type overflow occurs and file truncated to zero.

It would be better if there was an exception with message that Zip file cannot be more than 4 Gb and Zip64 format is not supported.

#34 Re: mORMot Framework » Created ZIP file is not valid » 2018-07-19 15:19:03

zed

Ah, I think it's because resulting file size is > 2Gb. In this case Zip64 format should be used (instead simple Zip format) but mORMot doesn't support it.

#35 Re: mORMot Framework » Created ZIP file is not valid » 2018-07-19 09:35:18

zed

What type of errors shows 7zip?

What shows unzip with -t switch?

#36 mORMot Framework » MongoDB 3.6 require "cursor" in aggregate requests » 2018-06-22 21:29:23

zed
Replies: 1

Calculation EngineLastID (when EngineAddCompute = eacMaxIDEachTime) stopped work in mORMot with MongoDB 3.6 because now mongo require cursor in aggregate requests:

Changed in version 3.6: MongoDB 3.6 removes the use of aggregate command without the cursor option unless the command includes the explain option. Unless you include the explain option, you must specify the cursor option.

To indicate a cursor with the default batch size, specify cursor: {}.

To indicate a cursor with a non-default batch size, use cursor: { batchSize: <num> }.

https://docs.mongodb.com/manual/referen … aggregate/

My pull request with fix: https://github.com/synopse/mORMot/pull/120

#37 Re: mORMot Framework » WebSockets memory usage » 2018-06-16 15:25:00

zed

Did you test it with 500 or 5000 clients?

I'm not sure exactly, but I think that mORMot can use some Thread poll and the dependence of memory usage on the number of clients will not be linear.

#38 Re: mORMot Framework » WebSockets memory usage » 2018-06-16 15:02:37

zed

Each Thread use 1 Mb of RAM to its stack, so if mORMot use one Thread per client there is no surprise.
https://msdn.microsoft.com/en-us/librar … s.85).aspx

#39 Re: mORMot Framework » Pattern match failed » 2018-02-23 21:52:06

zed

Ok, now it's work. Thank you!

#40 Re: mORMot Framework » Pattern match failed » 2018-02-23 19:19:26

zed

Yes, it helps.

But here is a new fail:

Assert(not IsMatch('ab[cd]e', 'abdde', False)); // ok
Assert(not IsMatch('ab[cd]ex', 'abddex', False)); // ok

Assert(not IsMatch('ab*.[cd]e', 'ab.dde', False)); // ok
Assert(not IsMatch('ab*.[cd]ex', 'ab.ddex', False)); // fail

#41 mORMot Framework » Pattern match failed » 2018-02-22 19:34:27

zed
Replies: 11

Test code:

IsMatch('ab*.[ef]xyz', 'ab.exyz', True);
IsMatch('ab*.[ef]xyz', 'abcd.exyz', True);
IsMatch('ab*.[ef]xyz', 'ab.fxyz', True);
IsMatch('ab*.[ef]xyz', 'abcd.fxyz', True);

all failed!

mORMot version: 1.18.4332.
Compiler: Delphi 2007.

#42 Re: mORMot Framework » Decrypt results differ for Win32 and Win64 (Delphi 10.2) » 2017-12-17 13:18:30

zed

ertank
Bug in this expression in your code: string(KeyPC)

To get Key as a string, use this code:

function GetKey: string;
const
  KeyPC: array of Char = [
    #00,  #101, #02,  #03,  #40,  #05,  #106, #07,
    #08,  #09,  #07,  #100, #110, #201, #117, #45,
    #10,  #11,  #12,  #13,  #140, #150, #160, #170,
    #13,  #1,   #17,  #130, #40,  #16,  #106, #70,
    #180, #190, #174, #200, #0,   #1,   #11,  #15,
    #80,  #91,  #72,  #130, #101, #111, #107, #45
  ];
var
  I: Integer;
begin
  SetLength(Result, Length(KeyPC));
  for I := 0 to Length(KeyPC) - 1 do begin
    Result[I+1] := KeyPC[I];
  end;
end;

#43 Re: mORMot Framework » FastFindInt64Sorted hangs on 32-bit build » 2017-11-20 15:10:42

zed

Fix:

function FastFindInt64Sorted(P: PInt64Array; R: PtrInt; const Value: Int64): PtrInt; overload;
var L: PtrInt;
    cmp: Integer;
begin
  L := 0;
  if 0<=R then
  repeat
    result := (L + R) shr 1;
    {$ifdef CPUX86} // circumvent Int64 comparison slowness
    cmp := SortDynArrayInt64(P^[result],Value);
    if cmp=0 then
      exit else
    if cmp<0 then
    {$else}
    if P^[result]=Value then
      exit else
    if P^[result]<Value then
    {$endif}
      L := result + 1 else
      R := result - 1;
  until (L > R);
  result := -1
end;

#44 mORMot Framework » FastFindInt64Sorted hangs on 32-bit build » 2017-11-20 14:59:28

zed
Replies: 2

Test code:

uses
  SysUtils,
  mORMot,
  SynCommons;

procedure DoTest;
var
  I, J: Integer;
  VLen: Integer;
  VArr: TIDDynArray;
begin
  VLen := 3;
  SetLength(VArr, VLen);
  for I := 0 to VLen - 1 do begin
    VArr[I] := I;
  end;
 J := FastFindInt64Sorted(PInt64Array(VArr), VLen-1, 2); // <-- hangs
end;

Previous worked version FastFindInt64Sorted:

function FastFindInt64Sorted(P: PInt64Array; R: PtrInt; const Value: Int64): PtrInt; overload;
var L: PtrInt;
    cmp: Int64;
begin
  L := 0;
  if 0<=R then
  repeat
    result := (L + R) shr 1;
    cmp := P^[result]-Value;
    if cmp=0 then
      exit;
    if cmp<0 then
      L := result + 1 else
      R := result - 1;
  until (L > R);
  result := -1
end;

Current, bugged version (infinite loop):

function FastFindInt64Sorted(P: PInt64Array; R: PtrInt; const Value: Int64): PtrInt; overload;
var L: PtrInt;
begin
  L := 0;
  if 0<=R then
  repeat
    result := (L + R) shr 1;
    {$ifdef CPUX86} // circumvent Int64 comparison slowness
    result := SortDynArrayInt64(P^[result],Value);
    if result=0 then
      exit else
    if result <0 then
    {$else}
    if P^[result]=Value then
      exit else
    if P^[result]<Value then
    {$endif}
      L := result + 1 else
      R := result - 1;
  until (L > R);
  result := -1
end;

I use Delphi 10.2 and x86 build for test.

#45 Re: mORMot Framework » WinHTTP, http.sys and WebSockets » 2017-11-14 14:19:43

zed
mpv wrote:
EMartin wrote:

Just for curiosity, why not just to use a function for readonly access in https://synopse.info/fossil/info/1ff1e5b5c276dcb5 ?

Indeed: see [6b4cc8c]. Thanks!

And function with 1 line of code should be marked as inline if it's possible.

#46 Re: mORMot Framework » Default Winhttp proxy modification request » 2017-08-16 16:46:42

zed

Option WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY replases WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, but not WINHTTP_ACCESS_TYPE_NO_PROXY!

So, if you want to change behavor when fProxyName is empty, you should use WINHTTP_ACCESS_TYPE_DEFAULT_PROXY for windows version < 8.1:

if (OSVersionInfo.dwMajorVersion>=6) and (OSVersionInfo.dwMinorVersion>=3) then
  OpenType := WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY else // Windows 8.1 and newer
    OpenType := WINHTTP_ACCESS_TYPE_DEFAULT_PROXY else // Windows 8 and older
OpenType := WINHTTP_ACCESS_TYPE_NAMED_PROXY;

#47 Re: mORMot Framework » [fixed] The datetime column of Server log suddenly becomes unreadable » 2017-02-07 09:44:54

zed

Use this option:

TSynLog.Family.HighResolutionTimeStamp := False;

#49 Re: mORMot Framework » Bug with parsing JSON array of double in TDocVariantData » 2017-02-02 08:48:44

zed

Oh, I found this breaking change commit: https://github.com/synopse/mORMot/commi … 3aec5db617 is it really so necessary to make this change? Have you some bugs without it? Because with it we definitely have a bugs. I hope you will revert it and set param AllowVarDouble to True by default.

And I think that is not obvious behavior, processing numbers with 4 digits after dot as a doubles, but with 5 digits as a strings. By default, behavior must be consistent.

#50 Re: mORMot Framework » Bug with parsing JSON array of double in TDocVariantData » 2017-02-02 07:14:11

zed

I propose return old behavior (process double values by default) and revert option dvoAllowDoubleValue to dvoDontAllowDoubleValue and use it in all places where you need strings.

Board footer

Powered by FluxBB