590 lines
20 KiB
ObjectPascal
590 lines
20 KiB
ObjectPascal
/// NexusDB 3.x direct access classes (embedded engine only)
|
|
// - this unit is a part of the freeware Synopse framework,
|
|
// licensed under a MPL/GPL/LGPL tri-license; version 1.18
|
|
unit SynDBNexusDB;
|
|
|
|
{
|
|
This file is part of Synopse framework.
|
|
|
|
Synopse framework. Copyright (C) 2022 Arnaud Bouchez
|
|
Synopse Informatique - https://synopse.info
|
|
|
|
*** BEGIN LICENSE BLOCK *****
|
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
The contents of this file are subject to the Mozilla Public License Version
|
|
1.1 (the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
for the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is Synopse mORMot framework.
|
|
|
|
The Initial Developer of the Original Code is Arnaud Bouchez.
|
|
|
|
Portions created by the Initial Developer are Copyright (C) 2022
|
|
the Initial Developer. All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
- Bas Schouten (initial uSGSynDBNexusDB.pas port)
|
|
|
|
Alternatively, the contents of this file may be used under the terms of
|
|
either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
|
of those above. If you wish to allow use of your version of this file only
|
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
|
use your version of this file under the terms of the MPL, indicate your
|
|
decision by deleting the provisions above and replace them with the notice
|
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
|
the provisions above, a recipient may use your version of this file under
|
|
the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
***** END LICENSE BLOCK *****
|
|
|
|
}
|
|
|
|
{$I Synopse.inc} // define HASINLINE CPU32 CPU64 OWNNORMTOUPPER
|
|
|
|
interface
|
|
|
|
|
|
{.$define SYNDB_FULLNEXUSDB}
|
|
// by default, only the NexusDB Free Embedded version is interfaced
|
|
// - you can define this conditional in project options to use all units
|
|
|
|
uses
|
|
Windows, SysUtils,
|
|
{$IFNDEF DELPHI5OROLDER}
|
|
Variants,
|
|
{$ENDIF}
|
|
Classes, Contnrs,
|
|
{$ifdef ISDELPHIXE2}Data.DB,{$else}DB,{$endif}
|
|
SynCommons,
|
|
SynTable,
|
|
SynLog,
|
|
SynDB,
|
|
SynDBDataset,
|
|
nxDB,
|
|
nxsdServerEngine,
|
|
nxsrServerEngine,
|
|
nxsqlEngine,
|
|
nxlgEventLog,
|
|
nxllTransport,
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
nxchCommandHandler,
|
|
nxsiServerInfoPluginServer,
|
|
nxtcCOMTransport,
|
|
nxtmSharedMemoryTransport,
|
|
nxtnNamedPipeTransport,
|
|
nxtsBlowfishRC4SecuredTransport,
|
|
nxtwWinsockTransport,
|
|
{$endif}
|
|
nxseAutoComponent;
|
|
|
|
|
|
{ -------------- NexusDB database engine native connection }
|
|
|
|
type
|
|
/// Exception type associated to the direct NexusDB connection
|
|
ESQLDBNexusDB = class(ESQLDBDataset);
|
|
|
|
// available communication protocols used by NexusDB between client and server
|
|
// - nxpFOLDER: default protocol, accessing NexusDB database in a Windows Folder
|
|
// - nxpTCPIP: TCP/IP transport, indicated by nxtcp://
|
|
// - nxpPIPE: Windows Named Pipe transport, indicated by nxpipe://
|
|
// - nxpMEM: direct memory transport, indicated by nxmem://
|
|
// - nxpBFISH: BlowFish transport, indicated by nxbfisch://
|
|
TNXProtocol = (
|
|
nxpUnknown,
|
|
nxpFOLDER,
|
|
nxpTCPIP,
|
|
nxpPIPE,
|
|
nxpCOM,
|
|
nxpMEM,
|
|
nxpBFISH);
|
|
|
|
// implement properties shared by native NexusDB connections
|
|
// - note that only the embedded engine is implemented by now - feedback needed!
|
|
TSQLDBNexusDBConnectionProperties = class(TSQLDBDatasetConnectionProperties)
|
|
private
|
|
fProtocol: TNXProtocol;
|
|
protected
|
|
/// initialize fForeignKeys content with all foreign keys of this DB
|
|
// - used by GetForeignKey method
|
|
procedure GetForeignKeys; override;
|
|
public
|
|
/// initialize the properties to connect to the NexusDB engine
|
|
// - this overridden method will initialize the protocol to be used as stated
|
|
// by aServerName i.e. nxpTCIP://11.23.34.43
|
|
// - Default protocol is nxpFolder
|
|
// - if protocol is nxpFolder then aDatabaseName will contain the path to the
|
|
// folder to be used
|
|
// - if protocol is other then nxpFolder than aServerName will contain the server
|
|
// to connect to and aDatabaseName will contains the alias of the database
|
|
// - Possible aServerName formats:
|
|
// $ <protocol>://<servername>/<alias> (aDatabaseName will be overwritten by this alias)
|
|
// $ <protocol>://servername (aDatabaseName will contain alias)
|
|
// $ '' (aDatabaseName contains path to nxpFOLDER database)
|
|
constructor Create(const aServerName, aDatabaseName, aUserID, aPassWord: RawUTF8); override;
|
|
/// convert a textual column data type, as retrieved e.g. from SQLGetField,
|
|
// into our internal primitive types
|
|
function ColumnTypeNativeToDB(const aNativeType: RawUTF8; aScale: integer): TSQLDBFieldType; override;
|
|
/// Determine if database exists
|
|
// - just test if the corresponding folder exists
|
|
function DatabaseExists: boolean; virtual;
|
|
/// create the database folder (if not existing)
|
|
function CreateDatabase: boolean; virtual;
|
|
/// delete the database folder
|
|
// - including all its files - so to be used carefully!
|
|
function DeleteDatabase: boolean; virtual;
|
|
/// create a new connection
|
|
// - caller is responsible of freeing this instance
|
|
// - this overridden method will create an TSQLDBNexusDBConnection instance
|
|
function NewConnection: TSQLDBConnection; override;
|
|
published
|
|
/// the transport protocol used to connect to the NexusDB engine
|
|
property Protocol: TNXProtocol read fProtocol;
|
|
end;
|
|
|
|
|
|
// implements a direct connection to the native NexusDB database
|
|
TSQLDBNexusDBConnection = class(TSQLDBConnectionThreadSafe)
|
|
protected
|
|
fDatabase: TnxDatabase;
|
|
fSession: TnxSession;
|
|
fServerEngine: TnxBaseServerEngine;
|
|
procedure SetServerEngine(aServerEngine: TnxBaseServerEngine);
|
|
public
|
|
/// prepare a connection to a specified NexusDB database server
|
|
constructor Create(aProperties: TSQLDBConnectionProperties); override;
|
|
/// release memory and connection
|
|
destructor Destroy; override;
|
|
/// connect to the specified NexusDB server
|
|
// - should raise an ESQLDBNexusDB on error
|
|
procedure Connect; override;
|
|
/// stop connection to the specified NexusDB database server
|
|
// - should raise an ESQLDBNexusDB on error
|
|
procedure Disconnect; override;
|
|
/// return TRUE if Connect has been already successfully called
|
|
function IsConnected: boolean; override;
|
|
/// create a new statement instance
|
|
function NewStatement: TSQLDBStatement; override;
|
|
/// begin a Transaction for this connection
|
|
procedure StartTransaction; override;
|
|
/// commit changes of a Transaction for this connection
|
|
// - StartTransaction method must have been called before
|
|
procedure Commit; override;
|
|
/// discard changes of a Transaction for this connection
|
|
// - StartTransaction method must have been called before
|
|
procedure Rollback; override;
|
|
/// access to the associated NexusDB connection instance
|
|
property Database: TnxDatabase read fDatabase;
|
|
/// associated NexusDB server engine
|
|
property ServerEngine: TnxBaseServerEngine read fServerEngine write SetServerEngine;
|
|
end;
|
|
|
|
// implements a statement via the native NexusDB connection
|
|
TSQLDBNexusDBStatement = class(TSQLDBDatasetStatement)
|
|
protected
|
|
/// initialize and set fQuery internal field as expected
|
|
procedure DatasetCreate; override;
|
|
/// set fQueryParams internal field as expected
|
|
function DatasetPrepare(const aSQL: string): boolean; override;
|
|
/// execute underlying TQuery.ExecSQL
|
|
procedure DatasetExecSQL; override;
|
|
public
|
|
end;
|
|
|
|
|
|
const
|
|
/// set aServerName to this value to create an in-memory table
|
|
// - do not use this constant, since it was not working as expected yet
|
|
NEXUSDB_INMEMORY = '#INMEM';
|
|
|
|
|
|
// determine NexusDB transport protocol (TNXProtocol) to be used, based on
|
|
// protocol indicator in connection string
|
|
// - if no protocol specifier is included in the connectionstring then nxpFOLDER
|
|
// is assumed.
|
|
// - aServerName will contain the URL to the Server if the protocol
|
|
// is not nxpFOLDER
|
|
function GetNXProtocol(const aConnectionString: RawUTF8; out aServerName: RawUTF8;
|
|
out aAlias: RawUTF8): TNXProtocol;
|
|
|
|
/// return the internal NexusDB embedded engine
|
|
// - initialize it, if was not already the case
|
|
function NexusEmbeddedEngine: TnxServerEngine;
|
|
|
|
/// release any internal NexusDB embedded engine
|
|
// - returns nil on success, or PtrInt(-1) if was not initialized
|
|
function DropNexusEmbeddedEngine: TnxServerEngine;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
nxreRemoteServerEngine,
|
|
uMiscellaneous,
|
|
{$endif}
|
|
nxsdConst,
|
|
nxsdTypes;
|
|
|
|
|
|
{ TSQLDBNexusDBConnectionProperties }
|
|
|
|
function TSQLDBNexusDBConnectionProperties.ColumnTypeNativeToDB(const aNativeType: RawUTF8;
|
|
aScale: integer): TSQLDBFieldType;
|
|
const CONV_TABLE: array[TnxFieldType] of TSQLDBFieldType = (
|
|
SynTable.ftInt64, SynTable.ftUTF8, SynTable.ftUTF8, SynTable.ftInt64,
|
|
SynTable.ftInt64, SynTable.ftInt64, SynTable.ftInt64, SynTable.ftInt64,
|
|
SynTable.ftInt64, SynTable.ftInt64, SynTable.ftInt64, SynTable.ftDouble,
|
|
SynTable.ftDouble, SynTable.ftDouble, SynTable.ftCurrency, SynTable.ftDate,
|
|
SynTable.ftDate, SynTable.ftDate, SynTable.ftInt64, SynTable.ftBlob,
|
|
SynTable.ftUTF8, SynTable.ftBlob, SynTable.ftBlob, SynTable.ftUTF8,
|
|
SynTable.ftUTF8, SynTable.ftUTF8, SynTable.ftInt64, SynTable.ftUTF8,
|
|
SynTable.ftCurrency, SynTable.ftUTF8, SynTable.ftDouble );
|
|
begin
|
|
result := CONV_TABLE[FieldDataTypesMapSQL(UTF8ToString(aNativeType))];
|
|
end;
|
|
|
|
constructor TSQLDBNexusDBConnectionProperties.Create(const aServerName, aDatabaseName, aUserID, aPassWord: RawUTF8);
|
|
var lServerURL, lAlias: RawUTF8;
|
|
begin
|
|
fDBMS := dNexusDB;
|
|
inherited Create(aServerName,aDatabaseName,aUserID,aPassWord);
|
|
fProtocol := GetNXProtocol(aServerName,lServerURL,lAlias);
|
|
if fProtocol=nxpFOLDER then
|
|
fServerName := '' else
|
|
if fProtocol>nxpFOLDER then
|
|
fServerName := lServerURL;
|
|
if fProtocol>nxpUnknown then
|
|
fDatabaseName := lAlias else
|
|
fDatabaseName := '';
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnectionProperties.GetForeignKeys;
|
|
begin
|
|
with Execute('select F.FK_CONSTRAINT_TABLE_NAME||''.''||C.FK_CONSTRAINT_REFERENCING_COLUMNS_NAME col, ' +
|
|
' F.FK_CONSTRAINT_REFERENCES_TABLE_NAME||''.''||R.FK_CONSTRAINT_REFERENCED_COLUMNS_NAME ref ' +
|
|
' from #FOREIGNKEY_CONSTRAINTS F, ' + ' #FOREIGNKEY_CONSTRAINTS_REFERENCING_COLUMNS C, ' +
|
|
' #FOREIGNKEY_CONSTRAINTS_REFERENCED_COLUMNS R ' + ' where ' +
|
|
' F.FK_CONSTRAINT_TABLE_NAME = C.FK_CONSTRAINT_TABLE_NAME' +
|
|
' and F.FK_CONSTRAINT_NAME = C.FK_CONSTRAINT_NAME' +
|
|
' F.FK_CONSTRAINT_TABLE_NAME = R.FK_CONSTRAINT_TABLE_NAME' +
|
|
' and F.FK_CONSTRAINT_NAME = R.FK_CONSTRAINT_NAME', []) do
|
|
while Step do
|
|
fForeignKeys.Add(ColumnUTF8(0),ColumnUTF8(1));
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnectionProperties.NewConnection: TSQLDBConnection;
|
|
begin
|
|
result := TSQLDBNexusDBConnection.Create(self);
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnectionProperties.DatabaseExists: boolean;
|
|
begin
|
|
if (fProtocol=nxpFOLDER) and (fDatabaseName<>NEXUSDB_INMEMORY) then
|
|
result := DirectoryExists(UTF8ToString(fDatabaseName)) else
|
|
result := True; // if we cannot determine directly, assume it exists
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnectionProperties.CreateDatabase: boolean;
|
|
begin
|
|
if fProtocol=nxpFOLDER then
|
|
if fDatabaseName=NEXUSDB_INMEMORY then
|
|
result := true else
|
|
result := ForceDirectories(UTF8ToString(fDatabaseName)) else
|
|
result := false;
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnectionProperties.DeleteDatabase: boolean;
|
|
begin
|
|
if fProtocol=nxpFOLDER then
|
|
if fDatabaseName=NEXUSDB_INMEMORY then
|
|
result := true else
|
|
result := DirectoryDelete(UTF8ToString(fDatabaseName)) else
|
|
result := false;
|
|
end;
|
|
|
|
|
|
{ TSQLDBNexusDBConnection }
|
|
|
|
procedure TSQLDBNexusDBConnection.Commit;
|
|
begin
|
|
inherited Commit;
|
|
try
|
|
fDatabase.Commit;
|
|
except
|
|
inc(fTransactionCount); // the transaction is still active
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnection.Connect;
|
|
var Log: ISynLog;
|
|
begin
|
|
Log := SynDBLog.Enter;
|
|
try
|
|
ServerEngine.Active := True;
|
|
ServerEngine.Connected := True;
|
|
fDatabase.Name := ClassName;
|
|
fDatabase.Connect;
|
|
inherited Connect; // notify any re-connection
|
|
except
|
|
on E: Exception do begin
|
|
Log.Log(sllError,E);
|
|
Disconnect; // clean up on fail
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
constructor TSQLDBNexusDBConnection.Create(aProperties: TSQLDBConnectionProperties);
|
|
var
|
|
lProp: TSQLDBNexusDBConnectionProperties;
|
|
var Log: ISynLog;
|
|
begin
|
|
Log := SynDBLog.Enter;
|
|
inherited Create(aProperties);
|
|
lProp := aProperties as TSQLDBNexusDBConnectionProperties; // type check to make sure
|
|
if lProp.Protocol=nxpUnknown then
|
|
raise ESQLDBNexusDB.CreateUTF8(
|
|
'%.Create: Unknown NexusDB protocol in Servername=[%]',
|
|
[self,lProp.ServerName]);
|
|
fDatabase := TnxDatabase.Create(nil);
|
|
fSession := TnxSession.Create(nil);
|
|
fSession.UserName := UTF8ToString(lProp.UserID);
|
|
fSession.Password := UTF8ToString(lProp.PassWord);
|
|
fDatabase.Session := fSession;
|
|
if lProp.Protocol=nxpFOLDER then begin
|
|
SetServerEngine(NexusEmbeddedEngine);
|
|
if not lProp.DatabaseExists then begin
|
|
Log.Log(sllDB,'Database % does not exists -> create folder',[lProp.DatabaseName]);
|
|
lProp.CreateDatabase;
|
|
end;
|
|
Database.AliasPath := lProp.DatabaseName;
|
|
Log.Log(sllDB,'NexusDB % using database folder %',
|
|
[fDatabase.Version,lProp.DatabaseName]);
|
|
end else begin
|
|
raise ESQLDBNexusDB.Create('Remote NexusDB engine not supported (yet)');
|
|
{ SetServerEngine(TnxRemoteServerEngine.Create(nil));
|
|
Database.AliasName := lProp.DatabaseName;
|
|
case lProp.Protocol of
|
|
nxpTCPIP: FTransport := TnxWinsockTransport.Create(nil);
|
|
nxpPIPE: FTransport := TnxNamedPipeTransport.Create(nil);
|
|
nxpCOM: FTransport := TnxRegisteredCOMTransport.Create(nil);
|
|
nxpMEM: FTransport := TnxSharedMemoryTransport.Create(nil);
|
|
nxpBFISH: FTransport := TnxBlowfishRC4SecuredTransport.Create(nil);
|
|
end;
|
|
TnxRemoteServerEngine(FServerEngine).Transport := FTransport;
|
|
FTransport.ServerName := lProp.Servername;
|
|
FTransport.CommandHandler := FCommandHandler;
|
|
FTransport.EventLog := FEventLog; }
|
|
end;
|
|
end;
|
|
|
|
destructor TSQLDBNexusDBConnection.Destroy;
|
|
begin
|
|
Disconnect;
|
|
inherited;
|
|
FreeAndNil(fDatabase);
|
|
FreeAndNil(fSession);
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnection.Disconnect;
|
|
begin
|
|
try
|
|
inherited Disconnect; // flush any cached statements
|
|
finally
|
|
if Assigned(fDatabase) then
|
|
fDatabase.Close;
|
|
if Assigned(fSession) and fSession.Active then begin
|
|
fSession.CloseInactiveTables;
|
|
fSession.CloseInactiveFolders;
|
|
fSession.Close;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnection.IsConnected: boolean;
|
|
begin
|
|
result := Assigned(fDatabase) and fDatabase.Connected;
|
|
end;
|
|
|
|
function TSQLDBNexusDBConnection.NewStatement: TSQLDBStatement;
|
|
begin
|
|
result := TSQLDBNexusDBStatement.Create(self);
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnection.Rollback;
|
|
begin
|
|
inherited Rollback;
|
|
fDatabase.Rollback;
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnection.SetServerEngine(aServerEngine: TnxBaseServerEngine);
|
|
begin
|
|
if FServerEngine<>aServerEngine then begin
|
|
FServerEngine := aServerEngine;
|
|
fSession.ServerEngine := aServerEngine;
|
|
end;
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBConnection.StartTransaction;
|
|
begin
|
|
inherited StartTransaction;
|
|
if not fDatabase.TryStartTransaction then
|
|
raise ESQLDBNexusDB.Create('Error occcured trying to start a transaction');
|
|
end;
|
|
|
|
|
|
{ TSQLDBNexusDBStatement }
|
|
|
|
function TSQLDBNexusDBStatement.DatasetPrepare(const aSQL: string): boolean;
|
|
begin
|
|
(fQuery as TnxQuery).SQL.Text := aSQL;
|
|
fQueryParams := TnxQuery(fQuery).Params;
|
|
result := fQueryParams<>nil;
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBStatement.DatasetExecSQL;
|
|
begin
|
|
(fQuery as TnxQuery).ExecSQL;
|
|
end;
|
|
|
|
procedure TSQLDBNexusDBStatement.DatasetCreate;
|
|
begin
|
|
fQuery := TnxQuery.Create(nil);
|
|
with TnxQuery(fQuery) do begin
|
|
Database := (fConnection as TSQLDBNexusDBConnection).Database;
|
|
Session := TSQLDBNexusDBConnection(fConnection).Database.Session;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ low-level NexusDB engine functions }
|
|
|
|
var
|
|
vNexusEmbeddedEngine: TnxServerEngine;
|
|
|
|
function GetNXProtocol(const aConnectionString: RawUTF8; out aServerName: RawUTF8;
|
|
out aAlias: RawUTF8): TNXProtocol;
|
|
const
|
|
NXPROTNAMES:array[nxpFOLDER..high(TNXProtocol)] of RawUTF8 = (
|
|
'nxemb','nxtcp','nxpipe','nxcom','nxmem','nxbfish');
|
|
var Prot, Alias,l,r: RawUTF8;
|
|
IsPath: boolean;
|
|
pr:TNXProtocol;
|
|
begin
|
|
Split(aConnectionString,':',Prot,Alias);
|
|
IsPath := (Prot='') or // no protocol indicated: assume it's a path (relative)
|
|
(Prot=NEXUSDB_INMEMORY) or
|
|
((Length(Prot)=1) and // check for drive letter
|
|
(Prot[1] in ['a'..'z','A' .. 'Z']) and
|
|
DirectoryExists(TFileName(Prot[1])+':\')) or // check if root folder can be found
|
|
IdemPChar(Pointer(aConnectionString),'.\') or
|
|
IdemPChar(Pointer(aConnectionString),'..\');
|
|
if IsPath then begin
|
|
result := nxpFOLDER;
|
|
aAlias := aConnectionString;
|
|
end else begin
|
|
result := nxpUnknown;
|
|
for pr := Low(NXPROTNAMES) to High(NXPROTNAMES) do
|
|
if prot=NXPROTNAMES[pr] then begin
|
|
result := pr;
|
|
break;
|
|
end;
|
|
if result=nxpFOLDER then begin
|
|
if prot<>'' then
|
|
aAlias := Alias else
|
|
aAlias := aConnectionString;
|
|
end else
|
|
if result>nxpFOLDER then begin
|
|
Split(aConnectionString,'://',l,r);
|
|
Split(r,'/',aServerName,aAlias);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function DropNexusEmbeddedEngine: TnxServerEngine;
|
|
var cmp: TComponent;
|
|
i: integer;
|
|
begin
|
|
if PtrInt(vNexusEmbeddedEngine)<>-1 then begin
|
|
if Assigned(vNexusEmbeddedEngine) then begin
|
|
vNexusEmbeddedEngine.Close;
|
|
vNexusEmbeddedEngine.SqlEngine := nil;
|
|
vNexusEmbeddedEngine.EventLog := nil;
|
|
// ensure our components get destroyed before destroying the engine
|
|
for i := vNexusEmbeddedEngine.ComponentCount-1 downto 0 do begin
|
|
cmp := vNexusEmbeddedEngine.Components[i];
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
if cmp is TnxServerCommandHandler then
|
|
with TnxServerCommandHandler(cmp) do begin
|
|
ServerEngine := nil;
|
|
Close;
|
|
Free;
|
|
end else
|
|
{$endif}
|
|
if cmp is TnxSqlEngine then
|
|
with TnxSqlEngine(cmp) do begin
|
|
Close;
|
|
Free;
|
|
end else
|
|
if cmp is TnxEventLog then
|
|
with TnxEventLog(cmp) do begin
|
|
Flush;
|
|
Free;
|
|
end;
|
|
end;
|
|
end;
|
|
FreeAndNil(vNexusEmbeddedEngine);
|
|
end;
|
|
result := vNexusEmbeddedEngine;
|
|
end;
|
|
|
|
function NexusEmbeddedEngine: TnxServerEngine;
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
var CommandHandler: TnxServerCommandHandler;
|
|
{$endif}
|
|
begin
|
|
if PtrInt(vNexusEmbeddedEngine)=-1 then
|
|
raise ESQLDBNexusDB.Create('Nexus Embedded engine was already finalized!') else
|
|
if vNexusEmbeddedEngine=nil then begin
|
|
vNexusEmbeddedEngine := TnxServerEngine.Create(nil);
|
|
//vNexusEmbeddedEngine.Options := vNexusEmbeddedEngine.Options+[seoInMemOnly];
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
CommandHandler := TnxServerCommandHandler.Create(vNexusEmbeddedEngine);
|
|
{$endif}
|
|
vNexusEmbeddedEngine.SqlEngine := TnxSqlEngine.Create(vNexusEmbeddedEngine);
|
|
vNexusEmbeddedEngine.EventLog := TnxEventLog.Create(vNexusEmbeddedEngine);
|
|
{$ifdef SYNDB_FULLNEXUSDB}
|
|
CommandHandler.ServerEngine := vNexusEmbeddedEngine;
|
|
{$endif}
|
|
end;
|
|
result := vNexusEmbeddedEngine;
|
|
end;
|
|
|
|
procedure FinalizeNXEmbeddedEngine;
|
|
begin
|
|
if PtrInt(vNexusEmbeddedEngine)<>-1 then
|
|
try
|
|
DropNexusEmbeddedEngine;
|
|
finally
|
|
PtrInt(vNexusEmbeddedEngine) := -1; // mark always as finalized
|
|
end;
|
|
end;
|
|
|
|
|
|
initialization
|
|
TSQLDBNexusDBConnectionProperties.RegisterClassNameForDefinition;
|
|
|
|
finalization
|
|
FinalizeNXEmbeddedEngine;
|
|
end.
|