You are not logged in.
It appears to be an interesting framework and just turns 3.0 (A lot of messages in fpc-pascal mail list today ). http://silvioprog.github.io/brookframework/
From its webpage: the Brook features
Advanced routes management – Actions are performed by means of routes. Brook knows how to receive a request and choose the correct URL and the correct method to reply to it.
Integrated data persistance – Brook offers a table object where data can be handled. Less instantiations, less coding, with an elegant syntax.
JSON native support – JSON is widespred in the web for data exchange purposes. You will really appreciate Brooks' good JSON support.
REST architecture support – REST is an architecture able to simplify and standardize data requests and replies. Brook is powerful even if you don't use REST – but you will want to use it.
Lazarus wizards for installation and usage - With Lazarus, development is easier; with the Brook wizards, only a few clicks are required to start and configure your Brook projects.
Could you help to share your opinions on it ? e.g., architectural, performance-wise, roadmap/future ...
On a side effect, it is noted that Brook can run in four modes:
CGI (with any HTTP server like Apache, nginx etc.);
FastCGI (with any HTTP server like);
Stand alone (with embedded server);
Stand alone service/daemon (with embedded daemon server).
Probably this helps with mORMot's switching to Linux ?
Last edited by ComingNine (2014-05-14 15:08:27)
Offline
Thank you for your time and knowledgeable comments !
Offline
Not much to see in this project yet...
Sounds more like a toy library to me.
For instance, the opf is a joke and features are pretty basic.
@ab, with respect, I think what you said is not fair to the brook framework.
Although I have not fully evaluated and test it, IIRC, just like Python's popular and elegant Flask web framework (http://flask.pocoo.org/), I guess Brook fro FPC is also inspired by the Sinatra framework for Ruby (http://www.sinatrarb.com/).
Actually, almost every mainstream languages has one or more Sinatra-inspired web framework that are quite widely used, well, except Dephi (http://en.wikipedia.org/wiki/Sinatra_(s … by_Sinatra)
That being said, the philosophies beyind all those Sinatra-inspired frameworks like brook are:
**simplicity** and **flexibility**
A quote from the wikipedia: the goal is to "quickly creating web-applications with minimal effort."
Want to use another ORM or data persistence library? No problem, and most importantly - it's easy and simple from the coder's POV, since usually you can just plug-in an extension or module.
In additional to **simplicity** (which has/is always a good thing and nowadays people embrace ), another benefit of Brook is **cross-platform**. (well, I really wish mormot will fully support free Pascal in the near future!)
What I said above doesn't remove my praise to mORMot, of course, but saying brook is a toy is far from fair.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
You have to code all route by hand.
See for instance the REST demo: you have to code every request with its own method.
Compare it with mORMot:
procedure TForm1.FormCreate(Sender: TObject);
begin
Model := TSQLModel.Create([TSQLSampleRecord]);;
DB := TSQLRestServerDB.Create(Model,ChangeFileExt(paramstr(0),'.db3'),true);
DB.CreateMissingTables(0);
Server := TSQLHttpServer.Create('8080',[DB],'+',useHttpApiRegisteringURI);
Server.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries
end;
I really like very much the "convention over configuration" aspect of mORMot.
To add a new table, just write:
Model := TSQLModel.Create([TSQLSampleRecord,TSQLRecord2]);;
There is a clean design of the data model.
In fact, TSQLModel is one big difference with what I call "toy" library.
And, with mORMot, method-based services gives you the same level of web access process:
procedure TSQLRestServer.Stat(Ctxt: TSQLRestServerURIContext);
begin
Ctxt.Returns(Stats.DebugMessage); // transmitted as JSON object
end;
procedure TSQLRestServer.TimeStamp(Ctxt: TSQLRestServerURIContext);
begin
Ctxt.Returns(Int64ToUtf8(ServerTimeStamp),HTML_SUCCESS,TEXT_CONTENT_TYPE_HEADER);
end;
You can return HTML the same way.
Even in its current state, mORMot helps "quickly creating web-applications with minimal effort.".
I suppose it will be quicker to implement than brook, since you have most of your needed features at hand.
And for the performance and scalability... you know what's up!
With method-based services, you can also use another ORM, of course, than mORMot's internal.
But it is so much easier, and faster, to use mORMot's!
And you have interface-based services, which are much more powerful than the model used by Sinatra for writing an SOA.
But of course, brook has a much smaller code base.
It is well designed, but since all "new born", it sounds pretty easy.
mORMot was very small, 4 years ago!
But brook has already some history, now.
But mORMot feature list is much bigger than brook.
I suspect we are comparing not apples and oranges, but apples and a fruit store.
Honestly, I see no feature that brook does, and mORMot does not.
I was not fair, you are right.
Brook is not a toy library.
But it is a web basic library.
There are regression tests supplied, which smells good for the future. Without our regression tests suite, I would never have been able to let mORMot evolve.
But could you use Brook in production, for AJAX applications?
There is no CORS support, for instance.
And you have to write everything at hand, so even your REST model could not be consistent, on the client side...
Offline
@ab, I'm sorry if my previous reply contains too strong languages
Thanks for the reply, your example code given above made me realized that, the document I started reading few days ago was old and the latest one is 1.18, and you know what? Few days ago I started integrating mORMot into a new program, and I have been getting WOW-effects - it's so powerful and easy to use (with the help of the supplied examples), and your example above made me downloaded the latest doc and found it's so easy to implement 'remote functions'!
Yes, I really like the 'convention over configuration' philology in mORMot which was popularized by RoR.
And yes, I really like the ' batteries included' feature of mORMot, it is so powerful!
Actually, in terms of feature-rich, mORMot is quite far ahead of Brook, while keep still its simplicity.
That being said, I wasn't actually comparing the two, all after all, they exist in two different platforms, and actually I was only commenting on your 'toy' comment, please don't get offended.
PS, I really wish mORMot will support Lazarus/FPC soon, that's cross-plat form! And I'm actually considering abandoning the VCL UI of the program I mentioned above, and make a standalone http server app, and keeping the code FPC-ready, so that one day mORMot become FPC-compatible, my app will become cross-platform. Why not? I've got my own little LIVEditor (http://liveditor.com) to develop the front end (ok, not quite ready, but it will ) A nice dream, isn't it
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Hello, it is my first post here.
I think an exaggeration to say which Brook is a toy.
I see nothing more simple, sleek, intuitive and flexible as this:
. My simple object (descending of any class, like TObject, for example) and my specialized OPF: https://github.com/silvioprog/brookfram … person.pas
. My web action, specialized with same object specialized in OPF: https://github.com/silvioprog/brookfram … /unit1.pas
Without SQL, decoupled code, fast (2890 requests by secound, vs PHP and Java, which only reached 2690 and 2610 respectively, in a httperf test). It is wonderful, extremely clean:
procedure TPersonRESTAction.Post;
begin
Entity.Validate;
FOpf.Add(Entity);
FOpf.Apply;
end;
The 'Entity' property represents my HTML form and implements my BO (business object). I just write:
<form action="/person.add" method="post">
<input type="text" name="id" />
<input type="text" name="name" />
<input type="submit" />
</form>
... and after request, I can:
Write('ID: %d, Name: %s', [Entity.id, Entity.name]);
... without the archaic architectures like 'Entity.FieldByName('id').AsInteger', or 'Fields['name'].AsString' etc.
Not to mention that Brook is maintained by developers around the world, Brazil, Russia, Spain, Portugal, China, Indonesia ... ie, is a constantly evolving project, and will survive for a long time.
Therefore, say which Brook is a toy, tendentiously you have not tested it and spoke on impulse! I'm using Brook in production for some time. I'm already profiting through this project, creating private APIs for Brazilian companies.
Sorry for my english which is no good, and congratulations for mORMot, I tested it, and it is (but not unique) a very nice project!
Offline
Hello Silvio - nice hearing from you.
I fell sorry if I hurt you by writing that it was a "toy library".
It was not my purpose.
I look at the source code only (pleasant and easy to read), because documentation is very small (main classes and method comments), and the supplied demos do not show much.
Some disappointing points:
- lack of documentation and more elaborate examples;
- In Brook, you have to put define all actions by hand - it is a "configuration over convention" framework;
- dopf is not able to create a table, does not know anything about SQL flavors, do not prepare statements, do not handle cardinality;
- no direct CORS support for AJAX applications.
Some nice ideas:
- The whole framework design is pretty abstract, so it is open and extensible, thanks to the "brooker" plugin system;
- There are some regression tests;
- Thanks to FPC, it is cross-platform and use existing libraries.
When I look at Brook, I'm very tempted to use FPC in addition to Delphi for my libraries.
Sounds like a better platform for Open Source projects.
So, sorry for the hard words.
Brook is well written, not a toy library.
But also consider my above post for what make mORMot not unique, but genuine.
You can easily implement a full web site with method-based services and Mustache logic-less templates. And also much more than this, like a full SOA multi-tier architecture, with SQL or NoSQL persistence.
Offline
Hello AB,
It's OK!
>> - lack of documentation and more elaborate examples;
You are right. The documentation is really small, but I have some explanation about this. At first, it was written by me, after that a brazillian friend wrote some more lines, finally, when Brook became public, other people gave more contribuition. However, it's necessary more detailed text and examples. I would be glad, if there were more contribution, nevertheless, in open source projects, lots of times, we have to wait a little more.
>> - In Brook, you have to put define all actions by hand - it is a "configuration over convention" framework;
Not everything. If I could understand what "by hand" means. Cofigurating a Brook action is so simple, that I didn't take time to write more "experts" (wizards). However, it is open to the ones who want to write them. Today, there are some experts to create actions, brokers and even projects.
>> - dopf is not able to create a table, does not know anything about SQL flavors, do not prepare statements, do not handle cardinality;
dOpf has a broker to SQLdb, native Free Pascal library. Therefore, it makes everything that the library and its broker implement. SQLdb, since when I know it, it creates tables dynamically, take a look at: http://wiki.freepascal.org/SqlDBHowto. Sure, today the greatest focus of dOpf it's not only allows a nice sintax to the programmers, but also to make possible the using of objects and native types, persisting in db.
>> - no direct CORS support for AJAX applications.
CORS is "a piece of cake" to configurate. Take a look at this:
// code suggested by https://github.com/jbsolucoes
TheResponse.SetCustomHeader('Access-Control-Allow-Origin','*');
TheResponse.SetCustomHeader('Access-Control-Allow-Credentials','true');
However, today I sent a comment suggesting to implement something that become CORS more simple, as e.g.:
initialization
BrookSettings.AllowOrigin := '*';
Please see: https://github.com/silvioprog/brookframework/issues/98
------------------------
>> - The whole framework design is pretty abstract, so it is open and extensible, thanks to the "brooker" plugin system;
That's true. This idea is strong of Brook, and it was suggested by one of its authors, João Morais: https://github.com/jcmoraisjr.
>> - There are some regression tests;
:-)
>> - Thanks to FPC, it is cross-platform and use existing libraries.
And more, Free Pascal has the FCLWeb, a mature library and much powerful to web development with pure Pascal. And thanks to FCLWeb, the main Brook plugins are:
BrookFCLCGIBroker - Allows CGI application development;
BrookFCLFCGIBroker - Allows Fast CGI application development;
BrookFCLHttpAppBroker - Allows own HTTP(S) application development (i.e., it doesn't depend on Apache and nginx);
BrookFCLHttpDaemonBroker - Allows own HTTP(S) application development, being able to install as Windows service or Linux daemon;
BrookFCLHttpClientBroker - Allows to make requests in external servers, as example, downloading a content of another site.
>> When I look at Brook, I'm very tempted to use FPC in addition to Delphi for my libraries.
Here I can say that, not only look at Brook as a mirror to reflect FPC, look at Brook as a sorce of ideas for you. ;-) Then, with more free time, see as Brook treats routes, dynamic variables etc. Until then, I promise that I will make more illustrative examples.
[cut]
>> You can easily implement a full web site with method-based services and Mustache logic-less templates. And also much more than this, like a full SOA multi-tier architecture, with SQL or NoSQL persistence.
The main idea of Brook is to facilitate the creation of online APIs, using modern architecture of web development like RESTful. However, Brook also allows the development of layers with codes legacy, even for those who write XMLs and/or HTMLs mixed with Pascal. There are plans to be developed the Brook Server Pages (BSP), however, although the project has been started, we had to pause it because of a memory leak found in Pascal Script, and until today it has not been fixed.
About Mustache, I don't know it deeply, I learned about it after someone comments on issues of Brook (https://github.com/silvioprog/brookframework/issues/91). If I understand correctly, it looks like the AngularJS (today maintained by Google). But, I don't use this approach, because in practice development, I use libraries like Kendo UI, Easy UI, jQuery UI and JTable, and these projects make easier my life to develop the back-end part, providing just links to access for these libraries. In this control panel, for example, I just used jTable and Bootstrap:
https://duallsistemas.com.br/api/cpanel - private area
Take a look at some pictures:
1 - http://imagebin.org/312085 (login page)
2 - http://imagebin.org/312086 (menu)
3 - http://imagebin.org/312087 (generating keys for direct access to the Dropbox via my own API)
4 - http://imagebin.org/312088 (registration pages)
5 - http://imagebin.org/312089 (small editing form)
6 - http://imagebin.org/312090 (popup)
7 - http://imagebin.org/312091 (reports)
So, that's all. Sorry for the long text. I don't have much time because I'm teaching web development (via video) with Brook here in Brazil. I have some plans to translate the final material and perhaps provide for the whole world. If it happens my dream would come true! :-)
Offline
@silvioprog, looks like this discussion got your attention, the Pascal/Delphi community is not very big, I guess
It's me who mentioned AB's Mustache Delphi port in that github issue And, well, Mustache it's a just a template engine - think the Format() function in Pascal, whilst AngularJS is a all-in-one web front end framework.
You and Arnaud (ab) are both great guys - You made the best web framework for FPC, and Arnaud made the best web framework for Delphi - this is just my own opinion, but I'm ready to defend my opinion if somebody doesn't agree
By reading Arnaud's blog posts and forum posts, and by looking at the projects and documents he's accomplished , people can know that he is a very passionated guy, sometimes he is opinionated (and most of the time I agree with his opinions), and he seems like to use strong languages sometimes, otherwise you won't be posting here, would you But he is still are very nice guy, and I wish some nice things will be sparkled by this communication.
You too are making the Delphi and Pascal world better, thanks!
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
If I could understand what "by hand" means. Cofigurating a Brook action is so simple, that I didn't take time to write more "experts" (wizards). However, it is open to the ones who want to write them. Today, there are some experts to create actions, brokers and even projects.
I guess you do not know exactly what Convention over configuration (also known as coding by convention) means.
See http://en.wikipedia.org/wiki/Convention … figuration
It is not about wizard, it is about having almost all done by convention.
For instance, AFAIK, to add a new class, and be able to access its content via REST:
- in mORMot, you just add the class to the model;
- in Brook, you have to define a class for the table, then methods for each operation (GET/POST/PUT/DELETE), and add features.
With mORMot, you have a whole consistent REST model, including routing, JSON marshalling, SQL generation, automatic lazy BLOB marshalling, security, logging, just by adding a class to the TSQLModel.
But you can also create your own method, with full power on input/output.
With a syntax diverse but as powerful and simple than brooks.
Please see my link about "method based services" above.
http://blog.synopse.info/post/2010/07/1 … phi-7-2010
Implementing SOA with Brooks is possible, but will be very verbose, and error prone.
Every method to code by hand!
Interface-based services (as implemented by mORMot, or WCF, or EJB) are much more efficient and productive.
http://blog.synopse.info/post/2012/03/0 … a-contract
This is one another example of "convention over configuration".
>> - dopf is not able to create a table, does not know anything about SQL flavors, do not prepare statements, do not handle cardinality;
SQLdb, since when I know it, it creates tables dynamically
No, it does not. You have to write the CREATE TABLE ... statements by hand.
Nothing close to a real ORM.
CORS is "a piece of cake" to configurate
indeed.
And more, Free Pascal has the FCLWeb
AFAIK it does not support IOCP.
About Mustache, it looks like the AngularJS (today maintained by Google)
It is not the same.
AngularJS is a whole MVC framework, on the client side. And a great one! Once you start to use it, you forget about jQuery. This is one example of "convention over configuration" framework.
Mustache is a logic-less rendering engine, i.e. only the View part of the MVC. But it could work on both client and server side.
Mustache is in fact much more powerfull than the templating engine included in Brooks.
https://duallsistemas.com.br/api/cpanel - private area
If you may put online a sample application using such a layout, it could benefit to all.
Offline
@Ab, in order to help 'idea sparkling', this discussion also has a 'branch' here: https://plus.google.com/115143382472228 … ZrMK9BB9Vg
And there are already comments I guess you'd want to reply
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Sorry, the comments were here at the FPC G+ community, not that Delphi G+ community:
https://plus.google.com/115143382472228 … kuSzWB7HQL
PS, I guess you can see the potential needs of 'mORMot for Linux' in that 'discussion branch'.
Last edited by edwinsn (2014-05-29 09:14:47)
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
@edwinsn, thank you for all your comments. They say really our reality. :-)
Offline
I read and finally understood what 'Convention over configuration' is. I see, after all our discussion, we use different approaches to web development. And, if you allow to make a comment, you are more bureaucratic, and I'm more practical. I'm not saying you're wrong and I'm right or vice versa, we just use different aproaches to reach the same goal: professional web development.
And more, you can be ahead in some things, or may even have already produced more code in mORMot, however, Brook is much younger than it, ie, it has prioritized the development of parts that can't miss to produce applications for distribution in production. Can I use a layer of third log, as Log4D, so how can I use the system of log Free Pascal, together with Brook, supplying the current lack of logging it. On the other hand, the log layer is already being implemented in some days, reusing the existing code in the FCL, ie, not being necessary to reinvent the wheel.
About the development of layers for persistence using the REST architecture, I've tried to do an automatic as you mensioned in the articles that you showed me, however, I got a serious problem of maintainability. Anyway, I changed part of the core code, and the change reflected in all other parts, in short, the code was becoming coupled due to do several automation. This may be fine for some people, but I personally don't like this approach, because at the end of it all, in some more specific parts, I end up using the good and old 'join' of SQL. And more, it doesn't mean that Brook doesn't automate more usual codes as CRUDs. Brook has a very strong power of inheritance in your persistence layer where the entities are present, so I can make a class with everything I want to automate and then immediately descend the parts to be automated of this layer. Without mentioning that the use of generics helps this activity because I can specialize entire classes, most of the time, creating simple things on a single line of code.
I would really like you to show me what aspects Brook could become prone to errors about implementing SOA.
Well, about the part how we develop, there really is not much to discuss , because it is clear that we follow different approaches. :-)
I swear I'll write more examples and make them available online. I'll even think of open source applications that use in production.
I'm really glad for all the explanations you made to me. Your information is important, clear and objective, and they have a lot of technical details, however, every day and mostly in a reality that customers charge me daily new projects, support and problem solution, I end up letting go a bit bureaucracies, and implement quick solutions that solve problems, and of course, that be able to solve the problems of others. Brook came up from an idea between friends, however, as time passed by, the project became very serious, and it is today my main "income" source.
About IOCP, I can not say if Free Pascal supports it. However, I can say without fear of contradiction that the code now implemented in Free Pascal would attend most of the cases with massive requests, I guess, it could attend even in the cluster cases, because the FCL is multi-thread, and Fast CGI with Apache or nginx, I can divide the processing in multiple machines, or creating a cluster.
I don't know if there would be any interest in the mORMot team to partner with Brook and try to make an exchange of ideas, implementing different development approach. Finally, and I believe that most of the current maintainers of Brook would think fondly about it and they would probably accept the idea.
In short, I 'm really amazed with mORMot project. I don't have it as a "threat" in case it comes to Free Pascal, because Brook is specifcly made to Free Pascal , its dependencies are just the FCL, and the code is very lean, because it suports just a compiler. I've thought a lot about porting Brook to Delphi, but I gave up, because Brook focus is the Free Pascal, and the platforms on which it supports. Of course, about what I read, mORMot attend diverse solutions in itself, but Brook focuses more on web prococols, like HTTP(S), leaving other responsibilities (persistence, reports, e-mail etc.) to its plugins, in a brief analogy to Android, Brook would be the Andoid itself, focused on what it does, and the other resources would be applications, focusing other situations.
Offline
"Bureaucratic"? I guess this is not the good word.
Just say that if you want to implement a known design pattern like Domain Driven Design, you will have all needed bricks available with mORMot to focus on modeling, and you will have to write much more code with Brook.
"Convention over configuration" means that web services, HTTP and REST are means, not goals. The conventions available in mORMot allow to write some code without any knowledge of what a GET/POST/PUT is, or how routing is handled. And if you need to tune the default behavior, you can.
You are right: most of the complexity of the mORMot internal core comes from the "conventional" approach and "abstract to technical details".
What you call "bureaucracy" is that modern serious coding (e.g. DDD) is to uncouple your logic from the technical details by which it is implemented.
It is not "bureaucracy", it is 21th century software design.
For instance, your business logic code should be uncoupled from implementation details like transport, security, persistence, marshaling.
This is all about the SOLID principles, and rely on abstraction.
IMHO interface support, dependency injection, and are mandatory for modern business project.
So that you can stub/mock any part of your application (DB, transport...) and maintain/test it.
It is mandatory for test-driven approach, and serious modern programming.
In short, you have several level of quality coding:
- RAD approach, which mixes UI and logic/persistence with components;
- OOP approach, which try to uncouple the tiers with classes;
- SOLID approach, which rely on abstraction and uncoupling at all levels, with interfaces.
Brook is a clean OOP solution, but not SOLID.
SOLID design may be something new to you, as it is for most pascal developers.
You may even think it is not worth it, and call it "bureaucracy" or "marketing stuff".
BTW, this is the reason why there is some mandatory design principles chapters in the mORMot documentation - take a look at the SAD 1.18 pdf.
I can assure you that SOLID is much more "practical" than regular OOP design.
This is quite the contrary.
mORMot SOLID design let you be much more productive than Brook's OOP design.
Just try to e.g. 10 small SOA services and consume them with clients in both models, and you will find out what I mean...
Brook, and even the current state of the FCL, are just not able to follow the SOLID pattern yet.
If I make mORMot compatible with Free Pascal, I guess it will even add a lot of features to the FCL, e.g. stubbing/mocking and such.
It could benefit to the community!
Some bugs need to be fixed with the FCL, if I want mORMot to work as expected.
For instance:
- the new code-page strings available in FPC 2.7 branch is not as consistent as Delphi 2009 (e.g. it changes the code page e.g. when you write aStr := '"'+aStr);
- TInvokeableVariantType.SetProperty() is broken and do not allow to set property values inside a variant via late-binding;
- some missing functions for old RTTI (e.g. dynamic array published properties support).
How do we create tickets for FPC? What is the best approach?
What amazed me is that you are making money with Brooks.
Honestly, mORMot does not give me much income.
I hope I would get my living with the framework, but yet it is not the case.
What is your business model? Training? Support?
Offline
I've written a blog article about this forum thread!
See http://blog.synopse.info/post/2014/05/3 … ID-and-OOP
Offline
I read your discussion, and just wan't to say something to prevent you all running in the wrong direction.
I'm writing Software for a long period of time now and use Delphi since Version 3
As you all know the prefered systems of the most clients in the world are Windows, Android, iOS, i don't know anyone who is using LINUX in practice.
May be I'm wrong but if you think as me you'll recognize that the mORMot System is optimal an does not really need fpc support.
But the CrossPlatform is very important to write Clients for mORMot.
I think come's time and the errors AB recognized in FPC are fixed, then its time to write on FPC if there is any who really is in need of it.
I personally don't need FPC support. And i don't need Brook atm
Last edited by itSDS (2014-05-30 08:58:44)
Rad Studio 12.1 Santorini
Offline
@itSDS,
Here:
"...the preferred systems of the most clients in the world are Windows, Android, iOS, i don't know anyone who is using LINUX in practice."
I thought like you, I did a proxy server between an existing application server and some mobile apps ( android & ios made with Titanium appcelerator ) using mORMot, that work drew attention of another customer who wants a similar project and he has already infrastructure on internet, to be precise three dedicated servers that can be used to put those little mORMot servers running, but guess what? All of them are running Linux, no Windows at all, Why? because they are cheap so offering him a solution based on mORMot is harder, not impossible, we all know virtual machines I could create one an run my server there or I can suggest him to pay for another dedicated server running Windows, or perhaps another alternative? for Desktop I almost agree with you, but on the server side it would be nice (and easier) if one could compile mORMot binaries using FPC for cases like this, I presume will become more frequent for me.
I can't speak for others but I thought it was worth to say.
Offline
As you all know the prefered systems of the most clients in the world are Windows, Android, iOS, i don't know anyone who is using LINUX in practice.
You must meant desktop systems, otherwise you must be joking
In the server world, Linux at least has "double" the market share of Windows, and yes, it's the cost that caused this market share. Here is a reference: http://en.wikipedia.org/wiki/Usage_shar … e_Internet
That being said, I think the main benefit of Linux support for mORMot would be being a Free Pascal web server framework that serves the web browsers, or any Windows/Android/iOS clients in a RESTful way.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Some bugs need to be fixed with the FCL, if I want mORMot to work as expected.
For instance:
- the new code-page strings available in FPC 2.7 branch is not as consistent as Delphi 2009 (e.g. it changes the code page e.g. when you write aStr := '"'+aStr);
- TInvokeableVariantType.SetProperty() is broken and do not allow to set property values inside a variant via late-binding;
- some missing functions for old RTTI (e.g. dynamic array published properties support).
How do we create tickets for FPC? What is the best approach?
Some interesting messages from today's FPC-maillist :
Message: 4
Date: Fri, 30 May 2014 22:53:11 -0500
From: Kenneth Cochran <kenneth.cochran@gmail.com>
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: [fpc-pascal] Typinfo incompatibilities between FPC and Delphi
Message-ID:
<CALe4hHWcU_OuntMyG=UDRu2ZncaTOTPQTDY9+GEWhpRhx7VBLg@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
I'm attempting to port GExperts from Delphi to Lazaurus and noticed the
definition of TPropInfo differs from Delphi's.
In FPC's TPropInfo the PropType field is PTypeInfo whereas in Delphi it is
PPTypeInfo. I'm not sure what is actually gained by this extra level of
indirection but it exists none the less.
Are there any plans to update TPropInfo to be compatible with Delphi or do
I need to wrap dependent code with compiler conditionals?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20140530/44a7fd17/attachment-0001.html>
Message: 6
Date: Sat, 31 May 2014 11:48:48 +0200
From: Sven Barth <pascaldragon@googlemail.com>
To: fpc-pascal@lists.freepascal.org
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID: <5389A580.5020701@googlemail.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
On 31.05.2014 05:53, Kenneth Cochran wrote:
> I'm attempting to port GExperts from Delphi to Lazaurus and noticed the
> definition of TPropInfo differs from Delphi's.
>
> In FPC's TPropInfo the PropType field is PTypeInfo whereas in Delphi it
> is PPTypeInfo. I'm not sure what is actually gained by this extra level
> of indirection but it exists none the less.
>
> Are there any plans to update TPropInfo to be compatible with Delphi or
> do I need to wrap dependent code with compiler conditionals?
There are no plans as we have to stay compatible with our own old
codebases as well. You'll need to use compiler conditionals.
Regards,
Sven
Message: 7
Date: Sat, 31 May 2014 11:57:40 +0200
From: Vincent Snijders <vincent.snijders@gmail.com>
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID:
<CAMDhvckvJo8vZNniFy+b-3p9T7_8Zv2mGFMzx9HuToMJai2=Uw@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
2014-05-31 11:48 GMT+02:00 Sven Barth <pascaldragon@googlemail.com>:
> On 31.05.2014 05:53, Kenneth Cochran wrote:
>
>> I'm attempting to port GExperts from Delphi to Lazaurus and noticed the
>> definition of TPropInfo differs from Delphi's.
>>
>> In FPC's TPropInfo the PropType field is PTypeInfo whereas in Delphi it
>> is PPTypeInfo. I'm not sure what is actually gained by this extra level
>> of indirection but it exists none the less.
>>
>> Are there any plans to update TPropInfo to be compatible with Delphi or
>> do I need to wrap dependent code with compiler conditionals?
>>
>
> There are no plans as we have to stay compatible with our own old
> codebases as well. You'll need to use compiler conditionals.
>
I think it is possible to write code without $ifdef (valid for Delphi and
FPC) if you use the typeinfo unit to extract the information.
http://www.freepascal.org/docs-html/rtl/typinfo/
Vincent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20140531/fd32bb13/attachment.html>
Offline
I already circumvent it.
But the issues I wrote about in above post are more serious..
http://bugs.freepascal.org/my_view_page.php
http://forum.lazarus.freepascal.org/index.php
http://lists.freepascal.org/cgi-bin/mai … fpc-pascal
:-D Maybe through these FPC-related links ? ...
Offline
AB, sorry for my delay to answer, I'm concluding the semester in the college, I had many works to deliver.
You got me wrong. When I said "bureaucratic", it was about you want to do everything in a single project. I use design patterns, I develop in MVC, and my layers are separated, but I dont put everything in single framework, I prefer to separate tasks into smaller projects. For example, Brook does not have persistence, it use a third party project, called dOpf (https://github.com/silvioprog/dopf). Brook does not send e-mail, it use a third party project, the XMailer (https://github.com/silvioprog/xmailer). And so on. Brook has plans to use JCore (https://github.com/jcmoraisjr/jcore) in a broker, that is a high level OPF project.
Brook can also use tasks of mORMt. If you want, I can help you to port some parts of mORMt for Free Pascal and, after that, we can write a "BrookmORMtBroker" broker. We could put our knowledge together and make a fusion between these two great projects, bucause porting code from Delphi to Free Pascal isn't an easy task.
I have a simple question, but first I would like to know if you can help me. It's about creating a simple example of CRUD with REST in mORMt, where I could compile in Dephi 7 (I have it here), and access a simple table in PostgreSQL.
This is the table:
create table person (
id serial not null primary key ,
name varchar ( 30 ) not null unique
);
And this is the object that I want to persist at the table above:
TPerson
Id Integer
Name String
If it does not take you so much time, could you make this example and send me the sources? My environment:
. PostgreSQL;
. Delphi 7;
. Windows XP 32-bit;
. Google Chrome with Advanced REST client extension.
If you agree, I will do the same example in Brook, and send you the sources for you to evaluate, finally, we could see in what aspects mORMt could help Brook to improve its persistence layer and if you accept it, I would implement the mORMt broker as I mentioned.
To make sure that I'm not in a competition, you can count with my help whenever you need to port mORMt for Free Pascal. It was nice to talk to you about those things, you are a great developer, who knows a lot about Object Pascal and also defends your work with all your strength, and has a sense of humor similar to mine! :-)
Offline
From my Third Person Point of view i Realy can't See any Reason why Arnaud should spent Time in brook or is anyone else here who is in Need of mormot to brook Support ?
Last edited by itSDS (2014-06-01 09:05:38)
Rad Studio 12.1 Santorini
Offline
Some bugs need to be fixed with the FCL, if I want mORMot to work as expected.
For instance:
- the new code-page strings available in FPC 2.7 branch is not as consistent as Delphi 2009 (e.g. it changes the code page e.g. when you write aStr := '"'+aStr);
- TInvokeableVariantType.SetProperty() is broken and do not allow to set property values inside a variant via late-binding;
- some missing functions for old RTTI (e.g. dynamic array published properties support).
How do we create tickets for FPC? What is the best approach?
Another useful message in today's FPC maillist:
Message: 5
Date: Sat, 31 May 2014 14:24:56 +0200
From: Maciej Izak <hnb.code@gmail.com>
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID:
<CAFTppY4_VZfUToXwe7WY9jpJHb7G7+H903YZOmviLfnA50qs+g@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
>
> In FPC's TPropInfo the PropType field is PTypeInfo whereas in Delphi it is
> PPTypeInfo. I'm not sure what is actually gained by this extra level of
> indirection but it exists none the less.
>
>
By Barry Kelly in comment :) :
[url]http://stackoverflow.com/questions/3443097/what-is-the-identity-pointer-before-a-ttypeinfo-there-for[/url]
"all typeinfo fixups - pointers from one blob of typeinfo to another - are
of type PPTypeInfo, not PTypeInfo, to handle the dynamic linking case. In
the case of static linkage, there needs to be an intermediate pointer for
the convention to work, and part of the typeinfo itself makes as much sense
as any. That is to say, it's not there for the linker; it's there because
of the convention, and the convention is there because of dynamic linking,
which is done the way it is to maximize potential for page sharing."
Regards,
Maciej Izak (hnb)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <[url]http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20140531/b755eb8c/attachment-0001.html[/url]>
------------------------------
Message: 6
Date: Sat, 31 May 2014 15:45:39 +0200 (CEST)
From: marcov@stack.nl (Marco van de Voort)
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID: <20140531134539.85117730B5@toad.stack.nl>
Content-Type: text/plain; charset="US-ASCII"
In our previous episode, Maciej Izak said:
> By Barry Kelly in comment :) :
>
> [url]http://stackoverflow.com/questions/3443097/what-is-the-identity-pointer-before-a-ttypeinfo-there-for[/url]
>
> "all typeinfo fixups - pointers from one blob of typeinfo to another - are
> of type PPTypeInfo, not PTypeInfo, to handle the dynamic linking case. In
> the case of static linkage, there needs to be an intermediate pointer for
> the convention to work, and part of the typeinfo itself makes as much sense
> as any. That is to say, it's not there for the linker; it's there because
> of the convention, and the convention is there because of dynamic linking,
> which is done the way it is to maximize potential for page sharing."
Thanks, I added it to the wiki:
[url]http://wiki.freepascal.org/packages#Details[/url]
Offline
From my Third Person Point of view i Realy can't See any Reason why Arnaud should spent Time in brook or is anyone else here who is in Need of mormot to brook Support ?
IMHO, it can only bring benefits when knowledgeable authors like ab and silvioprog start to communicate. Not to mention that silvioprog is kind enough to offer help to port mORMot to FPC.
Offline
I would appreciate if you could share the code from both projects. I'm trying to do something similar than your request but with Firebird. Thanks
Offline
For your sample, first you create the data model, which will be shared between client and server:
unit RESTModel;
interface
uses
SynCommons,
mORMot;
type
TPerson = class(TSQLRecord) // TSQLRecord has already ID: integer primary key
private
fName: RawUTF8;
published
/// ORM will create a NAME VARCHAR(80) column
property Name: RawUTF8 index 80 read fName write fName;
end;
function DataModel: TSQLModel;
const
SERVER_ROOT = 'root';
SERVER_PORT = '888';
implementation
function DataModel: TSQLModel;
begin
result := TSQLModel.Create([TPerson],SERVER_ROOT);
TPerson.AddFilterOrValidate('Name',TSynValidateText.Create); // ensure exists
end;
end.
Then you create the server:
program RESTserver;
{$APPTYPE CONSOLE}
uses
SynCommons, // framework core
mORMot, // RESTful server & ORM
mORMotSQLite3, // SQLite3 engine as ORM core
SynSQLite3Static, // staticaly linked SQLite3 engine
mORMotDB, // ORM using external DB
mORMotHttpServer, // HTTP server for RESTful server
SynDB, // external DB core
SynDBODBC, // external DB access via ODBC
RESTModel; // data model unit, shared between server and client
var
aModel: TSQLModel;
aProps: TSQLDBConnectionProperties;
aDB: TSQLRestServerDB;
aServer: TSQLHttpServer;
begin
// ODBC driver e.g. from http://ftp.postgresql.org/pub/odbc/versions/msi
aProps := TODBCConnectionProperties.Create('','Driver=PostgreSQL Unicode'+
{$ifdef CPU64}'(x64)'+{$endif}';Database=postgres;'+
'Server=localhost;Port=5432;UID=postgres;Pwd=postgresPassword','','');
try
// get the shared data model
aModel := DataModel;
// use PostgreSQL database for all tables
VirtualTableExternalRegisterAll(aModel,aProps);
try
// create main mORMot server
aDB := TSQLRestServerDB.Create(aModel,':memory:',false); // authentication=false
try
aDB.CreateMissingTables; // create tables or fields if missing
// server aDB over HTTP
aServer := TSQLHttpServer.Create(SERVER_PORT,[aDB],'+',useHttpApiRegisteringURI);
try
aServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries
writeln('Background server is running.'#10);
write('Press [Enter] to close the server.');
readln;
finally
aServer.Free;
end;
finally
aDB.Free;
end;
finally
aModel.Free;
end;
finally
aProps.Free;
end;
end.
And now you have:
- A RESTful server listening at localhost:888/root/person for GET/POST/PUT/DELETE commands
- Storing all data within a PostgreSQL database
- Creating the PERSON table automatically
- With no authentication yet, but you can add it with only one parameter
- You may add logging with one line
- Or add other RESTful services via methods
- Or add SOA services via interfaces
- ... and a lot of other features!
In few lines of code, you can have a full RESTful client, which will give you remote access to TPerson class content, as a remote ORM, over HTTP.
Here we used ODBC to connect to PostgreSQL, but we may have used FireDAC, UniDAC or Zeos/ZDBC.
For FireBird, you just use either TODBCConnectionProperties / TSQLDBZEOSConnectionProperties / TSQLDBFireDACConnectionProperties or TSQLDBUniDACConnectionProperties to connect to the DB.
See sample 15 for how connection strings are used.
You just switch from one database backend to another by changing the aProps: TSQLDBConnectionProperties instance. Then all SQL will be created depending on the provider and database (e.g. CREATE TABLE with corresponding column types).
For performance, see http://blog.synopse.info/post/2014/03/0 … PostgreSQL
I uploaded it as sample 28 in our source code repository.
Offline
Here is the client:
/// minimal REST client for a list of Persons from RESTserver.exe
program RESTclient;
{$APPTYPE CONSOLE}
uses
SynCommons, // framework core
mORMot, // RESTful server & ORM
mORMotHttpClient, // HTTP client to a mORMot RESTful server
RESTModel; // data model unit, shared between server and client
var aModel: TSQLModel;
aClient: TSQLHttpClient;
aPerson: TPerson;
aID: integer;
begin
aModel := DataModel;
try
aClient := TSQLHttpClientWinHTTP.Create('localhost',SERVER_PORT,aModel);
try
writeln('Add a new TPerson');
aPerson := TPerson.Create;
try
Randomize;
aPerson.Name := 'Name'+Int32ToUtf8(Random(10000));
aID := aClient.Add(aPerson,true);
finally
aPerson.Free;
end;
writeln('Added TPerson.ID=',aID);
aPerson := TPerson.Create(aClient,aID);
try
writeln('Name read for ID=',aPerson.ID,' from DB = "',aPerson.Name,'"');
finally
aPerson.Free;
end;
finally
aClient.Free;
end;
write(#10'Press [Enter] to quit');
readln;
finally
aModel.Free;
end;
end.
Sounds pretty easy and straightforward, no?
Offline
You got me wrong. When I said "bureaucratic", it was about you want to do everything in a single project. I use design patterns, I develop in MVC, and my layers are separated, but I dont put everything in single framework, I prefer to separate tasks into smaller projects.
As is written everywhere in the doc (starting from the Readme.txt file), the whole mORMot framework is modular.
It is already separated in smaller projects.
Some units (e.g. SynPdf, SynGdiPlus, SynBigTable, SynCommons, SynDB*,
SynSQLite3, SynMongoDB, SynMustache, mORMotReport) are used by mORMot,
but do not require the whole framework to be linked.
That is, you can use e.g. only PDF generation, SynDB fast database
access, a static-linked SQLite3 engine, direct MongoDB access, Mustache
templates, code-generated reports, or the TDocVariant, TDynArray,
TSynLog classes of SynCommons, without using the main mORMot units and
features (ORM, Client-Server, services, UI, reporting).
Some of those units can even be compiled with Delphi 5 (e.g. SynPdf, SynDB).
Brook can also use tasks of mORMt.
Honnestly, I do not see any benefit of using Brook instead of mORMot's already available method-based services.
It would be just more confusion, more duplicated code, be tied to FPC, less performance, missing other integrated features (like security or automatic logging).
I have a simple question, but first I would like to know if you can help me. It's about creating a simple example of CRUD with REST in mORMt, where I could compile in Dephi 7 (I have it here), and access a simple table in PostgreSQL.
This is sample 28, I just wrote above.
https://github.com/synopse/mORMot/tree/ … M%20Server
I guess you will find out what "convention over configuration" mean in mORMot, thanks to this example.
You just define the data model, the SQL access layer, and the communication classes, and the framework will tied up everything for you: ORM (with SQL table creation and high performance), REST routing, multi-thread in-process HTTP server, and client use with TSQLRest.Add/Retrieve/Update/Delete commands. And the whole is RESTful, using JSON for serialization, and directly AJAX ready, with a consistent layout.
You do not have to define any class, nor method. All is done by the framework.
And you are still allowed to customize it if needed, add access security, table or record level caching on server or client side, and/or services via methods or interfaces.
Offline
Some bugs need to be fixed with the FCL, if I want mORMot to work as expected.
For instance:
- the new code-page strings available in FPC 2.7 branch is not as consistent as Delphi 2009 (e.g. it changes the code page e.g. when you write aStr := '"'+aStr);
- TInvokeableVariantType.SetProperty() is broken and do not allow to set property values inside a variant via late-binding;
- some missing functions for old RTTI (e.g. dynamic array published properties support).
How do we create tickets for FPC? What is the best approach?
Another useful messages in today's FPC maillist:
Message: 8
Date: Sun, 01 Jun 2014 23:05:23 +0100
From: Graeme Geldenhuys <mailinglists@geldenhuys.co.uk>
To: fpc-pascal@lists.freepascal.org
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID: <538BA3A3.3040707@geldenhuys.co.uk>
Content-Type: text/plain; charset=UTF-8
On 2014-05-31 10:57, Vincent Snijders wrote:
> I think it is possible to write code without $ifdef (valid for Delphi
> and FPC) if you use the typeinfo unit to extract the information.
> http://www.freepascal.org/docs-html/rtl/typinfo/
Almost, but not quite. Good news is, it is not nearly as bad as Sven
makes it out to be.
The tiOPF project uses RTTI extensively. I have written a lot of that
code, and with the following helper function, I could eliminate a lot of
IFDEF's between FPC and Delphi RTTI behaviour.
function tiGetTypeInfo(PropInfo: PPropInfo): PTypeInfo;
begin
{$IFDEF FPC}
Result := PropInfo^.PropType;
{$ELSE}
Result := PropInfo^.PropType^;
{$ENDIF}
end;
I've also introduced an enhanced GetPropInfo() with a signature as follows:
function tiGetPropInfo(AClass: TClass; PropPath: string; PInstance:
Pointer): PPropInfo;
To see the complete code, take a look at the Core/tiRTTI.pas unit in the
tiOPF's 'tiopf2' branch.
That unit is also fully unit tested. Tests and usage examples can be
found in the following unit:
UnitTests/Tests/tiRTTI_TST.pas
Regards,
- Graeme -
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/
------------------------------
Message: 9
Date: Tue, 3 Jun 2014 11:08:08 +0200
From: Sven Barth <pascaldragon@googlemail.com>
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Typinfo incompatibilities between FPC and
Delphi
Message-ID:
<CAFMUeB9b9r_bW_9RUpg0g_BFCu9T0hWo6fE7SN3GmB7z1dZ8Rg@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Am 03.06.2014 10:26 schrieb "Graeme Geldenhuys" <
mailinglists@geldenhuys.co.uk>:
>
> On 2014-05-31 10:57, Vincent Snijders wrote:
> > I think it is possible to write code without $ifdef (valid for Delphi
> > and FPC) if you use the typeinfo unit to extract the information.
> > http://www.freepascal.org/docs-html/rtl/typinfo/
>
> Almost, but not quite. Good news is, it is not nearly as bad as Sven
> makes it out to be.
>
If one uses a helper function like you did then it's indeed not as bad, but
if one doesn't...
> function tiGetTypeInfo(PropInfo: PPropInfo): PTypeInfo;
> begin
> {$IFDEF FPC}
> Result := PropInfo^.PropType;
> {$ELSE}
> Result := PropInfo^.PropType^;
> {$ENDIF}
> end;
Out of curiosity: is this helper declared as "inline"? Would get rid of the
call completely in both Delphi and FPC...
>
> I've also introduced an enhanced GetPropInfo() with a signature as
follows:
>
> function tiGetPropInfo(AClass: TClass; PropPath: string; PInstance:
> Pointer): PPropInfo;
Might also profit from a declaration as "inline" :)
Yours,
Sven
Offline
About the more difficult parts, have you complained to the FPC community ? Are there URLs that we can go and vote for ?
Offline
Many thanks for your brilliance and efforts !
Offline
Well, I downloaded the samples via GIT, but, when I tried to compile it, I got:
[Error] SynSQLite3Static.pas(228): File not found: 'sqlite3fts3.obj'
I had no time to try to solve it, however, I could understand how it works, because I analized the sources. My greatest interest in this partnership would be to create a possibility to port everything to Free Pascal and try to reuse it, and maybe publishing this work in Free Pascal communities. However, if you think that doing this will let the code slower, without logging (remember that even Brook and Free Pascal have automatic logging), but it's OK, I'm not insisting with ideas or suggestions anymore.
Right now, the only sample that I have with REST is the one that already follow the Brook since the release of 3.0 version:
https://github.com/silvioprog/brookfram … os/db/rest
But is the same fallacy: you will continue thinking mORMot is all that a web programmer needs and Brook a just a 'toy'. :-)
Well, now my focus will be to implement RIA in Brook, because some people are asking that. A friend and I will create the expected BSP (Brook Server Pages) and, finally, I will start the development of BrookScript, an idea that I had to implement in Brook 3.1 and it has already been accepted successfully by the key members that follow the project.
Despite everything, I wish you good luck in cross-compiler implementation, it is not a simple task! :-)
Offline
@silvioprog, that .obj file can be downloaded here: http://synopse.info/fossil/wiki?name=Downloads
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
A side note for ab, I long have had the idea of suggesting you to put the sqlite3fts3.obj (also the pdf manual) to the source repository, these files are not big and nowadays network speed and disk space are more than enough to handle them, right?
By putting these necessary files into the source repo, will let new users get started with mORMot much easier, as opposed to having to find out where and then download these files separately. It's about user experience.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
The PDF is huge...
If someone is not able to follow or readme.txt instructions, I suspect he/she won't be able to use mORMot...
But I think it is time to release revision 1.18...
Offline
ab, yes, the pdf is huge, forget about it. but I still strongly suggest you to put the sqlite3fts3.obj file to the repository
Last edited by edwinsn (2014-06-21 07:37:31)
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline