2012-11-23

Speed comparison between WCF, Java, DataSnap and mORMot

Roberto Scheinders wrote a nice blog post about performance and stability of DataSnap XE3, compared with mORMot and some other available frameworks.

Compared frameworks were:

  • DataSnap (Delphi)
  • mORMot (Delphi)
  • ASP.NET WCF
  • Jersey/Grizzly (Java)
  • Node.JS (JavaScript)

In short, DataSnap was slow and not stable (concurrent test was crashing the application), whereas mORMot was very stable, very fast (faster than any other in concurrent mode), and used much less memory.

Continue reading

2012-11-20

Authentication in mORMot using Windows credentials

By default, the hash of the user password is stored safely on the server side. This may be an issue for corporate applications, since a new user name / password pair is to be defined by each client, which may be annoying.

Since revision 1.18 of the framework, mORMot is able to use Windows Authentication to identify any user. That is, the user does not need to enter any name nor password, but her/his Windows credentials, as entered at Windows session startup, will be used.

Thanks a lot Chaa for making public your code proposal!
Open Source is so great sometimes!
Keep the good work!

Continue reading

2012-11-13

Go language and Delphi

Do you know the Go language?

It is a strong-typed, compiled, cross-platform, and concurrent.
It features some nice high-level structures, like maps and strings, and still have very low-level access to the generated code: pointers are there, in a safe strong-typed implementation just like in pascal, and there is even a "goto", which sounds like an heresy to dogmatic coders, but does make sense to me, at least when you want to optimize code speed, in some rare cases.

It is created/pushed by Google, used internally by the company in their computer farms, and was designed by one of the original C creators.

Continue reading

2012-10-28

SynDBOracle: Open Source native Oracle access

(this is an update of the article published in 2011/07)

For our mORMot framework, and in completion to our SynOleDB unit, we added a new Open Source unit, named SynDBOracle. It allows direct access to any remote Oracle server, using the Oracle Call Interface.

Oracle Call Interface (OCI) is the most comprehensive, high performance, native unmanaged interface to the Oracle Database that exposes the full power of the Oracle Database. We wrote a direct call of the oci.dll library, using our DB abstraction classes introduced for SynOleDB.

We tried to implement all best-practice patterns detailed in the official Building High Performance Drivers for Oracle document

Resulting speed is quite impressive: for all requests, SynDBOracle is 3 to 5 times faster than a SynOleDB connection using the native OleDB Provider supplied by Oracle. We noted also that our implementation is 10 times faster than the one provided with ZEOS/ZDBC, which is far from optimized.

You can use the latest version of the Oracle Instant Client provided by Oracle - see this link - which allows you to run your applications without installing the standard (huge) Oracle client or having an ORACLE_HOME. Just deliver the dll files in the same directory than your application, and it will work.

Continue reading

2012-10-18

Interfaces are not evil; or are Delphi-ers the new Vampires?

A very interesting comment by mpv in our forum highlighted some points about potential interface (ab)use:

IMHO: Idea is good, but "the devil is in the details". To use mocking I must use interfaces. When I use interfaces I lost control on code, because I don't see implementation. Debugging an optimization became very hard. Especially if a beginner developer read something like GOF (Gang Of Four) and wherever necessary and where not use design templates like Visitor, Decorator and so on, and in debugging I don't understand at all what class actually implement passed interface. As for me, this is a biggest problem for .NET framework - developers use interfaces, don't look on implementation (and often don't have it in sources at all), do not learn by reading someone else's code and therefore produce monkey-code. This is only IMHO...

Could sounds rude, and like a trolling subject, but I perfectly understand this point of view.
Introducing stubs and mocks in mORMot was not the open door to all problems.. but,on the contrary, to help write robust, efficient, and maintainable code.
It does not mean that using interfaces and C#/Java is the root of all evils and code inefficiency, but that it may lead into problems.

Continue reading

2012-10-14

Advanced mocks and stubs

Let's see some advanced topics about mORMot's mocking and stubbing features:

  • How to handle complex values in parameters / arguments or results, like record;
  • Stubbing via a custom delegate or callback;
  • Calls tracing.

Continue reading

Interfaces in practice: dependency injection, stubs and mocks

In order to fulfill the SOLID principles, two features are to be available when handling interfaces:

  • Dependency injection; 
  • Stubbing and mocking of interfaces for proper testing.

We will show now how mORMot provides all needed features for such patterns, testing a simple "forgot my password" scenario: a password shall be computed for a given user name, then transmitted via SMS, and its record shall be updated in the database.

Continue reading

Stubs and Mocks for Delphi with mORMot

Our mORMot framework is now able to stub or mock any Delphi interface.

As usual, the best way to explain what a library does is to look at the code using it.
Here is an example (similar to the one shipped with RhinoMocks) of verifying that when we execute the "forgot my password" scenario, we remembered to call the Save() method properly:

procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
    UserRepository: IUserRepository;
begin
  TInterfaceStub.Create(TypeInfo(ISmsSender),SmsSender).
    Returns('Send',[true]);
  TInterfaceMock.Create(TypeInfo(IUserRepository),UserRepository,self).
    ExpectsCount('Save',qoEqualTo,1);
  with TLoginController.Create(UserRepository,SmsSender) do
  try
    ForgotMyPassword('toto');
  finally
    Free;
  end;
end;

And... that's all, since the verification will take place when IUserRepository instance will be release.

If you want to follow the "test spy" pattern (i.e. no expectation defined a priori, but manual check after the execution), you can use:

procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
    UserRepository: IUserRepository;
    Spy: TInterfaceMockSpy;
begin
  TInterfaceStub.Create(TypeInfo(ISmsSender),SmsSender).
    Returns('Send',[true]);
  Spy := TInterfaceMockSpy.Create(TypeInfo(IUserRepository),UserRepository,self);
  with TLoginController.Create(UserRepository,SmsSender) do
  try
    ForgotMyPassword('toto');
  finally
    Free;
  end;
  Spy.Verify('Save');
end;

This is something unique with our library: you can decide if you want to use the classic "expect-run-verify" pattern, or the somewhat more direct "run-verify" / "test spy" pattern.
With mORMot, you pick up your mocking class (either TInterfaceMock or TInterfaceMockSpy), then use it as intended. You can even mix the two aspects in the same instance! It is just a matter of taste and opportunity for you to use the right pattern.

Continue reading

- page 30 of 52 -