You are not logged in.
I use AddArrayOfConst to create the parameters.
When I add values of type double (returned by a method), the last value always prevails.
I assume it's being added by reference ...
Is there any way to avoid this?
PS: I am posting this session because the database-related methods also use FormatUTF8 internally, and the same occurs.
Sample code (Delphi 7):
procedure TForm8.Button1Click(Sender: TObject);
var
AParams : TTVarRecDynArray;
AWhere : RawUTF8;
begin
AWhere := '';
SQLAddWhereAnd(AWhere, 'ative = %');
AddArrayOfConst(AParams, [Ord(True)]);
SQLAddWhereAnd(AWhere, 'inative = %');
AddArrayOfConst(AParams, [Ord(False)]);
SQLAddWhereAnd(AWhere, 'date_ini >= %');
AddArrayOfConst(AParams, [IncDay(Date(),-2)]);
SQLAddWhereAnd(AWhere, 'date_end <= %');
AddArrayOfConst(AParams, [Date]);
Memo1.Lines.Add(FormatUTF8(AWhere,AParams));
//Produces: ative = 1 and inative = 0 and date_ini >= 43168 and date_end <= 43168
end;Using doubles directly does not occur.
procedure TForm8.Button1Click(Sender: TObject);
var
AParams : TTVarRecDynArray;
AWhere : RawUTF8;
begin
AWhere := '';
SQLAddWhereAnd(AWhere, 'ative = %');
AddArrayOfConst(AParams, [Ord(True)]);
SQLAddWhereAnd(AWhere, 'inative = %');
AddArrayOfConst(AParams, [Ord(False)]);
SQLAddWhereAnd(AWhere, 'my_float1 = %');
AddArrayOfConst(AParams, [4.99]);
SQLAddWhereAnd(AWhere, 'my_float2 = %');
AddArrayOfConst(AParams, [5.99]);
Memo1.Lines.Add(FormatUTF8(AWhere,AParams));
//Produces: ative = 1 and inative = 0 and my_float1 = 4.99 and my_float2 = 5.99
end;I use both ways.
But in this particular project the service is consumed exclusively by a delphi application, so I am not using services in this case.
But using services the JSON format will be the same, correct?
What you suggest would be to get the result in DocVariant. So do the parsing - in the service method - with the conversions and return formatted?
Ok thanks por reply.
Hi guys,
When retrieving the data in any (ORM Related) method that return JSON...
Are possible to generate TtimeLog type fields in ISO 8601 format instead of integer?
Example:
{
"Name": "The Name",
CreatedAt: "2018-02-02T12:57:17+00:00",
ModifiedAt: "2018-02-02T12:57:17+00:00"
}Thanks for the reply!
Is there any way to use / simulate an external db even using SQLite?
Im time, i use packages and getting this warning:
[Warning] Exported package threadvar 'mORMot.ServiceContext' cannot be used outside of this package
mORMot unit are inside a single package only.
I can safely ignore this warning?
Hi guys,
I using SQLite as DB.
Is possible to remap a field, without using a external table?
When i do:
AModels := TSQLModel.Create([TSQLBaby]);
AServer := TSQLRestServerDB.Create(AModels ,ADBFilePath,False, '');
AMyModels.Props[TSQLBaby].ExternalDB.MapField('ID','bay_cod');I get, an exception.
Due to i not using a external db, right?
Hi,
I'm trying to use TCurlHTTP to access services not mormot related.
But curl.easy_setopt is not accessible outside of SynCtrSock.pas, and i need to set some options like coFollowLocation to work properly.
Is there any way to access?
Or create a public/protected method in the next revision?
Like:
TCurlHTTP = class(THttpRequest)
protected
funtion SetOpt(...)..
function TCurlHTTP.SetOpt()...
result := curl.easy_setopt(...)I found my mistake, but i think that the type name induces to contrary what this feature does...
When i delete child row then the main row are deleted in cascade.
It is the opposite that i thinked.
I wanted to delete child row when main row are first deleted.
type
TSQLRecordClientID = type TID;
TSQLRecordClientToBeDeletedID = type TID;
TSQLOrder = class(TSQLRecord)
...
property Client: TID
read fClient write fClient;
property OrderedBy: TSQLRecordClientID
read fOrderedBy write fOrderedBy;
property OrderedByCascade: TSQLRecordClientToBeDeletedID
read fOrderedByCascade write fOrderedByCascade;
...If i implement this scenario the Order are deleted when the Client are deleted.
But TSQLRecordClientToBeDeletedID type name, indicate that the Client are deleted.
Sorry if I'm mistaking me or forget something again.
Also calling TSQLRestServerDB(Database.Server).Delete(TSQLtest, ATest.ID) child record are not deleted.
In AfterDeleteForceCoherency at mORMot.pas (37392) this test
if Ref^.FieldTableIndex=aTableIndex then
PerformCascade(aID,Ref);Are evaluted to false, because aTableIndex are 1 and Ref^.FieldTableIndex is 0.
Then PerformCascade are not executed.
PS: is not missing to set Ref value at position of I inside of "for"?
Because without this Ref always point to @Model.fRecordReferences[0];
var i: integer;
Ref: PSQLModelRecordReference;
begin
Ref := @Model.fRecordReferences[0];
if Ref<>nil then begin
for i := 1 to length(Model.fRecordReferences) do begin
if Ref^.FieldTableIndex=-2 then // lazy initialization
Ref^.FieldTableIndex := Model.GetTableIndexSafe(Ref^.FieldTable,false);
case Ref^.FieldType.SQLFieldType of
sftRecord: // TRecordReference published field
PerformCascade(RecordReference(aTableIndex,aID),Ref);
sftID: // TSQLRecord published field
if Ref^.FieldTableIndex=aTableIndex then //FieldTableIndex =0 aTableIndex =1
PerformCascade(aID,Ref);
sftTID: // TTableID = type TID published field
if Ref^.FieldTableIndex=aTableIndex then
PerformCascade(aID,Ref);
end;
inc(Ref);
end;
end;
result := true; // success even if no match found, or some cascade warnings
end;Please spend some time in the IDE/debugger to check why the cascaded deleted is not triggerred.
I debugged and Database.Delete are calling TSQLRest.Delete method that not call AfterDeleteForceCoherency.
To call TSQLRestServer.Delete that call AfterDeleteForceCoherency i need to use:
TSQLRestServerDB(Database.Server).Delete(TSQLtest, ATest.ID);
This cast are need?
I have created Database in this way:
Database := TSQLRestClientDB.Create(AModel,AModel,ACompleteDBPath,TSQLRestServerDB,False);
How do you delete the main row?
It should be via the ORM Delete method.
Yes, i using the ORM.
Database setup:
AModel := CreateModel;
Database := TSQLRestClientDB.Create(AModel,AModel,ExtractFilePath(ParamStr(0)) + 'db.db3', TSQLRestServerDB,False);
TSQLRestClientDB(DataBase).Server.CreateMissingTables();Then
if Database.Retrieve(ASelectedID, ATest, False) then
Database.Delete(TSQLtest, ATest.ID);Main row are deleted, child row not.
Sorry guys but I'm a little confused ...
I'm testing the cascade deletion, but even with TID reference is not happening ...
My code
TSQLtest_child = class;
TSQLtest_childToBeDeletedID = type TID;
//TSQLRecordtest_childToBeDeletedID = type TID; <-- Also tested with TSQLRecord*
TSQLtest = class(TSQLRecord)
protected
FChildToDelete: TSQLtest_childToBeDeletedID;
fName: RawUTF8;
fCreatedAt: TCreateTime;
FModifiedAt: TModTime;
published
property Name: RawUTF8 index 255 read fName write fName;
property CreatedAt: TCreateTime read fCreatedAt write fCreatedAt;
property ModifiedAt: TModTime read FModifiedAt write FModifiedAt;
property ChildToDelete: TSQLtest_childToBeDeletedID read FChildToDelete write FChildToDelete;
end;
TSQLtest_child = class(TSQLRecord)
private
protected
fName: RawUTF8;
fCreatedAt: TCreateTime;
FModifiedAt: TModTime;
published
property Name: RawUTF8 index 255 read fNome write fNome;
property CreatedAt: TCreateTime read fCreatedAt write fCreatedAt;
property ModifiedAt: TModTime read FModifiedAt write FModifiedAt;
end;
//Add OK
ATest := TSQLtest.Create;
ATestChild := TSQLtest_child.Create;
try
ATestChild.Name := 'Child';
ATest.ChildToDelete := TSQLtest_child(Database.Add(ATestChild, True)).ID;
ATest.Name := Edit1.Text;
if Database.Add(ATest, True) > 0 then
begin
AddItemToViewList(ListView1,ATest);
end;
finally
ATestChild.Free;
ATest.Free;
end;
//DELETE
Atest := Database.Retrieve(...);
Database.Delete(TSQLtest, ATest.ID);
Child row are not delete with main row.
Hi Friends,
The only way to set a cascade deletion is by TID, using a TSQLRecordXyzToBeDeletedID type?
With a TSQLRecord property is possible?
Example:
TSQLRecordChildTable = class(TSQLRecord)
...
end;
TSQLRecordMainTable = class(TSQLRecord)
...
property child : TSQLRecordChildTable read fchild write fchild; //Delete child row if main row is deleted
end;If only way is with TSQLRecordXyzToBeDeletedID type, i loose the CreateAndFillPrepareJoined functionality?
Realy strange.
This unit dont exists in my default installation of Delphi 7.
In Delphi xe5 exists.
For Delphi 7 i have found and downloaded from Jedi API
http://www.delphi-jedi.org/apilibrary.html
Now hi is calling for mozjs-45.dll
I have searched but dont found this dll to download.
Only mozjs-24.dll
Hi Friends,
Tried in Delphi 7 but ShLwApi.pas required in SyNode.pas (line 73) are missing.
unit SyNode;
...
uses
{$ifdef MSWINDOWS} Windows, ShLwApi,{$endif}
{$ifdef ISDELPHIXE2}System.SysUtils,{$else}SysUtils,{$endif}
Classes,I'm using SynSM unit.
My installation not was SyNode/...
I installing now...
Thanks!
I know that the main goal of integration with JavaScript is the server side.
But I'm trying to use to allow some interaction on the client side...
So is possible, for example, pass a class to the JS?
Example:
Engine.GlobalObject.MyForm := Self; //MainFormIn JS
MyForm.Caption = MyForm.Caption + ' - Changed from JS';If possible it would generate thread problems?
TTestChild = class(TSqlrecord)..
Ttest = class(TSqlrecord)
published
...
Child : TTestChild read FChild write FChild;
end;
//Retrieve child if exists
if ATest.Child <> nil then
begin
ATest.Child := TTestChild.Create(Database, ATest.Child);
Log(ATest.Child.Name);
end;But now, how i test if child is retrevied to avoid to retrieve again?
And ATest.Child assigned with this form is freed when ATest is freed?
Thanks
Thanks for reply.
Hi Friends,
It's possible to change the way that the autoincrement values are generated?
I do not want the same id to be reused in case of exclusion of the last added record.
But SELECT MAX (ID) ... makes it reused.
I want to store the last id in a specialized table. And the values would be consulted in this table instead of using SELECT max...
It's possible?
Thanks in advance
Solved.
I forgot TSQLRestServerDB(DataBase).CreateMissingTables();
Hi Friends,
I'm trying to start a project with the Framework.
It is compatible with Access (.mdb) database?
I'm not getting set properly.
type
TSQLtest = class(TSQLRecord)
protected
fName: RawUTF8;
published
property Name: RawUTF8 index 255 read fName write fName;
end;
(...)
var
AConnString : String;
AModel : TSQLModel;
AProp : TOleDBJetConnectionProperties;
AConn : TOleDBConnection; //to test connection only
ATest : TSQLtest;
ARow: Variant;
Database : TSQLRest;
(...)
AConnString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\tests\mormot\db\db.mdb;Persist Security Info=False;Jet OLEDB:Database Password=mypass';
AProp := TOleDBJetConnectionProperties.Create(AConnString,'','','mypass');
AProp.ConnectionString := AConnString; //It does not work if ConnectionString are not setted here
//Testing a connection. Always connect successfully
AConn := TOleDBConnection.Create(AProp);
AConn.Connect;
Memo1.Lines.Add('Connected: ' + IntToStr(Ord(AConn.Connected)));
//Testing a SELECT. This are OK too.
with AProp.Execute('SELECT * FROM test',[],@ARow) do
while Step do
Memo1.Lines.Add('Nome:' + ARow.Name);
//Now the ORM
AModel := TSQLModel.Create([TSQLtest]);
VirtualTableExternalRegisterAll(AModel,AProp);
//Also tried
//VirtualTableExternalRegister(AModel,TSQLteste,AProp,'test');
Database := TSQLRestServerDB.Create(AModel, ':memory:' , True);
ATest := TSQLtest.Create;
try
Database.Retrieve('Name = "Jhon"', ATest);
finally
ATest.Free;
end;Database.Retrieve... causes this error
Error SQLITE_ERROR (1) [SELECT RowID, Name FROM test WHERE Name = "Jhon"] using 3.14.1- no such table: test, extended_errcode=1Don't locate table test, and I do not understand why are using RowID instead of ID.
If i omit VirtualTableExternalRegisterAll(AModel,AProp) then he uses ID and error was:
Error SQLITE_ERROR (1) [SELECT ID, Name FROM test WHERE Name = "Jhon"] using 3.14.1- no such table: test, extended_errcode=1