Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2019-06

Troubles with SQLDBRESTBridge

15 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sven Barth

Hello together!

I've played around a bit with the SQLDBRESTBridge and encountered some troubles which I wanted to check up here on the list whether those are indeed bugs or not before reporting them to Mantis.

For the tests I've used FPC 3.0.4 and Lazarus 2.0 with the SQLDBRESTBridge and the Lazarus examples being from trunk on Friday 14th June.

As server I used the restmodule demo in
$lazarus/components/sqldbrest/demo/restmodule and changed it to use SQLite3 instead of PostgreSQL.
For the client I used the jsonclient demo in
$lazarus/components/sqldbrest/demo/jsonclient.

I created the database using the expenses-sqlite.sql script in $fpc/packages/fcl-web/examples/restbridge/expenses-sqlite.sql (and no I didn't execute expenses-data.sql at first which will be important further down ;) ).

I started the server and tried to access localhost:7331/REST/metadata (I changed the port from 8080), but this resulted in a 404 error which was displayed as an empty page (maybe something isn't correctly working here?). Using localhost:7331/metadata resulted in a "Not found" exception.

So I started to research what went wrong and found various points:
- the metadata was coupled with the rdoConnectionInURL flag in TSQLDBRestDispatcher.DoRegisterRoutes instead of rdoExposeMetadata (see patch exposematadata.patch)
- then it turned out that the routes are only registered once the module was loaded and thus they would never be found so I adjusted TSQLDBRestModule.HandleRequest to call the router again (this of course required to change the BasePath of the TSQLDBDispatcher in the example to 'REST' instead of '') (see patch reroute.patch) - this point I'm definitely not sure whether it is the right solution (but in the end it works)
- then the problem was that the module's route ('REST/*/') took precedence over the routes added by the TSQLDBRestDispatcher, so I implemented a sorting of the routes so that more specific ones are encountered first (see patch sort-routes.patch) - don't know whether this is the right approach either, but this *is* a problem
- then the fact that TSQLDBRestModule is by default set to wkOneShot lead to the routes being registered again or more precisely the old routes being left over and pointing to a freed TSQLDBRestDispatcher instance; thus I added a call to UnRegisterRoutes to TSQLDBRestDispatcher.Destroy (see unregister-routes.patch)

With these changes the server worked, but then I encountered two problems in the client:
- if the database table is empty an empty JSON object ('{}') is returned resulting in the client complaining about the missing metadata (after this I executed the expenses-data.sql script)
- when changing from one resource to another I got an exception that the operation is not possible on an active dataset; I solved this for me by closing the dataset before executing LoadFromStream (see patch jsonclient.patch)

And an additional note regarding the expenses-sqlite.sql script. The intention appears to be that the ID columns are auto increment. This will however *only* work if the type of the columns is "integer primary key". "bigint primary key" won't work here. See also: https://www.sqlite.org/autoinc.html
Thus as with patch expenses-sqlite.sql I updat the SQL script for that database.

If these are indeed bugs I'll either commit the patches as is (e.g. the one for the SQLite script is rather surely a bug) or open a bug report for the more complex ones.

I haven't tested more yet, so I don't know whether there are any further problems. :)

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 25 lines
Hello together! I've played around a bit with the SQLDBRESTBridge and encountered some troubles which I wanted to check up here on the list whether those are indeed bugs or not before reporting them to Mantis. For the tests I've used FPC 3.0.4 and Lazarus 2.0 with the SQLDBRESTBridge and the Lazarus examples being from trunk on Friday 14th June. As server I used the restmodule demo in $lazarus/components/sqldbrest/demo/restmodule and changed it to use SQLite3 instead of PostgreSQL. For the client I used the jsonclient demo in $lazarus/components/sqldbrest/demo/jsonclient. I created the database using the expenses-sqlite.sql script in $fpc/packages/fcl-web/examples/restbridge/expenses-sqlite.sql (and no I didn't execute expenses-data.sql at first which will be important further down ;) ). I started the server and tried to access localhost:7331/REST/metadata (I changed the port from 8080), but this resulted in a 404 error which was displayed as an empty page (maybe something isn't correctly working here?). Using localhost:7331/metadata resulted in a "Not found" exception.

This I fixed. I had noticed the same, but didn't have time to fix. It is fixed now.

Show quoted text 5 lines
So I started to research what went wrong and found various points: - the metadata was coupled with the rdoConnectionInURL flag in TSQLDBRestDispatcher.DoRegisterRoutes instead of rdoExposeMetadata (see patch exposematadata.patch)

This is not quite correct. The rdoConnectionInURL check is also necessary:

Both connection/metadata and /metadata must work.

connection/metadata is handled by HandleRequest (FindSpecialResource) So a special registration for metadata must be handled here.

But there was indeed a bug in the code, I fixed it properly.

Show quoted text 7 lines
- then it turned out that the routes are only registered once the module was loaded and thus they would never be found so I adjusted TSQLDBRestModule.HandleRequest to call the router again (this of course required to change the BasePath of the TSQLDBDispatcher in the example to 'REST' instead of '') (see patch reroute.patch) - this point I'm definitely not sure whether it is the right solution (but in the end it works)

This is not the correct solution.

The module itself handles the routes: the module is registered e.g. under /REST and then the request is dispatched to the router, and the dispatcher will take care of the rest.

This means of course that when you use a restmodule, the dispatcher 'RegisterRoutes' must not be called at all, and this can be achieved by setting Active to False.

Maybe the meaning of active is a bit obtuse. I put a comment in when I made it, but if that goes unnoticed...

In general, I added the rest module only for completeness. I think the simple datamodule approach (as demoed in restbridge demo) is the better way: this keeps the schema in memory. for cases where you want to control the connections through the REST api, this is needed anyway.

The REst Module has the additional disadvantage that you must have an initial /REST/ or whatever part in your URL. With the dispatcher on a datamodule, you can skip this if so desired...

Show quoted text 5 lines
- then the problem was that the module's route ('REST/*/') took precedence over the routes added by the TSQLDBRestDispatcher, so I implemented a sorting of the routes so that more specific ones are encountered first (see patch sort-routes.patch) - don't know whether this is the right approach either, but this *is* a problem

No, see above.

Show quoted text 5 lines
- then the fact that TSQLDBRestModule is by default set to wkOneShot lead to the routes being registered again or more precisely the old routes being left over and pointing to a freed TSQLDBRestDispatcher instance; thus I added a call to UnRegisterRoutes to TSQLDBRestDispatcher.Destroy (see unregister-routes.patch)

Well, since they are not supposed to be registered in the first place...

Show quoted text 6 lines
With these changes the server worked, but then I encountered two problems in the client: - if the database table is empty an empty JSON object ('{}') is returned resulting in the client complaining about the missing metadata (after this I executed the expenses-data.sql script)

Indeed.
I fixed that, an error on my end, probably got in after some refactoring :(

- when changing from one resource to another I got an exception that the operation is not possible on an active dataset; I solved this for me by closing the dataset before executing LoadFromStream (see patch jsonclient.patch)

Applied, thanks !

Show quoted text 8 lines
And an additional note regarding the expenses-sqlite.sql script. The intention appears to be that the ID columns are auto increment. This will however *only* work if the type of the columns is "integer primary key". "bigint primary key" won't work here. See also: https://www.sqlite.org/autoinc.html Thus as with patch expenses-sqlite.sql I updat the SQL script for that database.

Yes, the autoincrement in sqlite is rather weird, it seems I forgot to adapt the script for this :(

I applied your patch, thank you !

If these are indeed bugs I'll either commit the patches as is (e.g. the one for the SQLite script is rather surely a bug) or open a bug report for the more complex ones.

Well, I have applied patches where necessary.

I haven't tested more yet, so I don't know whether there are any further problems. :)

Well, I yesterday created a demo for TMS Software's TMS Web core using the SQLDB Rest bridge as a backend, so I'm pretty sure it works 99%. They will include a component that can be dropped on a web form which will allow you to enter SQL etc.

With your patches, we got closer to 100%, so many thanks for that !! :-)

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 10 lines
On Fri, 21 Jun 2019, Sven Barth via fpc-pascal wrote: > Hello together! > > I've played around a bit with the SQLDBRESTBridge and encountered some > troubles which I wanted to check up here on the list whether those are > indeed bugs or not before reporting them to Mantis. >

First of thanks for applying some of the patches and explaining the problems with the others. However see below.

Show quoted text 15 lines
> > So I started to research what went wrong and found various points: > - the metadata was coupled with the rdoConnectionInURL flag in > TSQLDBRestDispatcher.DoRegisterRoutes instead of rdoExposeMetadata (see > patch exposematadata.patch) This is not quite correct. The rdoConnectionInURL check is also necessary: Both connection/metadata and /metadata must work. connection/metadata is handled by HandleRequest (FindSpecialResource) So a special registration for metadata must be handled here. But there was indeed a bug in the code, I fixed it properly.

Ah, now I get the intention. :)

Show quoted text 32 lines
> - then it turned out that the routes are only registered once the module > was loaded and thus they would never be found so I adjusted > TSQLDBRestModule.HandleRequest to call the router again (this of course > required to change the BasePath of the TSQLDBDispatcher in the example > to 'REST' instead of '') (see patch reroute.patch) - this point I'm > definitely not sure whether it is the right solution (but in the end it > works) This is not the correct solution. The module itself handles the routes: the module is registered e.g. under /REST and then the request is dispatched to the router, and the dispatcher will take care of the rest. This means of course that when you use a restmodule, the dispatcher 'RegisterRoutes' must not be called at all, and this can be achieved by setting Active to False. Maybe the meaning of active is a bit obtuse. I put a comment in when I made it, but if that goes unnoticed... In general, I added the rest module only for completeness. I think the simple datamodule approach (as demoed in restbridge demo) is the better way: this keeps the schema in memory. for cases where you want to control the connections through the REST api, this is needed anyway. The REst Module has the additional disadvantage that you must have an initial /REST/ or whatever part in your URL. With the dispatcher on a datamodule, you can skip this if so desired...

Okay, independently of whether the REST module is the optimal solution or not, it should work, right? (and shouldn't the Wiki entry then mention the advantages/disadvantages of the two approaches? Cause when looking at the SQLDB REST module I thought "yay, less stuff to configure" and rolled with that)

Cause with the changes you committed the example provided with Lazarus still does not work (even if I change MyDispatcher.Active to False and MyDispatcher.BasePath to 'REST'). The error is always "INVALID RESOURCE" which means that ExtractRestResourceName returned an empty string (which is logical, cause there neither exists a route that sets 'resource' nor is HandleMetadataRequest ever called).

And regarding the comment of TSQLDBRestDispatcher.Active:
- first of I simply expected the example to work as is, so I definitely didn't look at any comments
- "Register or unregister HTTP routes" doesn't really say much and in what situations it should be used...

Also I've tested the restbridge example provided with Lazarus. It works better (after fixing a compilation error in restserver.lpr at line 59 where "Header:=Header+'; Using SSL');" should be "Header:=Header+'; Using SSL';"), but not correctly either:
- localhost:8080/metadata works
- localhost:8080/users returns "INVALID RESOURCE"
- and for some reason it prints that it's using SSL, but the 's'/'ssl' option isn't provided... :/ (ah, I just noticed why: TCustomHTTPApplication.GetUseSSL is empty :/ - probably should contain "Result:=HTTPHandler.UseSSL;" instead? Btw: is it by intention that the call to CheckOptions does not contain 's'/'ssl'?)

Here is the output (I first tried "localhost:8080/metadata" and then "localhost:8080/users"):

=== output begin ===

[HTTP] From: 127.0.0.1; URL: /metadata
[Resource] (User: ?) Resource: metadata; Operation: GET [Connection] (User: ?) Using connection to Host: ; Database: expenses.db [Result] (User: ?) Resource: metadata; Operation: GET; Status: 200; Text: OK [Result] (User: ?) Resource: ?; Operation: GET; Status: 404; Text: INVALID RESOURCE

=== output end ===

And yes, the JSON and Buf clients don't work either with that server example...

Show quoted text 12 lines
> > I haven't tested more yet, so I don't know whether there are any further > problems. :) Well, I yesterday created a demo for TMS Software's TMS Web core using the SQLDB Rest bridge as a backend, so I'm pretty sure it works 99%. They will include a component that can be dropped on a web form which will allow you to enter SQL etc. With your patches, we got closer to 100%, so many thanks for that !! :-)

Considering that I plan/want to use the SQLDB REST Bridge for a project of my own of course I want it to work correctly. ;)

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 9 lines
> The REst Module has the additional disadvantage that you must have an > initial /REST/ or whatever part in your URL. With the dispatcher on a > datamodule, you can skip this if so desired... Okay, independently of whether the REST module is the optimal solution or not, it should work, right? (and shouldn't the Wiki entry then mention the advantages/disadvantages of the two approaches? Cause when looking at the SQLDB REST module I thought "yay, less stuff to configure" and rolled with that)

What exactly is less to configure ? :)

Show quoted text 8 lines
Cause with the changes you committed the example provided with Lazarus still does not work (even if I change MyDispatcher.Active to False and MyDispatcher.BasePath to 'REST'). The error is always "INVALID RESOURCE" which means that ExtractRestResourceName returned an empty string (which is logical, cause there neither exists a route that sets 'resource' nor is HandleMetadataRequest ever called).

Ah. Documentation issue.
If you use a restmodule, then I expect the resource to be provided using ?resourceParam=Name, not in the URL.

See
function TSQLDBRestDispatcher.ExtractRestResourceName(IO: TRestIO): UTF8String;

We can of course change that to try and look in the URL as well using GetNextPathInfo on the request if the routes are not registered, that should work.

But then it needs to be done early on in the HandleRequest because the rdoInConnection needs to be observed, so the path can be read only once. It will probably require a new rdoUseRequestPathInfo, which could be set by the restmodule... I will look at this.

Show quoted text 6 lines
And regarding the comment of TSQLDBRestDispatcher.Active: - first of I simply expected the example to work as is, so I definitely didn't look at any comments - "Register or unregister HTTP routes" doesn't really say much and in what situations it should be used...

Correct.

Show quoted text 5 lines
Also I've tested the restbridge example provided with Lazarus. It works better (after fixing a compilation error in restserver.lpr at line 59 where "Header:=Header+'; Using SSL');" should be "Header:=Header+'; Using SSL';"), but not correctly either:

Ah, I will check that. I compile using 3.0.4 mostly. (to make sure that works)

- localhost:8080/metadata works - localhost:8080/users returns "INVALID RESOURCE"

Because it has rdoConnectionInURL set, and so you must do localhost:8080/expenses/users

- and for some reason it prints that it's using SSL, but the 's'/'ssl' option isn't provided... :/ (ah, I just noticed why: TCustomHTTPApplication.GetUseSSL is empty :/ - probably should contain "Result:=HTTPHandler.UseSSL;" instead?

Fixed.

Btw: is it by intention that the call to CheckOptions does not contain 's'/'ssl'?)

Oversight, fixed.

Here is the output (I first tried "localhost:8080/metadata" and then "localhost:8080/users"):

As said, the latter must be localhost:8080/expenses/users

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 15 lines
On Sat, 22 Jun 2019, Sven Barth via fpc-pascal wrote: >> The REst Module has the additional disadvantage that you must have an >> initial /REST/ or whatever part in your URL. With the dispatcher on a >> datamodule, you can skip this if so desired... > > Okay, independently of whether the REST module is the optimal > solution or not, it should work, right? (and shouldn't the Wiki entry > then mention the advantages/disadvantages of the two approaches? > Cause when looking at the SQLDB REST module I thought "yay, less > stuff to configure" and rolled with that) What exactly is less to configure ? :)

Looking at the Wiki again I was fooled by the Datamodule having 8 bullet points, the SQLDBRestModule having 5, but the later simply shortening stuff with point five... So yeah... not really less to configure... My fault. ^^'

Show quoted text 17 lines
> > Cause with the changes you committed the example provided with > Lazarus still does not work (even if I change MyDispatcher.Active to > False and MyDispatcher.BasePath to 'REST'). The error is always > "INVALID RESOURCE" which means that ExtractRestResourceName returned > an empty string (which is logical, cause there neither exists a route > that sets 'resource' nor is HandleMetadataRequest ever called). > Ah. Documentation issue. If you use a restmodule, then I expect the resource to be provided using ?resourceParam=Name, not in the URL. See function TSQLDBRestDispatcher.ExtractRestResourceName(IO: TRestIO): UTF8String;

Ah! But that isn't mentioned in the Wiki, right? Cause the Wiki only mentioned the URL based stuff and thus I assumed the SQLDBRESTModule to behave the same...

By the way: I sometimes get a EStreamError *after* all data had been sent to the client. I have not yet found a reproducible way for this...

Show quoted text 11 lines
We can of course change that to try and look in the URL as well using GetNextPathInfo on the request if the routes are not registered, that should work. But then it needs to be done early on in the HandleRequest because the rdoInConnection needs to be observed, so the path can be read only once. It will probably require a new rdoUseRequestPathInfo, which could be set by the restmodule... I will look at this.

Would at least be nice to not have to care how one needs to call the server side...

Show quoted text 5 lines
> - localhost:8080/metadata works > - localhost:8080/users returns "INVALID RESOURCE" Because it has rdoConnectionInURL set, and so you must do localhost:8080/expenses/users

Ahhhhhh! Hadn't seen that this option is active... Okay, then it indeed works as expected, both with and without rdoConnectionInURL.

By the way: I noticed a slight annoyance, but I don't know whether one can really do something about that: When I set rdoConnectionInURL to False inside the object inspector it turns on again, because rdoConnectionResource is set. Took me a moment to look at the source code to see that I need to disable rdoConnectionResource first. Don't know what a better solution would be...

Further thing I noticed when testing BufClient and CSVClient: Changing the resource doesn't work there either. I don't get an exception like with JSONClient, but simply nothing happens.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 12 lines
>> Okay, independently of whether the REST module is the optimal >> solution or not, it should work, right? (and shouldn't the Wiki entry >> then mention the advantages/disadvantages of the two approaches? >> Cause when looking at the SQLDB REST module I thought "yay, less >> stuff to configure" and rolled with that) > > What exactly is less to configure ? :) Looking at the Wiki again I was fooled by the Datamodule having 8 bullet points, the SQLDBRestModule having 5, but the later simply shortening stuff with point five... So yeah... not really less to configure... My fault. ^^'

It's OK. I will try to document it a little better.

Show quoted text 19 lines
>> Cause with the changes you committed the example provided with >> Lazarus still does not work (even if I change MyDispatcher.Active to >> False and MyDispatcher.BasePath to 'REST'). The error is always >> "INVALID RESOURCE" which means that ExtractRestResourceName returned >> an empty string (which is logical, cause there neither exists a route >> that sets 'resource' nor is HandleMetadataRequest ever called). >> > > Ah. Documentation issue. > If you use a restmodule, then I expect the resource to be provided using > ?resourceParam=Name, not in the URL. > > See > function TSQLDBRestDispatcher.ExtractRestResourceName(IO: TRestIO): > UTF8String; Ah! But that isn't mentioned in the Wiki, right? Cause the Wiki only mentioned the URL based stuff and thus I assumed the SQLDBRESTModule to behave the same...

Well, ideally it would be so, and I think I have a way to do it without additional options: the module can simply set the routing params before calling HandleRequest.

By the way: I sometimes get a EStreamError *after* all data had been sent to the client. I have not yet found a reproducible way for this...

Please make sure you have the latest version of everything: I had this a couple of times in case of an error. I fixed all occurrences, I hope.

But if you find additional cases: let me know.

Show quoted text 15 lines
> > We can of course change that to try and look in the URL as well using > GetNextPathInfo on the request if the routes are not registered, > that should work. > > But then it needs to be done early on in the HandleRequest because the > rdoInConnection needs to be observed, so the path can be read only > once. It will probably require a new rdoUseRequestPathInfo, which > could be set by > the restmodule... I will look at this. > Would at least be nice to not have to care how one needs to call the server side...

I agree, see above :)

Show quoted text 16 lines
>> - localhost:8080/metadata works >> - localhost:8080/users returns "INVALID RESOURCE" > > Because it has rdoConnectionInURL set, and so you must do > localhost:8080/expenses/users Ahhhhhh! Hadn't seen that this option is active... Okay, then it indeed works as expected, both with and without rdoConnectionInURL. By the way: I noticed a slight annoyance, but I don't know whether one can really do something about that: When I set rdoConnectionInURL to False inside the object inspector it turns on again, because rdoConnectionResource is set. Took me a moment to look at the source code to see that I need to disable rdoConnectionResource first. Don't know what a better solution would be...

Funny you mention this, I was fooled myself yesterday, I also had to look in the sources :(

One way would be to disable rdoConnectionResource if you disable rdoConnectionInURL. I will add this.

Further thing I noticed when testing BufClient and CSVClient: Changing the resource doesn't work there either. I don't get an exception like with JSONClient, but simply nothing happens.

Strange. I will test the examples again. Thanks for pointing it out !

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 18 lines
On Sun, 23 Jun 2019, Sven Barth via fpc-pascal wrote: >>> Okay, independently of whether the REST module is the optimal >>> solution or not, it should work, right? (and shouldn't the Wiki >>> entry then mention the advantages/disadvantages of the two >>> approaches? Cause when looking at the SQLDB REST module I thought >>> "yay, less stuff to configure" and rolled with that) >> >> What exactly is less to configure ? :) > > Looking at the Wiki again I was fooled by the Datamodule having 8 > bullet points, the SQLDBRestModule having 5, but the later simply > shortening stuff with point five... So yeah... not really less to > configure... My fault. ^^' It's OK. I will try to document it a little better.

Would probably be best, thank you. :)

Show quoted text 8 lines
> By the way: I sometimes get a EStreamError *after* all data had been > sent to the client. I have not yet found a reproducible way for this... Please make sure  you have the latest version of everything: I had this a couple of times in case of an error. I fixed all occurrences, I hope. But if you find additional cases: let me know.

Yes, I was using the latest version. But I'll try to find a reproduceable case. :)

Show quoted text 23 lines
> >>> - localhost:8080/metadata works >>> - localhost:8080/users returns "INVALID RESOURCE" >> >> Because it has rdoConnectionInURL set, and so you must do >> localhost:8080/expenses/users > > Ahhhhhh! Hadn't seen that this option is active... Okay, then it > indeed works as expected, both with and without rdoConnectionInURL. > > By the way: I noticed a slight annoyance, but I don't know whether > one can really do something about that: When I set rdoConnectionInURL > to False inside the object inspector it turns on again, because > rdoConnectionResource is set. Took me a moment to look at the source > code to see that I need to disable rdoConnectionResource first. Don't > know what a better solution would be... Funny you mention this, I was fooled myself yesterday, I also had to look in the sources :( One way would be to disable rdoConnectionResource if you disable rdoConnectionInURL. I will add this.

But wouldn't that lead to an analogous problem with rdoConnectionResource if rdoConnectionInURL is not set?

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 25 lines
>>>> - localhost:8080/metadata works >>>> - localhost:8080/users returns "INVALID RESOURCE" >>> >>> Because it has rdoConnectionInURL set, and so you must do >>> localhost:8080/expenses/users >> >> Ahhhhhh! Hadn't seen that this option is active... Okay, then it >> indeed works as expected, both with and without rdoConnectionInURL. >> >> By the way: I noticed a slight annoyance, but I don't know whether >> one can really do something about that: When I set rdoConnectionInURL >> to False inside the object inspector it turns on again, because >> rdoConnectionResource is set. Took me a moment to look at the source >> code to see that I need to disable rdoConnectionResource first. Don't >> know what a better solution would be... > > Funny you mention this, I was fooled myself yesterday, I also had to > look in > the sources :( > > One way would be to disable rdoConnectionResource if you disable > rdoConnectionInURL. I will add this. But wouldn't that lead to an analogous problem with rdoConnectionResource if rdoConnectionInURL is not set?

I fixed this: if you disable rdoConnectionInURL, rdoConnectionResource is disabled. If not, if rdoConnectionResource is included, rdoConnectionInURL will be set too.

I also fixed the use in a module. The module will set 'active' to false on the dispatcher. Before handling the request, it takes the request and uses pathinfo to set the routing parameters

With the sample module, I tested all possible cases:

No rdoConnectionInURL:
wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/users --content-on-error -O - -d --auth-no-challenge

rdoConnectionInURL set:
Basepath empty:
wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/expenses/users --content-on-error -O - -d --auth-no-challenge

BasePath set to Lola
wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/expenses/users --content-on-error -O - -d --auth-no-challenge

BasePath set to Lola/Pola

wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/expenses/users --content-on-error -O - -d --auth-no-challenge

I think I covered all cases. If I forgot one, do let me know...

I will update the Wiki.

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt

Michael Van Canneyt schrieb am Mo., 24. Juni 2019, 09:30:

Show quoted text 88 lines
On Sun, 23 Jun 2019, Sven Barth via fpc-pascal wrote: >>>>> - localhost:8080/metadata works >>>>> - localhost:8080/users returns "INVALID RESOURCE" >>>> >>>> Because it has rdoConnectionInURL set, and so you must do >>>> localhost:8080/expenses/users >>> >>> Ahhhhhh! Hadn't seen that this option is active... Okay, then it >>> indeed works as expected, both with and without rdoConnectionInURL. >>> >>> By the way: I noticed a slight annoyance, but I don't know whether >>> one can really do something about that: When I set rdoConnectionInURL >>> to False inside the object inspector it turns on again, because >>> rdoConnectionResource is set. Took me a moment to look at the source >>> code to see that I need to disable rdoConnectionResource first. Don't >>> know what a better solution would be... >> >> Funny you mention this, I was fooled myself yesterday, I also had to >> look in >> the sources :( >> >> One way would be to disable rdoConnectionResource if you disable >> rdoConnectionInURL. I will add this. > > But wouldn't that lead to an analogous problem with > rdoConnectionResource if rdoConnectionInURL is not set? I fixed this: if you disable rdoConnectionInURL, rdoConnectionResource is disabled. If not, if rdoConnectionResource is included, rdoConnectionInURL will be set too. I also fixed the use in a module. The module will set 'active' to false on the dispatcher. Before handling the request, it takes the request and uses pathinfo to set the routing parameters With the sample module, I tested all possible cases: No rdoConnectionInURL: wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/users --content-on-error -O - -d --auth-no-challenge rdoConnectionInURL set: Basepath empty: wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/expenses/users --content-on-error -O - -d --auth-no-challenge BasePath set to Lola wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/expenses/users --content-on-error -O - -d --auth-no-challenge BasePath set to Lola/Pola wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/expenses/metadata --content-on-error -O - -d --auth-no-challenge wget --auth-no-challenge --http-user=me --http-password=secret http://localhost:8080/REST/Lola/Pola/expenses/users --content-on-error -O - -d --auth-no-challenge I think I covered all cases. If I forgot one, do let me know... I will update the Wiki.

Awesome! Thank you! Though I don't know when I'll be able to test it next.

Regards,
Sven

Reply by email

Sven Barth
to Michael Van Canneyt: I fixed this: if you disable rdoConnectionInURL, rdoConnectionResource is disabled. If…
Michael Van Canneyt wrote
With the sample module, I tested all possible cases:

I updated both FPC and Lazarus and also tested the sample module. However those variants BasePath empty don't work. I get an exception at line 2053 of sqldbrestbridge.pp. It seems that BasePaths is an array of length 1 containing an empty string... :/ Don't know if that's supposed to be returned by the Split() method or not if the input string is empty...

By the way: is it correct that the sqldbrestdataset currently does not support editing/inserting/deleting entries? Do you plan to change this?

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 9 lines
Am 24.06.2019 um 09:30 schrieb Michael Van Canneyt: > > With the sample module, I tested all possible cases: I updated both FPC and Lazarus and also tested the sample module. However those variants BasePath empty don't work. I get an exception at line 2053 of sqldbrestbridge.pp. It seems that BasePaths is an array of length 1 containing an empty string... :/ Don't know if that's supposed to be returned by the Split() method or not if the input string is empty...

I will test. The Split() method has changed with regards to how to handle empty strings :(

By the way: is it correct that the sqldbrestdataset currently does not support editing/inserting/deleting entries? Do you plan to change this?

Ehm, no, of course it is supposed to support that. It would not be much good if it didn't :-)

Do you get errors ?

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 10 lines
> > By the way: is it correct that the sqldbrestdataset currently does > not support editing/inserting/deleting entries? Do you plan to change > this? Ehm, no, of course it is supposed to support that. It would not be much good if it didn't :-) Do you get errors ?

No. If I use the JSONClient example, list the Users resources, then edit an entry and commit all looks fine so far. However if I then use Get Resource Data again the original data will be restored (also a look into the database showed no change). Same when I add a new entry (btw: is it normal that all rows in the grid appear to be empty after pressing the Insert button and if I enter new data the other rows appear to have that data as well?) or delete one.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 18 lines
Am 01.07.2019 um 23:18 schrieb Michael Van Canneyt: > >> >> By the way: is it correct that the sqldbrestdataset currently does >> not support editing/inserting/deleting entries? Do you plan to change >> this? > > Ehm, no, of course it is supposed to support that. It would not be > much good if it didn't :-) > > Do you get errors ? No. If I use the JSONClient example, list the Users resources, then edit an entry and commit all looks fine so far. However if I then use Get Resource Data again the original data will be restored (also a look into the database showed no change). Same when I add a new entry (btw: is it normal that all rows in the grid appear to be empty after pressing the Insert button and if I enter new data the other rows appear to have that data as well?) or delete one.

As far as I know, the JSON client does not apply updates to the server ? Neither does the bufdataset client. That simply has not been coded.

I test all GET/PUT/POST/DELETE with curl or wget.
and with some pas2js & TMS Web Core clients, with those I know that the updates are coded.

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt

Michael Van Canneyt schrieb am Di., 2. Juli 2019, 08:20:

Show quoted text 30 lines
On Mon, 1 Jul 2019, Sven Barth via fpc-pascal wrote: > Am 01.07.2019 um 23:18 schrieb Michael Van Canneyt: >> >>> >>> By the way: is it correct that the sqldbrestdataset currently does >>> not support editing/inserting/deleting entries? Do you plan to change >>> this? >> >> Ehm, no, of course it is supposed to support that. It would not be >> much good if it didn't :-) >> >> Do you get errors ? > No. If I use the JSONClient example, list the Users resources, then edit > an entry and commit all looks fine so far. However if I then use Get > Resource Data again the original data will be restored (also a look into > the database showed no change). Same when I add a new entry (btw: is it > normal that all rows in the grid appear to be empty after pressing the > Insert button and if I enter new data the other rows appear to have that > data as well?) or delete one. As far as I know, the JSON client does not apply updates to the server ? Neither does the bufdataset client. That simply has not been coded. I test all GET/PUT/POST/DELETE with curl or wget. and with some pas2js & TMS Web Core clients, with those I know that the updates are coded.

Well, my plan is a desktop application that uses a web server backend. So I had hoped for a ready-made solution. Seems like I'll have to implement that in the SQLDBRestClient myself...

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 37 lines
Michael Van Canneyt schrieb am Di., 2. Juli 2019, 08:20: > > > On Mon, 1 Jul 2019, Sven Barth via fpc-pascal wrote: > >> Am 01.07.2019 um 23:18 schrieb Michael Van Canneyt: >>> >>>> >>>> By the way: is it correct that the sqldbrestdataset currently does >>>> not support editing/inserting/deleting entries? Do you plan to change >>>> this? >>> >>> Ehm, no, of course it is supposed to support that. It would not be >>> much good if it didn't :-) >>> >>> Do you get errors ? >> No. If I use the JSONClient example, list the Users resources, then edit >> an entry and commit all looks fine so far. However if I then use Get >> Resource Data again the original data will be restored (also a look into >> the database showed no change). Same when I add a new entry (btw: is it >> normal that all rows in the grid appear to be empty after pressing the >> Insert button and if I enter new data the other rows appear to have that >> data as well?) or delete one. > > As far as I know, the JSON client does not apply updates to the server ? > Neither does the bufdataset client. That simply has not been coded. > > I test all GET/PUT/POST/DELETE with curl or wget. > and with some pas2js & TMS Web Core clients, with those I know that the > updates are coded. > Well, my plan is a desktop application that uses a web server backend. So I had hoped for a ready-made solution. Seems like I'll have to implement that in the SQLDBRestClient myself...

Well, a 'RemoteServer' interface for TBufDataset is still on my todo list.

If you look at the pas2js JSON and rest datasets, they have the necessary functionality to apply updates on the server.

It should be fairly easy to add that same functionality to the native version of the JSONDataset. (I did the same for the indexes BTW.)

This is also on my todo list (which just reached Sirius A meanwhile). But if you (or someone else) want to take a shot at it, go ahead. I will gladly provide all the help you need... :)

I think it is safe to say that Rome wasn't built in a day, and neither was FPC :)

Michael.

Reply by email