#1 Re: mORMot 1 » Array params to server » 2014-03-13 13:40:04

Thank you for your reply Arnaud.

However in the future we might need to send an array as a parameter for an procedure.
It was a pleasure working with mORMot, hopefully what ever my boss will find as a replacement can resolve this issue.

Best of luck in the future

#2 Re: mORMot 1 » Array params to server » 2014-03-13 09:52:52

I also tried out a simple Integer Array, but that also gave me 150.000 values in the array.

I assume you should be able to send an Array to the server?

#3 Re: mORMot 1 » Array params to server » 2014-03-13 07:52:29

Hello,

I am using Oracle yes.
I also didn't check the code before posting here, because I was only looking at the parameters and forgot I left the test procedure in on the Server side.

The actual procedure requires 2 parameters ( ofc there are other procedures that should go through this function ).
I don't want to create a new function for every stored procedure with their respective parameters.

I also tried a pvParams as an array of Variants, but the same happend - ALOT of values while I only sent 2.

I apologize again for not checking my code before posting it here.

lvStatement := Self.fProps.NewThreadSafeStatementPrepared
      (aSQL, false);

which aSQL is 'BEGIN SETHOUSEHOLDHELPSTATUS(?,?); END;'

But the problem Ab wasn't with binding or anything, it is about the pvParams parameter having alot more data than I sent from the client.

What I want is ?an array? as parameter of the function where all parameters from the procedure are stored in, which could be string, dates etc.
Then Bind all those parameters to the statement one by one.

Is this the correct way, because I assume you should be able to send a variant or const array from the client to the server?

#4 mORMot 1 » Array params to server » 2014-03-12 15:14:49

SHEePYTaGGeRNeP
Replies: 6

Hello,

I am getting the hang of mORMot now I think, but the problem I now have is whenever I send an Array from the client to the server as a parameter for a function, the array becomes huge.
I have a very simple call function from the client:

 TMormotConnection.Connection.OpenDataset(lvDataset,
      'BEGIN SETHOUSEHOLDHELPSTATUS(:P1); END;', [63101, 1300135]);

and the OpenDataset function looks like this:

function TMormotConnection.OpenDataset(pvDataset: TClientDataset;
  pvSQL: RawUTF8; const pvParams: array of const): Boolean;
var
  fJSON: RawUTF8;
  // stmt : TSQLDBStatement;
begin
  if fService <> nil then
  begin
    fJSON := fService.ExecuteWithParams(pvSQL, pvParams, true, true);

When I look at the pvParams I can clearly see 2 values being correct.
However the function on the server which looks like this:

function TServiceRemoteSQL.ExecuteWithParams(const aSQL: RawUTF8;
  const pvParams: array of const; aExpectResults, aExpanded: Boolean): RawJSON;
var
  I: Integer;
  lvStatement: ISQLDBStatement;
begin
  if fProps = nil then
    raise Exception.Create('Connect call required before Execute')
  else
    lvStatement := Self.fProps.NewThreadSafeStatementPrepared
      ('BEGIN tempprocedure(?); END;', false);
  for I := 0 to Length(pvParams) do
    lvStatement.Bind(I + 1, pvParams[i].VInteger, paramIn);
  lvStatement.ExecutePrepared;

Has about 30.000 values in the array.
How does this happen, is this intentional and how do I fix this?
This is used for Stored Procedures and making a new function with the correct parameters for every Stored Procedure is not optimal.

Please help.

#5 mORMot 1 » dsp TMessage errors. » 2014-02-20 11:13:58

SHEePYTaGGeRNeP
Replies: 4

I am using Delphi XE5 and FireMonkey, this error had always occured but it never stopped me from debugging, until now.
In the SynCommons.pas:

function WndProcMethod(Hwnd: HWND; Msg,wParam,lParam: integer): integer; stdcall;
var obj: TObject;
    dsp: TMessage;
begin
  {$ifdef CPU64}
  obj := pointer(GetWindowLongPtr(HWnd,GWLP_USERDATA));
  {$else}
  obj := pointer(GetWindowLong(HWnd,GWL_USERDATA)); // faster than GetProp()
  {$endif}
  if not Assigned(obj) then
    result := DefWindowProc(HWnd,Msg,wParam,lParam) else begin

    dsp.msg := Msg;
    dsp.wParam := WParam;
    dsp.lParam := lParam;
    dsp.result := 0;
    obj.Dispatch(dsp);
    result := dsp.result;
  end;
end;

I get the errors:
[dcc32 Error] SynCommons.pas(21453): E2003 Undeclared identifier: 'msg'
[dcc32 Error] SynCommons.pas(21454): E2003 Undeclared identifier: 'wParam'
[dcc32 Error] SynCommons.pas(21455): E2003 Undeclared identifier: 'lParam'
[dcc32 Error] SynCommons.pas(21456): E2003 Undeclared identifier: 'result'
[dcc32 Error] SynCommons.pas(21458): E2003 Undeclared identifier: 'result'
[dcc32 Error] SynCommons.pas(21617): E2003 Undeclared identifier: 'WM_QUIT'

When I go to the definition of dsp : TMessage , the TMessage comes from FMX.Messages.pas.
Is this supposed to happen?

Please help, I cannot debug anymore.

#6 Re: mORMot 1 » Fill Dataset » 2014-02-19 14:53:34

Nvm we got it working smile

Removed pvDataset.Active and changed te JSONToClientDataSet statement from:

    JSONToClientDataSet(pvDataset, fJSON, fClient);

to

    JSONToClientDataSet(pvDataset, fJSON, fClient, mORMotMidasVCL.TClientDataSetMode.cdsNew );
function TMormotConnection.OpenDataset(pvDataset: TClientDataset;
  pvSQL: RawUTF8): Boolean;
var
  fJSON: RawUTF8;
begin
  if fService <> nil then
  begin
    fJSON := fService.Execute(pvSQL, true, true);
    JSONToClientDataSet(pvDataset, fJSON, fClient, mORMotMidasVCL.TClientDataSetMode.cdsNew );

Reply if you had this problem and this fixed it tongue

#7 mORMot 1 » Fill Dataset » 2014-02-19 12:32:51

SHEePYTaGGeRNeP
Replies: 1

Hello,

I am able to create a DataSet and fill it like this:

function TMormotConnection.GetDataset(pvSQL: RawUTF8): TClientDataset;

But I need to do it in this way:

function TMormotConnection.OpenDataset(pvDataset: TClientDataset; pvSQL: RawUTF8): Boolean;

But it keeps giving me errors.
The statement that calls the function is this one:

lvDataSet := TClientDataset.Create(nil);
lvDataSet := TMormotConnection.Connection.GetDataset(Format('SELECT * FROM AllKeyLists WHERE Name = ''%s''',
              [UpperCase(pvListName)]));

Here are the full functions.

function TMormotConnection.GetDataset(pvSQL: RawUTF8): TClientDataset;
var
  fJSON: RawUTF8;
  fSQLDataset: TSynSQLTableDataSet;
begin
  if fService <> nil then
  begin
    fJSON := fService.Execute(pvSQL, true, true);
    fSQLDataset := JSONToDataSet(nil, fJSON);
    Result := JSONToClientDataSet(fSQLDataset, fJSON, fClient);
  end
  else
    ShowMessage('There is no connection with the mORMot Server.');
end;
function TMormotConnection.OpenDataset(pvDataset: TClientDataset; pvSQL: RawUTF8): Boolean;
var
  fJSON: RawUTF8;
begin
  if fService <> nil then
  begin
    fJSON := fService.Execute(pvSQL, true, true);
    pvDataset.active := true;
    JSONToClientDataSet(pvDataset, fJSON, fClient);
  end
  else
    ShowMessage('There is no connection with the mORMot Server.');
  Result := True;
end;

The GetDataSet function works and returns the Dataset, but the OpenDataset function keeps giving me errors.
When I remove pvDataset.Active := true, I get the error: "Cannot perform this operation on a closed dataset."
When I add pvDataset.Active or pvDataset.Open I get the error: "Missing data provider or data packet.".

Please help.

Lorenzo / SHEePYTaGGeRNeP

#9 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-13 13:28:23

unit UserDataUnit;
/// it's a good practice to put all data definition into a stand-alone unit
// - this unit will be shared between client and server

interface

uses
  mORMot;

type
  /// here we declare the class containing the data
  // - it just has to inherits from TSQLRecord, and the published
  // properties will be used for the ORM (and all SQL creation)
  // - the beginning of the class name must be 'TSQL' for proper table naming
  // in client/server environnment


  // EDIT FILTERSETTINGS = UTF8STRING

  TSQLUserRecord = class(TSQLRecord)
  private
    // NUMBER
    fRECEIVERID, fAPPLICATIONS, fUSERRIGHTS, fUSERFUNCTIONS, fDEFAULTMEDIAID,
      fSTARTMEDIAID, fLEVELSMEDIAMENU, fSTARTINCOMINGID, fLEVELSINCOMINGMENU,
      fSTARTDOCUMENTID, fLEVELSDOCUMENTMENU, fSTARTCATEGORYID,
      fLEVELSCATEGORYMENU, fSTARTPROGRAMID, fSTARTPROGRAMMENU,
      fLEVELSPROGRAMMENU, fLEVELSCONTACTMENU: Integer;
    // VARCHAR2(60 CHAR)
    fUSERNAME, fUPASSWORD: UTF8String;
    // NUMBER
    fCAPACITY_MA, fCAPACITY_DI, fCAPACITY_WO, fCAPACITY_DO, fCAPACITY_VR,
      fCAPACITY_ZA, fCAPACITY_ZO, fDEFAULTPOOL, fPRIVATEPOOL, fALLOWEDMEDIA,
      fISACTIVE: Integer;
    // Date
    fMODIFIED: TDate;
    // NUMBER(1,0)
    fDELETED: Integer;
    // NUMBER
    fDEFFOLDERID: Integer;
    // VARCHAR2(60 CHAR)
    fEMAILADDRESS: UTF8String;
    // VARCHAR2(120 CHAR)
    fHOMEPAGE: UTF8String;
    // VARCHAR2(255 CHAR)
    fCONNECTMESSAGE: UTF8String;
    // NUMBER
    fDEFLOCATIONID, fUSEROPTIONS: Integer;
    // NUMBER(38,0)
    fRECEIVERRIGHTS, fMESSAGERIGHTS, fFILERIGHTS, fTASKRIGHTS: Integer;
    // CLOB
    fFILTERSETTINGS: UTF8String;
    // NUMBER
    fDELETEDBY, fMESSAGELIMIT: Integer;
    // NUMBER(38,0)
    fEXPORT_SELECT: Integer;
    // TIMESTAMP (6)
    fOUTLOOK2CS, fCS2OUTLOOK: TTime;
    // NUMBER(1,0)
    fSHOWAGENDAREJECT, fNOTIFYTASKCREATOR: Integer;
    // DATE
    fLASTPASSWORDCHANGE: TDate;
    // VARCHAR2(60 CHAR)
    fMD5PASSWORD: UTF8String;
    // VARCHAR(30 CHAR)
    fPINCODE: UTF8String;
    // VARCHAR(60 CHAR)
    fCOOKIE: UTF8String;
  published
    property RECEIVERID: Integer read fRECEIVERID write fRECEIVERID;
    property APPLICATIONS: Integer read fAPPLICATIONS write fAPPLICATIONS;
    property USERRIGHTS: Integer read fUSERRIGHTS write fUSERRIGHTS;
    property USERFUNCTIONS: Integer read fDEFAULTMEDIAID write fDEFAULTMEDIAID;
    property STARTMEDIAID: Integer read fSTARTMEDIAID write fSTARTMEDIAID;
    property LEVELSMEDIAMENU: Integer read fLEVELSMEDIAMENU
      write fLEVELSMEDIAMENU;
    property STARTINCOMINGID: Integer read fSTARTINCOMINGID
      write fSTARTINCOMINGID;
    property LEVELSINCOMINGMENU: Integer read fLEVELSINCOMINGMENU
      write fLEVELSINCOMINGMENU;
    property STARTDOCUMENTID: Integer read fSTARTDOCUMENTID
      write fSTARTDOCUMENTID;
    property LEVELSDOCUMENTMENU: Integer read fLEVELSDOCUMENTMENU
      write fLEVELSDOCUMENTMENU;
    property STARTCATEGORYID: Integer read fSTARTCATEGORYID
      write fSTARTCATEGORYID;
    property LEVELSCATEGORYMENU: Integer read fLEVELSCATEGORYMENU
      write fLEVELSCATEGORYMENU;
    property STARTPROGRAMID: Integer read fSTARTPROGRAMID write fSTARTPROGRAMID;
    property STARTPROGRAMMENU: Integer read fSTARTPROGRAMMENU
      write fSTARTPROGRAMMENU;
    property LEVELSPROGRAMMENU: Integer read fLEVELSPROGRAMMENU
      write fLEVELSPROGRAMMENU;
    property LEVELSCONTACTMENU: Integer read fLEVELSCONTACTMENU
      write fLEVELSCONTACTMENU;

    property USERNAME: UTF8String read fUSERNAME write fUSERNAME;
    property UPASSWORD: UTF8String read fUPASSWORD write fUPASSWORD;

    property CAPACITY_MA: Integer read fCAPACITY_MA write fCAPACITY_MA;
    property CAPACITY_DI: Integer read fCAPACITY_DI write fCAPACITY_DI;
    property CAPACITY_WO: Integer read fCAPACITY_WO write fCAPACITY_WO;
    property CAPACITY_DO: Integer read fCAPACITY_DO write fCAPACITY_DO;
    property CAPACITY_VR: Integer read fCAPACITY_VR write fCAPACITY_VR;
    property CAPACITY_ZA: Integer read fCAPACITY_ZA write fCAPACITY_ZA;
    property CAPACITY_ZO: Integer read fCAPACITY_ZO write fCAPACITY_ZO;
    property DEFAULTPOOL: Integer read fDEFAULTPOOL write fDEFAULTPOOL;
    property PRIVATEPOOL: Integer read fPRIVATEPOOL write fPRIVATEPOOL;
    property ALLOWEDMEDIA: Integer read fALLOWEDMEDIA write fALLOWEDMEDIA;
    property ISACTIVE: Integer read fISACTIVE write fISACTIVE;

    property MODIFIED: TDate read fMODIFIED write fMODIFIED;
    property DELETED: Integer read fDELETED write fDELETED;
    property DEFFOLDERID: Integer read fDEFFOLDERID write fDEFFOLDERID;
    property EMAILADDRESS: UTF8String read fEMAILADDRESS write fEMAILADDRESS;
    property HOMEPAGE: UTF8String read fHOMEPAGE write fHOMEPAGE;
    property CONNECTMESSAGE: UTF8String read fCONNECTMESSAGE
      write fCONNECTMESSAGE;

    property DEFLOCATIONID: Integer read fDEFLOCATIONID write fDEFLOCATIONID;
    property USEROPTIONS: Integer read fUSEROPTIONS write fUSEROPTIONS;

    property RECEIVERRIGHTS: Integer read fRECEIVERRIGHTS write fRECEIVERRIGHTS;
    property MESSAGERIGHTS: Integer read fMESSAGERIGHTS write fMESSAGERIGHTS;
    property FILERIGHTS: Integer read fFILERIGHTS write fFILERIGHTS;
    property TASKRIGHTS: Integer read fTASKRIGHTS write fTASKRIGHTS;

    property FILTERSETTINGS: UTF8String read fFILTERSETTINGS
      write fFILTERSETTINGS;
    property DELETEDBY: Integer read fDELETEDBY write fDELETEDBY;
    property MESSAGELIMIT: Integer read fMESSAGELIMIT write fMESSAGELIMIT;
    property EXPORT_SELECT: Integer read fEXPORT_SELECT write fEXPORT_SELECT;

    property OUTLOOK2CS: TTime read fOUTLOOK2CS write fOUTLOOK2CS;
    property CS2OUTLOOK: TTime read fCS2OUTLOOK write fCS2OUTLOOK;

    property SHOWAGENDAREJECT: Integer read fSHOWAGENDAREJECT
      write fSHOWAGENDAREJECT;
    property NOTIFYTASKCREATOR: Integer read fNOTIFYTASKCREATOR
      write fNOTIFYTASKCREATOR;
    PRoperty LASTPASSWORDCHANGE: TDate read fLASTPASSWORDCHANGE
      write fLASTPASSWORDCHANGE;
    property MD5PASSWORD: UTF8String read fMD5PASSWORD write fMD5PASSWORD;
    property PINCODE: UTF8String read fPINCODE write fPINCODE;
    property COOKIE: UTF8String read fCOOKIE write fCOOKIE;

  end;

  /// an easy way to create a database model for client and server
function CreateSampleModel: TSQLModel;

implementation

function CreateSampleModel: TSQLModel;
begin
  result := TSQLModel.Create([TSQLUserRecord]);
end;

end.

#10 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-13 11:00:36

ab wrote:

You are mixing ORM and SQL in the same code.
All this is a bit messy.

I only need to move data from the database that is not locally on the PC to the client via a server, so how do I do this?
I probably don't need the UserDataUnit class then, I guess?

There is only the sample "External DB perfomance" which has loads of code I don't need?

ab wrote:

What is your TSQLUserRecord type definition?
You should set the "index ... " to in the TSQLUserRecord type definition for VARCHAR2 fields, otherwise it will expect a CLOB content.

You mean this one?

  TSQLUserRecord = class(TSQLRecord)

What do you mean by set the index?

I'm sorry for knowing so little, have never worked wit Delphi, nor N-Tier architecture.

Looking forward to your answer.

#11 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-13 10:02:43

Hey Ab, so I created a new project, very basic.
I want to retreive data from the Oracle Database from within the Server.

I followed one of the example from project 4 and some others, but it gives me an error.

program ServerProject;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  mORMot,
  mORMotSQLite3,
  SynDBOracle,
  SynDB,
  UserDataUnit in 'UserDataUnit.pas';

var
  Model: TSQLModel;
  Connection: TSQLDBOracleConnection;
  Rows: ISQLDBRows;
  Result: UTF8String;
  User: Variant;

begin
  try
    Connection := TSQLDBOracleConnection.Create
      (TSQLDBOracleConnectionProperties.Create('SQL', 'devdb', 'dev', 'mmp'));
    Writeln('Connected to Oracle Database.');
    Connection.Properties.ThreadSafeConnection;
    Model := CreateSampleModel;
    try
      Rows := Connection.Properties.Execute
        ('SELECT * FROM USERS WHERE USERNAME<>?', ['PCMASTERRACE'], @User);
      Result := Rows.FetchAllAsJSON(false);
    finally
      Model.Free;
    end;
    { TODO -oUser -cConsole Main : Insert code here }

  finally
    Connection.Free;
  end;

end.

The problem is I get the message:
Unhandled type for property: USERNAME, which is a VARCHAR2 in the Oracle Database.
When it reaches

aModel := CreateSampleModel;

The screenshot is of an old project, but same UserDataUnit.
http://i.imgur.com/4eiDRKh.png


This is located in the "UserDataUnit.pas"

function CreateSampleModel: TSQLModel;
begin
  result := TSQLModel.Create([TSQLUserRecord]);
end;

Help sad?

#12 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-11 08:59:41

I just forgot to copy the sqlite3.obj files tongue
I'll let you know it everything is working.

#13 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-11 08:27:04

I removed them, but now I cannot compile TestSQL3:
[dcc32 Error] SynSQlite3Static.pas(227): E1026 File not found: 'sqlite3fts3.obj'
[dcc32 Error] SynSQlite3Static.pas(1029): E2065 Unsatisfied forward or external declaration: 'sqlite3_close'
[dcc32 Error] SynSQlite3Static.pas(1168): E2065 Unsatisfied forward or external declaration: 'sqlite3_initialize'
and a lot more.

Do I just copy sqlite3fts3.obj from the LVCL folder or what is the deal?

#14 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-10 14:49:53

Thx for the reply Ab,

I use Delphi XE5.
I added the LVCL folder to the Tools - Options - Library Directories.

I don´t think System.Pas changed has it :?

function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
  ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
  var ThreadId: TThreadID): THandle;
var
  P: PThreadRec;
begin
  if Assigned(SystemThreadFuncProc) then
    P := PThreadRec(SystemThreadFuncProc(ThreadFunc, Parameter))
  else
  begin
    New(P);
    P.Func := ThreadFunc;
    P.Parameter := Parameter;
  end;

  IsMultiThread := TRUE;

  Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
    CreationFlags, ThreadID);

  { P variable is supposed to be freed by the ThreadWrapper routine.
    If the call to CreateThread fails, then ThreadWrapper will not be called
    and P will not get freed. Check for failure now and free P if required.
  }
  if Result = 0 then
    Dispose(P);
end;

#15 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-10 12:50:51

Hello,

I finished downloading it and trying to compile the TestSQL3 project, but I get the error:
[dcc32 Error] Classes.pas(1576): E2033 Types of actual and formal var parameters must be identical

constructor TThread.Create(CreateSuspended: Boolean);
begin
  IsMultiThread := true; // for FastMM4 locking, e.g.
  inherited Create;
  FSuspended := CreateSuspended;
  FCreateSuspended := CreateSuspended;
  FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);        <-- This line
  if FHandle = 0 then
    raise Exception.Create(SysErrorMessage(GetLastError));
  SetThreadPriority(FHandle, THREAD_PRIORITY_NORMAL);
end;

What did I miss?

#16 Re: mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-10 10:57:56

I put the 2 lines of code in:

procedure TSQLDBOracleStatement.Prepare(const aSQL: RawUTF8;
  ExpectResults: boolean);
begin
            Check(AttrGet(oHandle, OCI_DTYPE_PARAM, @ColumnValueDBForm, nil,
              OCI_ATTR_CHARSET_FORM, fError), fError);
            Check(AttrGet(oHandle, OCI_DTYPE_PARAM, @ColumnValueDBCharSet, nil,
              OCI_ATTR_CHARSET_ID, fError), fError);
            // Columnvaluedbform := SQLCS_NCHAR;
            if (ColumnType = ftUTF8) then
              ColumnValueDBForm := SQLCS_NCHAR;
            case ColumnValueDBForm of
              SQLCS_IMPLICIT:
ab wrote:

Are you using the latest 1.18 "unstable" version?

I have 1.17 on SynDBOracle, but I updated them manually a couple of times.

EDIT: 12:11 Downloading the Snapshot at the moment.
EDIT: 12:20 Errors everywhere
[dcc32 Error] SQLite3Commons.pas(2313): E2037 Declaration of 'WriteObject' differs from previous declaration
[dcc32 Error] SQLite3Commons.pas(3290): E2003 Undeclared identifier: 'TVarDataDynArray'
[dcc32 Error] SQLite3Commons.pas(5314): E2003 Undeclared identifier: 'Iso8601'
[dcc32 Error] SQLite3Commons.pas(6912): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(7084): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(8107): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(8115): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(8265): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(8274): E2005 'TVarDataDynArray' is not a type identifier
[dcc32 Error] SQLite3Commons.pas(8648): E2137 Method 'AddTyped' not found in base class

#17 mORMot 1 » Basic Oracle DB Multi-Tier Project » 2014-02-10 10:26:00

SHEePYTaGGeRNeP
Replies: 17

Hello,

I have read some of the SAD Document and searched hours online for solutions and keep getting closer, but it's still not enough.
I do not have a lot of experience of Delphi nor Multi-tier applications.
I started with some DataSnap, but mORMot is a lot better so I had to give that a go.
I am an intern at a Software Engineering company who works with Delphi, but none of them ever worked with mORMot before.

I want to create a simple test project to start working on the real deal, but this is harder than I expected.
I have an Oracle Database and a Server and a Client. I think all the connections work, but the problem I have is that I can't seem to format the data from the database.

On the Server project I have:

    Connection: TSQLDBOracleConnection;
    Model: TSQLModel;
    DataBaseCache: TSQLRestServerDB;
    Server: TSQLite3HttpServer;

and when I click the Test button:

procedure TFormServer.Test(const aName: RawUTF8);
var
  Rows: ISQLDBRows;
  User: Variant;
  JSONBuffer: RawUTF8;
  Statement: TSQLDBOracleStatement;
  SQLTable: TSQLTableJSON;
  Tables: TRawUTF8DynArray;
begin
  Rows := Connection.Properties.Execute('select * from USERS where USERNAME<>?',
    [aName], @User);
  Connection.Properties.GetTableNames(Tables);
  JSONBuffer := Rows.FetchAllAsJSON(true);
  Writeln(UTF8ToString(Rows.FetchAllAsJSON(true)));

I didn't clean up the variables yet, because I tried a whole lot of things such as the ORM approach.

The issue I have is the VARCHAR2 data types in the Oracle Database gave errors, so I somewhat
fixed it by adding 2 lines of code in the SynDBOracle.pas:

            if (ColumnType = ftUTF8) then
              ColumnValueDBForm := SQLCS_NCHAR;

The problem I have now is that the "CLOB" Datatype is giving me this error:
ORA-24806: Incorrect LOB-form.
in the statement:

JSONBuffer := Rows.FetchAllAsJSON(true);

I have no clue how far I messed things up or fixed them.


Help would be much appreciated.

Lorenzo

Board footer

Powered by FluxBB