#1 Re: mORMot 1 » SOA & Cross Platform clients - inconsistency in TDateTime parameters » 2019-09-13 01:31:35

Is your FMX client running on Windows or Android?

For my coding where the FMX client runs on both Windows and Android the only fail safe way of passing a date as a parameter is to convert it into a string. Then pass the string as a parameter.

#2 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2017-09-10 05:33:23

When you run the Server please note the IP address.

Look at unit mORMot_Assist.

What is the constant IPAddress? It should be the same.

What is the constant ServerLogBase? Change that to suit your computer.

Run the Windows Client. Ensure that that works.

Ensure you have enabled the server through your firewall.

Before you run the Android Client. Use an app to check that you can
access the IPAddress from the Client device.

#3 Re: mORMot 1 » JSON record array on Android » 2017-07-17 02:28:41

I now have a solution for Android. This is :-

var
  RecsInArray    : Integer;
  iLen           : Integer;
  KindJSON       : SynCrossPlatformJSON.TJSONVariantKind;
  RecVariantData : SynCrossPlatformJSON.TJSONVariantData;
begin
  RecsInArray := 2;
  {Need to pass an array.
  So remove leading characters. Do not worry about trailing bracket}
  iLen := Length('{"MyRecArray":');
  { your routine here to remove leading characters from JSONStr }

  RecVariantData.Init(JSONStr);
  KindJSON := RecVariantData.Kind;
  if KindJSON <> jvArray then
    Exit;
  if RecVariantData.Count <> RecsInArray then
    Exit;

  SetLength(RecArray.MyRecArray, RecsInArray);

  RecArray.MyRecArray[0] := Variant2MyRecord(RecVariantData.Item[0]);
  RecOut1 := RecArray.MyRecArray[0]; {test}

  RecArray.MyRecArray[1] := Variant2MyRecord(RecVariantData.Item[1]);
  RecOut2 := RecArray.MyRecArray[1]; {test}
end;

#4 Re: mORMot 1 » JSON record array on Android » 2017-07-16 07:12:13

The JSON is this :-

{"MyRecArray":[{"CompanyId":"Company1","ClientId":"Client1"},{"CompanyId":"Company2","ClientId":"Client1"}]}

This JSON validates at the website JSONLint.

#5 mORMot 1 » JSON record array on Android » 2017-07-14 05:20:09

Peter Evans
Replies: 3

Subject : JSON record array on Android

Hello All,

I have been able to manipulate JSON array of records on Windows.

However, on Android I can not generate the array of records from the JSON.

This pseudo code works on Windows :-

  TMyRecord = record
    CompanyId : String;
    ClientId  : String;
  end;

  TRecArray = record
    MyRecArray : array of TMyRecord;
  end;

  Rec1     : TMyRecord;
  Rec2     : TMyRecord;
  JsonStr  : String;
  RecArray : TRecArray;
begin
  Rec1.CompanyId := 'Company1';
  Rec1.ClientId  := 'Client1';

  Rec2.CompanyId := 'Company2';
  Rec2.ClientId  := 'Client2';

  JsonStr := '{"MyRecArray":[';
  JsonStr := JsonStr +
             SynCommons.RecordSaveJSON(
                          Rec1,
                          TypeInfo(TMyRecord));
  JsonStr := JsonStr + ',' +
             SynCommons.RecordSaveJSON(
                          Rec2,
                          TypeInfo(TMyRecord));
  JsonStr := JsonStr + ']}';

  SetLength(RecArray.MyRecArray, 2);
  bResult := SynCommons.RecordLoadJSON(
                            RecArray,
                            JsonStr,
                            TypeInfo(TRecArray));
end;

On Android I can get the JSON using :-

var
  RecVariant : Variant;
begin
  JsonStr := '{"MyRecArray":[';

  RecVariant := TMyRecord2Variant(Rec1);

  JsonStr := JsonStr +
             SynCrossPlatformJSON.ValueToJSON(RecVariant);

  RecVariant := TMyRecord2Variant(Rec2);

  JsonStr := JsonStr + ',' +
             SynCrossPlatformJSON.ValueToJSON(RecVariant);

  JsonStr := JsonStr + ']}';

  {The JsonStr is the same as on Windows}
end;

Now on Android generating the array of records (This does not work) :-

begin
  RecVariant := SynCrossPlatformJSON.JSONToValue(JsonStr);

  RecArray := Variant2MyRecordArray(RecVariant, 2); {Error in this call}
end;
 

function Variant2MyRecordArray(var   aRecVariant  : Variant;
                               const aRecsInArray : Integer) : TRecArray;
var
  iIterate : Integer;
  Str      : String;
begin
  if aRecsInArray <= 0 then begin
    SetLength(Result.MyRecArray, 0);
    Exit;
  end;
  SetLength(Result.MyRecArray, aRecsInArray);
  for iIterate := 0 to (aRecsInArray - 1) do begin
    Str := aRecVariant.MyRecArray[iIterate].CompanyId; {Error - Variant method calls not supported}

    Result.MyRecArray[iIterate].CompanyId := Str;
    ...
  end;
end;       

This last part in Android doesn't work.
Perhaps there is a simpler way to achieve this on Android?

Any ideas?

Regards,
  Peter G. Evans

#6 Re: mORMot 1 » Upload and download of big files » 2016-11-29 01:20:43

I realise that I am a bit late to this conversation.
I haven't been in the situation where I have had to download such a large file.

My approach for smaller files is the following:-

1. Client calls the Server. This is an Interface call in mORMot.
(A method call in DataSnap)
The Server passes back the file size in bytes.
The Server passes back the CRC check sum.

2. Client calls the Server. This is a different Interface call.
Client can specify the "chunk" to be returned.
Alternative, the Server returns a set "chunk" size. If the Server does this
then the "chunk" size can be changed at the Server, on the fly, rather
than having to update all the Clients.
Server sets a flag when the end of the file is reached.

Now the Client can update the user interface, between calls to Server.
No need to perform the download in a separate thread, to make the user
interface appear responsive. Hopefully
increases the responsiveness of the Server to other Clients.

3. After file has been downloaded the Client checks the file size and CRC.

#7 Re: mORMot 1 » Authentication » 2016-09-15 06:41:58

On 2016-08-09 I posted in the thread 'Windows FMX Client versus Android FMX Client'
(see http://synopse.info/forum/viewtopic.php?id=3418) a link to a sample project group.

I think the sample does what you want :-

1) It uses Interfaces.
2) I access my own database for authentication ie. Logon and Logoff.

#8 Re: mORMot 1 » Generate code for FMX on Windows and Android for mORMot » 2016-09-11 02:15:06

ab: Thank you for your feedback.

In regards to GenerateRec. You are right, the records type definitions are
already generated by 'mORMotWrappers.pas' unit to 'mORMotClient.pas'.

I want to reference the records on the Server. On the Server I convert from
an object to a record, and from a record to an object. So I need to have
the two routines written.

On the Server I would have to have :-
  USES
    mORMotClient;

I do not know what the implications of this are. Pulling in cross platform units.
Perhaps I have done unnecessary work?

When I develop my programs I write the Interfaces first. Then I write the implementation
that the Server references. For this to compile I need the records. Perhaps one could
run the ServerWrapper program at this point in time?

#9 Re: mORMot 1 » Generate code for FMX on Windows and Android for mORMot » 2016-09-11 02:14:04

MMihelic: You may wish to create a new Topic for your issue.
Your issue is completely different.

#10 mORMot 1 » Generate code for FMX on Windows and Android for mORMot » 2016-09-09 05:13:22

Peter Evans
Replies: 6

I have been working to convert a Delphi with DataSnap program to its Delphi with mORMot equivalent.

On 2016-08-09 I posted in the thread 'Windows FMX Client versus Android FMX Client'
(see http://synopse.info/forum/viewtopic.php?id=3418) a link to a sample project group. That code is still relevant.

There were two missing pieces in the puzzle:

1) Records need to be hand coded from an Object. How to automate this?

2) A Parameter that is a TObjectList does not work. How to fix this problem?

I now provide a Delphi project group that has two (2) projects. It is located
at  http://www.cocolsoft.com.au/ba/GenerateRec_Version1.zip

The program GenerateRec :-

From the ReadMe "This program is used to generate record units based on object units.

The motivation for this program is to automate the process of making record units. If you have a large mORMot program with many objects you will need a corresponding record for each object. This supposes that you are running on Windows and Android.

Record units are required if you wish to use mORMot with Delphi FireMonkey on Windows and Delphi FireMonkey on Android.

Note : If you are only targeting Delphi FireMonkey on Windows then you may be able to do this using objects. You probably won't need records. In that case this program is not required.".

The program GenerateObjectList :-

From the ReadMe "This program is used to generate object list units based on an object name.

The motivation for this program is to automate the process of making object list units.
If you have a large mORMot program with many objects you may need to convert an object list into JSON or convert JSON into an object list.

Each generated unit has two main routines. One routine converts an object to JSON.
The other routine converts JSON into an object list. The JSON string can be passed as a parameter in an interface call. The generated unit has conditional compilation for Windows and Android.".

In this forum there have been proposed various ways to achieve the generation of object lists. I believe I use a different approach to those.

As well as the two ReadMe files there is a screen shot of their main forms.

The program GenerateRec requires you to simply markup your Object unit with the comment "{MormotGenerateRecord}". A Mustache template file is used in the generation of the record units. These have code for Windows and Android. A sample Object unit is provided.

The program GenerateObjectList uses a Mustache template file in the generation of the units. These have code for Windows and Android. This has been unit tested on Windows and unit tested on Android. (The unit tests are not provided.)

Enjoy the productivity.

#11 Re: mORMot 1 » Connect to server timeout from FireMonkey Android Client » 2016-09-09 04:07:51

Wangming: On a FireMonkey Android client you should not reference 'SynCommons.pas'.
You should reference the CrossPlatform units.

#12 mORMot 1 » Connect to server timeout from FireMonkey Android Client » 2016-08-19 04:21:29

Peter Evans
Replies: 4

My FireMonkey Android Client takes 2 minutes to timeout when the Server is not running.
I get the message "Impossible to connect to ... server'.

Is there a way to reduce that time to, say 15 seconds?

The Android Client calls:-

   mORMotClient.GetClient

That function is defined in the unit mORMotClient as :-

function GetClient(const aServerAddress, aUserName,aPassword: string;
  aServerPort: integer; const aServerRoot: string; aHttps: boolean): TSQLRestClientHTTP;
begin
  result := TSQLRestClientHTTP.Create(aServerAddress,aServerPort,
    GetModel(aServerRoot),true,aHttps); // aOwnModel=true
  try
    if (not result.Connect) or (result.ServerTimeStamp=0) then
      raise ERestException.CreateFmt('Impossible to connect to %s:%d server',
        [aServerAddress,aServerPort]);
    if not result.SetUser(TSQLRestServerAuthenticationDefault,aUserName,aPassword) then
      raise ERestException.CreateFmt('%s:%d server rejected "%s" credentials',
        [aServerAddress,aServerPort,aUserName]);
  except
    result.Free;
    raise;
  end;
end;

I changed the function TSQLRestClientHTTP.Create in unit SynCrossPlatformREST to :-

constructor TSQLRestClientHTTP.Create(const aServer: string;
  aPort: integer; aModel: TSQLModel; aOwnModel, aHttps: boolean
  {$ifndef ISSMS}; const aProxyName, aProxyByPass: string;
  aSendTimeout, aReceiveTimeout, aConnectionTimeOut: Cardinal{$endif});
begin
  inherited Create(aModel,aOwnModel);
  fParameters.Server := aServer;
  fParameters.Port := aPort;
  fParameters.Https := aHttps;
  {$ifndef ISSMS}
  fParameters.ProxyName := aProxyName;
  fParameters.ProxyByPass := aProxyByPass;

  {fParameters.ConnectionTimeOut := aConnectionTimeOut;}
  fParameters.ConnectionTimeOut := 15000; {15sec}                <===   

  {fParameters.SendTimeout := aSendTimeout;}
  fParameters.SendTimeout := 15000; {15sec}                    <===


  {fParameters.ReceiveTimeout := aReceiveTimeout;}
  fParameters.ReceiveTimeout := 15000; {15sec}                 <=== 

  {$endif}
  fKeepAlive := 20000;
end;

However this didn't affect the timeout.

Is there some other way to achieve this?

#13 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-08-18 23:01:46

Hope that the following explanation helps. mORMot correctly deals with both Windows and Android situations.

Assume you have a record with 2 fields:   Boolean1 and Boolean2.

Using FireMonkey Client on Windows:-
  Looking at the Server log. The call may look a bit like:

    {"Boolean1":true,"Boolean2":false}

Using FireMonkey Client on Android:-
  Looking at the Server log. The call may look a bit like:

    {"Boolean1":-1,"Boolean2":0}

#14 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-08-14 22:52:38

I have now fixed the problem of date handling.

The solution is to change any parameters from TDateTime to String;

The following works for Delphi FireMonkey on Windows and Delphi FireMonkey on Android.
It preserves milliseconds. Breaking this down into simple parts.

At the Server :-

var
  ServerTime    : TDateTime;
  ServerTimeStr : String;

ServerTime    := System.SysUtils.Now;
ServerTimeStr := System.DateUtils.DateToISO8601(ServerTime);

At the Client :-

var
  ServerTime        : TDateTime;
  ThisServerTimeStr : String;

ServerTime := System.DateUtils.ISO8601ToDate(ThisServerTimeStr);

#15 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-08-09 00:27:17

I have now put together a revised sample project group.
This sample now has a working version of Delphi FireMonkey on Android.

This group also simplifies the way the IP Address is used in the Clients.

Please see the 'ReadMe.txt' for information.

I did have to make one (1) change in mORMotClient to get Android to work.

The change is :-
  Amend in LoginAdmin
    DateTimeToIso8601(ServerTime) -->  0
    (This avoids a problem of date handling)

I do not understand why this code (generated by the Server Wrapper) crashes
with an invalid floating point operation.


The sample is located at
  http://www.cocolsoft.com.au/ba/testmorm … _toab2.zip

#16 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-25 10:43:19

It has taken me some days to put together a program outlining the problem I am having.
If my program is suitable then it might be considered as a Sample program for mORMot.
I have written it so that it can be added to the mORMot sample programs.

The problem I am having is with the Android Client. I can not get that to work. (What works is the Server, the Windows Client, and the server wrapper.)

(Most of the following is from the ReadMe that comes with the program.)

A sample program to assist people converting from the Delphi framework DataSnap
to the mORMot framework.

This Project Group 'TestMormotGroup1' consists of 4 projects.

1) TestMormotServer.
This server must run before you run one of the clients.

2) TestMormotWin.
Test program for mORMot running on Windows.
It is built in Delphi FireMonkey.

3) TestMormotAnd.
Test program for mORMot running on Android.
It is built in Delphi FireMonkey.

4) TestMormotServerWrapper.
A CLI program that is used to generate the unit 'mORMotClient.pas'.
That unit is used in the project TestMormotAnd.

The program is structured around DataSnap. For example, there is a unit
mORMot_ServerContainer and mORMot_ServerMethods.

If you wish to convert your own DataSnap program to mORMot then you can
follow the pattern of introducing these units in parallel with your
existing program. Then switching over to mORMot.

The program also shows how to keep any existing objects that you use
in DataSnap and make Record versions of them and how to convert from Object
to Record and Record to Object.

You will need to change the IP Address in 2 places :-

1) unit TestMormotWin1
2) unit TestMormotAnd1

You will need to change the Log path in unit 'Unit1.pas'.


The sample is located at
  http://www.cocolsoft.com.au/ba/testmorm … 1_toab.zip

I look forward to feedback on how I can get project TestMormotAnd to work.

Regards,
  Peter Evans

#17 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-19 22:30:10

Thank you for your reply. I am using Delphi 10.1 Berlin.
I will look again at this problem today. Especially the Indy clue you gave.
The Android version (FireMonkey Android client) of my system is the only part not working. (The FireMonkey Windows client works.)

#18 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-18 12:30:37

I'm pleased that the template has been tweaked. But back to my real problem...

My problem is in the line:-
  Int := mORMotClient.TServiceLoginAdmin.Create(FProxy);

I get the error:-  raised exception class EJMIException with message 'java.io.EOFException'.

This is raised in the Delphi unit System.Internal.ExcUtils

The last lines in that unit are :-

{$IFDEF ANDROID}
procedure DoRaiseJNIExceptionCallBack(const JNIExceptionClassName: string; const Msg: string);
begin
  raise EJNIException.CreateWithClassName(JNIExceptionClassName, Msg);
end;
{$ENDIF}

initialization
{$IFDEF ENABLE_SIGNAL_HANDLING}
  ExitProcessProc := PropagateSignals;
{$ENDIF ENABLE_SIGNAL_HANDLING}
{$IFDEF ANDROID}
  Androidapi.Jni.DoRaiseJNIException := DoRaiseJNIExceptionCallBack;
{$ENDIF}
end.

Any clues as to what may be the problem?

#19 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-18 07:12:18

I am running a test program on Android using Delphi FireMonkey.

Note - I have overcome my issue with passing objects as parameters. I now pass
records. I use a server wrapper to generate the unit mORMotClient.

The problem I am having is with these lines :-

var
FProxy : SynCrossPlatformREST.TSQLRestClientURI;

FProxy := mORMotClient.GetClient('999.999.9.99'         {not the correct name} {aServerName},
                                 'User'                 {aUserName},
                                 'synopse'              {aPassword},
                                  211                   {aServerPort},
                                  ROOT_NAME             {aServerRoot}
                                  {aHttps default is False} );


    Int := mORMotClient.TServiceLoginAdmin.Create(FProxy);

    if Assigned(Int) then begin
      if not             Int.LoginAdmin(aCompany,
                                        ...
                                        MemSettingRec     {Returned}) then begin
    ...

This is what gets generated in unit mORMotClient :-

/// service implemented by TServiceLoginAdmin
  // - you can access this service as such:
  // !var aLoginAdmin: ILoginAdmin;
  // !begin
  // !   aLoginAdmin := TLoginAdmin.Create(aClient);
  // !   // now you can use aLoginAdmin methods
  // !...
  ILoginAdmin = interface(IServiceAbstract)
    ['{A1767BC6-0A1A-41D9-AD6A-A4785458F9B8}']
    function LoginAdmin(const Company1: String; ...; var MemSettingRec: TMemSettingRec): Boolean;
  end;

  /// implements ILoginAdmin from http://localhost:888/root/LoginAdmin
  // - this service will run in sicShared mode
  TServiceLoginAdmin = class(TServiceClientAbstract,ILoginAdmin)
  public
    constructor Create(aClient: TSQLRestClientURI); override;
    function LoginAdmin(const Company1: String; ...; var MemSettingRec: TMemSettingRec): Boolean;
  end;

What I do not understand is the comment that you need to code :-
  aLoginAdmin := TLoginAdmin.Create(aClient);

I need to code :-
  mORMotClient.TServiceLoginAdmin.Create(FProxy);

The difference being the word "Service". Is the automatic comment wrong or is it something I am doing that is wrong?

What else might I need to change to get it working?

Regards,
  Peter Evans

#20 Re: mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-14 00:12:31

Thank you. I will investigate further and report back.

#21 mORMot 1 » Windows FMX Client versus Android FMX Client » 2016-07-13 12:27:20

Peter Evans
Replies: 15

I have successfully made a Delphi 10.1 Berlin, mORMot Windows Server.
Also a Windows FireMonkey Client can successfully log on and log off my system. This is excellent.

I have one parameter which is an object TMemSettingObj.

It is defined like:-

type
  TMemSettingObj = class
  private
  ...

So far so good.

When I make the Android FireMonkey Client I create the unit mORMotClient using a
server wrapper project.

On Android there are a few problems. For example,

  MemSettingObj := TableMemSettingObj.TMemSettingObj.CreateFromVariant(res[7]);

I get an error :-

  'TMemSettingObj' does not contain a member named 'CreateFromVariant'.

So I defined TMemSettingObj with conditional compilation:-

type
  TMemSettingObj = class
{$IFDEF SERVERWRAPPER}
                        (TSQLRecord)
{$ENDIF}
  private
  ...

The program now compiles under Android.

However when the Server runs I get error:_

TSQLRestRoutingREST.Error: {  "errorCode":406,  "errorText":"(sicShared) execution failed
(probably due to bad input parameters) for LoginAdmin.LoginAdmin"  }

Comparing the Log with the Log used to call from Windows FireMonkey Client the main differences are:

Android gets a prefix of    "ID":0,
  (I understand this as the class now descends from TSQLRecord)

Windows - "MainViewTimelineShow":true
Android - "MainViewTimelineShow":1

Do you have any tips on how I can get it working on both Windows and Android?

Regards,
  Peter Evans

#22 Re: mORMot 1 » Two problems I am having generating client wrappers » 2016-07-10 12:08:22

Thanks for that reply. I will look further into your question.

#23 mORMot 1 » Two problems I am having generating client wrappers » 2016-07-10 07:07:53

Peter Evans
Replies: 2

1)
The following is an extract from generated mORMotClient.
(I have stripped out some unnecessary parameters from the extract.)
The object TMemSettingObj is one I have devised.

Against this line :-

  MemSettingObj := TableMemSettingObj.TMemSettingObj.CreateFromVariant(res[7]);

I get an error :-

  'TMemSettingObj' does not contain a member named 'CreateFromVariant'.

  /// implements ILoginAdmin from http://localhost:888/root/LoginAdmin
  // - this service will run in sicShared mode
  TServiceLoginAdmin = class(TServiceClientAbstract,ILoginAdmin)
  public
    constructor Create(aClient: TSQLRestClientURI); override;
    function LoginAdmin(const Company1: String; ... var ServerTime: TDateTime; var MemSettingObj: TableMemSettingObj.TMemSettingObj): Boolean;
  end;

function TServiceLoginAdmin.LoginAdmin(const Company1: String; ... var ServerTime: TDateTime; var MemSettingObj: TableMemSettingObj.TMemSettingObj): Boolean;

var res: TVariantDynArray;
begin
  fClient.CallRemoteService(self,'LoginAdmin',9, // raise EServiceException on error
    [Company1, ... DateTimeToIso8601(ServerTime),ObjectToVariant(MemSettingObj)],res);
  LoginInfoInt := res[0];
  ...
  ServerTime := Iso8601ToDateTime(res[6]);
  MemSettingObj.Free; // avoid memory leak
  MemSettingObj := TableMemSettingObj.TMemSettingObj.CreateFromVariant(res[7]);
  Result := res[8];
end;

What do you suggest I need to do to fix this problem?


2)
The object TMemActiveObj is one I have devised.

Against this line :-

  [Company1,Name1,Token1,ObjectToVariant(MemActiveObj),iLastAutoInc],res);

I get an error :-

  Incompatible types: 'TSQlRecord' and 'TMemActiveObj'.

/// implements ILogoffAdmin from http://localhost:888/root/LogoffAdmin
  // - this service will run in sicShared mode
  TServiceLogoffAdmin = class(TServiceClientAbstract,ILogoffAdmin)
  public
    constructor Create(aClient: TSQLRestClientURI); override;
    function LogoffAdmin(const Company1: String; const Name1: String; const Token1: Integer; const MemActiveObj: TableMemActiveObj.TMemActiveObj; var iLastAutoInc: Integer): Boolean;
  end;


function TServiceLogoffAdmin.LogoffAdmin(const Company1: String; const Name1: String; const Token1: Integer; const MemActiveObj: TableMemActiveObj.TMemActiveObj; var iLastAutoInc: Integer): Boolean;
var res: TVariantDynArray;
begin
  fClient.CallRemoteService(self,'LogoffAdmin',2, // raise EServiceException on error
    [Company1,Name1,Token1,ObjectToVariant(MemActiveObj),iLastAutoInc],res);
  iLastAutoInc := res[0];
  Result := res[1];
end;

What do you suggest I need to do to fix this problem?

Regards,
  Peter Evans

#24 mORMot 1 » Generating client wrappers - how to add units to Uses » 2016-07-10 05:56:33

Peter Evans
Replies: 1

I am following the manual at Section 17.2 'Generating client wrappers'.

One of the generated interfaces has as parameter a class that I define.

My class is defined in a separate unit. Call it unit X.

Is there a way automatically generate in mORMotClient the reference to unit X?

Regards,
  Peter Evans

#25 mORMot 1 » Sample 27 Cross Platform Clients - my experiences » 2016-07-10 05:42:22

Peter Evans
Replies: 0

There are a number of projects in Sample 27. This is my experience with them.

I am using Delphi 10.1 Berlin.

a) Project 'MobileClient.dpr'.

In MobileMain.pas need to comment out the line 51 :-
    assert(json = ...

Then the program works on Android machine - Google Nexus 7.
Does not need a server to work.

b) Project 'FMClient.dpr'.

In FMMain.pas need to comment out the line 101 :-
   assert(json = ...

On Android machine - Google Nexus 7. When run get an
   EOpenError 'Cannot open file "/people.json".

I changed the name of the file from 'People.json' to 'people.json'. Then added
the file to the Deployment tab. (On Deployment tab I made the Remote Path = .\
I got the same error.


I then amended the code to read :-

USES
  System.IOUtils;

  {
  FN := 'people.json';
  for level := 1 to 4 do
    if FileExists(FN) then
      break else
      FN := IncludeTrailingPathDelimiter('..')+FN;
  }
  FN := TPath.GetDocumentsPath + PathDelim + 'people.json';


When run I get an error in function UTF8FileToString in unit
SynCrossPlatformJSON. The function is unable to find the file.

I am not sure why this is so.

c) Project14ServerHttpWrapper  [in this Sample 27]

To get this to work I had to place the files from
CrossPlatform/templates in the following hierarchy :-

    Folder For My Project\Project14ServerHttpWrapper
    CrossPlatform\template\copied files

Regards,
  Peter Evans

#26 Re: mORMot 1 » Compiling for Android - SynZip » 2016-07-10 04:53:42

Thank you for that information, I am looking into it.

#27 mORMot 1 » Compiling for Android - SynZip » 2016-07-07 13:10:00

Peter Evans
Replies: 2

I get the error - Undeclared identifier : AnsiString.

This points to AnsiString in :-

  function CompressGZip(var DataRawByteString; Compress: boolean): AnsiString;

in the unit SynZip.

When I compile the Client with FireMonkey on Windows these are the DCU generated:-

mORMot
mORMotHttpClient
SynBidirSock
SynCommons
SynCrtSock
SynCrypto
SynLog
SynLZ
SynSSPlAuth
SynTests
SynWinSock
SynZip.

I have read 'ReadMe.txt'.
I note that there are these Include files available: 'Synopse.inc', 'SynCrossPlatform.inc'.

I note that mORMot pulls in SynZip.

I placed in the Android client under Project | Options the 'Conditional defines' NEXTGEN.

Is there another conditional defines I need to use?

Should I be replacing some units with some from the CrossPlatform folder?


Regards,
  Peter Evans

#29 mORMot 1 » DataSnap with a main database - moving to Interfaces » 2016-07-04 11:15:03

Peter Evans
Replies: 2

My understanding is probably lacking in some areas.

I copied methods from my DataSnap program, and, rewrote them as methods using Interfaces.

I then realized that some of the methods have calls to SQL queries etc. They are against
the database ElevateDB from Elevate Software. (Aside - Apparantly there is an ODBC driver available from Elevate Software.) There is only one main database.

In Project 14 there is the TServiceCalculator with function Add. That function doesn't call
a database.

In DataSnap there is a form :-

   TServerMethods1 = class(TDSServerModule)

On the form I have components for :-
  Session, Database, Tables, Queries etc.

Here is an example of an existing DataSnap method converted to mORMot.
It does SQL queries within the method :-

  TLogoffAdmin = class(TInterfacedObject, ILogoffAdmin)
  public
    function LogoffAdmin(const Company1     : String;
                         const Name1        : String;
                         const Area1        : Integer;
                         const MemObj       : TMemObj;
                         var   iLastAutoInc : Integer) : Boolean;
  end;

What sample do you think I need to look at so that methods accessing the main database
can be successfully called?

Regards,
  Peter Evans

#30 Re: mORMot 1 » Sample 14 Interface based services - options 1 and 3 » 2016-07-03 22:31:36

I very much appreciate your solution.
The Samples are now working!

Best Regards,
  Peter Evans

#31 mORMot 1 » Sample 14 Interface based services - options 1 and 3 » 2016-07-03 06:41:01

Peter Evans
Replies: 2

Last week I downloaded mORMot and successfully got all the Tests to work.
I am very impressed with what I see.

I want to migrate a DataSnap program. It uses methods on the Server and
Client to communicate. The Server is Delphi VCL. One Client is FireMonkey
on Windows. Another Client is FireMonkey on Android.

So I am investigating Interface based services.

I have run Sample "14 - Interface based services". (Running on Windodws 10)

There are 3 options:-
1) HTTP / TCP-IP
2) Named Pipe
3) Weak HTTP / TCP-IP.

I can get option 2) to work.
But option 1) and option 3) I get an error. This is like :-

  Server not available - { "EWinHTTP":"winhttp.dll error 12029 (A
  connection with the server could not be established)" }

Is this a Windows permissions problem of some kind?

How do I go about pinpointing the error?

Regards,
  Peter Evans

Board footer

Powered by FluxBB