#1 2014-09-22 12:46:48

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

CreateMissingTables with MongoDB Enigma

Hi AB.

look at the code, if you do not call:
StaticMongoDBRegister (TSQLauthGroup, aRestServer, DB, 'myTSQLauthGroup')

I find in the db mytestcollection and myTSQLauthUser. With the basic initialization of the users (admin supervisor user).


But if I make the call, I find 3 tables but without initialization.



/// minimal REST server for a list of Persons stored on MONGODB
program RESTserver;

{$APPTYPE CONSOLE}

uses
  SynCommons,          // framework core
  mORMot,              // RESTful server & ORM
  mORMotSQLite3,       // SQLite3 engine as ORM core
  SynSQLite3Static,    // staticaly linked SQLite3 engine
  mORMotDB,            // ORM using external DB
  mORMotHttpServer,    // HTTP server for RESTful server
  SynDB,               // external DB core
  mORMotWrappers, //mormot
  SynMongoDB,mORMotMongoDB;

const
 SERVER_PORT='888';

type
 TSQLORM = class(TSQLRecord)
  private
    fAge: integer;
    fName: RawUTF8;
    fDate: TDateTime;
    fValue: variant;
    fInts: TIntegerDynArray;
    fCreateTime: TCreateTime;
    fData: TSQLRawBlob;
  published
    property Name: RawUTF8 read fName write fName stored AS_UNIQUE;
    property Age: integer read fAge write fAge;
    property Date: TDateTime read fDate write fDate;
    property Value: variant read fValue write fValue;
    property Ints: TIntegerDynArray index 1 read fInts write fInts;
    property Data: TSQLRawBlob read fData write fData;
    property CreateTime: TCreateTime read fCreateTime write fCreateTime;
  end;

var
  aHttpServer: TSQLHttpServer;

  aRestServer: TSQLRestServerDB;
  MongoClient : TMongoClient;
  Client: TSQLRestClientDB;
  DB: TMongoDatabase;
  Model:TSQLModel;
begin
  // define the log level
  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
    EchoToConsole := LOG_VERBOSE; // log all events to the console
  end;
  MongoClient := TMongoClient.Create('localhost',27017);
  DB := MongoClient.Database['testODM5'];
  Model := TSQLModel.Create([TSQLORM,TSQLauthGroup,TSQLauthUser]);

  try
   // create the main mORMot server
   aRestServer := TSQLRestServerDB.Create(Model,':memory:',true); // authentication=false
   try
    if StaticMongoDBRegister(TSQLauthUser,aRestServer,DB,'myTSQLauthUser')=nil then
    begin
     writeln('Error2 !'#10);  exit;
    end;
    if StaticMongoDBRegister(TSQLORM,aRestServer,DB,'mytestcollection')=nil then
    begin
     writeln('Error3 !'#10);  exit;
    end;
    if false  then //  <<<****************************************************************************
    begin
     if StaticMongoDBRegister(TSQLauthGroup,aRestServer,DB,'myTSQLauthGroup')=nil then
     begin
      writeln('Error1 !'#10);  exit;
     end;
    end;

    aRestServer.CreateMissingTables; // create tables or fields if missing
    // serve aRestServer data over HTTP
    aHttpServer := TSQLHttpServer.Create(SERVER_PORT,[aRestServer],'+',useHttpApiRegisteringURI);
    try
     aHttpServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries
     writeln('Background server is running.'#10);
     writeln('Press [Enter] to close the server.');
     readln;
    finally aHttpServer.Free; end;
   finally aRestServer.Free; end;
  finally Model.Free; end;
end.

ps: I use www.robomongo.org for mongoDb easy gui

Last edited by Sabbiolina (2014-09-22 12:48:02)

Offline

#2 2014-09-25 06:24:08

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: CreateMissingTables with MongoDB Enigma

Have a look at this post: http://synopse.info/forum/viewtopic.php … 710#p12710

If tables are defined external, they are also defined as static.
Initialization (of fields) in createmissingtables is then skipped.

You have to do this manually (after CreateMissingTables):

if not aRestServer.TableHasRows(TSQLAuthGroup) then TSQLAuthGroup.InitializeTable(aRestServer,'',[itoNoIndex4ID, itoNoIndex4UniqueField, itoNoIndex4NestedRecord, itoNoIndex4RecordReference]);

This works for MongoDB (as opposed to MySQL, for the user who posted this solution)

Offline

#3 2014-09-25 07:13:48

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: CreateMissingTables with MongoDB Enigma

Thanks, it works well.

I would add, for those who read the post, that the initialization of AuthGroup also creates Members in AuthUser table.

Offline

#4 2014-09-25 09:48:59

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: CreateMissingTables with MongoDB Enigma

It sounded a bit confusing to have to do it manually.

We have ensured that StoredClass.InitializeTable() is called by TSQLRestStorageMongoDB.Create() e.g. for TSQLAuthGroup and TSQLAuthUser tables automatic initialization.
See http://synopse.info/fossil/info/09e44c2569

So you do not need to run InitializeTable() manually any more.

Offline

#5 2014-09-25 11:29:49

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: CreateMissingTables with MongoDB Enigma

Tnxs

Offline

#6 2014-09-26 08:21:54

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: CreateMissingTables with MongoDB Enigma

There is a problem:
The call to InitializeTable is premature.
The function to be error because it can not find the sqlite tables in memory, given that createmissingtables has not yet been called.

constructor TSQLRestStorageMongoDB.Create(aClass: TSQLRecordClass; aServer: TSQLRestServer);
begin
  inherited Create(aClass,aServer);
  // ConnectionProperties should have been set in StaticMongoDBRegister()
  fCollection := fStoredClassProps.ExternalDB.ConnectionProperties as TMongoCollection;
  {$ifdef WITHLOG}
  fOwner.LogFamily.SynLog.Log(sllInfo,'will store % using %',[aClass,Collection],self);
  {$endif}
  BSONProjectionSet(fBSONProjectionSimpleFields,true,
    fStoredClassRecordProps.SimpleFieldsBits[soSelect],nil);
  BSONProjectionSet(fBSONProjectionBlobFields,false,
    fStoredClassRecordProps.BlobFieldsBits,@fBSONProjectionBlobFieldsNames);
  CreateIndexes;

//  if not TableHasRows(StoredClass) then <---- hangs here
//    StoredClass.InitializeTable(aServer,'',INITIALIZETABLE_NOINDEX);
end;

exception:
20140926 10020713 SQL       TSQLRestServerDB(02C6C800) INSERT INTO AuthGroup (Ident,SessionTimeout,AccessRights) VALUES (:('Admin'):,:(10):,:('47,1-256,0,1-256,0,1-256,0,1-256,0'):); prepared with 3 params
20140926 10021135 EXC       ESQLite3Exception ("Error SQLITE_ERROR (1) - \"no such table: AuthGroup\"") at 006B3BBB  stack trace API 0062A574
20140926 10021135 ERROR     TSQLRestServerDB(02C6C800) {"ESQLite3Exception(02D5FA50)":{}} for INSERT INTO AuthGroup (Ident,SessionTimeout,AccessRights) VALUES (:('Admin'):,:(10):,:('47,1-256,0,1-256,0,1-256,0,1-256,0'):); stack trace API 0062BCB2 006B705A 006B608A 0068CA5D 0067C1CB 0069DA66 0074A3DF 0074A26E 0074E64D 004CA56A 004CA417 004CA3F7 005DC1C5 00759542 76D6338A 77989F72 77989F45

Offline

#7 2014-09-26 10:33:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: CreateMissingTables with MongoDB Enigma

Indeed.
sad

We have added TSQLRestServer.InitializeTables() method to initialize void tables and replace CreateMissingTables process e.g. for MongoDB external storage
- to replace {282} buggy implementation.
See http://synopse.info/fossil/info/d79b3f7643

Offline

Board footer

Powered by FluxBB