#551 Re: mORMot 1 » XE4 and FireMonkey » 2014-06-26 09:48:43

Just as Addon concerning 0-Based Indexes:

The XE6 Debugger ignores the 0-Base and shows the Content of e.g. String-Buffers with 1 Based Index

I really don't like that 0-Base feature of Embacadero

#552 Re: mORMot 1 » XE4 and FireMonkey » 2014-06-25 11:33:50

I see you use this Compiler OPTION. In some other Part of my Software i didn't use it and got an error which i fixed as decribed in my former Post.

http://docwiki.embarcadero.com/RADStudi … s_(Delphi)

as decribed here it should not be used as global define only at little Subroutines.

#553 Re: mORMot 1 » XE4 and FireMonkey » 2014-06-25 10:32:27

Im just testing NEXTGEN Code with iOS and found a big Problem concerning:

http://docwiki.embarcadero.com/RADStudi … sktop_Apps

0-based index

procedure DoubleQuoteStr(var text: string);
var i,j: integer;
    tmp: string;
begin
{$if CompilerVersion < 27)}
  i := pos('"',text);
  if i=0 then begin
    text := '"'+text+'"';
    exit;
  end;
  tmp := '"'+copy(text,1,i)+'"';
  for j := i+1 to length(text) do
    if text[j]='"' then
      tmp := tmp+'""' else
      AppendChar(tmp,text[j]);
{$else}
  i := text.indexof('"');
  if i < 0 then begin
    text := '"'+text+'"';
    exit;
  end;
  inc(i);
  tmp := '"'+text.Substring(0,i)+'"';
  for j := i+1 to text.Length - 1 do
    if text.Chars[j] = '"' then
      tmp := tmp + '""'
    else
      tmp := tmp + text.Chars[j];
{$ifend}
  text := tmp+'"';
end;

i just rewrote this func as Example, but there a lot lines of code where you assume s[1] = s[1] but it is s[0] smile

br Stefan

#554 mORMot 1 » Correct way to Connect HttpServer to MySQL » 2014-06-18 11:27:11

itSDS
Replies: 1

Hi Arnaud,

I just want to switch from SQLite to MySQL in my REST - Server.

I wrote this code, but I'm not Sure if it is correct to pass a SQLITE_MEMORY_DATABASE_NAME to TSQLRestServerDB.Create as i did.

  Model1 := CreateModel1;
  Model2 := CreateModel2;
  fConnection := TSQLDBUniDACConnectionProperties.Create(TSQLDBUniDACConnectionProperties.URI(dMySQL,'localhost:3306'),'test','root','');
  VirtualTableExternalRegisterAll(Model1, fConnection);
  VirtualTableExternalRegisterAll(Model2, fConnection);
  SQLDB1 := TSQLDatabase.Create(SQLITE_MEMORY_DATABASE_NAME,'');
//  SQLDB1.UseCache := True;
  Model1DB := TSQLRestServerDB.Create(Model1,lSQLDB,false);
  Model1DB.CreateMissingTables(0);
  SQLDB2 := TSQLDatabase.Create(SQLITE_MEMORY_DATABASE_NAME,'');
//  SQLDB2.UseCache := True;
  Model2DB := TSQLRestServerDB.Create(TSJobsDataModel,jSQLDB,false);
  Model2.CreateMissingTables(0);
  Server := TSQLHttpServer.Create('8080',[Model1DB, Model2DB],'+',useHttpApiRegisteringURI, 32, secNone);
  Server.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries

Can you please look at this code an optimize it ?

#556 Re: mORMot 1 » Could you help to comment on the Brook framework ? » 2014-06-01 09:04:39

From my Third Person Point of view i Realy can't See any Reason why Arnaud should spent Time in brook or is anyone else here who is in Need of mormot to brook Support ?

#557 Re: mORMot 1 » Could you help to comment on the Brook framework ? » 2014-05-30 08:58:12

I read your discussion, and just wan't to say something to prevent you all running in the wrong direction.
I'm writing Software for a long period of time now and use Delphi since Version 3

As you all know the prefered systems of the most clients in the world are Windows, Android, iOS, i don't know anyone who is using LINUX in practice.
May be I'm wrong but if you think as me you'll recognize that the mORMot System is optimal an does not really need fpc support.
But the CrossPlatform is very important to write Clients for mORMot.

I think come's time and the errors AB recognized in FPC are fixed, then its time to write on FPC if there is any who really is in need of it.

I personally don't need FPC support. And i don't need Brook atm smile

#559 Re: mORMot 1 » New sample for JSON performance: mORMot vs SuperObject/dwsJSON/DBXJSON » 2014-05-27 20:35:35

Very good work. I put it in one of my Programs instead of JSON unit. And works fine.

ATM i have a Problem with the German Umlaute: öäüßÖÄÜ

I store them in a TDocVariant on the Server. Retrieve it with TSQLRecord. But after Loading the TDocVariant Field into TJSONVariantData with Init.
The ä has changed to : ä

It seems the ä is converted to UTF8 Representation of ä but after loading the UTF8 representation ist converted to Single Unicode Chars.

Can you give me a clue how to deal best with this ?
Should i Convert the "umlaute" to something else like &auml# or do you have something in your lib ?

#560 Re: mORMot 1 » Support for a TGUID field » 2014-05-21 11:36:45

I tested TGUID - Custom Property again today. The Exception still exists.
I think there must something be changed in TSQLRecordProperties.Create
The function AddParentsFirst throws an Exception cause of the GUID - Field before the Function InternalRegisterCustomProperties is called.

In my opinion custom properties should be made available and then you should create the field - List.

Hopefully you understand what i mean smile

#561 mORMot 1 » Missing 'd' in mormot.pas » 2014-05-20 12:07:55

itSDS
Replies: 1

line 13898

    raise EORMException.CreateFmt('Unhandled %s/%s type for property %s',

#562 Re: mORMot 1 » A suggestion - use more blank lines » 2014-05-20 09:43:45

Hi Edwin,

i think every Developer has its own style. If i want to read Arnauds code i use the feature of Rad Studio to reformat the Sourcecode.

#563 Re: mORMot 1 » New sample for JSON performance: mORMot vs SuperObject/dwsJSON/DBXJSON » 2014-05-18 10:40:16

Hardware: Macbook Pro (i7-2.8GHz) with Windows 8.1 in VMWare VM

32Bit DEBUG

   JSON benchmarking
  -------------------


1. Small content

 1.1. Synopse record:
  - Read: 50,000 assertions passed  172.87ms  289,231/s
  - Access: 100,000 assertions passed  914us  54,704,595/s
  - Write: 50,000 assertions passed  113.53ms  440,381/s
  Total failed: 0 / 200,000  - Synopse record PASSED  288.73ms

 1.2. Synopse variant:
  - Read: 50,000 assertions passed  260.27ms  192,101/s
  - Access direct: 100,000 assertions passed  52.18ms  958,184/s
  - Access late binding: 100,000 assertions passed  163.41ms  305,971/s
  - Write: 50,000 assertions passed  172.68ms  289,541/s
  Total failed: 0 / 300,000  - Synopse variant PASSED  651.15ms

 1.3. X super object record:
  - Read: 50,000 assertions passed  20.66s  2,419/s
  - Access: 100,000 assertions passed  911us  54,884,742/s
  - Write: 50,000 assertions passed  4.03s  12,400/s
  Total failed: 0 / 200,000  - X super object record PASSED  24.69s

 1.4. X super object properties:
  - Read: 50,000 assertions passed  16.30s  3,067/s
  - Access: 100,000 assertions passed  585.54ms  85,390/s
  - Write: 50,000 assertions passed  782.88ms  63,866/s
  Total failed: 0 / 200,000  - X super object properties PASSED  17.67s

 1.5. dws JSON:
  - Read: 50,000 assertions passed  308.65ms  161,993/s
  - Access: 100,000 assertions passed  77.20ms  647,626/s
  - Write: 50,000 assertions passed  312.43ms  160,031/s
  Total failed: 0 / 200,000  - dws JSON PASSED  700.71ms

 1.6. DBXJSON:
  - Read: 50,000 assertions passed  3.79s  13,161/s
  - Access: 100,000 assertions passed  41.85ms  1,194,486/s
  - Write: 50,000 assertions passed  566.02ms  88,335/s
  Total failed: 0 / 200,000  - DBXJSON PASSED  4.40s


2. Big content

 2.1. Depth content:
  - Download files if necessary: no assertion  781us
  - Synopse read variant: 1 assertion passed  265.45ms  188,357/s  337 KB
  - Synopse read to BSON: 2 assertions passed  3.17ms  15,762,925/s  175 KB
  - dws JSON read: 1 assertion passed  8.29ms  6,030,635/s  307 KB
  - DBXJSON read: 1 assertion passed  87.47ms  571,598/s  679 KB
  Total failed: 0 / 5  - Depth content PASSED  370.94ms

 2.2. Table content:
  - Download files if necessary: no assertion  753us  10,926,958/s
  - Synopse parse: 1 assertion passed  4.68ms  1,756,779/s  1.2 MB
  - Synopse ORM loop: 41,135 assertions passed  7.77ms  1,058,135/s  1.2 MB
  - Synopse ORM list: 41,135 assertions passed  8.63ms  953,191/s  952 KB
  - Synopse table direct: 41,135 assertions passed  31.49ms  261,182/s  1.1 MB
  - Synopse table variant: 41,135 assertions passed  29.99ms  274,324/s  1.1 MB
  - Synopse doc variant: 41,137 assertions passed  49.79ms  165,210/s  4.6 MB
  - Synopse late binding: 41,137 assertions passed  38.64ms  212,864/s  4.6 MB
  - Synopse to BSON: 2 assertions passed  10.39ms  791,819/s  1.1 MB
  - dws JSON: 41,136 assertions passed  33.89ms  242,720/s  4.7 MB
  - DBXJSON: 41,136 assertions passed  215.80ms  38,123/s  9.9 MB
  Total failed: 0 / 329,089  - Table content PASSED  446.50ms

 2.3. Huge content:
  - Download files if necessary: no assertion  733us
  - Synopse read record: 4 assertions passed  2.45s  84,247/s  122.6 MB
  - Synopse read variant: 2 assertions passed  3.37s  61,151/s  512.9 MB
  - Synopse read to BSON: 3 assertions passed  2.12s  97,275/s  168.1 MB
  - dws JSON read: 2 assertions passed  3.50s  59,005/s  672.7 MB
  - DBXJSON read: no assertion  615us  81,300,813/s
     DBXJSON will raise EOutOfMemory for 185 MB JSON in Win32 -> skip
  Total failed: 0 / 11  - Huge content PASSED  11.81s


Generated with: Delphi XE6 compiler

Time elapsed for all tests: 61.06s
Tests performed at 18.05.2014 12:32:17

Total assertions failed for all test suits:  0 / 1,629,105
! All tests passed successfully.

32Bit Release

   JSON benchmarking
  -------------------


1. Small content

 1.1. Synopse record:
  - Read: 50,000 assertions passed  126.96ms  393,800/s
  - Access: 100,000 assertions passed  988us  50,607,287/s
  - Write: 50,000 assertions passed  74.86ms  667,886/s
  Total failed: 0 / 200,000  - Synopse record PASSED  204.75ms

 1.2. Synopse variant:
  - Read: 50,000 assertions passed  201.74ms  247,841/s
  - Access direct: 100,000 assertions passed  50.88ms  982,685/s
  - Access late binding: 100,000 assertions passed  159.65ms  313,173/s
  - Write: 50,000 assertions passed  103.98ms  480,824/s
  Total failed: 0 / 300,000  - Synopse variant PASSED  518.63ms

 1.3. X super object record:
  - Read: 50,000 assertions passed  20.40s  2,450/s
  - Access: 100,000 assertions passed  984us  50,813,008/s
  - Write: 50,000 assertions passed  3.88s  12,883/s
  Total failed: 0 / 200,000  - X super object record PASSED  24.29s

 1.4. X super object properties:
  - Read: 50,000 assertions passed  16.07s  3,111/s
  - Access: 100,000 assertions passed  530.41ms  94,265/s
  - Write: 50,000 assertions passed  716.42ms  69,790/s
  Total failed: 0 / 200,000  - X super object properties PASSED  17.32s

 1.5. dws JSON:
  - Read: 50,000 assertions passed  224.79ms  222,428/s
  - Access: 100,000 assertions passed  64.19ms  778,864/s
  - Write: 50,000 assertions passed  159.79ms  312,893/s
  Total failed: 0 / 200,000  - dws JSON PASSED  451.24ms

 1.6. DBXJSON:
  - Read: 50,000 assertions passed  4.09s  12,218/s
  - Access: 100,000 assertions passed  42.63ms  1,172,855/s
  - Write: 50,000 assertions passed  531.19ms  94,126/s
  Total failed: 0 / 200,000  - DBXJSON PASSED  4.66s


2. Big content

 2.1. Depth content:
  - Download files if necessary: no assertion  758us
  - Synopse read variant: 1 assertion passed  69.91ms  715,133/s  337 KB
  - Synopse read to BSON: 2 assertions passed  2.60ms  19,208,605/s  175 KB
  - dws JSON read: 1 assertion passed  5.79ms  8,634,087/s  307 KB
  - DBXJSON read: 1 assertion passed  83.36ms  599,764/s  679 KB
  Total failed: 0 / 5  - Depth content PASSED  166.82ms

 2.2. Table content:
  - Download files if necessary: no assertion  758us  10,854,881/s
  - Synopse parse: 1 assertion passed  3.43ms  2,394,353/s  1.2 MB
  - Synopse ORM loop: 41,135 assertions passed  7.10ms  1,157,428/s  1.2 MB
  - Synopse ORM list: 41,135 assertions passed  5.43ms  1,513,428/s  952 KB
  - Synopse table direct: 41,135 assertions passed  22.68ms  362,694/s  1.1 MB
  - Synopse table variant: 41,135 assertions passed  26.37ms  311,900/s  1.1 MB
  - Synopse doc variant: 41,137 assertions passed  40.31ms  204,062/s  4.6 MB
  - Synopse late binding: 41,137 assertions passed  32.77ms  251,006/s  4.6 MB
  - Synopse to BSON: 2 assertions passed  8.97ms  916,249/s  1.1 MB
  - dws JSON: 41,136 assertions passed  30.23ms  272,146/s  4.7 MB
  - DBXJSON: 41,136 assertions passed  234.10ms  35,143/s  9.9 MB
  Total failed: 0 / 329,089  - Table content PASSED  426.91ms

 2.3. Huge content:
  - Download files if necessary: no assertion  666us
  - Synopse read record: 4 assertions passed  1.23s  167,382/s  122.6 MB
  - Synopse read variant: 2 assertions passed  2.16s  95,524/s  512.9 MB
  - Synopse read to BSON: 3 assertions passed  1.66s  124,376/s  168.1 MB
  - dws JSON read: 2 assertions passed  3.42s  60,266/s  672.7 MB
  - DBXJSON read: no assertion  335us  149,253,731/s
     DBXJSON will raise EOutOfMemory for 185 MB JSON in Win32 -> skip
  Total failed: 0 / 11  - Huge content PASSED  8.86s


Generated with: Delphi XE6 compiler

Time elapsed for all tests: 56.91s
Tests performed at 18.05.2014 12:36:06

Total assertions failed for all test suits:  0 / 1,629,105
! All tests passed successfully.

64Bit Release

   JSON benchmarking
  -------------------


1. Small content

 1.1. Synopse record:
  - Read: 50,000 assertions passed  168.00ms  297,619/s
  - Access: 100,000 assertions passed  1.85ms  26,910,656/s
  - Write: 50,000 assertions passed  84.16ms  594,049/s
  Total failed: 0 / 200,000  - Synopse record PASSED  255.94ms

 1.2. Synopse variant:
  - Read: 50,000 assertions passed  244.35ms  204,620/s
  - Access direct: 100,000 assertions passed  48.51ms  1,030,651/s
  - Access late binding: 100,000 assertions passed  153.71ms  325,287/s
  - Write: 50,000 assertions passed  111.38ms  448,909/s
  Total failed: 0 / 300,000  - Synopse variant PASSED  560.17ms

 1.3. dws JSON:
  - Read: 50,000 assertions passed  260.82ms  191,698/s
  - Access: 100,000 assertions passed  69.11ms  723,411/s
  - Write: 50,000 assertions passed  161.97ms  308,699/s
  Total failed: 0 / 200,000  - dws JSON PASSED  493.75ms

 1.4. DBXJSON:
  - Read: 50,000 assertions passed  2.89s  17,266/s
  - Access: 100,000 assertions passed  45.87ms  1,089,870/s
  - Write: 50,000 assertions passed  493.61ms  101,294/s
  Total failed: 0 / 200,000  - DBXJSON PASSED  3.43s


2. Big content

 2.1. Depth content:
  - Download files if necessary: no assertion  596us
  - Synopse read variant: 1 assertion passed  145.50ms  343,642/s  458 KB
  - Synopse read to BSON: 2 assertions passed  2.76ms  18,115,942/s  155 KB
  - dws JSON read: 1 assertion passed  5.61ms  8,912,655/s  414 KB
  - DBXJSON read: 1 assertion passed  53.63ms  932,157/s  877 KB
  Total failed: 0 / 5  - Depth content PASSED  213.25ms

 2.2. Table content:
  - Download files if necessary: no assertion  590us  13,945,762/s
  - Synopse parse: 1 assertion passed  2.95ms  2,784,094/s  1.4 MB
  - Synopse ORM loop: 41,135 assertions passed  5.99ms  1,372,310/s  1.3 MB
  - Synopse ORM list: 41,135 assertions passed  7.79ms  1,054,878/s  1.3 MB
  - Synopse table direct: 41,135 assertions passed  16.75ms  491,046/s  1.3 MB
  - Synopse table variant: 41,135 assertions passed  20.81ms  395,319/s  1.3 MB
  - Synopse doc variant: 41,137 assertions passed  40.20ms  204,651/s  7.0 MB
  - Synopse late binding: 41,137 assertions passed  32.70ms  251,544/s  7.0 MB
  - Synopse to BSON: 2 assertions passed  11.24ms  731,548/s  1.2 MB
  - dws JSON: 41,136 assertions passed  34.23ms  240,295/s  6.7 MB
  - DBXJSON: 41,136 assertions passed  195.13ms  42,161/s  16.6 MB
  Total failed: 0 / 329,089  - Table content PASSED  382.61ms

 2.3. Huge content:
  - Download files if necessary: no assertion  185us
  - Synopse read record: 4 assertions passed  2.07s  99,706/s  148.7 MB
  - Synopse read variant: 2 assertions passed  3.52s  58,559/s  766.1 MB
  - Synopse read to BSON: 3 assertions passed  1.97s  104,480/s  170.0 MB
  - dws JSON read: 2 assertions passed  7.64s  27,015/s  1.0 GB
  - DBXJSON read: 2 assertions passed  35.37s  5,839/s  3.0 GB
  Total failed: 0 / 13  - Huge content PASSED  51.07s


Generated with: Delphi XE6 64 bit compiler

Time elapsed for all tests: 56.42s
Tests performed at 18.05.2014 12:39:35

Total assertions failed for all test suits:  0 / 1,229,107
! All tests passed successfully.

#564 Re: mORMot 1 » Support for a TGUID field » 2014-05-16 07:42:14

I just tried the new Version - but get Exception:

Unhandled sftUnknown/tkRecord for property xyzID

the class function InternalRegisterCustomProperties was not called before the Error !

Also i get memory fault after in TSQLModel.Destroy i just added 1 line of code

destructor TSQLModel.Destroy;
var
  i,j: integer;
begin
  for i := 0 to fTablesMax do begin
// >>> ADDED
    if assigned(TableProps[i]) then
// <<< ADDED
      with TableProps[i].Props do begin
        EnterCriticalSection(fLock); // may be called from several threads at once

#565 Re: mORMot 1 » Support for a TGUID field » 2014-05-14 15:24:45

Yes you are right. In TSQLPropInfoRTTI.CreateFrom
the aType.Kind = tkRecord and aType.Name = 'TGUID'
aSQLFieldType = sftUnknown

#566 Re: mORMot 1 » XE4 and FireMonkey » 2014-05-14 13:03:37

You're right the TRestClient is undocumented by Embarcadero and you have to dig through the source code and Example to understand.
It is based on Indy and has a JSON decoder integrated.

#567 Re: mORMot 1 » Support for a TGUID field » 2014-05-14 12:26:02

There is a Problem in XE6 with registering the TGUID as described in the Handbook 1.18.

It throws Exception unhandled type for ... in TSQLPropInfoRTTI.CreateFrom

To test add
TSQLRecordCustomProps in SynSelfTests.pas ~ Line 8571 TSQLModel.Create(...., TSQLRecordCustomProps);

#568 Re: mORMot 1 » XE4 and FireMonkey » 2014-05-14 09:13:02

After reading a lot in the Forum i think this Post fits best here.

I try to develop a pure delphi app for iOS and Android with XE6, FMX.
For native Data Storage i use UniDac Components.

For Client/Server Communication  Sync / Dataexchange i prefer to use mORMot.
I'll write a native mORMot Server with a Port opened to the internet.

This should be secured with ssl and authentication.

ATM im confused which Client Strategy to use.

- How far is the mORMot Client ?
- Is there an Example for the propesed Indy - Client to Access mORMot Server ?
- Since XE5 there is a new Component in Delphi: TRestClient - which works on Android and iOS.
I have Problems to integrate the mORMot - Authentication is this Component - without Authentication it works. I need some hints (maybe example or Links) to program this.

#569 Re: mORMot 1 » Problem with TransactionBegin » 2014-05-13 14:34:39

Thanks for the answer, i changed add -> batchadd but my real Problem still persists.

It is not easy to explain for me in english. But i try with an example.

I have 2 Programm

One is the Server as in Example 004.
This Programm i start from Windows.

The Second Programm is the one I'm developing on. Lets call it Client.

I start Client and set Breakpoint in the "BatchAdd" - Loop in AddTestRecord....
As Breakpoint is reached i stop debugging with STRG+F2.
The Server does not get Rollback nor Commit.

I start Debugging again with Server running from prior test.
Now StartTransaction results in false.
Why this - the Client was restartet ?! Session is broken ?!
As Consequence i have to restart the Server. This is not good. In Practice there may be the same Problem if Client loses Connection in the loop.

The Point and my Question is how to debug without restarting the Server ?
Is there a Rollback for prior open Transactions or anything else ?

Or other Question I only use Transaction to speed it up - is this neccessary ?

#571 Re: mORMot 1 » define array of RawUTF8 for RegisterCustomJSONSerializerFromText » 2014-05-03 11:44:32

One more Question concerning this task.

Is it possible to interpret the Result from google directly with mORMot. Actual i use Indy to retrieve the http - Stream

        Stream := TStringStream.Create(res);
        try
          Str := TIDUri.UrlEncode(STR_WEB + AAdresse + '&sensor=false');
          IdHTTP.Get(Str, Stream);

          Infos := Stream.DataString;
          U := AnsiString(Infos);

          JSON := RecordLoadJSON(Cache,@U[1],TypeInfo(TGoogleGeoCodeJSON));

          if assigned(JSON) then try

#572 Re: mORMot 1 » define array of RawUTF8 for RegisterCustomJSONSerializerFromText » 2014-05-03 11:17:47

I think i have to provide my original piece of code to find the error:

i try to decode google geocode - Data.

This is my Structure

  TGoogleAdressComponentsJSON = packed record
    long_name, short_name : RawUTF8;
    types : array of RawUTF8;
  end;
  TGoogleLocationJSON = packed record
    lat, lng : double;
  end;
  TGoogleViewportJSON = packed record
    northeast : TGoogleLocationJSON;
    southwest : TGoogleLocationJSON;
  end;
  TGoogleGeometryJSON = packed record
    location : TGoogleLocationJSON;
    location_type : RawUTF8;
    viewport : TGoogleViewportJSON;
  end;
  TGoogleAdressJSON = packed record
    addess_components : array of TGoogleAdressComponentsJSON;
    formatted_address : RawUTF8;
    geometry : TGoogleGeometryJSON;
    partial_match : boolean;
    types : array of RawUTF8;
  end;
  TGoogleGeoCodeJSON = packed record
    results : array of TGoogleAdressJSON;
    status : RawUTF8;
  end;

const
  __TGoogleGeocodeJSON = 'results ['+
                           'address_components [long_name RawUTF8 short_name RawUTF8 types array of RawUTF8] '+
                           'formatted_address RawUTF8 ' +
                           'geometry {location {lat, lng double} '+
                           'location_type RawUTF8 '+
                           'viewport {northeast {lat, lng double} southwest {lat, lng double}}} '+
                           'partial_match boolean '+
                           'types array of RawUTF8'+
                         '] '+
                         'status RawUTF8';

I modified ProcessValue in SymCommons.pas

    ptArray: begin
      if P^<>'[' then
        exit; // we expect a true array here
      repeat inc(P) until P^<>' ';
      // allocate nested array at once
      ArrayLen := JSONArrayCount(P);
      if ArrayLen<0 then
        exit; // invalid JSON array
      Prop.AllocateNestedArray(PPtrUInt(Data)^,ArrayLen);
      // read array content
      if ArrayLen>0 then begin
        DynArray := PPointer(Data)^;
        for j := 1 to ArrayLen do begin
          {$ifdef ALIGNCUSTOMREC}
          BegDynArray := DynArray; // for 8 byte alignment of arrays
          {$endif}
          if Prop.NestedProperty[0].PropertyName='' then begin
            // array of integer/string/array/custom...
            if not ProcessValue(Prop.NestedProperty[0],P,DynArray) or (P=nil) then
              exit;
          end else // array of record
          if not Prop.ReadOneLevel(P,DynArray,Options) or (P=nil) then
            exit;
          {$ifdef ALIGNCUSTOMREC}
          inc(DynArray,(PtrUInt(DynArray)-PtrUInt(BegDynArray)) and 7);
          {$endif}
          if P^=',' then
            inc(P);
        end;
      end;
      if P=nil then
        exit;
      P := GotoNextNotSpace(P);
>> INSERTED
      if (EndOfObject = ']') and (P^='}') then begin
        EndOfObject := '}';
        inc(P);
      end else 
<< INSERTED
      if (P^=']') or (Prop.NestedProperty[0].PropertyName<>'') then begin
        if (P^<>']') then
          exit; // we expect a true array here
        repeat inc(P) until not(P^ in [#1..' ']);
        EndOfObject := P^;
        if P^<>#0 then //if P^=',' then
          inc(P);
      end;
    end;

and the parser work now.

(Now its working fine !)

#573 Re: mORMot 1 » define array of RawUTF8 for RegisterCustomJSONSerializerFromText » 2014-05-03 10:02:07

Thank you the Preparation now works fine,

but in ReadOneLevel / ParseValue is an Error in parsing the array.
EndElement is set to ] not to } as expected from the parser after parsing the String array

"types" : [ "testtype_1" ]

the Parser exits with error.

Example :

{
   "test" : [
            {
               "name1" : "name1_1",
               "name2" : "name2_1",
               "types" : [ "testtype_1" ]
            },
            {
               "name1" : "name1_2",
               "name2" : "name2_2",
               "types" : [ "testtype_2" ]
            }
   ]
}

#574 Re: mORMot 1 » Problem with TransactionBegin » 2014-05-03 09:24:18

Yes was using zip from 22.4.2014

#575 mORMot 1 » Problem with TransactionBegin » 2014-04-30 14:06:16

itSDS
Replies: 5

Hi, i wrote one first Program for Mormot. The Task is easy copying data from one SQLite3 Table to mORMot ORM.
To speed it up i use TransactionBegin and BatchStart ...

examplecode in Client - App (Server is as Project Sample 04):

  procedure AddTestRecord(const AField1, AField2, ... : String);
  var
    test : TSQLTestRecord;
    id : integer;
  begin
    test := TSQLTestRecord.Create;
    try
      test.field1 := AField1;
      test.field2 := AField2;
      id := Database.Add(test, true);
    finally
      test.Free;
    end;
  end;

var
  props: TSQLDBConnectionProperties;
  I : ISQLDBRows;
  G : Variant;
  Results: TIntegerDynArray;
begin
  if FileExists('source.db') then begin
    props := TSQLDBSQLite3ConnectionProperties.Create(StringToUTF8('source.db'),'','','');
    try
      I := props.Execute('select * from sourcetable', [], @G);
      if Database.TransactionBegin(TSQLTestRecord) then try
        Database.BatchStart(TSQLTestRecord);
        while I.Step do
          AddTestRecord(G.field1, G.field2, ...);
        Database.BatchSend(Results);
        Database.Commit;
      except
        Database.RollBack;
      end;
    finally
      props.Free;
    end;
  end;
end;

On normal Processing everything works fine !

But i debugged the Program with the Debugger and if i abort the Program with (STRG+F2) in AddTestRecord, i had to restart the Serverapp before starting the client a second time because TransactionBegin failed.
So my Question: what should a client Program do if there is an unclosed Transaction (from another Session) on the ServerApp ?

In Praxis there could be an interrupt in Transmissiting Data from a client.

#576 mORMot 1 » define array of RawUTF8 for RegisterCustomJSONSerializerFromText » 2014-04-30 13:54:35

itSDS
Replies: 7

Hi, given the following packed record:

  TTestComponentsJSON = packed record
    name1, name2 : RawUTF8;
    types : array of RawUTF8;
  end;

  TTest2JSON = packed record
    test : array of TTestComponentsJSON;
  end;

i have Problems to define the rtti - Text Const for the array of RawUTF8 !

__TTestJSON = 'test [name1 RawUTF8 name2 RawUTF8 types [array RawUTF8]]';

My Question: How i have to specify the array of RawUTF8 ?

#577 mORMot 1 » BaaS Client for Rad Studio XE6 » 2014-04-24 15:15:44

itSDS
Replies: 1

I'm trying to create an IOS - App and found mORMot very interesting for this.
Since Delphi XE6 there is a new BaaS REST Api.

What do you think about creating a Backend for mORMot ?

Board footer

Powered by FluxBB