#1 Re: mORMot 1 » How to properly create a database model ? » 2012-04-04 08:16:20

Thanks, I will try it. I know about as "safe" typecast, that hard typecast came from the old docs. I have to update my brain to the new version :-)

#2 Re: mORMot 1 » How to properly create a database model ? » 2012-04-03 22:36:39

The same problem remains. When I call TSQLRestServerDB(FClient).CreateMissingTables; from my example above and step into it with debugger I fail with AV on the first line on condition if DB.TransactionActive then because DB is at that time nil.

procedure TSQLRestServerDB.CreateMissingTables(user_version: cardinal);
var t,f: integer;
    TableNamesAtCreation, aFields: TRawUTF8DynArray;
    TableJustCreated: TSQLFieldTables;
    aSQL: RawUTF8;
begin
  if DB.TransactionActive then // here DB = nil, thus fails with AV
    raise EBusinessLayerException.Create('CreateMissingTables: Transaction');

#3 Re: mORMot 1 » How to properly create a database model ? » 2012-04-03 13:10:17

@Arnaud, thanks a lot!
I'll try it as soon as I get home to my D2009. I'll let you know later on.

#4 Re: mORMot 1 » How to properly create a database model ? » 2012-04-03 08:22:59

I've checked the same versions I've mentioned in Delphi 2007 and it works there, but in my D2009 doesn't. It would be hard to tell you here what everything I have installed there, because it's lot of stuff, but it causes the AV in MainDemo.
Never mind, I'll stick back to standalone SQLite.

Thanks anyway!

#5 Re: mORMot 1 » Bug in MainDemo Sample » 2012-04-01 18:54:12

@coblongpamor:
> I'll have to wait for another user who will report it too
You did http://synopse.info/forum/viewtopic.php?id=660 :-)
The same in Delphi 2009

#6 Re: mORMot 1 » How to properly create a database model ? » 2012-03-31 10:21:47

I think I did, I've downloaded this zip archive and these SQLite3 object files.

c:\Users\Public\Documents\Synopse\ - path where I've copied the framework (this is also where I have the SQLite *.obj files), and it's 100% the only place where it is
c:\Users\Public\Documents\Synopse\SQLite3\Samples\MainDemo\SynFile.dpr - trying to run this project gives me an access violation at start caused by what I've described

The AV is thrown from SynCommons.pas in TSynCache.Reset when the Count is being read; could you please check you are reading the right value ?

Forgot to mention I'm using Delphi 2009 on Windows 7, if it's important.
Or does it mean I should download trunk or SQLite3 object files from somewhere else ?
About the zip archives, do they contain the trunk or should I download each file per one ?

Thank you!

#7 mORMot 1 » How to properly create a database model ? » 2012-03-31 00:11:36

TLama
Replies: 9

Hi again,

I've upgraded from the latest stable version to the latest trunk without leaf and my previosly created application stops to work. Especially it's not possible to CreateMissingTables nor do the Client.Update (if I tried it with the old, already created DB). I've used the TSQLRest base class because in the future I'd like to use different kind of clients.

Here's how am I creating the database model:

unit SynSQLiteTestUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SynCommons, SQLite3Commons, SQLite3;

type
  TBaseSQLRecord = class(TSQLRecord)
  private
    FCreatedAt: TTimeLog;
    FCreatedBy: RawUTF8;
    FUpdatedAt: TTimeLog;
    FUpdatedBy: RawUTF8;
  published
    property CreatedAt: TTimeLog read FCreatedAt write FCreatedAt;
    property CreatedBy: RawUTF8 read FCreatedBy write FCreatedBy;
    property UpdatedAt: TTimeLog read FUpdatedAt write FUpdatedAt;
    property UpdatedBy: RawUTF8 read FUpdatedBy write FUpdatedBy;
  end;

  TSQLEmployee = class(TBaseSQLRecord)
  private
    FNumber: Integer;
    FFirstName: RawUTF8;
    FLastName: RawUTF8;
  published
    property Number: Integer read FNumber write FNumber;
    property FirstName: RawUTF8 read FFirstName write FFirstName;
    property LastName: RawUTF8 read FLastName write FLastName;
  end;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FClient: TSQLRest;
    FSQLModel: TSQLModel;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FSQLModel := TSQLModel.Create([
    TSQLEmployee
  ]);
  FClient := TSQLRestClientDB.Create(FSQLModel, nil,
    ChangeFileExt(Application.ExeName,'.sqlite'), TSQLRestServerDB);
  TSQLRestServerDB(FClient).CreateMissingTables;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FClient.Free;
  FSQLModel.Free;
end;

end.

What has changed from the latest stable version till now ? I've checked the docs and on the page 68 seems to be the same way to create a database model and even MainDemo fails in the FileServer.pas on line with CreateMissingTables. The problem is laying somewhere in the TSQLRestServerDB.CreateMissingTables, the first line check DB.TransactionActive throws the access violation because the DB is nil.

Can you suggest me what am I doing wrong or tell if it's a bug, please ?

Thanks a lot!

#8 Re: mORMot 1 » How to fetch the N rows from 1:N relationship in TSQLRecord ? » 2012-03-30 13:38:20

It tented me to look for a function containing Prepare word, but I was using the latest stable version, where this is not included. Now I know I have to keep my eyes opened, because the development of this project is really very active. Thanks for the response and for the whole project!

#9 mORMot 1 » How to fetch the N rows from 1:N relationship in TSQLRecord ? » 2012-03-29 20:42:29

TLama
Replies: 3

Hi Arnaud,

I'm really new to mORMot and I would like to ask you, how to fetch the N rows from 1:N relationship using FillMany.
I know this must be answered zillion times here already, but it's probably hidden somewhere deep inside of the posts.
Let's assume I have the following DB Model:

type
  TSQLTaskReceiverList = class;
  TSQLTask = class(TSQLRecord)
  private
    FTitle: RawUTF8;
    FDescr: RawUTF8;
    FReceivers: TSQLTaskReceiverList;
  public
    property Title: RawUTF8 read FTitle write FTitle;
    property Descr: RawUTF8 read FDescr write FDescr;
    property Receivers: TSQLTaskReceiverList read FReceivers;
  end;

  TSQLReceiver = class(TSQLRecord)
  private
    FFirstName: RawUTF8;
    FLastName: RawUTF8;
  published
    property FirstName: RawUTF8 read FFirstName write FFirstName;
    property LastName: RawUTF8 read FLastName write FLastName;
  end;

  TSQLTaskReceiverList = class(TSQLRecordMany)
  private
    FSource: TSQLTask;
    FDest: TSQLReceiver;
  published
    property Source: TSQLTask read FSource;
    property Dest: TSQLReceiver read FDest;
  end;

Now I wanted to get the list of receivers like it's stated in the PDF manual, by using FillMany:

When a TSQLRecordMany published property exists in a TSQLRecord, it is initialized automatically during TSQLRecord.Create constructor execution into a real class instance.
This TSQLRecordMany instance is indeed available to access directly the pivot table records, via FillMany then FillRow, FillOne and FillRewind methods to loop through records

So I've tried to fetch one task record, then FillMany its ReceiverList and tried to access the first receiver record (in real I need to fetch all task receivers, but here I've tried to do it with the only one)

begin
var
  I: Integer;
  TaskID: Integer;
  SQLTask: TSQLTask;
begin
  TaskID := 2;
  // fetch the task with the specified ID
  SQLTask := TSQLTask.CreateAndFillPrepare(FDatabase, 'ID=?', [], [TaskID]);
  try
    // fill the local variable with task data
    if SQLTask.FillOne then
    begin
      // here I've tried to use FillMany, it returns correctly 2 rows to be fetched
      SQLTask.ReceiverList.FillMany(FDatabase, TaskID);
      // I hoped the FillOne here will fill up the SQLTask.ReceiverList record, but it doesn't
      if SQLTask.ReceiverList.FillOne then
      begin
        // here I'm getting the access violation, what am I doing wrong ?
        ShowMessage(UTF8ToString(SQLTask.ReceiverList.Dest.FirstName) +
          UTF8ToString(SQLTask.ReceiverList.Dest.LastName));
      end;
    end;
  finally
    SQLTask.Free;
  end;
end;

What am I doing wrong that I'm getting the access violation when FillOne returned True and FillMany returned correct count of rows to be fetched ?
Or even better, is there a more efficient way to get those task receivers without creating new TSQLTaskReceiverList nor TSQLReceiver instances ?

Sorry for being so (T)Lame smile
Thanks a lot!

Board footer

Powered by FluxBB