#2 Re: mORMot 1 » SynCrossPlatformJSON - Null json TInterfacedCollection with 2 levels » 2017-05-06 22:16:07

I tried to tailor the example below, but also returned null for additional collections.

  TLevel3 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level2: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level2: Integer read FID_Level2 write FID_Level2;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel3 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel3;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
      function Add: TLevel3;
  end;

  TLevel2 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level1: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level1: Integer read FID_Level1 write FID_Level1;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel2 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel2;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
      function Add: TLevel2;
  end;

  TLevel1 = class(TCollectionItem)
  private
    FID: Integer;
    FID_AnyProp1: Integer;
    FName: RawUTF8;
  published
    property ID: Integer read FID write FID;
    property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel1 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel1;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
      function Add: TLevel1;
  end;

  TLevel0 = class
   private
      FID: Integer;
      FName: RawUTF8;
      FListLevel1: TListLevel1;
      FListLevel2: TListLevel2;
      FListLevel3: TListLevel3;
    published
      property ID   : Integer  read FID   write FID;
      property Name : RawUTF8  read FName write FName;
      property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
      property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
      property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
      constructor Create;
      destructor Destroy; override;
  end;

JSON

{
  "ID": 1,
  "Name": "ANY TEXT LEVEL 0",
  "ListLevel1": [
    {
      "ID": 1,
      "ID_AnyProp1": 1,
      "Name": "ANY TEXT LEVEL 1"
    }
  ],
  "ListLevel2": [
    null
  ],
  "ListLevel3": [
    null,
    null
  ]
}

#3 mORMot 1 » SynCrossPlatformJSON - Null json TInterfacedCollection with 2 levels » 2017-05-06 20:20:49

edismo
Replies: 2

Hello AB,

I try to generate json (with multiple levels of collections), but, level 2 is generated null.
Can you help me?

The example is below.

My Unit

unit UnitSample;

interface

uses
  System.Classes,
  mORMot,
  SynCommons;

type

  TLevel3 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level2: Integer;
    FName: RawUTF8;
  public
    property ID: Integer read FID write FID;
    property ID_Level2: Integer read FID_Level2 write FID_Level2;
    property Name: RawUTF8 read FName write FName;
  end;

  TListLevel3 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel3;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
      function Add: TLevel3;
  end;

  TLevel2 = class(TCollectionItem)
  private
    FID: Integer;
    FID_Level1: Integer;
    FName: RawUTF8;
    FListLevel3: TListLevel3;
  public
    property ID: Integer read FID write FID;
    property ID_Level1: Integer read FID_Level1 write FID_Level1;
    property Name: RawUTF8 read FName write FName;
    property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
    destructor Destroy; override;
  end;

  TListLevel2 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel2;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
      function Add: TLevel2;
  end;

  TLevel1 = class(TCollectionItem)
  private
    FID: Integer;
    FID_AnyProp1: Integer;
    FName: RawUTF8;
    FListLevel2: TListLevel2;
  published
    property ID: Integer read FID write FID;
    property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
    property Name: RawUTF8 read FName write FName;
    property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
    destructor Destroy; override;
  end;

  TListLevel1 = class(TInterfacedCollection)
   private
      function GetCollItem(aIndex: Integer): TLevel1;
    protected
      class function GetClass: TCollectionItemClass; override;
    public
      property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
      function Add: TLevel1;
  end;

  TLevel0 = class
   private
      FID: Integer;
      FName: RawUTF8;
      FListLevel1: TListLevel1;
    published
      property ID   : Integer  read FID   write FID;
      property Name : RawUTF8  read FName write FName;
      property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
      constructor Create;
      destructor Destroy; override;
  end;

implementation

uses
  SysUtils;

{ TListLevel1 }

function TListLevel1.Add: TLevel1;
begin
  result := TLevel1(inherited Add);
  result.FListLevel2 := TListLevel2.Create;
end;

class function TListLevel1.GetClass: TCollectionItemClass;
begin
  result := TLevel1;
end;

function TListLevel1.GetCollItem(aIndex: Integer): TLevel1;
begin
  result := TLevel1(GetItem(aIndex));
end;

{ TListLevel2 }

function TListLevel2.Add: TLevel2;
begin
  result := TLevel2(inherited Add);
  result.FListLevel3 := TListLevel3.Create;
end;

class function TListLevel2.GetClass: TCollectionItemClass;
begin
  result := TLevel2;
end;

function TListLevel2.GetCollItem(aIndex: Integer): TLevel2;
begin
  result := TLevel2(GetItem(aIndex));
end;

{ TListLevel3 }

function TListLevel3.Add: TLevel3;
begin
  result := TLevel3(inherited Add);
end;

class function TListLevel3.GetClass: TCollectionItemClass;
begin
  result := TLevel3;
end;

function TListLevel3.GetCollItem(aIndex: Integer): TLevel3;
begin
  result := TLevel3(GetItem(aIndex));
end;

{ TLevel0 }

constructor TLevel0.Create;
begin
  FListLevel1 := TListLevel1.Create;
end;

destructor TLevel0.Destroy;
begin
  FreeAndNil(FListLevel1);
  inherited;
end;

{ TLevel1 }

destructor TLevel1.Destroy;
begin
  FreeAndNil(FListLevel2);
  inherited;
end;

{ TLevel2 }

destructor TLevel2.Destroy;
begin
  FreeAndNil(FListLevel3);
  inherited;
end;

end.

Values of sample

var
  Level0: TLevel0;
  LocalJson: RawJSON;
begin
  Level0 := TLevel0.Create;
  try
    Level0.ID := 1;
    Level0.Name := 'ANY TEXT LEVEL 0';

    with TLevel1(Level0.ListLevel1.Add) do
    begin
      ID := 1;
      ID_AnyProp1 := Level0.ID;
      Name := 'ANY TEXT LEVEL 1';

      with TLevel2(ListLevel2.Add) do
      begin
        ID := 1;
        ID_Level1 := 1;
        Name := 'ANY TEXT LEVEL 2';
        with TLevel3(ListLevel3.Add) do
        begin
          ID := 1;
          ID_Level2 := 1;
          Name := 'ANY TEXT LEVEL 3 A';
        end;
        with TLevel3(ListLevel3.Add) do
        begin
          ID := 2;
          ID_Level2 := 1;
          Name := 'ANY TEXT LEVEL 3 B';
        end;
      end;
    end;
    LocalJson := ObjectToJson(Level0);

    Memo.Text := LocalJson;
  finally
    FreeAndNil(Level0);
  end;

JSON gerated

{
  "ID": 1,
  "Name": "ANY TEXT LEVEL 0",
  "ListLevel1": [
    {
      "ID": 1,
      "ID_AnyProp1": 1,
      "Name": "ANY TEXT LEVEL 1",
      "ListLevel2": [
        null
      ]
    }
  ]
}


      "ListLevel2": [
        null
      ]

#5 Re: mORMot 1 » getting json invalid return with two methods called » 2014-10-28 18:12:50

Sorry,

else if condition will never be true.
Changed to

 else if (WR.lastchar <> JSONSEND_WITHID[ForceServiceResultAsJSONObject][1]) then

But the tests did not pass.

 2.7. Service oriented architecture:
  - Weak interfaces: 56 assertions passed  405us
  - Service initialization: 243 assertions passed  2.30ms
  - Direct call: 583,392 assertions passed  24.99ms
  - Server side: 583,411 assertions passed  25.31ms

! Exception EInterfaceFactoryException raised with messsage:
!  Invalid TInterfacedObjectFake.FakeCall() for IComplexCalculator.Collections:
Invalid returned JSON content: expects {"result":...}

#6 Re: mORMot 1 » getting json invalid return with two methods called » 2014-10-28 17:59:36

hi AB,

I tried to change to solve the problem.
Tests for Service oriented architecture passed.

unit: mORMot.pas
class: TSQLRestServerURIContext
method: ServiceResultEnd

See if this is correct:

procedure TSQLRestServerURIContext.ServiceResultEnd(WR: TTextWriter; ID: integer);
const JSONSEND_WITHID: array[boolean] of RawUTF8 = ('],"id":','},"id":');
      JSONSEND_NOID: array[boolean] of AnsiChar = (']','}');
begin // InternalExecuteSOAByInterface has set ForceServiceResultAsJSONObject
  if (ID=0) and (WR.lastchar <> JSONSEND_NOID[ForceServiceResultAsJSONObject]) then
      WR.Add(JSONSEND_NOID[ForceServiceResultAsJSONObject])
  else if (WR.lastchar <> JSONSEND_WITHID[ForceServiceResultAsJSONObject]) then
  begin
    WR.AddString(JSONSEND_WITHID[ForceServiceResultAsJSONObject]);
    WR.Add(ID); // only used in sicClientDriven mode
  end;
  WR.Add('}');
end;

#7 Re: mORMot 1 » getting json invalid return with two methods called » 2014-10-08 17:14:53

Thanks AB.

I'm glad to help.

Ticket UUID: 4cf639afe6b45925a76260106c976c217947a9a3

#8 Re: mORMot 1 » getting json invalid return with two methods called » 2014-10-08 12:53:14

Hi AB,

Below is the code of my example.

Server.dpr

program Server;

uses
  Vcl.Forms,
  MainServer in 'MainServer.pas' {FrmApp},
  mORMot,
  SynCommons,
  main in 'main.pas';

{$R *.res}

begin

  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
    EchoToConsole := LOG_VERBOSE; // log all events to the console
  end;

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TFrmApp, FrmApp);
  ReportMemoryLeaksOnShutdown := True;
  Application.Run;
end.

MainServer (Form)

unit MainServer;

interface

uses
  System.SysUtils, Vcl.Forms, System.Classes, Vcl.Controls, Vcl.StdCtrls,
  Vcl.ExtCtrls,
  main;

type

  TFrmApp = class(TForm)
    BtnConnect: TButton;
    cbBridge: TCheckBox;
    Panel1: TPanel;
    Panel2: TPanel;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure BtnConnectClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    MyServer: TMyHTTPServer;
  public
  end;

var
  FrmApp: TFrmApp;

implementation

{$R *.dfm}

procedure TFrmApp.BtnConnectClick(Sender: TObject);
begin
  if (cbBridge.Checked) then
  begin
    IP_Bridge := Edit2.Text;
    Porta_Bridge := Edit1.Text;
  end;

  if Assigned(MyServer) then
  begin
    FreeAndNil(MyServer);
    BtnConnect.caption := 'Desconectado';
  end else
  begin

    MyServer := TMyHTTPServer.Create('773', 1);
    if (cbBridge.Checked) then
      MyServer.ServiceRegister(TMyClassBridge, TypeInfo(IMyInterface), '1')
    else
      MyServer.ServiceRegister(TMyClassDirect, TypeInfo(IMyInterface), '1');

    BtnConnect.caption := 'Connect';
  end;
end;

procedure TFrmApp.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(MyServer);
end;

end.

Main.pas

unit main;

interface

uses
  SynCommons, mORMot, mORMotHttpServer, mORMotHttpClient;


type

  TMyService = class(TSQLRestServerFullMemory)
  published
    procedure myapp(Ctxt: TSQLRestServerURIContext);
  end;

  TMyHTTPServer = class(TSQLHttpServer)
  private
    oModel: TSQLModel;
    oSQLRestServerFullMemory: TMyService;
  public
    function ServiceRegister(AImplementationClass: TInterfacedClass; const AInterfaces: PTypeInfo;
      const AContractExpected: RawUTF8): boolean;
    constructor Create(const APorta: RawUTF8; AThreadPoolCount: Integer); reintroduce;
    destructor Destroy; override;
  end;

  TMyHTTPClient = class
  private
    oSQLModel1: TSQLModel;
    oSQLHttpClient1: TSQLHttpClient;
    FIPServidor: String;
    FPortaMultiEmpresa: String;
  public
    constructor Create(const AIPServidor: String; const APortaServidor: String); overload;
    function HttpServerConnect: Boolean;
    function GetInterface(AInterface: PTypeInfo; const AVersaoInterface: RawUTF8; out Obj): Boolean;
    function ServerTimeStampSynchronize: Boolean;
    procedure CloseConnection;
  end;

  TMyObject = class
  private
    FFoo: RawUTF8;
  published
    property foo: RawUTF8 read FFoo write FFoo;
  end;

  IMyInterface = interface(IInvokable)
  ['{E6C6ADFD-5977-4759-B400-AA4140F1D683}']
    function sample: RawJSON;
  end;

  TMyClassDirect = class(TInterfacedObject, IMyInterface)
  public
    function sample: RawJSON;
  end;

  TMyClassBridge = class(TInterfacedObjectWithCustomCreate, IMyInterface)
  protected
    FInstanciaInterface: IMyInterface;
    oHTTPClient: TMyHTTPClient;
  public
    function sample: RawJSON;
    constructor Create; override;
    destructor Destroy; override;
  end;

var
  IP_Bridge: String;
  Porta_Bridge: String;

implementation

uses
  System.SysUtils, MainServer, Vcl.Forms, Winapi.Windows;

{ TMyClassBridge }

constructor TMyClassBridge.Create;
begin
  inherited;
  oHTTPClient := TMyHTTPClient.Create(IP_Bridge, Porta_Bridge);
  oHTTPClient.HttpServerConnect;
  oHTTPClient.GetInterface(TypeInfo(IMyInterface), '1', FInstanciaInterface);
end;

destructor TMyClassBridge.Destroy;
begin
  FreeAndNil(oHTTPClient);
  inherited;
end;

function TMyClassBridge.sample: RawJSON;
var
  iEmpresaTerminal: Cardinal;
begin
  try
    Result := FInstanciaInterface.sample;
  except
    on E:Exception do
      Result := E.Message;
  end;
end;

{ TMyClassDirect }

function TMyClassDirect.sample: RawJSON;
var
  MyObject: TMyObject;
begin

  MyObject := TMyObject.Create;
  MyObject.foo := 'bar';

  Result := ObjectToJson(MyObject, []);

  FreeAndNil(MyObject);
end;

{ TMyService }

procedure TMyService.myapp(Ctxt: TSQLRestServerURIContext);
var
  sFileName: TFileName;
begin
  sFileName := Ctxt.ResourceFileName;

  if sFileName = '' then
    Ctxt.Redirect('myapp/index.html')
  else
    Ctxt.ReturnFile(ExtractFilePath(Application.ExeName) + sFileName, true);

end;

{ TMyHTTPServer }

constructor TMyHTTPServer.Create(const APorta: RawUTF8; AThreadPoolCount: Integer);
begin
  oModel := TSQLModel.Create([], 'app');
  oSQLRestServerFullMemory := TMyService.Create(oModel, '', false, false);
  inherited Create(APorta, [oSQLRestServerFullMemory], '+', useHttpApiRegisteringURI, AThreadPoolCount);
end;

function TMyHTTPServer.ServiceRegister(AImplementationClass: TInterfacedClass; const AInterfaces: PTypeInfo;
  const AContractExpected: RawUTF8): boolean;
begin
  oSQLRestServerFullMemory.ServiceRegister(AImplementationClass,
    [AInterfaces], sicSingle).ContractExpected := AContractExpected;
  Result := true;
end;

destructor TMyHTTPServer.Destroy;
begin
  FreeAndNil(oModel);
  FreeAndNil(oSQLRestServerFullMemory);
  inherited;
end;

{ TMyHTTPClient }

procedure TMyHTTPClient.CloseConnection;
begin
  FreeAndNil(oSQLHttpClient1);
  oSQLHttpClient1 := nil;
  FreeAndNil(oSQLModel1);
  oSQLModel1 := nil;
end;

constructor TMyHTTPClient.Create(const AIPServidor,
  APortaServidor: String);
begin
  inherited Create;
  FIPServidor := AIPServidor;
  FPortaMultiEmpresa := APortaServidor;
end;

function TMyHTTPClient.GetInterface(AInterface: PTypeInfo;
  const AVersaoInterface: RawUTF8; out Obj): Boolean;
var
  sInterfaceName: RawUTF8;
begin
  Result := False;
  try
    if (HttpServerConnect) then
    begin
      sInterfaceName := Copy(AInterface.Name, 2, Length(AInterface.Name));

      if not(Assigned(oSQLHttpClient1.Services[sInterfaceName])) then
        Result := oSQLHttpClient1.ServiceRegister(AInterface, sicSingle, AVersaoInterface) <> nil;

      if (Result) then
        Result := oSQLHttpClient1.Services[sInterfaceName].Get(Obj);
    end;
  except
    on E:Exception do
    begin
      Result := False;
    end;
  end;
end;

function TMyHTTPClient.HttpServerConnect: Boolean;
var
  i: integer;
begin
  if (Assigned(oSQLHttpClient1)) then
    CloseConnection;

  for i := 1 to 2 do
  begin
    try
      if Assigned(oSQLModel1) then
        oSQLModel1.Free;

      oSQLModel1 := TSQLModel.Create([], 'app');
      oSQLHttpClient1 := TSQLHttpClient.Create(FIpServidor, FPortaMultiEmpresa ,
        oSQLModel1, False, '', '', 30000, 30000);

      Break;
    except
      on e: Exception do
      begin
        if i = 1 then
        begin
          oSQLHttpClient1.Free;
          oSQLModel1.Free;
        end
        else
          raise;
      end;
    end;
  end;

  Result := Assigned(oSQLHttpClient1) and (oSQLHttpClient1.ServerTimeStamp > 0);

  if (not(Result)) then
    raise Exception.Create('Connection server fail. ' +
      oSQLHttpClient1.LastErrorMessage + ' error code: ' +
      IntToStr(oSQLHttpClient1.LastErrorCode))

end;

function TMyHTTPClient.ServerTimeStampSynchronize: Boolean;
var
  dServerDateTime: TDateTime;
  dSystemTime: TSystemTime;
begin
  try
    Result := HttpServerConnect and oSQLHttpClient1.ServerTimeStampSynchronize;

    if (Result) then
    begin
      dServerDateTime := TimeLogToDateTime(oSQLHttpClient1.ServerTimeStamp);
      if (dServerDateTime > 0) then
      begin
        DateTimeToSystemTime(dServerDateTime, dSystemTime);
        SetLocalTime(dSystemTime);
      end;
    end;
  finally
    CloseConnection;
  end;
end;

end.

Json Valid (Direct)
http://127.0.0.1:773/app/MyInterface/sample

{"result":[{"foo":"bar"}]}

Json InValid (Bridge)
http://127.0.0.1:773/app/MyInterface/sample

{"result":[{"foo":"bar"}]]}

#9 Re: mORMot 1 » getting json invalid return with two methods called » 2014-10-03 14:36:39

sorry,

invalid json is

{"result":[{"Foo":"bar"}]]}

not

{"result":["Foo":"bar"}]}

including this character ]

#10 mORMot 1 » getting json invalid return with two methods called » 2014-10-03 12:54:44

edismo
Replies: 8

My application can have two different behave, depending on the customer's network.

Has two classes that implement the same interface.
One of the classes makes access to the database and the other creates a httpclient object to consume the class that makes access to the database.

All methods return RawJSON, when I use a simple structure that uses only one instance of the application class that makes access to the database JSON return is correct.

But when I use two instances of the application (consuming one another) the first return JSON is ok, and in the second the JSON is invalid.

See sample:

IMyInterface = interface (IInvokable)
  function sample: RawJSON;
end;

TMyClassDirect = class (TInterfacedObject, IMyInterface)
public
  function sample: RawJSON;
end;

TMyClassBridge = class (TInterfacedObjectWithCustomCreate, IMyInterface)
private
  fSQLModel: TSQLModel;
  fSQLHttpClient: TSQLHttpClient;
  fMyClassDirect: IMyInterface;
public
  function sample: RawJSON;
  constructor Create; override;
end;

function TMyClassDirect.sample: RawJSON;
var
  MyObject: TMyObject;
begin
  MyObject: = TMyObject.Create;
  MyObject.Foo: = 'bar';
  Result: = ObjectToJson (MyObject);
  FreeAndNil (MyObject);
end;

function TMyClassBridge.sample: RawJSON;
begin
  Result: = fMyClassDirect.Sample;
end;

valid JSON

http://{direct host}:778/root/app/sample 
{"result":[{"Foo":"bar"}]}

invalid JSON

http://{bridge host}:778/root/app/sample
{"result":["Foo":"bar"}]}

The difference is that it lacks the character {.

I hope you understood my explanation of the problem.

I can help?

#11 Re: mORMot 1 » THttpApiServer and TSQLRestServerFullMemory » 2014-09-23 16:39:59

Hello AB,

Thank you.

"localhost:888/root/Files" running my index.html file

It is possible to make "localhost 888/root/" redirects to index.html?

#12 Re: mORMot 1 » THttpApiServer and TSQLRestServerFullMemory » 2014-09-22 16:50:16

Hi again AB,

Similar of sample 26 - RESTful ORM with Blob method?

I do not understand, how or who will call the Files method.

Could you explain further or build a simple example with index.html?

Thank you for your attention

#14 mORMot 1 » THttpApiServer and TSQLRestServerFullMemory » 2014-09-19 14:49:01

edismo
Replies: 5

Hello ab,

I'm trying to integrate AngularJs and mORMot.
for development use the "grunt serves" to the single page app and it consumes one TSQLRestServerFullMemory server, it is working ok.

But to deploy THttpApiServer need to use a server as in example 09 - HttpApi web server. And I'm not understanding how this works.

Must have the same executable using THttpApiServer TSQLRestServerFullMemory?

Is this possible?
I did not understand the architecture?

thanks for listening

#16 mORMot 1 » mORMot + AngularJS is possible? » 2014-09-15 17:37:39

edismo
Replies: 2

Hi people,

I wonder if it is possible to consume one server mORMot with AngularJS  and if someone has already done this or know of any examples of how to do this.

Thanks

#17 PDF Engine » Image column » 2014-04-17 12:45:17

edismo
Replies: 1

Hi,

I need to add lines of text to the right of the image.
It is possible to add an image column?

I use DrawTextAcrossCols for String.

Maybe something like this:

  AddColumnHeaders(['Image','Description');
  AddColumn( 10,  50, caLeft, False); // Image
  AddColumn( 50, 100, caCenter, False); // String

  DrawAcrossCols(
    [MyBitmap, 'Line 1 description'],
      [drBMP, drText]);
  DrawAcrossCols(
    [nil, 'Line 2 description'],
    [drBMP, drText]);
  DrawAcrossCols(
    [nil, 'Line 3 description'],
    [drBMP, drText]);

#18 Re: PDF Engine » Report with only one page » 2014-04-17 11:45:27

Hi

I need print in mini printer of continuos paper.

I set height max 9469 (NewPageLayout(80,9469)), greater than that 9469 occurs error Out of system resources. But it does not solve why if the report has a few printed lines will print blank paper.

I tried to calculate previously the lines of the report but not very accurate, the report also has pictures.

I also tried to change the margins to remove the space between the pages, but did not work as expected.

That should work or is wrong?

    PageMargins := Rect(0,0,0,0);
    Top := 0;
    LeftMargin := 0;
    BeginDoc;

Can you help me with some alternative?

Thanks Ab.

#19 PDF Engine » Report with only one page » 2014-04-16 19:12:40

edismo
Replies: 2

Hi,

I use TGDIPages.NewPageLayout to define width and Height, but i need report with only one page, independent of Height.
It´s possibile?

#21 mORMot 1 » Filtering with property of set type » 2014-02-03 13:46:55

edismo
Replies: 2

I need help with ORM, do not know filtering with property of set type.

See a Sample:

TMySet = (msOne, msTwo);
TMySets = set of TMySet;

TSample = class(TSQLRecord)
private
  FMySets = TMySets;
published
  property   MySets = TMySets read FMySets write FMySets;
end;
...
var
  Sample: TSample;
begin
  Sample := TSample.CreateAnFillPrepare(SQLrest, 'MySets = ?, [Byte(msOne)]';

See records in table:

id | MySets
----------------
1|1 // msOne
2|2 // msTwo
3|3 // msOne and msTwo

I need to return two records when where clause is msOne or msTwo (bits 1 and 3 or 2 and 3).

In my sample return only one record, but not corresponding with where.
What do I need to return two records?

#23 Re: mORMot 1 » New function Iso8601ToDateTime » 2014-01-27 11:44:22

In Delphi 6 "Internal error: URW699" when compiling.
But PIso8601 (@ ADataIso8601mORMot) ^. ToDateTime works.
Iso8601ToDateTime is simpler

#24 mORMot 1 » New function Iso8601ToDateTime » 2014-01-24 18:37:53

edismo
Replies: 4

Hi AB,

Today exists Iso8601ToDateTime only RawUTF8 to TDateTime.
It´s possible new function add in SynCommons to convert Int64 to TDateTime?

Sample:

function Iso8601ToDateTime(const Value: Int64): TDateTime; overload;
begin
  Result := PIso8601(@Value)^.ToDateTime;
end;

I need using with IncDay.

Sample:

  ReferenceDate := IncDay(Iso8601ToDateTime(MySQLRecord.CreatedAt), Days);

#27 Re: mORMot 1 » Migrate table by hand » 2013-10-17 18:46:24

Thank AB.

Created the tiket

#28 Re: mORMot 1 » Migrate table by hand » 2013-10-17 18:00:38

The errors were returned: 400 - "Bad Request" and 1 - "no such table: SampleCopy".

I tryed create new instance of TSQLDataBase and run method execute('...rename...') before launching the ORM kernel, and running ok.
After Server.CreateMissingTables(0) tryed UnLock and run method execute('insert...'), but ocurred "database is locked".

Without CreateMissingTables(0) I can create table with erros.
And mORMot know create tables with types and collations correct better than me.

Is there any place where I can do this? Is it possible?

Thank AB

#29 Re: mORMot 1 » Migrate table by hand » 2013-10-17 12:47:07

Yes, run...
But my application must be able to know migrate alone. User does not know.
I really need to use the application to do this without any external tool.

Sorry, title "migrate by hand", better "migrate automatic", but code by hand and not automatic by mORMot.

#30 mORMot 1 » Migrate table by hand » 2013-10-16 20:05:10

edismo
Replies: 8

Hi

I create my TSQLRestClientDB in initialization and Server.CreateMissingTables(0) is executed in Create.

I need migrate a table to rename/alter type/remove a field, but without losing data.
Before of CreateMissignTables i need execute:

alter table SAMPLE rename to SAMPLECOPY

And after of CreateMissingTables i need execute

insert into SAMPLE select field1, field3 from SAMPLECOPY
drop table SAMPLECOPY

I tryed to use those methods  EngineExecute(), ExecuteList(), DB.ExecuteAll(), DB.Execute(), DB.ExecuteNoException(), but no results.


Can help me?

#32 Re: mORMot 1 » about mORMot.TSQLRestClientURI.ExecuteList » 2013-10-07 12:15:24

Thanks AB,

It worked!

This would be the best option?

var
   Person: TPerson;
   Car: TCar;
begin
   Person: = TPerson.CreateAndFillPrepare (DatabaseServer,'');
   Person.FillOne;
   EdtFirstName.Text: = Person.FirstName;
   EdtLastName.Text: = Person.LastName;
   Car: TCar.Create = (DatabaseServer, Person.Car);
   EdtCarColor.Text: = Car.Color;

#33 Re: mORMot 1 » about mORMot.TSQLRestClientURI.ExecuteList » 2013-10-04 19:20:37

Thanks AB,

I used RowID returned the same message: "SQL logic error or missing database '

  SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car where Person.Car = Car.RowID');

TSynDBProperties not found in documentation.
Found TSQLDBSQLite3ConnectionProperties = class (TSQLDBConnectionProperties), is this?

I not found method that returns TSQLTableJSON.
What would be the correct one to use?

#34 mORMot 1 » about mORMot.TSQLRestClientURI.ExecuteList » 2013-10-04 18:29:33

edismo
Replies: 6

Hi,

I'm having problems with mORMot.TSQLRestClientURI.ExecuteList.
I use the version 1.18.
see...

Simple example code...

Database information

  ConnectionProperties := TSQLDBSQLite3ConnectionProperties.Create('.\data\sample.db3','','','');
  VirtualTableExternalRegisterAll(MyModel, ConnectionProperties);
  inherited Create(MyModel, nil, ':memory:', TSQLRestServerDB);
  Server.CreateMissingTables(0);

Tables

TCar class=(TSQLRecord)
private
  fColor: RawUTF8;
published
  property   Color: RawUTF8 read fColor write fColor;
end;

TPerson class=(TSQLRecord)
private
  fFirstName: RawUTF8;
  fCar: TCar;
published
  FirstName: RawUTF8 read fFirstName write fFirstName;
  Car: TCar read fCar write fCar;
end;

Data for tables
Table Person
ID|FirstName|Car|
1|Chuck|1|

Table Car
ID|Color|
1|Red|

load data Person/Car

SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car');

it´s OK,
in SynSQLite3.TSQLRequest.Execute step return SQLITE_DONE
in mORMotDB.TSQLVirtualTableCursorExternal.Search (fStatement <> nill) is false

But...

// Multiples data for tables
Person table
ID|FirstName|Car|
1|Chuck|1|
2|Zinedine|2|

Car table
ID|Color|
1|Red|
2|Black|

Excpetion

SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car where Person.Car = Car.ID');

Exception occurs

in sqlite3.prepare_v2 return SQLITE_ERROR, then SynSQLite3.sqlite3_check raise
Message is: 'no such column: Car.Id'

Excpetion - remove condition where:

SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car');

then...
in SynSQLite3.TSQLRequest.Execute step return SQLITE_ERROR
in mORMotDB.TSQLVirtualTableCursorExternal.Search (fStatement <> nill) is true
Message is: 'SQL logic error or missing database'

Changing for:

SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName from Person');

Even including TCar and multiple records, but only from Person. Works.


Can you help me?That should work or not is the correct way?

Board footer

Powered by FluxBB