#1 Re: mORMot 2 » MORMOT2 license in simple way? » 2023-06-24 09:56:57

zed

Read the link from my previous post, it answers to all your questions.

#2 Re: mORMot 2 » MORMOT2 license in simple way? » 2023-06-24 06:07:50

zed

MPL/GPL/LGPL Three-License

The framework is licensed under a disjunctive three-license giving you the choice of one of the three following sets of free software/open source licensing terms:

    Mozilla Public License, version 1.1 or later;
    GNU General Public License, version 2.0 or later;
    GNU Lesser General Public License, version 2.1 or later.

This allows the use of our code in as wide a variety of software projects as possible, while still maintaining copy-left on code we wrote. See the full licensing terms.

https://github.com/synopse/mORMot2/blob … LICENCE.md

#3 Re: mORMot 1 » How to change collation in an existing database? » 2023-03-14 06:27:11

zed

In SQLiteStudio you can define your own collation (Tools - Open collations editor) and open DB as usual.

1678775092.png


For the SYSTEMNOCASE you can try this snippet:

function system_nocase(a, b)
{   
    a = a.toUpperCase();
    b = b.toUpperCase();

    return (a < b ? -1 : (a > b ? 1 : 0));  
}

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

zed

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

#5 Re: mORMot 1 » 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

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

zed

libcurl backend supports http2.

#9 Re: mORMot 1 » 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.

#10 Re: mORMot 1 » No support for trigram FTS5 tokenizer added in SQLit3.34.0(2020-12-01) » 2020-12-22 09:02:01

zed

Do you link with sqlite3.dll or with SynSQLite3Static.pas?

#11 mORMot 1 » 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.

#12 Re: mORMot 1 » 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.

#13 Re: mORMot 1 » 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()

#14 Re: mORMot 1 » 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).

#15 mORMot 1 » 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)?

#16 Re: mORMot 1 » Fast MM5 » 2020-05-05 18:21:20

zed

Is this topic still about FastMM5?

#17 Re: mORMot 1 » 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.

#18 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.

#20 Re: mORMot 1 » 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).

#21 Re: mORMot 1 » 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

#22 Re: mORMot 1 » 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.

#23 Re: mORMot 1 » 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.

#24 Re: mORMot 1 » 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?

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

zed

Explain, what is not working for you?

#26 Re: mORMot 1 » 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.

#27 Re: mORMot 1 » 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;

#28 mORMot 1 » 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.

#30 Re: mORMot 1 » 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.

#31 mORMot 1 » 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.

#32 Re: mORMot 1 » 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?

#34 mORMot 1 » 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;

#36 Re: mORMot 1 » 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.

#37 Re: mORMot 1 » 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.

#38 Re: mORMot 1 » 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?

#39 mORMot 1 » 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

#40 Re: mORMot 1 » 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.

#41 Re: mORMot 1 » 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

#42 Re: mORMot 1 » Pattern match failed » 2018-02-23 21:52:06

zed

Ok, now it's work. Thank you!

#43 Re: mORMot 1 » 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

#44 mORMot 1 » 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.

#45 Re: mORMot 1 » 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;

#46 Re: mORMot 1 » 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;

#47 mORMot 1 » 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.

#48 Re: mORMot 1 » 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.

#49 Re: mORMot 1 » 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;

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

zed

Use this option:

TSynLog.Family.HighResolutionTimeStamp := False;

Board footer

Powered by FluxBB