You are not logged in.
Pages: 1
NP. I got it work so far:
{"result":"288765500+46CDD1D8F9F632615E77F8E70B6A4A9F9065A6C34E4DEB78C4CB252F8DBCDEAC","logonid":3,"logonname":"User","logondisplay":"User","logongroup":3,"timeout":60,"server":"Project14ServerHttp","version":""}
Hi AB,
I already read that but still not clear how can I calc the PassWord in the second call, I want to simulate that using browser or Postman in order to be clear to me.
I tried this from project14:
SHA256('root'+{model root}
'be092c9049c07d3a73381f7dc1c8cee65d55b1330867ea1d219a8a7b46f9a016'+{server nonce from 1st call}
'fe69ac7d604148b7935ac58213b6323f'+{client nonce random 32 GUID}
'User'+{username}
SHA256('salt'+'synopse'){'salt'+password});
The result always is something like this:
{"result":"2e195bbd72b09b4de054ee2ceaa0862b1241bc9456bea40084cc5f8113a5d044"}
And NOT:
{"result":"1217222202+DC28B0E7941311C870624AB83E4BC7ECD5E462940A8F218F78CDDD567ED4B396","logonid":3,"logonname":"User","logondisplay":"User","logongroup":3,"server":"Project14ServerExternal","version":"0.0.0.0"}
Am I missing something?! I'll appreciate any help :-)
I need to understand that scheme in order to give my clients clean instructions on how to connect to the REST server.
I don't know which language they will use: Python, Java, JS, Delphi, C++...
I just follow the documentation:
https://blog.synopse.info/?post/2013/06 … horization
The first step is clean and understood.
The second step where the client needs to generate a random nonce (length >=32) it's not clear, because in some posts in this forum I see different explanations than the instruction from the link above:
- Client sends a GET ModelRoot/auth?UserName=...&PassWord=...&ClientNonce=...
1. Username= User (default)
2. ClientNonce= random (length>=32)
3. PassWord= computed from the log-on and password entered by the User... (what do you mean computed from the log-on ??)
I don't know how exactly to calculate the password :-)
Hello mormots:
Can I test the authentication from Browser/Postman? If yes how I calc the Sha256 (using online tool?)
I tried the example 14 from the browser:
http://localhost:8888/root/Auth?UserName=User
Result:
{"result":"00cc540c5f75a80f0a397efa7d8c7780d5e30c3bcb8d5bfb617af11caa71529f"}
------------------------------------
Next (as the document says):
------------------------------------
- Client sends a GET ModelRoot/auth?UserName=...&PassWord=...&ClientNonce=... request to the remote server, in which ClientNonce is a random value used as Client nonce, and PassWord is
computed from the log-on and password entered by the User, using both Server and Client nonce as salt;
--> I need more explanation here because I searched the forum and found this:
where xxxxxxxxxxxxxxx = sha256hash( 'root' + servernonce + clientnonce+ clientname + passwordhashhexa )
and passwordhashexa = sha256hash( "salt" + password )
Where "salt" is actually the word: salt
Is that right?
I understand now, Thank you ab and I think Erick should correct that in his book.
Hello,
I'm reading the book of Erick about mORMot trying to understand the conecept of the ORM/DDD/Aggregate: I understand that is doesn't 'join' table as I thought firstly but it's technology or a way for representing your data as DDD/ORM.
Erick show an example in page 183 but when I run that code the 'pTree' field in 'plant' table is 'bigint' not json as showed in Erick book, can someone tell why?
Erick's table:
Erick says : "The descendant classes are technically stored as JSON, and when you read them, they are retrieved and de-serialized back to the structured format."
TTree = class(TSQLRecord)
private
fnumTreeHouses: integer;
frequireleafpickup: TDate;
published
property tNumTreeHouses: integer read fnumTreeHouses write fnumTreeHouses;
property trequireleafpickup: TDate read frequireleafpickup write frequireleafpickup;
end;
TPlant = class(TSQLRecord)
private
fType: RawUTF8;
fheight: integer; // cm or inches
fleafcolor: integer;
fTree : TTree;
published
property pType: RawUTF8 index 20 read fType write fType stored AS_UNIQUE;
property pHeight: integer read fheight write fheight;
property pLeafColor: integer read fleafcolor write fleafcolor;
property pTree : TTree read ftree write ftree;
end;
....
Plant, plant2 : TPlant;
aServerName:= TSQLDBZeosConnectionProperties.URI(dMySQL,aRawServerName);
Model:= TSQLModel.Create([TTree,TPlant],ROOT_NAME);
props:=propsClass.Create(aServerName,aDatabaseName,aUserID,aPassword);
VirtualTableExternalRegister(Model,TPlant,props);
VirtualTableExternalRegister(Model,TTree,props);
// save aggregate root
plant := TPlant.Create(DB,'');
plant.pType := 'oak';
plant.pTree := TTree.Create;
plant.pTree.fnumTreeHouses := 1;
plant.pTree.frequireleafpickup := now;
DB.Add( plant, True);
plant.pTree.Free;
plant.Free;
Yes I use mySQL.
Thanx I'll try that.
Ok I'll explain I have two TSQLRecords that represent my two tables like this:
TContacts = class(TSQLRecord)
private
fCname: RawUTF8;
fCemail: RawUTF8;
fCcel: RawUTF8;
fCtel: RawUTF8;
published
property Cname: RawUTF8 read fCname write fCname;
property Cemail: RawUTF8 read fCemail write fCemail;
property Ccel: RawUTF8 read fCcel write fCcel;
property Ctel: RawUTF8 read fCtel write fCtel;
end;
Tbooks = class(TSQLRecord)
private
fcontactsid: TID;
fbookname: RawUTF8;
fbookyear: TDate;
published
property Bookname:RawUTF8 read fBookname write fBookname;
property contactsid:TID read fcontactsid write fcontactsid;
property bookyear:TDate read fbookyear write fbookyear;
end;
I want to call a method from client side: let us call it 'getContactsA' :
procedure TDB.getContactsA(Ctxt: TSQLRestServerURIContext);
var
sqlResult:Rawjson;
sqlText:RawUTF8;
begin
sqlText:='SELECT cname,bookname FROM contacts LEFT JOIN books ON books.contactsid=contacts.id';
sqlResult:=ExecuteJson([],sqlText);
Ctxt.Results([sqlResult]);
end;
So from browser I call like this: http://localhost:8080/service/getContactsA
Then it executed in server side and I get this error:
True, it's there how to add it to the query?
When I use this code to retrieve joined tables I got an error that 'contacts.id' unknown column.
So I can't declare the id of [TContacts] because it already managed internally by mORMot framework.
How could I execute this:
procedure TDB.getContactsA(Ctxt: TSQLRestServerURIContext);
var
sqlResult:Rawjson;
sqlText:RawUTF8;
begin
sqlText:='SELECT cname,bookname FROM contacts LEFT JOIN books ON books.contactsid=contacts.id';
sqlResult:=ExecuteJson([],sqlText);
Ctxt.Results([sqlResult]);
end;
Thank you in advance
We all waiting for the DDD example.
ab, I will review the link again.
I edited my last post.
Thank you again for a great framework .
I will follow all possible posts in this forum that could give me light for solving my issue.
Could any one give a straight forward example how to work with sharding/DDD.
We need a full sample app that uses 'sharding/DDD' and this is will be most valuable reference to all of us.
Thanks for your help,
But:
- when the 'GetBooks' fired?
- What the purpose of the 'TArrayHelper'?
I still didn't manage to get all books for specific student, for example: http://localhost:8080/service/students/10/books
My database is mySQL, I can learn easily from an example I'm trying to follow the third-party example of 'Megajek' but I can't understand how he did the connection between the tables, I also opened the .db3 using sqlite manager just to understand the structure of the tables and I see a table 'TTasks' that contains 'source' & 'dest' fields ? I don't know why? And even I dropped that table, I know that it will be recreated after I launch the example next time, I know the 'creatingmissingtables..' maybe doing that, but in real time app or at least the way I worked till now (sql) I just join two tables @ runtime I don't need third table to hold 'source' / 'dest'.
Please ab, be more patient with us I have read almost all the forum posts related to this issue, and I still fighting to get my project run as expected for a basic thing, please explain to use how to make the connection and how to tell mormot the index field? I also read the 'enterprise-delphi-databases-2nd' by Erick, and also his explanation is sometimes missing or cutting and jumping to another subject.
Another question as I continue with mORMot:
I want to retrieve the 'books' of a 'student' how I do it the ORM way.
The table 'books' has a field 'studentID' that identify the student (by id), and the student may have more than one book.
type
TBooks = class(TSQLRecord)
private
fbookname: RawUTF8;
fbookyear: TDate;
published
property bookname: RawUTF8 read fbookname write fbookname;
property bookyear: TDate read fbookyear write fbookyear;
end;
And I modified the TRecord:
...
fBooks: TBooks;
...
property Books: TBooks read fBooks write fBooks;
How to tell mORMot to use the field 'studentID' to know the books of a student?
Thanx in advance
Thank you for fast response, I understand.
Till now about ~50 views of this post is that mean that my code is OK.
Another question: I compare this - server response - with sample (18) after I put both project in remote server and here the result:
I test it using chrome like this: http://x.x.x.x:8080/ROOT/samplerecord/10
- sample (18): 90ms
- mySQL: 1.1sec
As you can see there is really difference between the response from server in both projects, can someone till me why? is it because I use mySQL and there is dll in middle? or there is something else with my code?
Thanks in advance
Hello mORMot,
It is really amazing framework, and I really appreciate your hard work, it's been a long that I looking for a really RESTfull web service, and had some options: tms, remobjects, datasnap but neither of them was I expected especially their price.
So I read about mORMot and I have started my first project I would like your help to review this code and tell me that this is the right way to do it so I can continue work with mORMot.
Request: web service for various clients (android app, iphone...) that return result as json (for starting no security will be needed).
Code (Server): this is working project
program mormot_1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils,windows,messages,variants,classes,mormot,SynCommons,
mormotsqlite3,mormotdb,syndb,syndbsqlite3,syndbdataset,syndbzeos,synsqlite3,
synsqlite3static, dateutils, mORMotHttpServer;
const
ROOT_NAME = 'service';
var
Model: TSQLModel;
srHTTP: TSQLHttpServer;
DB: TSQLRestServerDB;
//------------------------------------------------------------------------------
type
TRecord = class(TSQLRecord)
private
fCname: RawUTF8;
fCemail: RawUTF8;
fCcel: RawUTF8;
fCtel: RawUTF8;
published
property Cname: RawUTF8
read fCname write fCname;
property Cemail: RawUTF8
read fCemail write fCemail;
property Ccel: RawUTF8
read fCcel write fCcel;
property Ctel: RawUTF8
read fCtel write fCtel;
end;
//------------------------------------------------------------------------------
procedure start_db(const aRawServerName, aDatabaseName, aUserID, aPassword: RawUTF8);
var
propsClass: TSQLDBConnectionPropertiesClass;
props: TSQLDBConnectionProperties;
aServerName: RawUTF8;
aTableName : RawUTF8;
rec: TRecord;
MainDBName: RawUTF8;
begin
aTableName:='contacts';
MainDBName:= SQLITE_MEMORY_DATABASE_NAME;
propsClass:= TSQLDBZeosConnectionProperties;
aServerName:= TSQLDBZeosConnectionProperties.URI(dMySQL,aRawServerName);
Model:= TSQLModel.Create([TRecord],ROOT_NAME);
rec := TRecord.Create;
props:=propsClass.Create(aServerName,aDatabaseName,aUserID,aPassword);
VirtualTableExternalRegister(Model,TRecord,props,'contacts');
DB:=TSQLRestServerDB.Create(Model,':memory:',false);
DB.CreateMissingTables;
end;
//------------------------------------------------------------------------------
procedure start_server;
begin
try
srHTTP := TSQLHttpServer.Create('8080', [DB], '+',HTTP_DEFAULT_MODE);
srHTTP.AccessControlAllowOrigin := '*';
finally
writeln('OK.');
end;
end;
//------------------------------------------------------------------------------
procedure stop_client;
begin
srHTTP.Free;
DB.Free;
Model.Free;
end;
//------------------------------------------------------------------------------
var s: string;
begin
try
//Test('localhost:3306','myphonebook','root','1234');
writeln('starting db server...');
start_db('localhost:3306','myphonebook','root','1234');
writeln('starting http server...');
start_server;
Readln(s);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Pages: 1