#1 Re: mORMot 1 » Warning message on compile: [dcc32 Warning] W1029 Duplicate ... » 2015-06-12 01:16:40

Using Git Pull do not make diference in my case, Thanks for the idea!
But Arnoud show me a light... I revised my code and find the absence of  "{$I SynDprUses.inc}" inside the client .dpr file
Thanks!!!!

I am using XE7 Up1 with Windos 7 up1 64bits in a VMWare machine, but the target is 32bits.

#2 Re: mORMot 1 » Warning message on compile: [dcc32 Warning] W1029 Duplicate ... » 2015-06-11 02:12:32

Hi!

Yes... I get using TortoiseGit.

git.exe fetch -v --progress "origin"

From https://github.com/synopse/mORMot
= [up to date]      master     -> origin/master

Success (1045 ms @ 10/06/2015 23:07:59)

#3 mORMot 1 » Warning message on compile: [dcc32 Warning] W1029 Duplicate ... » 2015-06-09 02:11:42

Luzcka
Replies: 5

Hi!

When compiling I am getting the following message:

[dcc32 Warning] W1029 Duplicate constructor 'TSQLRecord.CreateAndFillPrepareJoined' with identical parameters will be inacessible from C++
[dcc32 Warning] W1029 Duplicate constructor 'TSQLRecord.CreateAndFillPrepareMany' with identical parameters will be inacessible from C++
[dcc32 Warning] W1029 Duplicate constructor 'TSQLRecord.CreateAndFillPrepareJoined' with identical parameters will be inacessible from C++
[dcc32 Warning] W1029 Duplicate constructor 'TSQLRecord.CreateAndFillPrepareMany' with identical parameters will be inacessible from C++
Success
Elapsed time: 00:00:01.0

But in mormot.pas, where TSQLRecord is declared, I do not see anything wrong

Any idea?
Thanks in advance!

#4 Re: mORMot 1 » Will there be TSynLog and TMemoryMapText for linux OS ? » 2015-06-06 01:47:09

Hi! I get the lasted version from Git and I found an error in SynDBFirebird, missing SynLog unit in uses.

#5 Re: mORMot 1 » AV Error inside Method-based services using transactions... » 2013-11-08 14:07:44

Hi Arnaud!

I just send the files to the webcontact01 email.

Thanks in advance!

#6 Re: mORMot 1 » AV Error inside Method-based services using transactions... » 2013-11-08 10:47:11

Hi Arnaud!

Yesterday I sent to you by email the data connection info for FTP, there can access the necessary files: Log, Map, Exe and etc.

Thanks

#7 Re: mORMot 1 » AV Error inside Method-based services using transactions... » 2013-11-07 16:04:21

Hi Arnaud!

I'm using the latest version (downloaded today Leaf: [baf1521dc9]), changed the TSQLLog.Family to use Level: = [sllException, sllExceptionOS, sllMemory, sllStackTrace]; and generated the .MAP file. How can I send this data to you? I tried to email via the forum, but allows only 64KB of text.

I'm using Firebird-Zeos.

Tkz.

#8 mORMot 1 » AV Error inside Method-based services using transactions... » 2013-11-06 17:16:10

Luzcka
Replies: 7

Hi!!!!!

In the past I asked about transactions inside Method-based services (http://synopse.info/forum/viewtopic.php?id=1427)
and got the following code:

function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; const Params: array of const; aExpanded: Boolean = True): RawJSON;
var
  Res: ISQLDBRows;
  Conn: TSQLDBConnection;
begin
  if fProps=nil then
    raise Exception.Create('Objeto database não associado.');
  Conn := fProps.ThreadSafeConnection;
  Conn.Connect;
  try
    Conn.StartTransaction;
    try
      res := fProps.Execute(aSQL, Params);
      if res=nil then
        result := ''
      else
        result := res.FetchAllAsJSON(aExpanded);
      Conn.Commit;
    except
      Conn.Rollback;
    end;
  finally
    Conn.Disconnect;
  end;
end;

This code works on my computer, but when deploy on a basic amazon server it causes an AV error... this error is intermittent.

{
"ErrorCode":500,
"ErrorText":"Exception EAccessViolation: Access violation at address 0040C45C in module 'ServidorTeste.exe'. Read of address 00200055"
}

I created a test application to try to reproduce the error, and this actually happened due to the Path structure
(containing spaces and other characters). On the server I created a small folder structure with no special characters,
but the problem persists.


It occurs after the final 'end;' but is caused by 'conn.Disconnect;' as if this line is extracted (or all with 'conn')
the error no longer exists.


On my local computer the error happens in the following function (remember, in my experiment is because the path):

function TSQLPropInfoRTTICurrency.CompareValue(Item1,Item2: TObject; CaseInsensitive: boolean): PtrInt;

Any idea is welcome...

Thanks in advance.

#9 Re: mORMot 1 » Some questions about database access in method-based services » 2013-09-27 19:44:04

Well... changing the code it work!
I add a   "Conn.Connect;" before the starttransaction!
and now it save info in LOG table!  :-)
Thanks to Mvp and Ab.

but I still wonder if I use the best structure for using mORMot using method-based service...
and again I ask, what would be the best class to remotely access the Firebird (or multi user access)??

The altered code:


function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
var
  res: ISQLDBRows;
  conn: TSQLDBConnection;
begin
  if fProps=nil then
    raise Exception.Create('Objeto database não associado.');
  conn := fProps.ThreadSafeConnection;
  Conn.Connect;
  Conn.StartTransaction;
  try
    res := fProps.ExecuteInlined(aSQL, aExpectResults);
    if res=nil then
      result := ''
    else
      result := res.FetchAllAsJSON(aExpanded);
    conn.Commit;
  except
    conn.Rollback;
  end;
end;

#10 Re: mORMot 1 » Some questions about database access in method-based services » 2013-09-27 18:49:24

Mvp, I have erred, I don't see before the lack of StartTransaction. I changed the code by putting the line you mentioned,

but the error persist: "ErrorText":"Exception ESQLDBException: TSQLDBZEOSConnection on firebird-2.5:?
Liblocation=... database... should be connected"

The impression is a database not connected, but without a transaction contro it work (the select, not the insert).

#11 Re: mORMot 1 » Some questions about database access in method-based services » 2013-09-27 17:22:04

Hello!

For this particular case I need... inside the stored procedure "Login" is executed another stored procedure that performs an Insert in LOG table ...

Inside a method-service is possible to make a transaction??? Looking my code... any mistake?

Tkz!

#12 Re: mORMot 1 » Some questions about database access in method-based services » 2013-09-27 16:31:15

Hi Mpv,

Do not work...

Error: Invalid TSQLDBZeosConnection.Commit call

I'm change de code to:

function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
var
  res: ISQLDBRows;
  conn: TSQLDBConnection;
begin
  if fProps=nil then
    raise Exception.Create('Objeto database não associado.');
  conn := fProps.ThreadSafeConnection;
  try
    res := fProps.ExecuteInlined(aSQL, aExpectResults);
    if res=nil then
      result := ''
    else
      result := res.FetchAllAsJSON(aExpanded);
    conn.Commit;
  except
    conn.Rollback;
  end;
end;

Is posible the fact of the Embedded Database be the problem??? Not make sence to me... but...

#13 Re: mORMot 1 » Some questions about database access in method-based services » 2013-09-27 16:08:34

Hi Mpv!

Thanks for the quick reply, I will test this solution

#14 mORMot 1 » Some questions about database access in method-based services » 2013-09-27 15:24:12

Luzcka
Replies: 8

Hello!

I have some questions and I appreciate if you can help me, I'll be straight.

I'm create a mORMot server (without using ORM) that accesses a database Firebird 2.5.2, on the other hand there is an application
Asp.Net (Oxygen / Prism) accessing the server with Method-based services.

questions/dudes:

1) I'm not sure if this method to access the database is the best or recommended, show the main structure and would like a review.
  In tests with one access it have worked, I do not know if it would have multiple access problem as we have not performed tests.
 
  Statements for base access, within the class TServiceRemoteSQL was declared the Field FProps TSQLDBConnectionProperties.

   IRemoteSQL = interface(IInvokable)
    ['{1B6CFCCB-9077-4767-B242-A7928643DB07}']
    procedure Connect(const aServerName, aDatabaseName, aUserID, aPassWord: RawUTF8);
    function  GetTableNames: TRawUTF8DynArray;
    function  Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
  end;

  TServiceRemoteSQL = class(TInterfacedObject, IRemoteSQL)
  protected
    fProps: TSQLDBConnectionProperties;
    FConn: TSQLDBZEOSConnection;
  public
    destructor Destroy; override;
  public // implements IRemoteSQL methods
    procedure Connect(const aServerName, aDatabaseName, aUserID, aPassWord: RawUTF8);
    function  GetTableNames: TRawUTF8DynArray;
    function  Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
    function  ExecuteNoResult(const aSQL: RawUTF8; const Params: array of const): Integer;
  end;

and the class TServiceRemoteSQL is used inside the TServiceServer in following way:

type
  TServiceServer = class(TSQLRestServerFullMemory)
  private
    FDatabase: TServiceRemoteSQL;
  public
    constructor Create(aModel: TSQLModel; const aFileName: TFileName='';
      aBinaryFile: boolean=false; aHandleUserAuthentication: boolean=false); reintroduce; virtual;
    destructor Destroy; override;
  published
    ...
  end;
 
  ...
 
constructor TServiceServer.Create(aModel: TSQLModel; const aFileName: TFileName; aBinaryFile, aHandleUserAuthentication: boolean);
var
  vDatabase: RawUTF8;
  vDBUser  : RawUTF8;
  vDBPass  : RawUTF8;
begin
  inherited Create(aModel, aFileName, aBinaryFile, aHandleUserAuthentication);
  FDatabase := TServiceRemoteSQL.Create;
  vDatabase := StringToUTF8(Format('%s\%s', [ExtractFileDir(System.ParamStr(0)), 'Database\UTF8.FDB']));
  vDBUser := 'sysdba';
  vDBPass := 'masterkey';
  FDatabase.Connect(StringToUTF8('LocalHost'), vDatabase, vDBUser, vDBPass);
end;
 
var
  aModel: TSQLModel;
  aServer: TSQLRestServer;
  aHTTPServer: TSQLHttpServer;

begin
  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
    EchoToConsole := LOG_VERBOSE;
  end;
  AllocConsole;
  TextColor(ccLightGray);
  aModel := TSQLModel.Create([],ROOT_NAME);
  try
    aServer := TServiceServer.Create(aModel,'users.json',false, {$ifdef USE_SECURITY}True{$else}False{$endif});
    try
      {$ifdef USE_JSON}
      aServer.ServicesRouting := rmJSON_RPC;
      {$else}
      aServer.ServicesRouting := rmREST;
      {$endif}
      aHTTPServer := TSQLHttpServer.Create('8080',[aServer],'+',useHttpApiRegisteringURI);
      try
        aHTTPServer.AccessControlAllowOrigin := '*';
        writeln(#10'Background server is running.'#10);
        writeln('Press [Enter] to close the server.'#10);
        ConsoleWaitForEnterKey;
      finally
        aHTTPServer.Free;
      end;
    finally
      aServer.Free;
    end;
  finally
    aModel.Free;
  end;
end.

This would be a valid way?? Any recommendations?

2) Which class would be recommended for use with Firebird since TSQLDBZEOSConnectionProperties only supports database embeded?
   Until I started some changes for use in multi user environment, but have no time now to continue.

3) I have a problem that I believe is caused by transaction, since the information is not saved in the database, where I run a stored procedure:

  TDAL_Seguranca = class
    private
      FDatabase       : TServiceRemoteSQL;
    public
      constructor Create(pDatabase: TServiceRemoteSQL);
      function Login(const EMail: RawUTF8; Senha: RawUTF8; IP : RawUTF8): RawJSON;
  end;

  Execution:
 
function TDAL_Seguranca.Login(const EMail: RawUTF8; Senha: RawUTF8; IP : RawUTF8): RawJSON;
const
  cDML = 'Select IdUsuario, NomeUsuario, NivelAcesso, Situacao, IdEntidade, NomeFantasia, PageToGo' +
         '  From Login(%s, %s, %s)';
var
  vDML: RawUTF8;
begin
  vDML := StringToUTF8(Format(cDML, [QuotedStr(EMail), QuotedStr(Senha), QuotedStr(IP)]));
  result := FDatabase.Execute(vDML, True, True);
end;


Within the stored procedure that checks the login and get other information runs a second stored procedure that saves the
information on table LOG, indicating whether the login was successful or not, IP access, Timestamp, etc. LOG data not being saved ...
checked if the stored procedure is executed and she really is, so I suspect a Transaction problem.
At first I tried to solve using StartTransaction but an error occurs which obviously must be my misuse ...
The error code and follow. What would be the correct way to start a transaction and perform the Commit / Rollback? for this case?

"ErrorText":"Exception ESQLDBException: TSQLDBZEOSConnection on firebird-2.5:?
Liblocation=... database... should be connected"

function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
var res: ISQLDBRows;
begin
  if fProps=nil then
    raise Exception.Create('Objeto database não associado.');
  fProps.MainConnection.StartTransaction;
  try
    res := fProps.ExecuteInlined(aSQL, aExpectResults);
    if res=nil then
      result := ''
    else
      result := res.FetchAllAsJSON(aExpanded);
    fProps.MainConnection.Commit;
  except
    fProps.MainConnection.Rollback;
  end;
end;

mORMot has proved very reliable and elegant, and it is for these reasons that I have used on a personal project.

Thank you very much for the excellent tool and clarification.

#15 mORMot 1 » Call methods from browser / GetHttp » 2013-06-18 03:44:38

Luzcka
Replies: 4

Hi!
I changed the demo 16 (Execute SQL via services) to work with Zeos-Firebird, worked fine
with the client program's own demo. But I would like to access methods via browser as shown
below where access DataSnap server using Synapse.

if HttpGetText ('http://127.0.0.1:8888/datasnap/rest/TLogMethods/Register/Mi Test', vResponse) then (...)

The idea is to be able to access the methods using any language without thinking for now in security...
I tried using the following URL: http://localhost:8080/root/RemoteSQL {"method": "Connect", "params": ['localhost', '. \Data\DB-UTF8.FDB', 'sysdba' , 'masterkey'], "id": 0}

Adding the following line: aServer.ServicesRouting: = rmJSON_RPC

The complete code would be:

const
   cntDatabaseFile = 'ECONSULTOR UTF8.FDB-';
var
   Amodel: TSQLModel;
   aServer: TSQLRestServer;
   aHTTPServer: TSQLHttpServer;
begin
   TSQLLog.Family begin with the
     Level: = LOG_VERBOSE;
     EchoToConsole: = LOG_VERBOSE;
   end;
   AllocConsole;
   TextColor (ccLightGray);
   Amodel: TSQLModel.Create = ([], ROOT_NAME);
   try
     aServer: = TSQLRestServerFullMemory.Create (Amodel, 'users.json', false, false) // Era true en la autenticacion
     try
       
       aServer.ServicesRouting: = rmJSON_RPC;
      
       aHTTPServer: = TSQLHttpServer.Create ('8080 '[aServer] "+", useHttpApiRegisteringURI);
       try
         aHTTPServer.AccessControlAllowOrigin: = '*';
         writeln (# 10'Background server is running. '# 10);
         writeln ('Press [Enter] to close the server.' # 10);
         ConsoleWaitForEnterKey;
       finally
         aHTTPServer.Free;
       end;
     finally
       aServer.Free;
     end;
   finally
     aModel.Free;
   end;
end.

But the response is:

{
"ErrorCode": 400,
"ErrorText": "Bad Request"
}

Without the line "aServer.ServicesRouting: = rmJSON_RPC;" and using the URL
http://localhost:8080/root/RemoteSQL.Connect  (intentionally without parameters)
the response is:

{
"ErrorCode":400,
"ErrorText":"Parameters required"
}

but the parameter formats I tried did not work...

What is the correct format?? What is the best format thinking of something simple that can be easily mounted??
For the case of wanting to use the parameters in this way is best to use interface-based services or Methods-based services??
Is it possible to register more services using "aServer.ServiceRegister (...)" in order to separate the classes and their methods using the same server??

#16 Re: mORMot 1 » Test mORMmot + Zeos +Firebird » 2013-06-05 21:22:42

Hi!
Sorry the delay... Making a code trace I get it:

0)function TSQLDBConnectionProperties.ExecuteInlined(const aSQL: RawUTF8; ExpectResults: Boolean): ISQLDBRows;
1)TSQLDBConnectionProperties.NewThreadSafeStatementPrepared(const aSQL: RawUTF8; ExpectResults: Boolean; RaiseExceptionOnError: Boolean=false): ISQLDBStatement;
2a) function TSQLDBConnectionPropertiesThreadSafe.ThreadSafeConnection: TSQLDBConnection;
---- (2b Executed on exit 2a)
2b)function TSQLDBConnection.NewStatementPrepared(const aSQL: RawUTF8;ExpectResults: Boolean; RaiseExceptionOnError: Boolean=false): ISQLDBStatement;
  // default implementation with no cache
  Stmt := nil;
  try
    InternalProcess(speActive);
    try
      Stmt := NewStatement;
      Stmt.Prepare(aSQL,ExpectResults);  <---- Enter here. aSQL = 'Select * from Material_Texto', ExpectResults = true
3)procedure TSQLDBZEOSStatement.Prepare(const aSQL: RawUTF8;ExpectResults: boolean);      
     inherited Prepare(aSQL,ExpectResults); // connect if necessary   <---- Enter here
4)procedure TSQLDBZEOSConnection.Connect;
5)procedure TZInterbase6Connection.Open;
  DPB = #1#$1C#6'sysdba'#$1D#8'masterkey'
  DBName = ('1', '2', '7', '.', '0', '.', '0', '.', '1', ':', 'E', ':', '\', 'T', 'r', 'a', 'b', 'a', 'j', 'o', 's', '\', 'D', 'a', 't', 'a', '\', 'E', 'C', 'O', 'N', 'S', 'U', 'L', 'T', 'O', 'R', '-', 'U', 'T', 'F', '8', '.', 'F', 'D', 'B', #0,....)
  FStatusVector = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  FHandle = 0
  FDPBLength = 19
call GetPlainDriver.isc_attach_database(@FStatusVector, StrLen(DBName), DBName, @FHandle, FDPBLength, DPB); 
 
6) function TZFirebirdBaseDriver.isc_attach_database(status_vector: PISC_STATUS; db_name_length: Short; db_name: PAnsiChar; db_handle: PISC_DB_HANDLE; parm_buffer_length: Short; parm_buffer: PAnsiChar): ISC_STATUS; 
7)function CheckInterbase6Error(PlainDriver: IZInterbasePlainDriver;StatusVector: TARRAY_ISC_STATUS; LoggingCategory: TZLoggingCategory = lcOther;SQL: string = '') : Integer;
                StatusVector[0] = 1 and StatusVector[1] = 335544324
                ------> First Error messge = ' Your user name and password are not defined. Ask your database administrator to set up a Firebird login.'  //I confirm the user and pass. work in Zeos
               
                After execute line: ErrorCode := PlainDriver.isc_sqlcode(@StatusVector);
                ------> msg = ' invalid database handle (no active connection)' 
                ------> ErrorSQLMessage = 'can''t format message 13:96 -- message file C:\Windows\firebird.msg not found'
                ------> Firebird Error Meassage = 'SQL error: invalid database handle (no active connection. Error Code: -904 Unsuccessful execution caused by an unavaliable resource.'

#17 Re: mORMot 1 » Test mORMmot + Zeos +Firebird » 2013-05-29 14:49:53

>AFAIK ZDbcInterbase6 is needed from Zeos point of view.
>It defines the Interbase API, which is used by Firebird AFAIK.

I understand the need to use ZDbcInterbase6 (since Firebird is a fork of Interbase6), and to understand share some code, but these definitions (and uses) could not be used internally in units Firebird? What I say is because it seems a little strange ... and may end up confusing and complicating the user.

>Yes, we only tested Firebird via Zeos using embedded Firebird, by now.
>This is why such feedback as yours is precious!
>Thanks!

I will conduct further tests and analyze the cause of the error, where I can help the project will be happy to do! :-)


>Have you something to propose for TSQLDBZEOSConnectionProperties.URI() work as expected in remote mode?
>Perhaps an overloaded method including the server?

I liked the idea of the method TSQLDBZEOSConnectionProperties.URI (), but in my opinion I would create a method with parameters "Host", "Port", "Database", "User", "Password" (common in most databases connections), and with this I would check if the "Host" is remote to decide whether I can create the database, and if it a local host (informed or not) try to verify if it is a file or an "Alias" (Alias has no path) and if there is a file that is not there ... I would! Using Alias is recommended for safety and ease since there informs nor require the client application to know the name of the file or database and its physical location.

So we could go a little further and implement the procedure URI as a function that returns a small class "Connection String" (which are actually the properties ...) This function has the parameters mentioned properties and would have to set some parameters that would be restricted to common parameters in DBMS's and finally having a property to set parameters specific to the dbms. I put here a small example that is just an idea and would have to be analyzed to better define the properties.

TStringConnection = class
  private
     FHost: RawUTF8;
     FPort: Cardinal;
     FDabatabse: RawUTF8;
     FUser: RawUTF8;
     FPassword: RawUTF8;  //Be encrypted???
     FCharset:...
     FBlaBlaBla:...

     procedure Set...
     function   Get...
  public
     constructor Create(pHost: RawUTF8; pPort: Cardinal; pDatabase: RawUTF8; pUser: RawUTF8; pPass: RawUTF8);
     function AsString: RawUTF8;
  published
     property Host: RawUTF8..
     property Port: Cardinal..
     property Dabatabse: RawUTF8...
     property User: RawUTF8...
     property Password: RawUTF8...
     property Charset:...
     property Params:...
end;

...

TSQLDBZEOSConnectionProperties.URI (pHost: RawUTF8; pPort: Cardinal; pDatabase: RawUTF8; pUser: RawUTF8; pPass: RawUTF8): TStringConnection;

...

var 
  vStringConnection: TStringConnection;

  vStringConnection := TSQLDBZEOSConnectionProperties.URI ('127.0.0.1' {or empty},  3050 {or 0}, 'C:\...\MyDB.FDB' {or Alias}, 'sysdba', 'masterkey').AsString;
  vStringConnection.Charset := UFT8; {or other property or other value etc...} {if omited use default...}
  vStringConnection.Params.Set('Specific_DBMS_Property', 'Specific_Value');

With this I think I can specify the connection properties of any database using the URI idea, but open the user to optemize the connection.

>(in your code, you can use FormatUTF8('%\%', [...]) instead of a temporary conversion to string)

Thanks for the info! I ended up not bothering me much to use library functions and used what was easiest to test, but I use to be able to start getting used to! ;-)

#18 mORMot 1 » Test mORMmot + Zeos +Firebird » 2013-05-28 22:01:50

Luzcka
Replies: 3

Hello!
I've been doing some testing with access to database mORMmot using Zeos and Firebird, for it I create a separate application that only uses TSQLDBZEOSConnectionProperties to run a query. Using as a basis of information the demo "15 - External DB performance" and thus had some doubts:

Using Embedded:
1) Using the embedded Firebird I found that it is necessary to include the unit ZDbcInterbase6, something that had not already thought that I wanted to use only the Firebird ... The absence of the unit does not cause compilation error, but generates an error when trying to connect to the server. Am I correct to include this unit? Would not it be clearer to separate what is from Interbase and what is from Firebird?

Using Server:
1) The method TSQLDBZEOSConnectionProperties.URI returns a string not usable (or I failed to use the method) where I want to inform a host and a port. To perform the tests created by hand the following string:

'zdbc:firebird-2.5://127.0.0.1:3050/eConsultor-UTF8?LibLocation=fbclient.dll;username=sysdba;password=masterkey'

The method URI should not have parameters Host, Port, User and Pass?

2) I noticed that when trying to use a Firebird server using alias (can be defined in one or more alias file aliases.conf and use the name as the string that rode hand) the class is lost and tries to create a database outside and that he lost at one point the Host and Port. This problem occurs when trying to connect. Can I use Alias? Would not it be better to use a connection string (URI return) in the method TSQLDBZEOSConnectionProperties.Create out instead of the current parameters?

3) was unable to perform a query to the server, even changing the alias for the full file name of the database. The error occurs when trying to start a transaction. Follows the code that created and below the method name and line where the error occurs. Any explanation or assistance is welcome in the case of my misuse, or if it is a bug and if they want, I can try to find a solution.

My Code:

//Executed OK
procedure TServiceRemoteSQL.Connect(const aServerName, aDatabaseName, aUserID, aPassWord: RawUTF8);
var
  Server: RawUTF8;
  vDatabase: RawUTF8;
begin
//  vDatabase := aDatabaseName;
  vDatabase := StringToUTF8(Format('%s\%s', [ExtractFileDir(Application.ExeName), 'Data\ECONSULTOR-UTF8.FDB']));
  {$ifdef CPU64}
    Suffix := '64';
  {$endif}
  if fProps<>nil then
    raise Exception.Create('Connect called more than once');
//  Server := TSQLDBZEOSConnectionProperties.URI(dFirebird, 'fbembed.dll'); //'gds32.dll' 'fbclient.dll'
//  Server := 'zdbc:firebird-2.5://127.0.0.1:3050/eConsultor-UTF8?LibLocation=fbclient.dll;username=sysdba;password=masterkey';
  Server := 'zdbc:firebird-2.5://127.0.0.1:3050/E:\Trabajos\Data\ECONSULTOR-UTF8.FDB?LibLocation=fbclient.dll;username=sysdba;password=masterkey';
  fProps := TSQLDBZEOSConnectionProperties.Create(Server,vDatabase,aUserID,aPassWord);
end;


//Executed with error
function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
var res: ISQLDBRows;
begin
  if fProps=nil then
    raise Exception.Create('Connect call required before Execute');
  res := fProps.ExecuteInlined(aSQL, aExpectResults);   ---------------> Error
  if res=nil then
    result := ''
  else
    result := res.FetchAllAsJSON(aExpanded);
end;


mORMot code error

procedure TZInterbase6Connection.StartTransaction;
var
  Params: TStrings;
  PTEB: PISC_TEB;
begin
  PTEB := nil;
  Params := TStringList.Create;

  { Set transaction parameters by TransactIsolationLevel }
  //Params.Values['isc_dpb_lc_ctype'] := FClientCodePage; //Set CharacterSet allways if option is set
  Params.Add('isc_tpb_version3');
  case TransactIsolationLevel of
    tiReadCommitted:
      begin
        Params.Add('isc_tpb_read_committed');
        Params.Add('isc_tpb_rec_version');
        Params.Add('isc_tpb_nowait');
      end;
    tiRepeatableRead:
      begin
        Params.Add('isc_tpb_concurrency');
        Params.Add('isc_tpb_nowait');
      end;
    tiSerializable:
      begin
        Params.Add('isc_tpb_consistency');
      end;
  else
    begin
      { Add user defined parameters for transaction }
      Params.Clear;
      Params.AddStrings(Info);
    end;
  end;

  try
    { GenerateTPB return PTEB with null pointer tpb_address from default
      transaction }
    PTEB := GenerateTPB(Params, FHandle);
    GetPlainDriver.isc_start_multiple(@FStatusVector, @FTrHandle, 1, PTEB);
    CheckInterbase6Error(GetPlainDriver, FStatusVector, lcTransaction);            ---------------> Eror gerated here
    DriverManager.LogMessage(lcTransaction, PlainDriver.GetProtocol,
      'TRANSACTION STARTED.');
  finally
    FreeAndNil(Params);
    StrDispose(PTEB.tpb_address);
    FreeMem(PTEB);
  end
end;

#19 Re: mORMot 1 » Object to JSON » 2013-05-21 21:11:05

Thanks, I'll download the version 1.18 for analyze SAD and sample 20.

#20 mORMot 1 » Object to JSON » 2013-05-21 17:33:30

Luzcka
Replies: 2

Hi!
I'm new in this tool and have some questions, but to facilitate research in the forum'll ask the questions in separate threads and obviously after searching, reading and trying to solve it myself.
The problem in question is to convert an object to JSON, where the manual and examples I use ObjectToJSON taking care to use the directive {$ M +} or the class is a descendant of TPersistence, this works perfectly ... but have difficulty in properties that are a TObjectList <> or are Dynamic Arrays of objects ... I understand I could use TJSONSerializer.RegisterCustomSerializer creating a class with callback's for reading and writing. Below is a code example and would like to know the best way to solve (or only one way) the problem.

{$M+}
type
  TDataType = (tlTemperature, tlHumidity);
  TData = class
    private
      FPortId  : Integer;
      FDataType: TDataType;
      FValue   : Double;
      function Get_PortId: Integer;
      function Get_DataType: TDataType;
      function Get_Value: Double;
      procedure Set_PortId(const Value: Integer);
      procedure Set_DataType(const Value: TDataType);
      procedure Set_Value(const Value: Double);
    published
      property PortId  : Integer read Get_PortId write Set_PortId;
      property DataType: TDataType read Get_DataType write Set_DataType;
      property Value   : Double read Get_Value write Set_Value;
  end;

  TDataList = class (TList<TData>)
  end;
  TDataArray = Array of TData;

  TAcquisitionBoard = class
    private
      FIdentify: RawUTF8;
      FModel   : RawUTF8;
      FData : TDataArray;
      function Get_Identify: RawUTF8;
      function Get_Model: RawUTF8;
      function Get_Data: TDataArray;
      procedure Set_Identify(const Value: RawUTF8);
      procedure Set_Model(const Value: RawUTF8);
    public
      constructor Create;
      destructor Destroy; override;

      function AddData: TData;
    published
      property Identify: RawUTF8 read Get_Identify write Set_Identify;
      property Model   : RawUTF8 read Get_Model write Set_Model;
      property Data    : TDataArray read Get_Data;
  end;

Whereas the objects have the following data:

Identify: 12345 Model: A2013
Temperature: 23.79
Temperature: 30.02

When running memoJSON.Lines.Text: = UTF8ToString (ObjectToJSON (FAcquisitionBoard, []));

I get: {"Identify": "12345", "Model": "A2013", "Data": []}
Without informing the content of the property "Data".

How to get complete information? Data as Dynamic Array or TObjectList<> or other structure...

Thanks in advance!

Board footer

Powered by FluxBB