You are not logged in.
Pages: 1
Hi ab,
confirmed working! That fixes the issue, thanks!
Value is 'test@test.com'
ValueLen is 13
fieldType oftVariant
here's the call stack up until and into JsonToAnyVariant:
mormot.core.variants.JsonToAnyVariant(Unassigned,('test@test.com', 'test@test.com', 7, True, ' '),$119F930,False)
mormot.orm.base.Complex
mormot.orm.base.ValueVarToVariant('test@test.com',13,oftVariant,(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil {#0}, nil, 0, False, nil, 0, 0, 0, 0, 0, 0, 0, nil, nil, nil, nil, nil, (nil, nil), (0, 0, 0), (0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0)),True,nil,[dvoReturnNullForUnknownProperty,dvoValueCopiedByReference])
mormot.orm.base.TOrmTableAbstract.GetAsVariant(9,1,Unassigned,False,False,False,[dvoReturnNullForUnknownProperty,dvoValueCopiedByReference])
mormot.orm.base.TOrmTableAbstract.ToDocVariant(2,Unassigned,[dvoReturnNullForUnknownProperty,dvoValueCopiedByReference],False,False,False)
mormot.orm.base.TOrmTableAbstract.ToDocVariant((???, Unassigned),False)
mormot.orm.base.TOrmTableAbstract.ToDocVariant(Unassigned,False)
mormot.orm.rest.TRestOrm.RetrieveDocVariantArray(TConfigHistory,'','JOIN Config AS c ON (MasterId=c.ID) WHERE EndTime=0',(...),'Key,Data,StartTime,CreatedBy',nil,nil)
mormot.rest.core.TRest.RetrieveDocVariantArray(TConfigHistory,'','JOIN Config AS c ON (MasterId=c.ID) WHERE EndTime=0',(...),'Key,Data,StartTime,CreatedBy',nil,nil)
mormot2_rvda_issue.mormot2_rvda_issue
it then goes through GetJsonField which sets Value to nil.
I assume GetJsonField would only return it as string if the input value was wrapped in quotes?
Please see rev3 of the gist for an even more simplified version of the code.
Sorry, that was just a wild guess.
Here's a gist to demonstrate the issue: https://gist.github.com/oti-ud/61151cff … a1c5b5edf2
If you look at the log file generated, the dump of the cfg variable shows the second row Data property to be null; it should be a string instead (i.e. the sample email address as populated in the db).
@ab, I stepped through the code with the debugger, and it looks like the issue is with converting the JSON string to a variant.
The
T := MultiFieldValues(Table, FieldsCsv, FormatSqlWhere, BoundsSqlWhere);
call in TRestOrm.RetrieveDocVariantArray correctly pulls the data from the table into a JSON string:
'[{"Key":"NotDnsSrv","Data":"xyz","StartTime":1730216625567,"CreatedBy":0},{"Key":"NotExpWrn", ...
note how the Data property is identified as a string here.
The subsequent conversion to variant however gets the value of this property without quotes, so does not recognize it as a string and hence flags it as unknown (i.e. returns null). This happens in the JsonToAnyVariant call in mormot.core.variants: it gets all the way to the end to
begin
Info.Json := J;
goto parse;
end;
but then the jump to parse calls Info.GetJsonField which cannot identify it as a string (lacks the quotes) and returns nil instead.
Let me know if this helps in identifying the issue, or if I need to put together some demo code.
Right: totally forgot about mentioning that. I'm using SQLite3 via mormot.db.raw.sqlite3
1) This is the debug output I'm getting for this call:
20241028 13402909 0 SQL ols_rest.TOlsRestServer(02b5f690) 246us returned 8 rows as 598 B SELECT Key,Data,StartTime,CreatedBy FROM ConfigHistory JOIN Config AS c ON (MasterId=c.ID) WHERE EndTime=0
20241028 13402909 0 res mormot.db.raw.sqlite3.TSqlDatabase(02c3aa28) [{"Key":"NotDnsSrv","Data":"1.1.1.1","StartTime":1697574402827,"CreatedBy":0},{"Key":"NotExpWrn","Data":"7","StartTime":1697574402842,"CreatedBy":0},{"Key":"MaintTime","Data":"256","StartTime":1697574402842,"CreatedBy":0},{"Key":"MaintLogD","Data":"365","StartTime":1697574402858,"CreatedBy":0},{"Key":"MaintBakF","Data":"14","StartTime":1697574402858,"CreatedBy":0},{"Key":"AccSesLen","Data":"1","StartTime":1729798793575,"CreatedBy":1},{"Key":"NotViaEml","Data":"1","StartTime":1729798819683,"CreatedBy":1},{"K... (truncated) length=598
Is there some way to configure the logging so it does not truncate the output? The relevant value is just beyond the portion that is cut off...
2) That's next, but I will have to move my code to a console app first as it is currently running as a Windows service app.
3) Sorry about that, I will keep that in mind.
I just finished converting a project from mORMot 1 to mORMot 2. Everything is working great so far, except the result of a RetrieveDocVariantArray call, which is returning null for Data for one row of the table. It should be returning a string value (this particular entry is holding an email address).
The relevant code:
var
cfg: Variant;
begin
...
cfg := RetrieveDocVariantArray(TConfigHistory, '', 'JOIN Config AS c ON (MasterId=c.ID) WHERE EndTime=0', [], 'Key,Data,StartTime,CreatedBy');
...
end;
TConfig and TConfigHistory are defined as follows:
TConfig = class(TSQLRecord)
private
fKey: RawUTF8; // alphanumeric string acting as a unique key
published
property Key: RawUTF8 index 32 read fKey write fKey stored AS_UNIQUE;
end;
TConfigHistory = class(TSQLRecord)
private
fMasterId: TConfigToBeDeletedID; // reference to the master TConfig record (w/ ON DELETE CASCADE)
fStartTime: TUnixMSTime; // time stamp when record was first active
fEndTime: TUnixMSTime; // time stamp when record was last active; will be 0 for currently active records
fCreatedBy: TUserToBeDeletedID; // table ID of user who created the record (w/ ON DELETE CASCADE)
fData: Variant; // data
published
property MasterId: TConfigToBeDeletedID read fMasterId write fMasterId;
property StartTime: TUnixMSTime read fStartTime write fStartTime;
property EndTime: TUnixMSTime read fEndTime write fEndTime;
property CreatedBy: TUserToBeDeletedID read fCreatedBy write fCreatedBy;
property Data: Variant read fData write fData;
end;
The strange thing is, if I overwrite the value with an integer (5 for example), it will return 5 as the field value. Any string results in null.
If I use this function to pull that particular entry, the correct value is returned from the table:
function GetConfigVar(const Key: RawUTF8; var Value: Variant): Boolean;
var
aConfig: TConfig;
aConfigHistory: TConfigHistory;
begin
aConfig := TConfig.CreateAndFillPrepare(aRestServer.Orm, 'Key=?', [Key]);
try
Result := aConfig.FillOne;
if Result then begin
aConfigHistory := TConfigHistory.CreateAndFillPrepare(aRestServer.Orm, 'MasterId=? AND EndTime=0',
[aConfig.ID]); // get the currently active history record
try
Result := aConfigHistory.FillOne;
if Result then
Value := aConfigHistory.Data;
finally
aConfigHistory.Free;
end;
end;
finally
aConfig.Free;
end;
end;
Anyone have any suggestions as to what the issue might be?
Sorry... my bad! it's working... it ran into my catchall which was returning the code 400.
Is it possible to re-route requests to existing REST server methods?
I tried adding:
aRestServer := TVspsRestServer.CreateWithOwnModel([], False, 'vsps');
try
aHttpServer := TRestHttpServer.Create(SERVER_PORT, [aRestServer], '+', useHttpSocket);
try
aHttpServer.AccessControlAllowOrigin := '*';
aHttpServer.Route.Get('/vsps/test', '/vsps/createport');
but am getting a 400 - Bad Request when I try a GET on /vsps/test.
the method is defined as:
procedure TVspsRestServer.CreatePort(Ctxt: TRestServerURIContext);
mpv,
was already thinking along those lines. Thanks for sharing the config sample and the link!
Hi ab,
yes, the front-end will call REST endpoints where appropriate.
I had started experimenting with a mORMotHttpServer Request override, but it looks like I would have to handle everything myself that way (correct me if I'm wrong), including session management and paying attention to when it's a static content request and when it's a REST call (since I used '/' as the additionalUrl in the Create call).
I'll explore the idea of using nginx to serve the front-end.
Thanks for sharing your insight!
Looking for some advice on how to approach a project with mORMot serving as the back-end to a Vue.js based front-end.
We currently have a working application that uses mORMot MVC templates to serve a browser based UI, with some interface based code to do the required work on the server. The plan is to upgrade the UI using Vue.js. Since this would shift the view and controller part to the client, the server would only need to server static files.
What would be the best approach?
Drop the MVC part, keep the interface code and have mORMot server the UI as static files?
Use a dedicated web server (e.g. nginx) to serve the UI files, only keeping the mORMot interface code?
Or another, even better approach?
Any insights are welcome.
Thanks ab. That did the trick!
Was that mentioned anywhere in the mORMot docs? Looks like I missed that...
Do I have to call a function before I can use OSVersion or OSVersionText?
I'm running an application on Windows 10 Pro, yet OSVersionText gives me "Windows 8 64bit (6.2.9200)". winver.exe says "Version 1803 (OS Build 17134.286)". mORMot is at 1.18.4847.
I guess some deprecated protocol problem: the server doesn't accept some TLS protocols, which are set by Windows Seven.
Hadn't thought of that!
Ok, I'll probably end up adding some code to only set the property if it's running on a system with a know certificate issue.
Thanks for help, much appreciated.
Regards,
Ulrich
You can try to set the THttpRequest.IgnoreSSLCertificateErrors property, which is exactly for such cases.
Thanks ab, that makes the error go away.
I can't help wondering though what can of worms I open by setting this property?
Is there no way of finding out what winhttp is bothered by?
First post, so: thanks for the mORMot Framework - great stuff!
Now on to the issue at hand...
Got an odd problem here: I have a server/client application that communicates via SSL secured interface functions. So far, everything has been working great and I have no issue running server and client on two different Windows 10 PCs. However, I just installed my client on Windows 7 and it's giving me the following error:
20180727 20361848 ! debug RequestSync
20180727 20361848 ! + mORMotHttpClient.TSQLHttpClientWinHTTP(028DDDB0).CallBackGet ols/Timestamp
20180727 20361848 ! + mORMotHttpClient.TSQLHttpClientWinHTTP(028DDDB0).InternalURI GET
20180727 20361856 ! EXC EWinHTTP ("WinHTTP security error. Status 65536, statusInfo: 16") at 0074FA18 SynCrtSock.TWinHTTP.InternalConnect (10491) stack trace API
20180727 20361857 ! - 00.137.235
20180727 20361857 ! - 00.137.254
20180727 20361857 ! warn mORMotHttpClient.TSQLHttpClientWinHTTP(028DDDB0) /Timestamp call failed -> Server not available
20180727 20361857 ! info mORMotHttpClient.TSQLHttpClientWinHTTP(028DDDB0) Destroy ols
How can I find out what exactly the problem is, or where the status/statusinfo values for this error are defined?
I'm suspecting the client on Windows 7 doesn't like something about the certificate of the server, as there's nothing logged about the connection attempt on the server side.
The certificate I'm using on the server side is created on demand during installation (as it has to be customized to the server: SAN field holds host name and IP address). The CA certificate that is used to sign the server certificate was added to the "Local Computer\Trusted Root Certification Authorities" on the client.
BTW: browsing to the MVC web page of the server works fine from Windows 7 (no certificate issues).
Any pointers would be greatly appreciated!
Pages: 1