You are not logged in.
Pages: 1
Sorry, the properties were public rather than published
I tried to tailor the example below, but also returned null for additional collections.
TLevel3 = class(TCollectionItem)
private
FID: Integer;
FID_Level2: Integer;
FName: RawUTF8;
public
property ID: Integer read FID write FID;
property ID_Level2: Integer read FID_Level2 write FID_Level2;
property Name: RawUTF8 read FName write FName;
end;
TListLevel3 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel3;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
function Add: TLevel3;
end;
TLevel2 = class(TCollectionItem)
private
FID: Integer;
FID_Level1: Integer;
FName: RawUTF8;
public
property ID: Integer read FID write FID;
property ID_Level1: Integer read FID_Level1 write FID_Level1;
property Name: RawUTF8 read FName write FName;
end;
TListLevel2 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel2;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
function Add: TLevel2;
end;
TLevel1 = class(TCollectionItem)
private
FID: Integer;
FID_AnyProp1: Integer;
FName: RawUTF8;
published
property ID: Integer read FID write FID;
property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
property Name: RawUTF8 read FName write FName;
end;
TListLevel1 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel1;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
function Add: TLevel1;
end;
TLevel0 = class
private
FID: Integer;
FName: RawUTF8;
FListLevel1: TListLevel1;
FListLevel2: TListLevel2;
FListLevel3: TListLevel3;
published
property ID : Integer read FID write FID;
property Name : RawUTF8 read FName write FName;
property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
constructor Create;
destructor Destroy; override;
end;
JSON
{
"ID": 1,
"Name": "ANY TEXT LEVEL 0",
"ListLevel1": [
{
"ID": 1,
"ID_AnyProp1": 1,
"Name": "ANY TEXT LEVEL 1"
}
],
"ListLevel2": [
null
],
"ListLevel3": [
null,
null
]
}
Hello AB,
I try to generate json (with multiple levels of collections), but, level 2 is generated null.
Can you help me?
The example is below.
My Unit
unit UnitSample;
interface
uses
System.Classes,
mORMot,
SynCommons;
type
TLevel3 = class(TCollectionItem)
private
FID: Integer;
FID_Level2: Integer;
FName: RawUTF8;
public
property ID: Integer read FID write FID;
property ID_Level2: Integer read FID_Level2 write FID_Level2;
property Name: RawUTF8 read FName write FName;
end;
TListLevel3 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel3;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel3 read GetCollItem; default;
function Add: TLevel3;
end;
TLevel2 = class(TCollectionItem)
private
FID: Integer;
FID_Level1: Integer;
FName: RawUTF8;
FListLevel3: TListLevel3;
public
property ID: Integer read FID write FID;
property ID_Level1: Integer read FID_Level1 write FID_Level1;
property Name: RawUTF8 read FName write FName;
property ListLevel3: TListLevel3 read FListLevel3 write FListLevel3;
destructor Destroy; override;
end;
TListLevel2 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel2;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel2 read GetCollItem; default;
function Add: TLevel2;
end;
TLevel1 = class(TCollectionItem)
private
FID: Integer;
FID_AnyProp1: Integer;
FName: RawUTF8;
FListLevel2: TListLevel2;
published
property ID: Integer read FID write FID;
property ID_AnyProp1: Integer read FID_AnyProp1 write FID_AnyProp1;
property Name: RawUTF8 read FName write FName;
property ListLevel2: TListLevel2 read FListLevel2 write FListLevel2;
destructor Destroy; override;
end;
TListLevel1 = class(TInterfacedCollection)
private
function GetCollItem(aIndex: Integer): TLevel1;
protected
class function GetClass: TCollectionItemClass; override;
public
property Item[aIndex: Integer]: TLevel1 read GetCollItem; default;
function Add: TLevel1;
end;
TLevel0 = class
private
FID: Integer;
FName: RawUTF8;
FListLevel1: TListLevel1;
published
property ID : Integer read FID write FID;
property Name : RawUTF8 read FName write FName;
property ListLevel1: TListLevel1 read FListLevel1 write FListLevel1;
constructor Create;
destructor Destroy; override;
end;
implementation
uses
SysUtils;
{ TListLevel1 }
function TListLevel1.Add: TLevel1;
begin
result := TLevel1(inherited Add);
result.FListLevel2 := TListLevel2.Create;
end;
class function TListLevel1.GetClass: TCollectionItemClass;
begin
result := TLevel1;
end;
function TListLevel1.GetCollItem(aIndex: Integer): TLevel1;
begin
result := TLevel1(GetItem(aIndex));
end;
{ TListLevel2 }
function TListLevel2.Add: TLevel2;
begin
result := TLevel2(inherited Add);
result.FListLevel3 := TListLevel3.Create;
end;
class function TListLevel2.GetClass: TCollectionItemClass;
begin
result := TLevel2;
end;
function TListLevel2.GetCollItem(aIndex: Integer): TLevel2;
begin
result := TLevel2(GetItem(aIndex));
end;
{ TListLevel3 }
function TListLevel3.Add: TLevel3;
begin
result := TLevel3(inherited Add);
end;
class function TListLevel3.GetClass: TCollectionItemClass;
begin
result := TLevel3;
end;
function TListLevel3.GetCollItem(aIndex: Integer): TLevel3;
begin
result := TLevel3(GetItem(aIndex));
end;
{ TLevel0 }
constructor TLevel0.Create;
begin
FListLevel1 := TListLevel1.Create;
end;
destructor TLevel0.Destroy;
begin
FreeAndNil(FListLevel1);
inherited;
end;
{ TLevel1 }
destructor TLevel1.Destroy;
begin
FreeAndNil(FListLevel2);
inherited;
end;
{ TLevel2 }
destructor TLevel2.Destroy;
begin
FreeAndNil(FListLevel3);
inherited;
end;
end.
Values of sample
var
Level0: TLevel0;
LocalJson: RawJSON;
begin
Level0 := TLevel0.Create;
try
Level0.ID := 1;
Level0.Name := 'ANY TEXT LEVEL 0';
with TLevel1(Level0.ListLevel1.Add) do
begin
ID := 1;
ID_AnyProp1 := Level0.ID;
Name := 'ANY TEXT LEVEL 1';
with TLevel2(ListLevel2.Add) do
begin
ID := 1;
ID_Level1 := 1;
Name := 'ANY TEXT LEVEL 2';
with TLevel3(ListLevel3.Add) do
begin
ID := 1;
ID_Level2 := 1;
Name := 'ANY TEXT LEVEL 3 A';
end;
with TLevel3(ListLevel3.Add) do
begin
ID := 2;
ID_Level2 := 1;
Name := 'ANY TEXT LEVEL 3 B';
end;
end;
end;
LocalJson := ObjectToJson(Level0);
Memo.Text := LocalJson;
finally
FreeAndNil(Level0);
end;
JSON gerated
{
"ID": 1,
"Name": "ANY TEXT LEVEL 0",
"ListLevel1": [
{
"ID": 1,
"ID_AnyProp1": 1,
"Name": "ANY TEXT LEVEL 1",
"ListLevel2": [
null
]
}
]
}
"ListLevel2": [
null
]
This post saved my day and a sprint.
Thank you
Sorry,
else if condition will never be true.
Changed to
else if (WR.lastchar <> JSONSEND_WITHID[ForceServiceResultAsJSONObject][1]) then
But the tests did not pass.
2.7. Service oriented architecture:
- Weak interfaces: 56 assertions passed 405us
- Service initialization: 243 assertions passed 2.30ms
- Direct call: 583,392 assertions passed 24.99ms
- Server side: 583,411 assertions passed 25.31ms
! Exception EInterfaceFactoryException raised with messsage:
! Invalid TInterfacedObjectFake.FakeCall() for IComplexCalculator.Collections:
Invalid returned JSON content: expects {"result":...}
hi AB,
I tried to change to solve the problem.
Tests for Service oriented architecture passed.
unit: mORMot.pas
class: TSQLRestServerURIContext
method: ServiceResultEnd
See if this is correct:
procedure TSQLRestServerURIContext.ServiceResultEnd(WR: TTextWriter; ID: integer);
const JSONSEND_WITHID: array[boolean] of RawUTF8 = ('],"id":','},"id":');
JSONSEND_NOID: array[boolean] of AnsiChar = (']','}');
begin // InternalExecuteSOAByInterface has set ForceServiceResultAsJSONObject
if (ID=0) and (WR.lastchar <> JSONSEND_NOID[ForceServiceResultAsJSONObject]) then
WR.Add(JSONSEND_NOID[ForceServiceResultAsJSONObject])
else if (WR.lastchar <> JSONSEND_WITHID[ForceServiceResultAsJSONObject]) then
begin
WR.AddString(JSONSEND_WITHID[ForceServiceResultAsJSONObject]);
WR.Add(ID); // only used in sicClientDriven mode
end;
WR.Add('}');
end;
Thanks AB.
I'm glad to help.
Ticket UUID: 4cf639afe6b45925a76260106c976c217947a9a3
Hi AB,
Below is the code of my example.
Server.dpr
program Server;
uses
Vcl.Forms,
MainServer in 'MainServer.pas' {FrmApp},
mORMot,
SynCommons,
main in 'main.pas';
{$R *.res}
begin
with TSQLLog.Family do begin
Level := LOG_VERBOSE;
EchoToConsole := LOG_VERBOSE; // log all events to the console
end;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TFrmApp, FrmApp);
ReportMemoryLeaksOnShutdown := True;
Application.Run;
end.
MainServer (Form)
unit MainServer;
interface
uses
System.SysUtils, Vcl.Forms, System.Classes, Vcl.Controls, Vcl.StdCtrls,
Vcl.ExtCtrls,
main;
type
TFrmApp = class(TForm)
BtnConnect: TButton;
cbBridge: TCheckBox;
Panel1: TPanel;
Panel2: TPanel;
Edit1: TEdit;
Edit2: TEdit;
procedure BtnConnectClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
MyServer: TMyHTTPServer;
public
end;
var
FrmApp: TFrmApp;
implementation
{$R *.dfm}
procedure TFrmApp.BtnConnectClick(Sender: TObject);
begin
if (cbBridge.Checked) then
begin
IP_Bridge := Edit2.Text;
Porta_Bridge := Edit1.Text;
end;
if Assigned(MyServer) then
begin
FreeAndNil(MyServer);
BtnConnect.caption := 'Desconectado';
end else
begin
MyServer := TMyHTTPServer.Create('773', 1);
if (cbBridge.Checked) then
MyServer.ServiceRegister(TMyClassBridge, TypeInfo(IMyInterface), '1')
else
MyServer.ServiceRegister(TMyClassDirect, TypeInfo(IMyInterface), '1');
BtnConnect.caption := 'Connect';
end;
end;
procedure TFrmApp.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(MyServer);
end;
end.
Main.pas
unit main;
interface
uses
SynCommons, mORMot, mORMotHttpServer, mORMotHttpClient;
type
TMyService = class(TSQLRestServerFullMemory)
published
procedure myapp(Ctxt: TSQLRestServerURIContext);
end;
TMyHTTPServer = class(TSQLHttpServer)
private
oModel: TSQLModel;
oSQLRestServerFullMemory: TMyService;
public
function ServiceRegister(AImplementationClass: TInterfacedClass; const AInterfaces: PTypeInfo;
const AContractExpected: RawUTF8): boolean;
constructor Create(const APorta: RawUTF8; AThreadPoolCount: Integer); reintroduce;
destructor Destroy; override;
end;
TMyHTTPClient = class
private
oSQLModel1: TSQLModel;
oSQLHttpClient1: TSQLHttpClient;
FIPServidor: String;
FPortaMultiEmpresa: String;
public
constructor Create(const AIPServidor: String; const APortaServidor: String); overload;
function HttpServerConnect: Boolean;
function GetInterface(AInterface: PTypeInfo; const AVersaoInterface: RawUTF8; out Obj): Boolean;
function ServerTimeStampSynchronize: Boolean;
procedure CloseConnection;
end;
TMyObject = class
private
FFoo: RawUTF8;
published
property foo: RawUTF8 read FFoo write FFoo;
end;
IMyInterface = interface(IInvokable)
['{E6C6ADFD-5977-4759-B400-AA4140F1D683}']
function sample: RawJSON;
end;
TMyClassDirect = class(TInterfacedObject, IMyInterface)
public
function sample: RawJSON;
end;
TMyClassBridge = class(TInterfacedObjectWithCustomCreate, IMyInterface)
protected
FInstanciaInterface: IMyInterface;
oHTTPClient: TMyHTTPClient;
public
function sample: RawJSON;
constructor Create; override;
destructor Destroy; override;
end;
var
IP_Bridge: String;
Porta_Bridge: String;
implementation
uses
System.SysUtils, MainServer, Vcl.Forms, Winapi.Windows;
{ TMyClassBridge }
constructor TMyClassBridge.Create;
begin
inherited;
oHTTPClient := TMyHTTPClient.Create(IP_Bridge, Porta_Bridge);
oHTTPClient.HttpServerConnect;
oHTTPClient.GetInterface(TypeInfo(IMyInterface), '1', FInstanciaInterface);
end;
destructor TMyClassBridge.Destroy;
begin
FreeAndNil(oHTTPClient);
inherited;
end;
function TMyClassBridge.sample: RawJSON;
var
iEmpresaTerminal: Cardinal;
begin
try
Result := FInstanciaInterface.sample;
except
on E:Exception do
Result := E.Message;
end;
end;
{ TMyClassDirect }
function TMyClassDirect.sample: RawJSON;
var
MyObject: TMyObject;
begin
MyObject := TMyObject.Create;
MyObject.foo := 'bar';
Result := ObjectToJson(MyObject, []);
FreeAndNil(MyObject);
end;
{ TMyService }
procedure TMyService.myapp(Ctxt: TSQLRestServerURIContext);
var
sFileName: TFileName;
begin
sFileName := Ctxt.ResourceFileName;
if sFileName = '' then
Ctxt.Redirect('myapp/index.html')
else
Ctxt.ReturnFile(ExtractFilePath(Application.ExeName) + sFileName, true);
end;
{ TMyHTTPServer }
constructor TMyHTTPServer.Create(const APorta: RawUTF8; AThreadPoolCount: Integer);
begin
oModel := TSQLModel.Create([], 'app');
oSQLRestServerFullMemory := TMyService.Create(oModel, '', false, false);
inherited Create(APorta, [oSQLRestServerFullMemory], '+', useHttpApiRegisteringURI, AThreadPoolCount);
end;
function TMyHTTPServer.ServiceRegister(AImplementationClass: TInterfacedClass; const AInterfaces: PTypeInfo;
const AContractExpected: RawUTF8): boolean;
begin
oSQLRestServerFullMemory.ServiceRegister(AImplementationClass,
[AInterfaces], sicSingle).ContractExpected := AContractExpected;
Result := true;
end;
destructor TMyHTTPServer.Destroy;
begin
FreeAndNil(oModel);
FreeAndNil(oSQLRestServerFullMemory);
inherited;
end;
{ TMyHTTPClient }
procedure TMyHTTPClient.CloseConnection;
begin
FreeAndNil(oSQLHttpClient1);
oSQLHttpClient1 := nil;
FreeAndNil(oSQLModel1);
oSQLModel1 := nil;
end;
constructor TMyHTTPClient.Create(const AIPServidor,
APortaServidor: String);
begin
inherited Create;
FIPServidor := AIPServidor;
FPortaMultiEmpresa := APortaServidor;
end;
function TMyHTTPClient.GetInterface(AInterface: PTypeInfo;
const AVersaoInterface: RawUTF8; out Obj): Boolean;
var
sInterfaceName: RawUTF8;
begin
Result := False;
try
if (HttpServerConnect) then
begin
sInterfaceName := Copy(AInterface.Name, 2, Length(AInterface.Name));
if not(Assigned(oSQLHttpClient1.Services[sInterfaceName])) then
Result := oSQLHttpClient1.ServiceRegister(AInterface, sicSingle, AVersaoInterface) <> nil;
if (Result) then
Result := oSQLHttpClient1.Services[sInterfaceName].Get(Obj);
end;
except
on E:Exception do
begin
Result := False;
end;
end;
end;
function TMyHTTPClient.HttpServerConnect: Boolean;
var
i: integer;
begin
if (Assigned(oSQLHttpClient1)) then
CloseConnection;
for i := 1 to 2 do
begin
try
if Assigned(oSQLModel1) then
oSQLModel1.Free;
oSQLModel1 := TSQLModel.Create([], 'app');
oSQLHttpClient1 := TSQLHttpClient.Create(FIpServidor, FPortaMultiEmpresa ,
oSQLModel1, False, '', '', 30000, 30000);
Break;
except
on e: Exception do
begin
if i = 1 then
begin
oSQLHttpClient1.Free;
oSQLModel1.Free;
end
else
raise;
end;
end;
end;
Result := Assigned(oSQLHttpClient1) and (oSQLHttpClient1.ServerTimeStamp > 0);
if (not(Result)) then
raise Exception.Create('Connection server fail. ' +
oSQLHttpClient1.LastErrorMessage + ' error code: ' +
IntToStr(oSQLHttpClient1.LastErrorCode))
end;
function TMyHTTPClient.ServerTimeStampSynchronize: Boolean;
var
dServerDateTime: TDateTime;
dSystemTime: TSystemTime;
begin
try
Result := HttpServerConnect and oSQLHttpClient1.ServerTimeStampSynchronize;
if (Result) then
begin
dServerDateTime := TimeLogToDateTime(oSQLHttpClient1.ServerTimeStamp);
if (dServerDateTime > 0) then
begin
DateTimeToSystemTime(dServerDateTime, dSystemTime);
SetLocalTime(dSystemTime);
end;
end;
finally
CloseConnection;
end;
end;
end.
Json Valid (Direct)
http://127.0.0.1:773/app/MyInterface/sample
{"result":[{"foo":"bar"}]}
Json InValid (Bridge)
http://127.0.0.1:773/app/MyInterface/sample
{"result":[{"foo":"bar"}]]}
sorry,
invalid json is
{"result":[{"Foo":"bar"}]]}
not
{"result":["Foo":"bar"}]}
including this character ]
My application can have two different behave, depending on the customer's network.
Has two classes that implement the same interface.
One of the classes makes access to the database and the other creates a httpclient object to consume the class that makes access to the database.
All methods return RawJSON, when I use a simple structure that uses only one instance of the application class that makes access to the database JSON return is correct.
But when I use two instances of the application (consuming one another) the first return JSON is ok, and in the second the JSON is invalid.
See sample:
IMyInterface = interface (IInvokable)
function sample: RawJSON;
end;
TMyClassDirect = class (TInterfacedObject, IMyInterface)
public
function sample: RawJSON;
end;
TMyClassBridge = class (TInterfacedObjectWithCustomCreate, IMyInterface)
private
fSQLModel: TSQLModel;
fSQLHttpClient: TSQLHttpClient;
fMyClassDirect: IMyInterface;
public
function sample: RawJSON;
constructor Create; override;
end;
function TMyClassDirect.sample: RawJSON;
var
MyObject: TMyObject;
begin
MyObject: = TMyObject.Create;
MyObject.Foo: = 'bar';
Result: = ObjectToJson (MyObject);
FreeAndNil (MyObject);
end;
function TMyClassBridge.sample: RawJSON;
begin
Result: = fMyClassDirect.Sample;
end;
valid JSON
http://{direct host}:778/root/app/sample
{"result":[{"Foo":"bar"}]}
invalid JSON
http://{bridge host}:778/root/app/sample
{"result":["Foo":"bar"}]}
The difference is that it lacks the character {.
I hope you understood my explanation of the problem.
I can help?
Hello AB,
Thank you.
"localhost:888/root/Files" running my index.html file
It is possible to make "localhost 888/root/" redirects to index.html?
Hi again AB,
Similar of sample 26 - RESTful ORM with Blob method?
I do not understand, how or who will call the Files method.
Could you explain further or build a simple example with index.html?
Thank you for your attention
Thanks AB,
I'll try it.
Hello ab,
I'm trying to integrate AngularJs and mORMot.
for development use the "grunt serves" to the single page app and it consumes one TSQLRestServerFullMemory server, it is working ok.
But to deploy THttpApiServer need to use a server as in example 09 - HttpApi web server. And I'm not understanding how this works.
Must have the same executable using THttpApiServer TSQLRestServerFullMemory?
Is this possible?
I did not understand the architecture?
thanks for listening
Thanks AB
Hi people,
I wonder if it is possible to consume one server mORMot with AngularJS and if someone has already done this or know of any examples of how to do this.
Thanks
Hi,
I need to add lines of text to the right of the image.
It is possible to add an image column?
I use DrawTextAcrossCols for String.
Maybe something like this:
AddColumnHeaders(['Image','Description');
AddColumn( 10, 50, caLeft, False); // Image
AddColumn( 50, 100, caCenter, False); // String
DrawAcrossCols(
[MyBitmap, 'Line 1 description'],
[drBMP, drText]);
DrawAcrossCols(
[nil, 'Line 2 description'],
[drBMP, drText]);
DrawAcrossCols(
[nil, 'Line 3 description'],
[drBMP, drText]);
Hi
I need print in mini printer of continuos paper.
I set height max 9469 (NewPageLayout(80,9469)), greater than that 9469 occurs error Out of system resources. But it does not solve why if the report has a few printed lines will print blank paper.
I tried to calculate previously the lines of the report but not very accurate, the report also has pictures.
I also tried to change the margins to remove the space between the pages, but did not work as expected.
That should work or is wrong?
PageMargins := Rect(0,0,0,0);
Top := 0;
LeftMargin := 0;
BeginDoc;
Can you help me with some alternative?
Thanks Ab.
Hi,
I use TGDIPages.NewPageLayout to define width and Height, but i need report with only one page, independent of Height.
It´s possibile?
That's it
Thanks AB.
I need help with ORM, do not know filtering with property of set type.
See a Sample:
TMySet = (msOne, msTwo);
TMySets = set of TMySet;
TSample = class(TSQLRecord)
private
FMySets = TMySets;
published
property MySets = TMySets read FMySets write FMySets;
end;
...
var
Sample: TSample;
begin
Sample := TSample.CreateAnFillPrepare(SQLrest, 'MySets = ?, [Byte(msOne)]';
See records in table:
id | MySets
----------------
1|1 // msOne
2|2 // msTwo
3|3 // msOne and msTwo
I need to return two records when where clause is msOne or msTwo (bits 1 and 3 or 2 and 3).
In my sample return only one record, but not corresponding with where.
What do I need to return two records?
thanks AB
In Delphi 6 "Internal error: URW699" when compiling.
But PIso8601 (@ ADataIso8601mORMot) ^. ToDateTime works.
Iso8601ToDateTime is simpler
Hi AB,
Today exists Iso8601ToDateTime only RawUTF8 to TDateTime.
It´s possible new function add in SynCommons to convert Int64 to TDateTime?
Sample:
function Iso8601ToDateTime(const Value: Int64): TDateTime; overload;
begin
Result := PIso8601(@Value)^.ToDateTime;
end;
I need using with IncDay.
Sample:
ReferenceDate := IncDay(Iso8601ToDateTime(MySQLRecord.CreatedAt), Days);
Thanks AB.
Let's test it.
You can help Arnaud?
Thank AB.
Created the tiket
The errors were returned: 400 - "Bad Request" and 1 - "no such table: SampleCopy".
I tryed create new instance of TSQLDataBase and run method execute('...rename...') before launching the ORM kernel, and running ok.
After Server.CreateMissingTables(0) tryed UnLock and run method execute('insert...'), but ocurred "database is locked".
Without CreateMissingTables(0) I can create table with erros.
And mORMot know create tables with types and collations correct better than me.
Is there any place where I can do this? Is it possible?
Thank AB
Yes, run...
But my application must be able to know migrate alone. User does not know.
I really need to use the application to do this without any external tool.
Sorry, title "migrate by hand", better "migrate automatic", but code by hand and not automatic by mORMot.
Hi
I create my TSQLRestClientDB in initialization and Server.CreateMissingTables(0) is executed in Create.
I need migrate a table to rename/alter type/remove a field, but without losing data.
Before of CreateMissignTables i need execute:
alter table SAMPLE rename to SAMPLECOPY
And after of CreateMissingTables i need execute
insert into SAMPLE select field1, field3 from SAMPLECOPY
drop table SAMPLECOPY
I tryed to use those methods EngineExecute(), ExecuteList(), DB.ExecuteAll(), DB.Execute(), DB.ExecuteNoException(), but no results.
Can help me?
thanks for help.
Thanks AB,
It worked!
This would be the best option?
var
Person: TPerson;
Car: TCar;
begin
Person: = TPerson.CreateAndFillPrepare (DatabaseServer,'');
Person.FillOne;
EdtFirstName.Text: = Person.FirstName;
EdtLastName.Text: = Person.LastName;
Car: TCar.Create = (DatabaseServer, Person.Car);
EdtCarColor.Text: = Car.Color;
Thanks AB,
I used RowID returned the same message: "SQL logic error or missing database '
SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car where Person.Car = Car.RowID');
TSynDBProperties not found in documentation.
Found TSQLDBSQLite3ConnectionProperties = class (TSQLDBConnectionProperties), is this?
I not found method that returns TSQLTableJSON.
What would be the correct one to use?
Hi,
I'm having problems with mORMot.TSQLRestClientURI.ExecuteList.
I use the version 1.18.
see...
Simple example code...
Database information
ConnectionProperties := TSQLDBSQLite3ConnectionProperties.Create('.\data\sample.db3','','','');
VirtualTableExternalRegisterAll(MyModel, ConnectionProperties);
inherited Create(MyModel, nil, ':memory:', TSQLRestServerDB);
Server.CreateMissingTables(0);
Tables
TCar class=(TSQLRecord)
private
fColor: RawUTF8;
published
property Color: RawUTF8 read fColor write fColor;
end;
TPerson class=(TSQLRecord)
private
fFirstName: RawUTF8;
fCar: TCar;
published
FirstName: RawUTF8 read fFirstName write fFirstName;
Car: TCar read fCar write fCar;
end;
Data for tables
Table Person
ID|FirstName|Car|
1|Chuck|1|
Table Car
ID|Color|
1|Red|
load data Person/Car
SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car');
it´s OK,
in SynSQLite3.TSQLRequest.Execute step return SQLITE_DONE
in mORMotDB.TSQLVirtualTableCursorExternal.Search (fStatement <> nill) is false
But...
// Multiples data for tables
Person table
ID|FirstName|Car|
1|Chuck|1|
2|Zinedine|2|
Car table
ID|Color|
1|Red|
2|Black|
Excpetion
SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car where Person.Car = Car.ID');
Exception occurs
in sqlite3.prepare_v2 return SQLITE_ERROR, then SynSQLite3.sqlite3_check raise
Message is: 'no such column: Car.Id'
Excpetion - remove condition where:
SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName, Car.Color from Person, Car');
then...
in SynSQLite3.TSQLRequest.Execute step return SQLITE_ERROR
in mORMotDB.TSQLVirtualTableCursorExternal.Search (fStatement <> nill) is true
Message is: 'SQL logic error or missing database'
Changing for:
SQLTableJSON := DatabaseServer.ExecuteList([TPerson, TCar],'select Person.FirstName from Person');
Even including TCar and multiple records, but only from Person. Works.
Can you help me?That should work or not is the correct way?
Pages: 1