You are not logged in.
Another post with some linked posts that worth spending hours to read, thanks!
Yes, I agree with you. I'm a believer and lover of mORMot's ORM/REST/RemoteAPI approaches.
I'm just posting for people's information ![]()
I'm not a big fan of GraphQL, but it's kinda hot in recent years.
And today I came across the first Delphi implementation of GraphQL by Luca Minuti:
https://github.com/lminuti/graphql
I think ab and other mORMot users might find it interesting though.
Speaking of SQLite FTS5, what's missing is the `offsets` function, which was provided by FTS3/4...
Yes, "composition over inheritance" ![]()
Great! Spring4D is great too but in most cases I don't want to introduce another not-so-small dependency, and now we have generic collections in mORMot2 too!
I like that the methods are directly attached to IList and IKeyValue. On the other hand, with Spring4D you have a LOT of interfaces and types to explorer in order to find what you need.
One question - What's the **best practice** to implement a reusable descendant of IList<T>?
With my past experiences of using **interface-based** collections, I won't say I like it very much, because, for example, with TObjectList, I can easily create an extended TObjectListEx, which I add a lot of new methods.
Let's face it - we don't have very much situations where we need a list to treat the Interger, String, Doubles, Objects, and so on, with the exactly same logic. Sometimes, it's just **too generic**.
So after years of using spring4D, I go back to use my TObjectList descendant, because in the end I figured out that all I need is just "generic collections with powerful features (loop, some, filter, etc) packed without bloating the EXE".
Hope it makes sense.
@sakura, I appreciate your sharing of the details and it's inspiring. I'll take some time to consider how/if I can take advantage of the `attribute` language feature in my projects!
edwinsn wrote:Is the use of [Attributes] a new feature in mORMot 2? That sounds good, ...
Just part of Delphi, the creation and use of them is part of our internal development team.
I'm still interested, what does you team use the attributes for?
I know there are some uses of attributes are very helpful:
- In Delphi Event Bus, you can use attributes to define whether you want your event handler to be run in the main thread, in the calling thread or in a dedicated thread.
- Some ORM framework uses attributes to define the object models ( I do wish I can define default db values in mORMot, BTW).
the [Attributes] which gives me an amazing power to extend mORMot easily even further - and I love it :-) Many things in our new app will be working by simply marking things using attributes, up to replacing whole classes in services with more refined versions.
Thanks sakura! Is the use of [Attributes] a new feature in mORMot 2? That sounds good, but I just did a grep search into the mORMot2 source and didn't find anything related to `TCustomAttribute`... would you point me to any place that has such example or info?
I agree with sakura and thanks him for sharing his experiences.
@sakura, speaking of similarity of mORMot1 and mORMot2, how does it feel?
Over the years I've built up a bunch of utility functions and classes based on mORMot1, I wonder in the future if I will be able to easily port them to mORMot 2.
I think you should use the latest source from the github repository?
https://github.com/synopse/mORMot/commits/master
PS, interesting project with well-written documents ![]()
ok, quite easy if you know how to do it, here is a working example might might be helpful for others:
class procedure TSQLMyTable.InitializeTable(Server: TSQLRestServer; const FieldName: RawUTF8; Options:
TSQLInitializeTableOptions);
begin
inherited;
// the engine is adding the missing MyField1 field, we need to update the db table for this field to
// have the default value, because the mORMot engine has no direct support for 'default field value'
// see: https://synopse.info/forum/viewtopic.php?id=5469
if (FieldName = 'MyField1') then
UpdateDefaultValueForCardTextSourceProp(Server);
end;
class procedure TSQLMyTable.UpdateDefaultValueForCardTextSourceProp(const aServer: TSQLRestServer);
var
sql: RawUTF8;
begin
sql := FormatUtf8('UPDATE % SET MyField1 = % WHERE MyField1 IS NULL',
[self.SQLTableName, cDefaultValueForMyField1]);
aServer.Execute(sql);
end;@ab,
Maybe it's worth to add new property called TSQLPropInfo.DefaultValue and use that proper when constructing the SQL for adding the column in the db?
SQLite itself supports the `default` clause for the `alter table` statement, something like:
alter table t1 add column status integer default 100Setting default field values in the constructor only works for **new rows**, but not an existing row with missing field(s).
For the latter, you might need to take the "override TSQLRecord.InitializeTable then run TSQLRest.UpdateField() to put some default value when the field is detected as missing." approach, which is not very convenient, as described in https://synopse.info/forum/viewtopic.php?id=5469
It's nice to see more photos of yours! ![]()
And this is your only photo on the internet? ![]()
Wow, you are quick and you've just given a short review of the library!
I use mORMot and hopefully mORMot2 in the future!
With a very low-level API.
I guess that's the reason I've stopped digging into it many years ago when I came across it for the first time.
@ab,
Although I haven't checked it, I think the auto-scaling and auto-deployment features of the following new open source project is very interesting, so thought I'd post it here:
Amazing work again, ab!
With all these mORMot2 improvements, I just hope it'll not that difficult when upgrading from mORMot1 in the future.
Yes, it seems that Barry Kelly was against such changes to please existing customers.
Marco, on the contrary, pushed for the breaking behavior.
I don't know if it is a personal idea, or coming from some other managers.
At least, it is consistent with other decisions: they are not afraid of breaking existing code.
I hate breaking changes! They just want to break the old code and push the users to upgrade to their new IDE.
And that's why I offered to help spending their money by consuming their always-free VM ![]()
Great finding and Great job! However, my visa credit card failed to register...
I remember SIMDJson, it was hot on hacker news: https://hn.algolia.com/?q=simdjson
And this simple project of mpv, it's really a simple example for wrapping a C++ project into a C DLL then used by Pascal. Thanks for sharing!
@ab and @chaa, Thanks for the explanation.
I guess the value of TSQLHttpServer.HttpServer.RemoteIPHeader should be set to 'X-Forwarded-For' by default?
Because according to the Mozilla docs:
The X-Forwarded-For (XFF) header is a de-facto standard header for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or a load balancer.
the `USEPACKAGES` conditional was already in use ![]()
Reference for myself (and others might encounter the same issue in the future):
If you encounter the following error:
[dcc32 Error] E2201 Need imported data reference ($G) to access 'SUPERVISOR_ACCESS_RIGHTS' from unit 'mORMotHttpServer'
One of the reasons is because you are compiling a package which includes/uses a unit which in turn uses the `mORMot.pas' unit.
Solution
===
I have no solution yet. Maybe @ab has hints ![]()
Workaround
===
Just don't use the `mormot.pas` unit in your package...
libuv FPC wrapper:
https://github.com/zamronypj/libuv-pas
Use mORMot2 (in test state) instead: https://github.com/synopse/mORMot2
yep, maybe, you get what you pay for...
And it turned out that they are not able to accept payments from people in China... very strange nowadays - we use Vista cards, paypal, and so on...
Since I'm experiencing some RDP connection issues with my vultr Windows VPS recently (the issue maybe on my side, you know, GFW...), today I'm checking the pricing of Contabo. Wow, it's even cheaper than vultr, and the spec is better. Not sure about real use experience though...
The CromisLibrary scheduler seems to use the Windows or LCL timer. So it is not very suitable for a daemon/server with no main loop.
Actually Cromis Scheduler uses a separated thread to perform the loop:
https://github.com/CPsoftBE/BackupOfCro … .pas#L1048
Well done! So QuickJS is now available in mORMot2 ![]()
https://github.com/CarlosHe/oauth2-server
Found it today and for your reference ![]()
It seems that https://github.com/tondrej/chakracore-delphi is not in the benchmark list? ![]()
@ab, the screenshot posted by flydev doesn't look right to me - Sqlite is backward compatible, what do you think about allowing mORMot to be compatible with **new versions** of SQLite?
Take this screenshot as an example, mORMot complains about 3.34.0 is missing while 3.34.1 (the newer version) is already provided?
@sakura,
What ab meant is that, he'll wait for sqlite 3.34.3 which is expected to be available in a few days and he'll then update mORMot to work with that new 3.34.3 sqlite release.
@ab,
A side question - what's your tool chain for fiddling the c/c++ stuff like this?
About QuickJS, I will put it into mORMot 2, but anyone could backport it to mORMot 1 and make a pull request.
Sounds cool! Maybe one can use mORMot v1 and v2 together...
@ab,
I'm so exciting about the upcoming integration of QuickJs to the mORMot framework!
Will it also available for mORMot 1?
BTW, I prefer js over pascal for **scripting*, because all the Pascal script engine are **dialects** (not fully compatible with Delphi or FPC). The main issue is that, when you have a problem, you'll find that you can't find enough documents, examples or other resources to help you solve the issue. On the other hand, you can instantly find a solution for any js problem!
Yes, finally! `DROP COLUMN` is great too!
New "RETURNING" clause in the latest SQLite engine seems to be very helpful!
Exceprt from https://nalgeon.github.io/sqlite-3-35/:
DELETE, INSERT and UPDATE queries now can return the rows that they deleted, added, or changed respectively.
E.g., return the id of a new record:
create table users (
id integer primary key,
first_name text,
last_name text
);
insert into users (first_name, last_name)
values ('Jane', 'Doe')
returning id;Or return products with increased price:
update products set price = price * 1.10
where price <= 99.99
returning name, price as new_price;Scheduler from the now-disappeared-but-has-a-backup-on-github CromisLibrary is the best for such a task as far as I know.
Great work and thanks for sharing!
Cheers!
I'm glad and like the fact that @ab has chosen iso8601 as the format for storing datetime values:
ISO 8601: the better date format
Cheers!
@ab,
IIRC, the mORMot master/slave replication does not intercept raw SQL execution direction to the db?
Also, it cannot be used to sync an old db?
And, the target must have a mORmot server running?