#1 Re: mORMot 1 » Case insensitive sql like function » 2016-03-05 18:29:48

but it seems to me that this has no effect on the behavior of the LIKE operator, and it can only be changed by modifying the database engine

#2 Re: mORMot 1 » Case insensitive sql like function » 2016-03-04 19:32:11

I had a similar problem with Polish letters. I solved this by modifying sqlite3.c - I extend sqlite3UpperToLower array (to handle all Polish characters just add about 120 items) and changed:


# define GlobUpperToLower(A)   if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }

to:

# define GlobUpperToLower(A)   if( !((A)&~0x17f) ){ A = sqlite3UpperToLower[A]; }

previously I had such a solution like this:

static u32 tryPolishLetters(u32 A) {
    switch(A) {        
        case 0x17B: // Ż
            return 0x17C;
        case 0x179: // Ź
            return 0x17A;
        case 0x15A: // Ś
            return 0x15B;
        case 0xD3:  // Ó
            return 0xF3;
        case 0x143: // Ń
            return 0x144;
        case 0x141: // Ł
            return 0x142;
        case 0x118: // Ę
            return 0x119;
        case 0x106: // Ć
            return 0x107;
        case 0x104: // Ą
            return 0x105;
    }
    return A;
}

#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A)    (*((*A)++))
# define GlobUpperToLower(A)   A = sqlite3UpperToLower[A]
#else
# define GlobUpperToLower(A)   if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; } else { A = tryPolishLetters(A); }
#endif

but i think the first is better.

It may not be the best solution, but it works smile

#3 Re: mORMot 1 » I do not know how to use setWeak » 2015-06-28 10:09:09

I changed to something like that ("LocalVariable" should be released at the exit of FillList), but still there is an error:

procedure FillList(const AList: TList<IParent>);
var
    parent: IParent;
    child: IChild;
begin
    parent := TParent.Create;
    AList.Add(parent);
    child := TChild.Create(parent);
    parent.getChildList.Add(child);
end;

var
    list: TList<IParent>;
begin
    FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true;

    list := TList<IParent>.Create;
    FillList(list);
    list.Free; // BOOM
end.
---------------------------
Project1.exe: Memory Error Detected
---------------------------
FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed. 

Modified byte offsets (and lengths): 12(3)

The previous block size was: 24

This block was previously allocated by thread 0x2B98, and the stack trace (return addresses) at the time was:
406A0A [System.pas][System][@GetMem$qqri][4351]
408A77 [System.pas][System][TObject.NewInstance$qqrv][15578]
40E191 [System.pas][System][TInterfacedObject.NewInstance$qqrv][36448]
4091A6 [System.pas][System][@ClassCreate$qqrpvzc][16888]
5DBB6E [Project1.dpr][Project1][TChild.$bctr$qqrx44System.%DelphiInterface$t16Project1.IParent%][64]
5E2D40 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.Add$qqrx44System.%DelphiInterface$t16Project1.IParent%][845]
5DBC05 [Project1.dpr][Project1][FillList$qqrxp85System.Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%][76]
5E72B3 
76D2337A [BaseThreadInitThunk]
772592B2 [Unknown function at RtlInitializeExceptionChain]
77259285 [Unknown function at RtlInitializeExceptionChain]

The block was previously used for an object of class: TChild

The allocation number was: 384

The block was previously freed by thread 0x2B98, and the stack trace (return addresses) at the time was:
406A26 [System.pas][System][@FreeMem$qqrpv][4399]
408A95 [System.pas][System][TObject.FreeInstance$qqrv][15587]
5D9D92 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][49750]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
408B8E [System.pas][System][TObject.$bdtr$qqrv][15647]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E1D05 [Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.DeleteRange$qqrii]
2579336 [GetRawStackTrace]
5E0F3C [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCount$qqri][675]
5E0EBA [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCapacity$qqri][664]
5E1403 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.$bdtr$qqrv][817]
408B9B [System.pas][System][TObject.Free$qqrv][15655]
5DBB20 [Project1.dpr][Project1][TParent.$bdtr$qqrv][52]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E34E9 [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5E2720 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5E269E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5E2BE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]
408B9B [System.pas][System][TObject.Free$qqrv][15655]

The current thread ID is 0x2B98, and the stack trace (return addresses) leading to this error is:
41335A [FastMM4.pas][FastMM4][InternalScanMemoryPool$qqruiui][9109]
413435 [FastMM4.pas][FastMM4][ScanMemoryPoolForCorruptions$qqrv][9183]
412F67 [FastMM4.pas][FastMM4][DebugFreeMem$qqrpv][8852]
406A26 [System.pas][System][@FreeMem$qqrpv][4399]
40CBDA [System.pas][System][@DynArrayClear$qqrrpvpv][34241]
40C03E [System.pas][System][@FinalizeArray$qqrpvt1ui][31517]
40BF1D [System.pas][System][@FinalizeRecord$qqrpvt1][31189]
408C13 [System.pas][System][TObject.CleanupInstance$qqrv][15792]
408A8E [System.pas][System][TObject.FreeInstance$qqrv][15586]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5D9B5F [mORMot.pas][mORMot][TSetWeakZeroInstance.$bdtr$qqrv][49690]
408B9B [System.pas][System][TObject.Free$qqrv][15655]
52D424 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqri][42486]
52D465 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqrp14System.TObject][42493]
5D9D68 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][49746]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5DBB3C [Project1.dpr][Project1][TParent.$bdtr$qqrv][54]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E34E9 [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5E2720 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5E269E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5E2BE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]

Current memory dump of 256 bytes starting at pointer address 7EF127C0:
88 52 5F 00 7C 55 5F 00 7C 55 5F 00 00 00 00 00 7C 55 5F 00 7C 55 5F 00 14 55 8B 0F 7C 55 5F 00
7C 55 5F 00 7C 55 5F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ˆ  R  _  .  |  U  _  .  |  U  _  .  .  .  .  .  |  U  _  .  |  U  _  .  .  U  ‹  .  |  U  _  .
|  U  _  .  |  U  _  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

---------------------------
OK   
---------------------------

#4 Re: mORMot 1 » I do not know how to use setWeak » 2015-06-27 13:18:32

I tested on version 1.18 and the latest from github

#5 Re: mORMot 1 » I do not know how to use setWeak » 2015-06-27 00:00:02

And in this example I have a out of memory

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
    FastMM4,
  System.SysUtils,
  Generics.Collections,
  mORMot, SynCommons;

type
    IParent = interface;

    IChild = interface
    ['{B71BD1C3-CE4C-438A-8090-DA6AACF0B3C4}']
    end;

    TChild = class(TInterfacedObject, IChild)
    private
        _parent: IParent;
    public
        Constructor Create(const AParent: IParent);
    end;

    IParent = interface
    ['{3C02359E-D6DA-40E0-A12E-30B239DA7D9F}']
        function getChildList: TList<IChild>;
    end;

    TParent = class(TInterfacedObject, IParent)
    private
        _childList: TList<IChild>;
    public
        Constructor Create;
        destructor Destroy; override;

        function getChildList: TList<IChild>;
    end;

{ TParent }

constructor TParent.Create;
begin
    inherited Create;
    _childList := TList<IChild>.Create;
end;

destructor TParent.Destroy;
begin
    _childList.Free;
    inherited;
end;

function TParent.getChildList: TList<IChild>;
begin
    Result := _childList;
end;

{ TChild }

constructor TChild.Create(const AParent: IParent);
begin
    inherited Create;
    SetWeak0(@_parent, AParent);
end;

var
    list: TList<IParent>;
    parent: IParent;
    child: IChild;
begin
    FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true;

    list := TList<IParent>.Create;
    parent := TParent.Create;
    list.Add(parent);
    child := TChild.Create(parent);
    parent.getChildList.Add(child);
    parent := nil;
    child := nil;

    list.Free; // BOOM

end.
---------------------------
Project1.exe: Memory Error Detected
---------------------------
FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed. 



Modified byte offsets (and lengths): 12(3)



The previous block size was: 24



This block was previously allocated by thread 0x9720, and the stack trace (return addresses) at the time was:

406A0E [System.pas][System][@GetMem$qqri][4351]

40848B [System.pas][System][TObject.NewInstance$qqrv][15578]

40DFC9 [System.pas][System][TInterfacedObject.NewInstance$qqrv][36448]

408BBA [System.pas][System][@ClassCreate$qqrpvzc][16888]

5F2EF6 [Project1.dpr][Project1][TChild.$bctr$qqrx44System.%DelphiInterface$t16Project1.IParent%][64]

5FC624 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.Add$qqrx44System.%DelphiInterface$t16Project1.IParent%][845]

600598 

75CD337A [BaseThreadInitThunk]

778692B2 [Unknown function at RtlInitializeExceptionChain]

77869285 [Unknown function at RtlInitializeExceptionChain]



The block was previously used for an object of class: TChild



The allocation number was: 301



The block was previously freed by thread 0x9720, and the stack trace (return addresses) at the time was:

406A2A [System.pas][System][@FreeMem$qqrpv][4399]

4084A9 [System.pas][System][TObject.FreeInstance$qqrv][15587]

5F114A [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][39469]

408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]

4085A2 [System.pas][System][TObject.$bdtr$qqrv][15647]

40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]

40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]

40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]

40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]

5FB5E9 [Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.DeleteRange$qqrii]

2869336 [GetRawStackTrace]

5FA820 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCount$qqri][675]

5FA79E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCapacity$qqri][664]

5FACE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.$bdtr$qqrv][817]

4085AF [System.pas][System][TObject.Free$qqrv][15655]

5F2EA8 [Project1.dpr][Project1][TParent.$bdtr$qqrv][52]

40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]

40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]

40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]

40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]

5FCDCD [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]

5FC004 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]

5FBF82 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]

5FC4CB [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]

4085AF [System.pas][System][TObject.Free$qqrv][15655]



The current thread ID is 0x9720, and the stack trace (return addresses) leading to this error is:

414EFE [FastMM4.pas][FastMM4][InternalScanMemoryPool$qqruiui][9109]

414FD9 [FastMM4.pas][FastMM4][ScanMemoryPoolForCorruptions$qqrv][9183]

414B0B [FastMM4.pas][FastMM4][DebugFreeMem$qqrpv][8852]

406A2A [System.pas][System][@FreeMem$qqrpv][4399]

40C8DA [System.pas][System][@DynArrayClear$qqrrpvpv][34241]

40BD1E [System.pas][System][@FinalizeArray$qqrpvt1ui][31517]

40BBFD [System.pas][System][@FinalizeRecord$qqrpvt1][31189]

408627 [System.pas][System][TObject.CleanupInstance$qqrv][15792]

4084A2 [System.pas][System][TObject.FreeInstance$qqrv][15586]

408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]

5F0F23 [mORMot.pas][mORMot][TSetWeakZeroInstance.$bdtr$qqrv][39408]

4085AF [System.pas][System][TObject.Free$qqrv][15655]

574D10 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqri][36443]

574D51 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqrp14System.TObject][36450]

5F1120 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][39465]

408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]

5F2EC4 [Project1.dpr][Project1][TParent.$bdtr$qqrv][54]

40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]

40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]

40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]

40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]

5FCDCD [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]

5FC004 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]

5FBF82 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]

5FC4CB [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]



Current memory dump of 256 bytes starting at pointer address 7EF88BF0:

8C E2 60 00 80 E5 60 00 80 E5 60 00 00 00 00 00 80 E5 60 00 80 E5 60 00 87 53 DF 0F 80 E5 60 00

80 E5 60 00 80 E5 60 00 00 00 00 00 81 8F F8 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

83 01 00 00 0E 6A 40 00 DF A1 40 00 6C A6 40 00 67 B4 40 00 E2 11 5F 00 8B 14 5F 00 01 15 5F 00

1A 2F 5F 00 98 05 60 00 7A 33 CD 75 B2 92 86 77 85 92 86 77 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 20 97 00 00 20 97 00 00 2A 6A 40 00 FE A2 40 00 54 12 5F 00 8B 14 5F 00

01 15 5F 00 1A 2F 5F 00 98 05 60 00 7A 33 CD 75 B2 92 86 77 85 92 86 77 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Ś  â  `  .  €  ĺ  `  .  €  ĺ  `  .  .  .  .  .  €  ĺ  `  .  €  ĺ  `  .  ‡  S  ß  .  €  ĺ  `  .

€  ĺ  `  .  €  ĺ  `  .  .  .  .  .    Ź  ř  ~  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

ƒ  .  .  .  .  j  @  .  ß  ˇ  @  .  l  ¦  @  .  g  ´  @  .  â  .  _  .  ‹  .  _  .  .  .  _  .

.  /  _  .  ˜  .  `  .  z  3  Í  u  ˛  ’  †  w  …  ’  †  w  .  .  .  .  .  .  .  .  .  .  .  .

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

.  .  .  .  .  .  .  .     —  .  .     —  .  .  *  j  @  .  ţ  ˘  @  .  T  .  _  .  ‹  .  _  .

.  .  _  .  .  /  _  .  ˜  .  `  .  z  3  Í  u  ˛  ’  †  w  …  ’  †  w  .  .  .  .  .  .  .  .

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .


---------------------------
OK   
---------------------------

I can not find where the bug is sad

#6 mORMot 1 » I do not know how to use setWeak » 2015-06-26 20:40:25

pszawa
Replies: 5

Hi,

I have a problem with SetWeak. I have a parent who has a children list. I did something similar to this example, but then there were problems with the memory. It seems to me that  problem occurs after  calling TDynArrayHashed.ReHash.
In this example, when you call CreateStructure with ANumber = 243, then everything is ok. With ANumber = 244 TParent.FRefCount becomes smaller than zero.

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Generics.Collections,
  mORMot, SynCommons;

type
    IParent = interface;

    IChild = interface
    ['{B71BD1C3-CE4C-438A-8090-DA6AACF0B3C4}']
    end;

    TChild = class(TInterfacedObject, IChild)
    private
        _parent: IParent;
    public
        Constructor Create(const AParent: IParent);
    end;

    IParent = interface
    ['{3C02359E-D6DA-40E0-A12E-30B239DA7D9F}']
        function getChildList: TList<IChild>;
    end;

    TParent = class(TInterfacedObject, IParent)
    private
        _childList: TList<IChild>;
    public
        Constructor Create;
        destructor Destroy; override;

        function getChildList: TList<IChild>;
        function _Release: Integer; stdcall;
    end;

{ TParent }

constructor TParent.Create;
begin
    inherited Create;
    _childList := TList<IChild>.Create;
end;

destructor TParent.Destroy;
begin
    _childList.Free;
    inherited;
end;

function TParent.getChildList: TList<IChild>;
begin
    Result := _childList;
end;

function TParent._Release: Integer;
begin
  Result := AtomicDecrement(FRefCount);
  if Result = 0 then
    Destroy
  else if Result < 0 then
    raise Exception.Create('Something goes wrong');
end;

{ TChild }

constructor TChild.Create(const AParent: IParent);
begin
    inherited Create;
    SetWeak0(@_parent, AParent);
end;

procedure CreateStructure(const ANumber: integer);
var
    i: integer;
    parent: IParent;
    child: IChild;
    list: TList<IParent>;
begin
    list := TList<IParent>.Create;
    for i := 0 to ANumber - 1 do
    begin
        parent := TParent.Create;
        child := TChild.Create(parent);

        parent.getChildList.Add(child);
        list.Add(parent);
    end;
    parent := nil;
    child := nil;
    list.Free;
end;

begin
    try
      CreateStructure(244); // 243 is ok
    except
    on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
end.

What am I doing wrong?

#7 Re: mORMot 1 » Local and remote database » 2014-06-13 14:53:53

It's super, that is, on the client side I do not need a server.
It's even better than I thought.

Thank you for your help.
I am very pleased that when I started my project I chose mORMot. smile

#8 Re: mORMot 1 » Local and remote database » 2014-06-13 11:49:34

Yes, I have version 1.18

I checked the samples and on the basis of samples implemented the services. However, in the samples is always communication Client - HTTPClient - HTTPServer - Server and I would like to be able to skip HTTP.
The connection to the remote server works very well, but the problem I have when I want to do a local version.

Example project:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus,
  Vcl.StdCtrls, cxButtons, SynCommons, mORMotdb, SynDB, mORMot, mORMotSqlite3, SynSQLite3Static;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure Run;
  public
    { Public declarations }
  end;

  IMyServices = interface(IInvokable)
    ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
    function Add(n1,n2: integer): integer;
  end;

  TMyServices = class(TInterfacedObject, IMyServices)
    public
        function Add(n1,n2: integer): integer;
  end;
var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyServices }

function TMyServices.Add(n1, n2: integer): integer;
begin
    Result := n1+n2;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    run;
end;

procedure TForm1.Run;
var
    server: TSQLRestServerDB;
    services: IMyServices;
    client: TSQLRestClientDB;
    model: TSQLModel;
begin
    model := TSQLModel.Create([]);
    server := TSQLRestServerDB.Create(model, 'db.db');
    server.ServiceRegister(TMyServices, [TypeInfo(IMyServices)], sicClientDriven);
    client := TSQLRestClientDB.Create(model, nil, server.DB, TSQLRestServerDB);
    client.ServiceRegisterClientDriven(TypeInfo(IMyServices),services); // booom
    client.SetUser('User','synopse');
end;

end.

#9 mORMot 1 » Local and remote database » 2014-06-13 10:45:54

pszawa
Replies: 5

Hi,

my program is available in two versions - with a local database and remote.

In the main application, it would look something like this:

{$IFDEF DBHTTP}
 _client := TSQLHttpClient.Create('server.com','7878',_model);
{$ELSE}
_server := TSQLRestServerDB.Create(_model, _pathToDb);
_server.ServiceRegister(TMyServices, [TypeInfo(IMyServices)], sicClientDriven);

_client := TSQLRestClientDB.Create(_model, nil, _server.DB, TSQLRestServerDB);
 {$ENDIF}

_client.ServiceRegisterClientDriven(TypeInfo(IMyServices), _myServices);
_model.Owner := _client;

only that there is a problem when I try to register IMyServices:

---------------------------
Debugger Exception Notification
---------------------------
Project App.exe raised exception class ESQLite3Exception with message 'near "[]": syntax error'.
---------------------------
Break   Continue   Help   
---------------------------

:76e6c42d KERNELBASE.RaiseException + 0x58
:006c26e6 HookedRaiseException + $66
SynSQLite3.sqlite3_check(95735112,1)
SynSQLite3.TSQLRequest.Prepare(95735112,'[]')
SynSQLite3.TSQLRequest.ExecuteAll(95735112,'[]')
SynSQLite3.TSQLDatabase.ExecuteAll('[]')
mORMotSQLite3.TSQLRestServerDB.EngineExecuteAll('[]')
mORMot.TSQLRestServerURIContext.ExecuteORMWrite
mORMot.TSQLRestServerURIContext.Execute(execORMWrite)
mORMot.TSQLRestServer.URI($18F683)
mORMotSQLite3.TSQLRestClientDB.InternalURI($18F683)
mORMot.TSQLRestClientURI.URI('root/MyServices._contract_','POST',$18F75C {''},$18F758 {''},$18F760 {'[]'})
mORMot.TServiceFactoryClient.InternalInvoke('_contract_','',$18F7DC {''},$18F7E0 {''},nil,nil)
mORMot.TServiceFactoryClient.Create($54AE4A0,$1009B88,sicClientDriven,'')
mORMot.TServiceContainer.AddInterface($1009B88,sicClientDriven,'')
mORMot.TSQLRestClientURI.ServiceRegister($1009B88,sicClientDriven,'')
mORMot.TSQLRestClientURI.ServiceRegisterClientDriven($1009B88,(no value),'')

How do I resolve this issue? I do not want to run a local HTTP server, because this is a drop in performance were unnecessary.

#10 mORMot 1 » TDocVariant and external DLL » 2014-06-05 11:53:18

pszawa
Replies: 1

Is it possible that external DLL return JSON object (TDocVariant)?
At this moment I get an exception ESynException: Unhandled variant type 271.
I noticed that SynRegisterCustomVariantType method is called twice (once by the DLL and once by the main program, I presume) and once the returned value is VarType = 271 and the second time the VarType = 274.

Can it be solved somehow?

Board footer

Powered by FluxBB