Skip to content

DelphiMVCFramework 3.2.0-boron-RC5

Pre-release
Pre-release
Compare
Choose a tag to compare
@danieleteti danieleteti released this 13 Feb 23:02
· 1180 commits to master since this release

WARNING! This release fixes a serious vulnerability which affects some deployments which use the built-in WebServer. It doesn't add new features and fix only this issue. However, it is a strongly raccomended update for all dmvcframework users which use the built-in webserver to serve static files.

Many thanks to Stephan Munz to have discovered the bug.

  • New! Added Nullable support in MVCActiveRecord! Check activerecord_showcase sample.
  • New! Complete support for nullable types in the default serializer.
  • New! Added Swagger support (thanks to João Antônio Duarte and Geoffrey Smith)
  • New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
  • New! Added support for interfaces serialization - now it is possible to serialize Spring4D collections (thanks to João Antônio Duarte)
  • New! Added support for Spring4D Nullable Types - check (thanks to João Antônio Duarte)
  • Added TMVCJSONRPCExecutor.ConfigHTTPClient to fully customize the inner THTTPClient (e.g. ConnectionTimeout, ResponseTimeout and so on)
  • Improved! Now the router consider Accept:*/* compatible for every MVCProduces values
  • Improved! Greatly improved support for HATEOAS in renders. Check TRenderSampleController.GetPeople_AsObjectList_HATEOS and all the others actions end with HATEOS in renders.dproj sample)
//Now is really easy to add "_links" property automatically for each collection element while rendering
Render<TPerson>(People, True,
    procedure(const APerson: TPerson; const Links: IMVCLinks)
    begin
      Links.AddRefLink
        .Add(HATEOAS.HREF, '/people/' + APerson.ID.ToString)
        .Add(HATEOAS.REL, 'self')
        .Add(HATEOAS._TYPE, 'application/json')
        .Add('title', 'Details for ' + APerson.FullName);
      Links.AddRefLink
        .Add(HATEOAS.HREF, '/people')
        .Add(HATEOAS.REL, 'people')
        .Add(HATEOAS._TYPE, 'application/json');
    end);

		
//Datasets have a similar anon method to do the same thing
Render(lDM.qryCustomers, False,
  procedure(const DS: TDataset; const Links: IMVCLinks)
  begin
	Links.AddRefLink
	  .Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
	  .Add(HATEOAS.REL, 'self')
	  .Add(HATEOAS._TYPE, 'application/json');
	Links.AddRefLink
	  .Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString + '/orders')
	  .Add(HATEOAS.REL, 'orders')
	  .Add(HATEOAS._TYPE, 'application/json');
  end);

//Single object rendering allows HATEOAS too!
Render(lPerson, False,
  procedure(const AObject: TObject; const Links: IMVCLinks)
  begin
	Links.AddRefLink
	  .Add(HATEOAS.HREF, '/people/' + TPerson(AObject).ID.ToString)
	  .Add(HATEOAS.REL, 'self')
	  .Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
	Links.AddRefLink
	  .Add(HATEOAS.HREF, '/people')
	  .Add(HATEOAS.REL, 'people')
	  .Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
  end);
	
  • Better packages organization (check packages folder)
  • New! TMVCActiveRecord.Count method (e.g. TMVCActiveRecord.Count(TCustomer) returns the number of records for the entity mapped by the class TCustomer)
  • Change! TMVCACtiveRecord.GetByPK<T> raises an exception by default if the record is not found - optionally can returns nil using new parameter RaiseExceptionIfNotFound
  • New! contains clause has been added in the RQL compiler for Firebird and Interbase
  • New! TMVCAnalyticsMiddleware to do automatic analytics on the API (generates a CSV file). Based on an idea by Nirav Kaku (https://www.facebook.com/nirav.kaku). Check the sample in \samples\middleware_analytics\
  • New! TMVCActiveRecord.DeleteAll deletes all the records from a table
  • New! TMVCActiveRecord.DeleteRQL deletes records using an RQL expression as where clause.
  • New! TMVCActiveRecord.Store which automatically executes Insert or Update considering primary key value.
  • New! Microsoft SQLServer Support in MVCActiveRecord and RQL (thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework and DMSContainer)
  • New! SQLite support in MVCActiveRecord and RQL, so that MVCActiveRecord can be used also for Delphi mobile projects!
  • Default JSON Serializer can verbatim pass properties with type JsonDataObjects.TJSONObject without using string as carrier of JSON
  • Improved! ActiveRecordShowCase sample is much better now.
  • Improved! In case of unhandled exception TMVCEngine is compliant with the default response content-type (usually it did would reply using text/plain).
  • Added! New overloads for all the Log* calls. Now it is possible to call LogD(lMyObject) to get logged lMyObject as JSON (custom type serializers not supported in log).
  • New! StrDict(array of string, array of string) function allows to render a dictionary of strings in a really simple way. See the following action sample.
procedure TMy.GetPeople(const Value: Integer);
begin
  if Value mod 2 <> 0 then
  begin
    raise EMVCException.Create(HTTP_STATUS.NotAcceptable, 'We don''t like odd numbers');
  end;
  Render(
    StrDict(
      ['id', 'message'],
      ['123', 'We like even numbers, thank you for your ' + Value.ToString]
    ));
end;
  • New! Custom Exception Handling (Based on work of David Moorhouse). Sample "custom_exception_handling" show how to use it.
  • Improved! Exceptions rendering while using MIME types different to application/json.
  • Improved! JSONRPC Automatic Object Publishing can not invoke inherited methods if not explicitly defined with MVCInheritable attribute.
  • SSL Server support for TMVCListener (Thanks to Sven Harazim)
  • Improved! Datasets serialization speed improvement. In some case the performance improves of 2 order of magnitude. (Thanks to https://github.com/pedrooliveira01)
  • New! Added in operator in RQL parser (Thank you to João Antônio Duarte for his initial work on this)
  • New! Added TMVCActiveRecord.Count<T>(RQL) to count record based on RQL criteria
  • New! Calling <jsonrpcendpoint>/describe returns the methods list available for that endpoint.
  • New! Experimental (alpha stage) support for Android servers!
  • New! Added support for X-HTTP-Method-Override to work behind corporate firewalls.
  • New Sample! Server in DLL
  • Added new method in the dataset helper to load data into a dataset from a specific JSONArray property of a JSONObject procedure TDataSetHelper.LoadJSONArrayFromJSONObjectProperty(const AJSONObjectString: string; const aPropertyName: String);
  • Improved! New constants defined in HTTP_STATUS to better describe the http status response.
  • Improved! Now Firebird RQL' SQLGenerator can include primary key in CreateInsert if not autogenerated.
  • New! Added support for TArray<String>, TArray<Integer> and TArray<Double> in default JSON serializer (Thank you Pedro Oliveira)
  • Improved JWT Standard Compliance! Thanks to Vinicius Sanchez for his work on issue #241
  • Improved! DMVCFramework now has 130+ unit tests that checks its functionalities at each build!
  • New! StrToJSONObject function to safely parse a string into a JSON object.
  • New! Serialization callback for custom TDataSet descendants serialization in TMVCJsonDataObjectsSerializer.
procedure TMainForm.btnDataSetToJSONArrayClick(Sender: TObject);
var
  lSer: TMVCJsonDataObjectsSerializer;
  lJArray: TJSONArray;
begin
  FDQuery1.Open();
  lSer := TMVCJsonDataObjectsSerializer.Create;
  try
    lJArray := TJSONArray.Create;
    try
      lSer.DataSetToJsonArray(FDQuery1, lJArray, TMVCNameCase.ncLowerCase, [],
        procedure(const aField: TField; const aJsonObject: TJSONObject; var Handled: Boolean)
        begin
          if SameText(aField.FieldName, 'created_at') then
          begin
            aJsonObject.S['year_and_month'] := FormatDateTime('yyyy-mm', TDateTimeField(aField).Value);
            Handled := True;
          end;
        end);
	  //The json objects will not contains "created_at" anymore, but only "year_and_month".
      Memo1.Lines.Text := lJArray.ToJSON(false);
    finally
      lJArray.Free;
    end;
  finally
    lSer.Free;
  end;
end;
  • New! Shortcut render' methods which simplify RESTful API development

    • procedure ResponseCreated(const Location: String = ''; const Reason: String = 'Created'); virtual;
    • procedure ResponseAccepted(const HREF: String; const ID: String; const Reason: String = 'Accepted'); virtual;
    • procedure ResponseNoContent(const Reason: String = 'No Content'); virtual;
  • Added de/serializing iterables (e.g. generic lists) support without MVCListOf attribute (Thank you to João Antônio Duarte).

    It is now possible to deserialize a generic class like this:

      TGenericEntity<T: class> = class
      private
        FCode: Integer;
        FItems: TObjectList<T>;
        FDescription: string;
      public
        constructor Create;
        destructor Destroy; override;
        property Code: Integer read FCode write FCode;
        property Description: string read FDescription write FDescription;
        // MVCListOf(T) <- No need
        property Items: TObjectList<T> read FItems write FItems;
      end;

    Before it was not possible because you should add the MVCListOf attribute to the TObjectList type property.

  • New! The MVCAREntitiesGenerator can optionally register all the generated entities also in the ActiveRecordMappingRegistry (Thanks to Fabrizio Bitti from bit Time Software)

  • Fixed! issue184

  • Fixed! issue278

  • Fixed! issue164

  • Fixed! issue182

  • Fixed! issue232 (Thanks to João Antônio Duarte)

  • Fixed! issue289 (Thanks to João Antônio Duarte)

  • Fixed! issue291 (Thanks to João Antônio Duarte)

  • Fixed! issue305 (Thanks to João Antônio Duarte)

  • Fixed! issue312

  • Breaking Change! In MVCActiveRecord attribute MVCPrimaryKey has been removed and merged with MVCTableField, so now TMVCActiveRecordFieldOption is a set of foPrimaryKey, foAutoGenerated, foTransient (check activerecord_showcase.dproj sample).

  • Breaking Change! Middleware OnAfterControllerAction are now invoked in the same order of OnBeforeControllerAction (previously were invoked in reversed order).

  • Breaking Change! TDataSetHolder doesn't renders dataset in a property called items but in a property named data (to be more standard).

  • Fixed! Has been patched a serious security bug affecting deployment configurations which uses internal WebServer to serve static files (do not affect all Apache, IIS or proxied deployments). Thanks to Stephan Munz to have discovered it. Update to dmvcframework-3.2-RC5+ is required for all such kind of deployments.

  • New Installation procedure!

    • Open the project group (select the correct one from the following table)
    • Build all
    • Install the design-time package (dmvcframeworkDT)
    • Add the following paths in the Delphi Library Path (here, C:\DEV\dmvcframework is the dmvcframework main folder)
      • C:\DEV\dmvcframework\sources
      • C:\DEV\dmvcframework\lib\loggerpro
      • C:\DEV\dmvcframework\lib\swagdoc\Source
      • C:\DEV\dmvcframework\lib\dmustache
Delphi Version Project Group
Delphi 10.3 Rio packages\d103\dmvcframework_group.groupproj
Delphi 10.2 Tokyo packages\d102\dmvcframework_group.groupproj
Delphi 10.1 Berlin packages\d101\dmvcframework_group.groupproj
Delphi 10.0 Seattle packages\d100\dmvcframework_group.groupproj