#101 Re: mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-28 12:04:54

Arnold, I would like to thank you for your comments here and apologize for the lack of knowledge in the framework, I'm still new to mormot, but I'll get there. Digging around the framework I discovered the properties:

TServiceFactoryServer's SetWholeOption([???])
optResultAsJsonObjectWithoutResult or optResultAsJsonObject

I just put the optResultAsJsonObjectWithoutResult option and the json I wanted was already returned the way I needed it.

function Busca(pId: Int64; var abc: TDTOProjeto; out pProjeto: TDTOProjeto; out pPaineis: TDTOPaineis): TServiceCustomStatus;

{
    "abc": {
        "RowID": 1,
        "Nome": "Projeto c",
        "DataCriacao": "2023-03-18T12:34:09",
        "UltimaAlteracao": "2023-03-18T12:34:09",
        "IdCriador": 5,
        "Paineis": []
    },
    "pProjeto": {
        "RowID": 1,
        "Nome": "Projeto c",
        "DataCriacao": "2023-03-18T12:34:09",
        "UltimaAlteracao": "2023-03-18T12:34:09",
        "IdCriador": 5,
        "Paineis": [
            {
                "RowID": 1,
                "Nome": "painel a",
                "DataCriacao": "2023-03-20T10:08:48",
                "UltimaAlteracao": "2023-03-20T10:08:48",
                "IdCriador": 5,
                "IdProjeto": 1
            }
        ]
    },
    "pPaineis": [
        {
            "RowID": 1,
            "Nome": "painel a",
            "DataCriacao": "2023-03-20T10:08:48",
            "UltimaAlteracao": "2023-03-20T10:08:48",
            "IdCriador": 5,
            "IdProjeto": 1
        }
    ],
    "Result": 0
}

long live the mormot!

#102 Re: mORMot 1 » Implementing OAuth2 » 2023-03-23 09:54:45

I world like a copy too please. Cannyou put on github?

#103 Re: GDI+ » RTL Error on closing delphi when using SYNGDI » 2023-03-21 16:28:33

I can do this into component, or i will need call manually into application when using the component?

#104 Re: GDI+ » RTL Error on closing delphi when using SYNGDI » 2023-03-21 11:27:46

i have commented the picture (GIF) that was registred. the error happen yet

I removed TGifImage of matrixes too

const
  PicturesExt: array[0..4] of TFileName =
    ('jpg','jpeg','png','tif','tiff');
  PictureClasses: array[0..4] of TGraphicClass =
    (TJpegImage,TJpegImage,TPngImage,TTiffImage,TTiffImage);

....

procedure TGDIPlus.RegisterPictures;
var
  i: integer;
begin
  SendDebug('register!');
  // launch Gdip.RegisterPictures to initialize the GDI+ library if necessary
  if (Self=nil) and (Gdip=nil) then
  begin
    SendDebug('gdipo criando!');
    Gdip := TGDIPlus.Create('gdiplus.dll');
  end;
  // register JPG and PNG pictures as TGraphic
  if GetClass('TTiffImage')=nil then
  begin
    RegisterClass(TJpegImage);
    RegisterClass(TPngImage);
    //RegisterClass(TGifImage);   <<<<<<<<<<<<
    RegisterClass(TTiffImage);
    for i := 0 to high(PicturesExt) do
      TPicture.RegisterFileFormat(PicturesExt[i],
        PictureName(PictureClasses[i]),PictureClasses[i]);
  end;
end;

#105 GDI+ » RTL Error on closing delphi when using SYNGDI » 2023-03-20 21:13:10

mrbar2000
Replies: 4

AB,

Do you still provide any support for SynGDI Plus?

I have created a ThumbView component that uses the GR32 lib. In this component I put:

uses
  Windows, Messages, Math, SysUtils, Classes, Controls, Types,
  StdCtrls, Dialogs, Contnrs, CommCtrl, ActiveX, Graphics, Forms,
  GR32_Image, GR32, GR32_Transforms, GR32_RangeBars, GR32_Blend,
  SynGdiPlus,
  BackgroundWorker;

....

//initialization
//  Gdip.RegisterPictures;
end.

When I install the component without this initialization I can close delphi without any problems.

but if i uncomment that initialization Gdip.RegisterPictures, when I close delphi I get the following message

erro.png

#106 Re: GDI+ » Register SynGdiPlus formats in Delphi 7 IDE? » 2023-03-19 13:07:47

I have The same problem. I remove line that registerclass tgif because my delphi são that is duplicated register class.

Then now when I closet The delphi I get a Access violation in rtl70.bpl

#107 Re: mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-18 13:15:55

What u think Arnold?

What i can see about the code, all workflow abou soa via interfaces is internal. Then i think this idea is viable.

#108 Re: mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-15 14:27:40

Good Morning Arnold,

I thought TServiceCustomStatus was only for non mormot clients.

Atualmente o mormot traz no result uma matriz com valores diversos. E não é possível ler isso de clientes não mormot. Veja isso.

TPaineis = array or TPainel

function BuscaPaineis(idProject: integer; out paineis: TPaineis): boolean;

// if I put an idProject that doesn't exist, for example, a Json arrives in this format:
{
  "result" = [ [], false ]
}

// if I put an idProject that exists for example a Json arrives in this format:
{
  "result" = [ [{"painel": 'painel1'}, {"painel": 'painel1'}],  true ] 
}

A non-mormot client is expecting just an array of TPainel. Which is not the case with the true and false into array.

An example response that mormot could return and handle without impacting applications that use interface-based SOA could look like this:

function BuscaPaineis(idProject: integer; out paineis: TPaineis): boolean;

{
  "result" = [{"painel": 'painel1'}, {"painel": 'painel1'}],
  "return" = true
}

I will further detail the problems I am trying to solve as I want to work with interface based SOA. But I need the mormot server to return the JSON in a way that can be read by any 3rd party application.

1) Return the custom HTTP code
2) The returned JSON should follow a pattern for when the result is 200..399.
3) When the return is 400..599 I need the returned JSON to follow an exception pattern with the proper error message. This type really should not be an exception, even though they are expected errors. They should not be logged or handled by the framework.

When I use TServiceCustomStatus I can return the statuscode that I want, great!
But when I return a code between 400...599 I have to return a Json with the reason for this error.
So I thought of TServiceCustomStatus as a record. And I adjusted the code so that anyone who wants to use Mormot and is not using a Mormot client.

Maybe a way to standardize this would be that every return from mormot would return

{ 
    "<result> or <classname>": <Jsonobject> or <JsonArray> 
    "errormessage": "<empty> or <custom error message>"  <<< not out parameter but a TServiceCustomStatus.ErroMessage field 
    "return" : <null is procedure> or <value of function result>   <<< if function is TServiceCustomStatus then TServiceCustomStatus.Status
}

Without losing the cardinal TServiceCustomStatus obviously. HTTPStatus code would return TServiceCustomStatus.Status too.

I'm asking this because my frontend tool (as well as many others) already evaluates the http statuscode to be able to direct the workflow to a success or error routine.

We don't always have control over the frontend that will be using our API, and some of these clients don't have the facility to change their programming.
I know someone here may say that it is the clients that should implement according to the API specification, but I have clients that use no-code tools that just receive the json and treat this json according to the returned http statuscode.

In summary. Your mormot clients would not have to change their programming at all, because if I have the following methods in the interface they would return the following json:

function TABC.FindOrder(Id: Integer; out Order: TOrder; out Items: TItems): TServiceCustomStatus;
{ 
    "output1" or "order": { "id": 1, ... } 
    "output2" or "items": [{ "id": 10, ... }, { "id": 11, ... }, { "id": 12, ... }]
    "errormessage": ""
    "return" : 200  <<<< the same of HTTPStatus code returned
}

function TABC.FindOrder(Id: Integer; out Order: TOrder; out Items: TItems): boolean;
{ 
    "output1" or "order": { "id": 1, ... } 
    "output2" or "items": [{ "id": 10, ... }, { "id": 11, ... }, { "id": 12, ... }]
    "errormessage": ""
    "return" : true <<<< HTTPStatus code always 200 if result <> TServiceCustomStatus
}

To internaol SOA process, "errormessage" field would be ignored unless the programmer put an out errormessage in the parameters.

#109 Re: mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-14 15:09:03

Hi, I make some changes in TServiceCustomStatus
and put a PR #160

What did u think?
Are u see some problem in my changes?

#110 Re: mORMot 2 » TOrm with ChildObjects » 2023-03-08 13:11:36

Hi guys I try. look this sample:

  TPainel = class;

  TPaineis = array of TPainel;

  TProjeto = class(TOrm)
  private
    FPaineis: TPaineis;
  published
    property Paineis: TPaineis read FPaineis;
  end;

  TPainel = class(TOrm)
  private
    FIdProjeto: TProjeto;
  published
    property IdProjeto: TProjeto read FIdProjeto write FIdProjeto;
  end;

when I use this code

function TProjetoService.Busca(pId: Int64): TServiceCustomAnswer;
var
  vProjeto: TProjeto;
  vAuto: IAutoFree;
begin
  vAuto := TOrm.AutoFree([@vProjeto, TProjeto]);
  if not GlobalRepository.Orm.Retrieve(pId, vProjeto) then
    Result := ReturnRecordNotFound
  else
    Result.Content := ObjectToJson(vProjeto);
end;

I receive this:

{
    "RowID": 1,
    "Nome": "Projeto a",
    "DataCriacao": 135770589581,
    "UltimaAlteracao": 135770590233,
    "IdCriador": 5,
    "Paineis": "[{\"RowID\":1,\"Nome\":\"painel a\",\"DataCriacao\":0,\"UltimaAlteracao\":0,\"IdCriador\":5,\"IdProjeto\":1},{\"RowID\":2,\"Nome\":\"painel b\",\"DataCriacao\":0,\"UltimaAlteracao\":0,\"IdCriador\":5,\"IdProjeto\":1},{\"RowID\":3,\"Nome\":\"painel c\",\"DataCriacao\":0,\"UltimaAlteracao\":0,\"IdCriador\":5,\"IdProjeto\":1}]"
}

I whould like this:

{
    "Id": 1,
    "Nome": "Projeto a",
    "IdCriador": 5
    "Paineis": [
        {
	    "Id": 1,
	    "Nome": "painel a",
	    "IdCriador": 5,
	    "IdProjeto":1
	 },
	{
	    "Id": 2,
	    "Nome": "painel b",
	    "IdCriador": 5,
	    "IdProjeto":1
	 },
	{
	    "Id": 3,
	    "Nome": "painel c",
	    "IdCriador": 5,
	    "IdProjeto":1
	}
    ]
}

1) How orm method i should be use to RETRIEVE the object TProjeto with the array Paineis filled? There are some?

2) This model create 2 tables Painel and Projeto but fill just Projeto and create a string field into Projeto table to store all TPanel as json. How I can store projeto and painel in diferent tables, but yet so make the same RETRIEVE above?

#112 Re: mORMot 2 » TOrm with ChildObjects » 2023-03-07 12:54:37

In this sample TBO. What type of TOrmPhoneObjArray? and How I can get a person id=? and the orm bring the person with all phones?

#113 Re: mORMot 2 » TOrm with ChildObjects » 2023-03-07 12:18:19

Thanks. Phone is just a sample.

I will use this strategy for more complex classes. Order and OrderItem for sample.
I dont think that OrderItem shoud be saved into a blob into order table.

Reasons:
1) Will be dificult mount reports. because by default FastReport and others reports generators work with Datasets, then we need get the records master detail in tables.
2) A bussiness inteligence tool that work with database need get OrderItems to make the graphics. Imagine this stored in blobs.
3) How to find something into objects that are store in this field blob?
    Sample1: I want bring all orders that have product "xyz" (where product is into a blob field)
    Sample2: I want sum(orderitem.total) where product "xyz" in a period (where product is into a blob field)
4) I think that exist other reason that do not appear in my mind at the moment.

How u treat this? Store all objects as documents (nosql style)?

#114 Re: mORMot 2 » TOrm with ChildObjects » 2023-03-06 19:08:00

I see all documentation. But TOrmMany is to pivottable, and i dont have source and dest in this case.
I what just a property returning list of objects TPhone into person!
Or I dont understand very well how to use!

Remerber that Tperson 1 - (0..n) Tphone (on database are different tables)

#115 Re: mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-06 15:45:10

Problem with this is that we have to treat all input/output parameters of service method, getting of Ctx. very hard work!

There are some other way?

#116 mORMot 2 » TOrm with ChildObjects » 2023-03-06 15:42:11

mrbar2000
Replies: 9

I Have 2 tables in my database

Person (id, name)
Phone (id, idPerson, number)

1) How can i map this in mormot?

  TPerson = class;

  TPhone = class(TOrm);
  private
    FIdPerson: TPerson;
    FNumber: RawUTF8;
  published
    property Number: RawUTF8 index 25 read FNumber write FNumber;
    property IdPerson: TPerson read FIdPersonwrite FIdPerson;
   

  TPerson = class(TOrm)
  private
    FNome: RawUTF8;
  published
    property Nome: RawUTF8 index 100 read FNome write FNome;
    property Phones: ???????? read FPhones   <<<<  that property type can i use here? (need persist in 2 separated tables)
  end;

2) How I can call retrieve on orm and bring some person (id=10 for sample) and all your Phones?

#117 mORMot 2 » SOA by Interfaces with custom HTTP Status » 2023-03-06 14:00:11

mrbar2000
Replies: 11

Hi All,

I see that when implementing services interface based the framework always return 200.
But we whould like return others httpstatus.

then we discover TServiceCustomAnswer. this resolve the httpstatus problem, but this return do not accept parameters out neither var

sample. What i would like do:

function TProjetoService.GetProjetoPaineis(out pProjeto: TOrmProjeto): TServiceCustomAnswer;
begin
  if not FRestOrm.Retrieve(pProjeto.Id, pProjeto) then
    Result := ReturnError(Format('(%s) '+cErrorRecordNotFound, [GetClassName]), HTTP_NOTFOUND)
  // else following the course, will return 200 ok!!!!
end;

function TServiceBase.ReturnError(const pErrorMessage: RawUTF8; pStatus: cardinal): TServiceCustomAnswer;
var
  vError: Variant;
begin
  TDocVariant.New(vError);
  vError.ErrorMessage := pErrorMessage;
  vError.StatusCode := pStatus;
  Result.Content := VariantSaveJson(vError);
  Result.Status := pStatus;
end;


How we can do this? What the recomendation?

#118 Re: mORMot 2 » Validation, Nullables, FKs » 2023-03-03 01:44:37

ab wrote:

2) You have a set of TSynFilter and TSynValidate sub-classes available at ORM level.

Ok then, if by sample, I want validate a integer field at ORM Level, to just receive values > 5, what validate TSynValidate sub-classes i should be to use? TSynValidatePattern? I hate regular expressions. How u would do? should I be make others subclasses?

ab wrote:

ti-pattern to let other projects make direct changes to the DB (******* I AGREE *******)

All right. Still talking about foreign key, constraints, and not null fields. Is there any way to intercept the creation of the table and fields in order to add these options to the database according to the reading via RTTI of the TOrm classes? I know that some types database does not have these options, but most databases have.

Maybe we can embedded some class on ORM that implement some interface where we could put things like foreign key, constraints, not null fields, descriptions etc...

I'm only saying this Arnold because many developers are so rooted in their old relational paradigms that they would find it very odd that the ORM framework doesn't provide this natively. Then we could offer the possibility for these people to see MORMOT as a tool they can trust. not that it makes a difference to you or me. do you understand?

What you think?

#119 mORMot 2 » Validation, Nullables, FKs » 2023-03-01 21:00:33

mrbar2000
Replies: 3

I start my study and develop with mormot, congratulations, excelent framework.

Some doubts.

1) I see on documentation that I can use TNullableXXX to treat nullables.
This is working on mormot2?
How ORM can create database field as "not null"? CreateMissingTables are creating all fields as "accept null"

2) Where I find the validators class to make things as:
    - field is filled or is null (field integer or string).
    - Length validator
    - max and min values
    - number interval
    - etc... (i just see to ipvalidator email and some others)

3) Serious that framwork do not generate FK Keys?
    This is a great problem when database is filled by others applications, or if the programmer need make changes on database directly.
    how u grant the integrity in yours applications guys?

#121 mORMot 2 » A framework RESTFULL using Interfaces » 2023-02-24 21:56:49

mrbar2000
Replies: 1

Hi Guys,

I starting develop mormot using mormot2.
I trying build a ticket system as prove of concept.

I had read this topics and I would like know why not can use PUT/DELETE with SOA interfaced based?
https://synopse.info/forum/viewtopic.php?id=1833

Congratulations for the Server.Route.Get/Post/Put/Delete article. I'm using this approach.
But do not works to DELETE/PUT

Server.Route.Get('/projeto/<id>', 'root/find/<id>');  // works
Server.Route.Delete('/projeto/<id>', 'root/delete/<id>');  // dont works

Why Route DELETE cannot get the instace of service and call your delete(id: integer) method as the GET does?

And some base classe that implements IInvokable could expose a virtual method called DoRequest(Ctxt: TRestServerUriContext)? so the programmer could be treat others situations not implemented by mormot!


What you think?

#122 Re: Other components » UDP Sample of SynCRTSocket » 2016-10-27 12:47:02

Can you post some few lines of code about:

1 - how to Send message strings? this is correct way?

  FClient := TCrtSocket.Open('192.168.1.255', '12001', cslUDP);

  if FClient.SockIn = nil then
    FClient.CreateSockIn;
  if FClient.Sock < 0 then
  begin
    ShowMessage('Socket not found!');
    exit;
  end;
  FClient.SockSend(['Teste aaaaaaaaaaaaaaa']);
  FClient.SockSendFlush;   <<<< I neeed really this??????

lookin on wireshark i see :

41    2.147148    192.168.1.72    192.168.1.255    LLC    65    U F, func=UA; DSAP ISO Network Layer (OSLAN 2) Individual, SSAP 0x64 Response
Why Wireshark shows LLC instead UDP???????

2 - how to Send message steams?

3 - how to treat exceptions?

#123 Other components » UDP Sample of SynCRTSocket » 2016-10-26 21:44:41

mrbar2000
Replies: 2

I need use UDP communication, but i dont see any sample about your use?

Can anyone here post a simple sample of client and server using this protocol??

Thanks

Board footer

Powered by FluxBB