unit uDAZeosDriver; {----------------------------------------------------------------------------} { Data Abstract Library - Driver Library } { } { compiler: Delphi 6 and up , FPC } { platform: Win32 } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the Data Abstract } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$I ..\DataAbstract.inc} interface uses Classes, DB, ZConnection, ZSqlMetadata, uDAInterfaces, uDAADOInterfaces, uDAIBInterfaces, uDASQLiteInterfaces, uDAOracleInterfaces, uDAMySQLInterfaces, uDAPostgresInterfaces, uROClasses, uDAEngine, uDAUtils; type TDAZEOSDriverType = ( dazUnknown, dazADO, dazASA, dazIBMDB2, dazInterBase, dazMSSQL, dazMySQL, dazOracle, dazPostgreSQL, dazSQLite, dazSybase); const ZEOS_ADO = 'ado'; ZEOS_ASA = 'asa'; ZEOS_IBMDB2 = 'db2'; ZEOS_Interbase = 'interbase'; ZEOS_Firebird = 'firebird'; ZEOS_MSSQL = 'mssql'; ZEOS_MySQL = 'mysql'; ZEOS_ORACLE = 'oracle'; ZEOS_PostgreSQL = 'postgresql'; ZEOS_SQLite = 'sqlite'; ZEOS_SYBASE = 'sybase'; type { TDAZeosDriver } TDAZeosDriver = class(TDADriverReference) end; { TDAESampleDriver } TDAESampleDriver = class(TDAEDriver, IDADriver40) // TDAESampleDriver = class(TDAIBDriver, IDADriver40) protected function GetConnectionClass: TDAEConnectionClass; override; //procedure CustomizeConnectionObject(aConnection: TDAEConnection); override; //procedure DoSetTraceOptions(TraceActive: boolean; TraceFlags: TDATraceOptions; Callback: TDALogTraceEvent); override; { IDADriver } function GetDriverID: string; override; safecall; function GetDescription: string; override; safecall; // function GetMajVersion: byte; override; safecall; // function GetMinVersion: byte; override; safecall; procedure GetAuxDrivers(out List: IROStrings); override; safecall; procedure GetAuxParams(const AuxDriver: string; out List: IROStrings); override; function GetAvailableDriverOptions: TDAAvailableDriverOptions; override; safecall; // procedure Initialize; override; safecall; // procedure Finalize; override; safecall; // function GetDefaultCustomParameters: string; override; safecall; function GetDefaultConnectionType(const AuxDriver: string): string; override; safecall; { IDADriver40 } function GetProviderDefaultCustomParameters(Provider: string): string; safecall; public end; TZEOSConnection = class(TDAConnectionWrapper) private fConnection: TZConnection; fMetaData: TZSQLMetaData; protected function GetConnected: Boolean; override; procedure SetConnected(Value: boolean); override; public constructor Create(AOwner: TComponent); override; property Connection: TZConnection read fConnection write fConnection; end; { TDAESampleConnection } TDAESampleConnection = class(TDAEConnection, IDAConnection, IDAADOConnection, IDAInterbaseConnection, //IDAIBTransactionAccess, IDAIBConnectionProperties, IDAOracleConnection, IDAMySQLConnection, IDASQLiteConnection, IDAPostgresConnection, // IDAConnectionModelling, IDACanQueryDatabaseNames, IDAFileBasedDatabase, // IDADirectoryBasedDatabase, IDAUseGenerators, IDACanQueryGeneratorsNames, IDATestableObject) private fNativeConnection: TZEOSConnection; fDriverType: TDAZEOSDriverType; fDriverName: string; fADOProviderName: string; fADOProviderType: TDAOleDBProviderType; fMSSQLSchemaEnabled: Boolean; procedure DoGetNames(AList: IROStrings; AObjectType: TDAObjecttype); protected function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall; function CreateCustomConnection: TCustomConnection; override; function CreateMacroProcessor: TDASQLMacroProcessor; override; function GetDatasetClass: TDAEDatasetClass; override; function GetStoredProcedureClass: TDAEStoredProcedureClass; override; procedure DoApplyConnectionString(aConnStrParser: TDAConnectionStringParser; aConnectionObject: TCustomConnection); override; // transaction support function DoBeginTransaction: integer; override; procedure DoCommitTransaction; override; procedure DoRollbackTransaction; override; function DoGetInTransaction: boolean; override; procedure DoGetTableNames(out List: IROStrings); override; procedure DoGetViewNames(out List: IROStrings); override; procedure DoGetStoredProcedureNames(out List: IROStrings); override; procedure DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); override; // procedure DoGetQueryFields(const aSQL: string; aParamsIfNeeded: TDAParamCollection; out Fields: TDAFieldCollection); override; // procedure DoGetViewFields(const aViewName: string; out Fields: TDAFieldCollection); override; procedure DoGetStoredProcedureParams(const aStoredProcedureName: string; out Params: TDAParamCollection); override; procedure DoGetForeignKeys(out ForeignKeys: TDADriverForeignKeyCollection); override; function DoGetLastAutoInc(const GeneratorName: string): integer; override; { IDATestableObject } // procedure Test; override; safecall; { IDAConnection } function GetSPSelectSyntax(HasArguments: Boolean): string; override; safecall; function GetQuoteChars: TDAQuoteCharArray; override; safecall; // function IdentifierIsQuoted(const iIdentifier: string): boolean; override; safecall; function IdentifierNeedsQuoting(const iIdentifier: string): boolean; override; safecall; // function QuoteIdentifierIfNeeded(const iIdentifier: string): string; override; safecall; // function QuoteIdentifier(const iIdentifier: string): string; override; safecall; // function QuoteFieldNameIfNeeded(const aTableName, aFieldName: string): string; override;safecall; // function QuoteFieldName(const aTableName, aFieldName: string): string; override; safecall; // function NewCommand(const Text: string; CommandType: TDASQLStatementType; const aCommandName: string = ''): IDASQLCommand; override; safecall; // function NewDataset(const SQL: string; const aDatasetName: string = ''): IDADataset; override; safecall; // function isAlive: Boolean; override; safecall; // function GetQueryBuilder: TDAQueryBuilder; override; safecall; { IDAADOConnection } function GetProviderName: string; safecall; function GetProviderType: TDAOleDBProviderType; safecall; function GetCommandTimeout: Integer; safecall; procedure SetCommandTimeout(const Value: Integer); safecall; { IDAInterbaseConnection } // nothing { IDAIBTransactionAccess } //function GetTransaction: TObject; safecall; //procedure CommitRetaining; safecall; //procedure RollbackRetaining; safecall; { IDAIBConnectionProperties } function GetRole: string; safecall; procedure SetRole(const Value: string); safecall; function GetSQLDialect: integer; safecall; procedure SetSQLDialect(Value: integer); safecall; function GetCharset: string; safecall; procedure SetCharset(const Value: string); safecall; procedure Commit; safecall; // procedure CommitRetaining; safecall; procedure Rollback; safecall; // procedure RollbackRetaining; safecall; { IDAOracleConnection } // nothing { IDAConnectionModelling } // function FieldToDeclaration(aField: TDAField): string; safecall; // function BuildCreateTableSQL(aDataSet: TDADataSet; const aOverrideName: string = ''): string; safecall; // procedure CreateTable(aDataSet: TDADataSet; const aOverrideName: string = ''); safecall; { IDACanQueryDatabaseNames } function GetDatabaseNames: IROStrings; { IDAFileBasedDatabase } function GetFileExtensions: IROStrings; { IDADirectoryBasedDatabase } // nothing { IDAUseGenerators } function GetNextAutoinc(const GeneratorName: string): integer; safecall; { IDACanQueryGeneratorsNames } function GetGeneratorNames: IROStrings; public constructor Create(aDriver: TDAEDriver; aName: string = ''); override; end; { TDAESampleQuery } TDAESampleQuery = class(TDAEDataset {, IDAMustSetParams}) protected // procedure PrepareSQLStatement; override; function CreateDataset(aConnection: TDAEConnection): TDataset; override; procedure DoPrepare(Value: boolean); override; safecall; // function DoExecute: integer; override; safecall; procedure DoSetSQL(const Value: string); override; safecall; function DoGetSQL: string; override; safecall; // function intVCLTypeToDAType(aFieldType: TFieldType): TDADataType;override; { IDASQLCommand } // procedure RefreshParams; override; safecall; // function Execute: integer; override; safecall; // function DoGetRecordCount: integer; override; // function DoGetActive: boolean; override; // procedure DoSetActive(Value: boolean); override; // function DoGetBOF: boolean; override; // function DoGetEOF: boolean; override; // procedure DoNext; override; // function DoLocate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override; // IDAMustSetParams // procedure SetParamValues(Params: TDAParamCollection); safecall; // procedure GetParamValues(Params: TDAParamCollection); safecall; public end; { TDAESampleStoredProcedure } TDAESampleStoredProcedure = class(TDAEStoredProcedure {, IDAMustSetParams}) protected // Internal // function DoGetStoredProcedureName: string; override; // procedure DoSetStoredProcedureName(const Name: string); override; procedure DoPrepare(Value: boolean); override; // procedure RefreshParams; override; safecall; // IDAStoredProcedure function GetStoredProcedureName: string; override; safecall; procedure SetStoredProcedureName(const Name: string); override; safecall; // procedure PrepareSQLStatement; override; function CreateDataset(aConnection: TDAEConnection): TDataset; override; // function DoExecute: integer; override; safecall; procedure DoSetSQL(const Value: string); override; safecall; function DoGetSQL: string; override; safecall; // function intVCLTypeToDAType(aFieldType: TFieldType): TDADataType;override; { IDASQLCommand } // procedure RefreshParams; override; safecall; // function Execute: integer; override; safecall; // function DoGetRecordCount: integer; override; // function DoGetActive: boolean; override; // procedure DoSetActive(Value: boolean); override; // function DoGetBOF: boolean; override; // function DoGetEOF: boolean; override; // procedure DoNext; override; // function DoLocate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override; // IDAMustSetParams // procedure SetParamValues(Params: TDAParamCollection); safecall; // procedure GetParamValues(Params: TDAParamCollection); safecall; end; procedure Register; function GetDriverObject: IDADriver; stdcall; implementation uses {$IFDEF FPC}LResources,{$ENDIF} {$IFNDEF LINUX}Windows, {$ENDIF} Variants, Types, SysUtils, uDADriverManager, uDARes, uDASQL92Interfaces, ZDbcIntfs, zClasses, ZDataset, ZStoredProcedure; {$IFNDEF FPC} {$R DataAbstract_ZeosDriver_Glyphs.res} {$ENDIF} var _driver : TDAEDriver = nil; procedure Register; begin RegisterComponents(DAPalettePageName, [TDAZeosDriver]); end; function GetDriverObject: IDADriver; begin if (_driver = nil) then _driver := TDAESampleDriver.Create(nil); result := _driver; end; function ZEOSDriverIdToZEOSDriverType(aAuxDriver: string): TDAZEOSDriverType; begin aAuxDriver := LowerCase(aAuxDriver); if aAuxDriver = '' then Result := dazUnknown else if Pos(ZEOS_ADO, aAuxDriver) = 1 then Result := dazADO else if Pos(ZEOS_ASA, aAuxDriver) = 1 then Result := dazASA else if Pos(ZEOS_IBMDB2, aAuxDriver) = 1 then Result := dazIBMDB2 else if Pos(ZEOS_Interbase, aAuxDriver) = 1 then Result := dazInterBase else if Pos(ZEOS_Firebird, aAuxDriver) = 1 then Result := dazInterBase else if Pos(ZEOS_MSSQL, aAuxDriver) = 1 then Result := dazMSSQL else if Pos(ZEOS_MySQL, aAuxDriver) = 1 then Result := dazMySQL else if Pos(ZEOS_ORACLE, aAuxDriver) = 1 then Result := dazOracle else if Pos(ZEOS_PostgreSQL, aAuxDriver) = 1 then Result := dazPostgreSQL else if Pos(ZEOS_SQLite, aAuxDriver) = 1 then Result := dazSQLite else if Pos(ZEOS_SYBASE, aAuxDriver) = 1 then Result := dazSybase else Result := dazUnknown; end; { TDAESampleConnection } procedure TDAESampleConnection.DoApplyConnectionString(aConnStrParser: TDAConnectionStringParser; aConnectionObject: TCustomConnection); var i : Integer; sName, sValue : string; begin inherited; with aConnStrParser do begin fDriverName := AuxDriver; fDriverType := ZEOSDriverIdToZEOSDriverType(AuxDriver); fADOProviderName := AuxParams['Provider']; FADOProviderType := OleDBDriverIdToOleDBProviderType(FADOProviderName); fNativeConnection.fConnection.Protocol := AuxDriver; if (Self.UserID <> '') then fNativeConnection.fConnection.User := Self.UserID else fNativeConnection.fConnection.User := UserID; if (Self.Password <> '') then fNativeConnection.fConnection.Password := Self.Password else fNativeConnection.fConnection.Password := Password; if Server <> '' then fNativeConnection.fConnection.HostName := Server; if Database <> '' then begin fNativeConnection.fConnection.Database := Database; if fDriverType <> dazSQLite then fNativeConnection.fConnection.Catalog := Database; end; for i := 0 to AuxParamsCount - 1 do begin sName := AuxParamNames[i]; if sName = '' then Continue; sValue := AuxParams[AuxParamNames[i]]; if AnsiSameText(sName, 'role') then begin if fDriverType = dazInterBase then sName := 'rolename'; end else if AnsiSameText(sName, 'charset') then begin if fDriverType = dazInterBase then sName := 'codepage'; end else if AnsiSameText(sName, 'port') then begin if StrToIntDef(sValue, -1) <> -1 then fNativeConnection.fConnection.Port := StrToInt(sValue); end else begin if sName[1] = '@' then sName := Pchar(sName) + 1; end; fNativeConnection.fConnection.Properties.Values[sName] := sValue; end; if fDriverType = dazADO then begin if fADOProviderName = '' then raise EDADriverException.Create('No proviver specified for ADO auxdriver'); fNativeConnection.fConnection.Properties.Values['User ID'] := fNativeConnection.fConnection.User; fNativeConnection.fConnection.Properties.Values['Password'] := fNativeConnection.fConnection.Password; if FADOProviderType = oledb_Jet then begin fNativeConnection.fConnection.Properties.Values['Data Source'] := Database; end else begin if Database <> '' then begin if fADOProviderType = oledb_Postgresql then fNativeConnection.fConnection.Properties.Values['Location'] := Database else fNativeConnection.fConnection.Properties.Values['Initial Catalog'] := Database; end; if Server <> '' then fNativeConnection.fConnection.Properties.Values['Data Source'] := Server; if fADOProviderType <> oledb_Postgresql then fNativeConnection.fConnection.Properties.Values['OLE DB SERVICES'] := '-2'; end; fNativeConnection.fConnection.Database := ''; for i := 0 to fNativeConnection.fConnection.Properties.Count - 1 do begin sName:=fNativeConnection.fConnection.Properties.Names[i]; sValue:=fNativeConnection.fConnection.Properties.Values[sName]; fNativeConnection.fConnection.Database:=fNativeConnection.fConnection.Database + sName+'='+sValue+';' end; end; end; end; function TDAESampleConnection.DoBeginTransaction: integer; begin fNativeConnection.fConnection.StartTransaction; Result := 0; end; procedure TDAESampleConnection.DoCommitTransaction; begin fNativeConnection.fConnection.Commit; end; function TDAESampleConnection.CreateCustomConnection: TCustomConnection; begin fNativeConnection := TZEOSConnection.Create(nil); result := fNativeConnection; end; function TDAESampleConnection.GetDatasetClass: TDAEDatasetClass; begin result := TDAESampleQuery; end; function TDAESampleConnection.GetStoredProcedureClass: TDAEStoredProcedureClass; begin result := TDAESampleStoredProcedure; end; procedure TDAESampleConnection.DoRollbackTransaction; begin fNativeConnection.fConnection.Rollback; end; function TDAESampleConnection.DoGetInTransaction: boolean; begin Result := fNativeConnection.fConnection.InTransaction end; function TDAESampleConnection.QueryInterface(const IID: TGUID; out Obj): HResult; begin Result := E_NOINTERFACE; if IsEqualGUID(IID, IDAADOConnection) then begin if fDriverType <> dazADO then Exit; end else if IsEqualGUID(IID, IDAInterbaseConnection) then begin if fDriverType <> dazInterbase then Exit; end else if IsEqualGUID(IID, IDAIBTransactionAccess) then begin if fDriverType <> dazInterbase then Exit; end else if IsEqualGUID(IID, IDAIBConnectionProperties) then begin if fDriverType <> dazInterbase then Exit; end else if IsEqualGUID(IID, IDAOracleConnection) then begin if fDriverType <> dazOracle then Exit; end else if IsEqualGUID(IID, IDASQLiteConnection) then begin if fDriverType <> dazSQLite then Exit; end else if IsEqualGUID(IID, IDAPostgresConnection) then begin if fDriverType <> dazPostgreSQL then Exit; end else if IsEqualGUID(IID, IDAMySQLConnection) then begin if fDriverType <> dazMySQL then Exit; end else if IsEqualGUID(IID, IDACanQueryDatabaseNames) then begin if (fDriverType in [dazInterBase, dazSQLite]) then Exit; end else if IsEqualGUID(IID, IDAFileBasedDatabase) then begin if not (fDriverType in [dazInterBase, dazSQLite]) then Exit; end else if IsEqualGUID(IID, IDAUseGenerators) then begin if not (fDriverType in [dazInterBase, dazOracle, dazPostgreSQL]) then Exit; end else if IsEqualGUID(IID, IDACanQueryGeneratorsNames) then begin if not (fDriverType in [dazInterBase]) then Exit; end // else if IsEqualGUID(IID, IDAConnectionModelling) then // else if IsEqualGUID(IID, IDADirectoryBasedDatabase) then ; Result := inherited QueryInterface(IID, Obj); end; constructor TDAESampleConnection.Create(aDriver: TDAEDriver; aName: string); begin inherited Create(aDriver, aName); fMSSQLSchemaEnabled := True; end; function TDAESampleConnection.CreateMacroProcessor: TDASQLMacroProcessor; begin case fDriverType of dazInterBase: Result := IB_CreateMacroProcessor; dazMSSQL: Result := MSSQL_CreateMacroProcessor; dazOracle: Result := Oracle_CreateMacroProcessor; else Result := inherited CreateMacroProcessor; end; end; function TDAESampleConnection.GetFileExtensions: IROStrings; begin case fDriverType of dazInterBase: Result := IB_GetFileExtensions; dazSQLite: Result := SQLite_GetFileExtensions; else Result := NewROStrings; end; end; function TDAESampleConnection.GetGeneratorNames: IROStrings; begin case fDriverType of dazInterBase: Result:= IB_GetGeneratorNames(GetDatasetClass.Create(Self)); else Result := NewROStrings; end; end; procedure TDAESampleConnection.DoGetTableNames(out List: IROStrings); begin inherited; case fDriverType of dazMSSQL: MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotTable, fMSSQLSchemaEnabled); dazInterBase: IB_GetObjectNames(GetDatasetClass.Create(Self), List, dotTable); dazMYSQL: MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotTable, fNativeConnection.fConnection.Catalog); dazSQLite: SQLite_GetObjectNames(GetDatasetClass.Create(Self), List, dotTable); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotTable, fMSSQLSchemaEnabled) else begin DoGetNames(List, dotTable); end; end end; procedure TDAESampleConnection.DoGetViewNames(out List: IROStrings); begin inherited; case fDriverType of dazMSSQL: MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotView, fMSSQLSchemaEnabled); dazInterBase: IB_GetObjectNames(GetDatasetClass.Create(Self), List, dotView); dazMYSQL: MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotView, fNativeConnection.fConnection.Catalog); dazSQLite: SQLite_GetObjectNames(GetDatasetClass.Create(Self), List, dotView); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotView, fMSSQLSchemaEnabled) else begin DoGetNames(List, dotView); end; end end; procedure TDAESampleConnection.DoGetStoredProcedureNames( out List: IROStrings); begin inherited; case fDriverType of dazMSSQL: MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotProcedure, fMSSQLSchemaEnabled); dazInterBase: IB_GetObjectNames(GetDatasetClass.Create(Self), List, dotProcedure); dazMYSQL: MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotProcedure, fNativeConnection.fConnection.Catalog); dazSQLite: SQLite_GetObjectNames(GetDatasetClass.Create(Self), List, dotProcedure); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then MSSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotProcedure, fMSSQLSchemaEnabled) else begin DoGetNames(List, dotProcedure); end; end end; procedure TDAESampleConnection.DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); var lschema, ltbl : string; fld : TDAField; begin case fDriverType of dazMSSQL: MSSQL_DoGetTableFields(QuoteIdentifierIfNeeded(aTableName), GetDatasetClass.Create(Self), Fields); dazInterBase: IB_GetTableFields(QuoteIdentifierIfNeeded(aTableName), GetDatasetClass.Create(Self), Fields); dazMySQL: MYSQL_DoGetTableFields(QuoteIdentifierIfNeeded(aTableName),GetDatasetClass.Create(Self),Fields, fNativeConnection.fConnection.Catalog); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then MSSQL_DoGetTableFields(QuoteIdentifierIfNeeded(aTableName), GetDatasetClass.Create(Self), Fields) else begin inherited; if Pos('.', aTableName) > 0 then begin lschema := Trim(Copy(aTableName, 1, Pos('.', aTableName) - 1)); ltbl := Trim(Copy(aTableName, Pos('.', aTableName) + 1, Length(aTableName))); end else begin lschema := ''; ltbl := aTableName; end; // required+default value with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetColumns(fNativeConnection.fConnection.Catalog, lschema, ltbl, '') do while Next do begin fld := Fields.FindField(GetStringByName('COLUMN_NAME')); if fld = nil then Continue; fld.Required := GetStringByName('IS_NULLABLE') = 'NO'; fld.DefaultValue := GetStringByName('COLUMN_DEF'); if not TestDefaultValue(fld.DefaultValue, fld.DataType) then fld.DefaultValue := ''; end; // pk with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetPrimaryKeys(fNativeConnection.fConnection.Catalog, lschema, ltbl) do while Next do begin fld := Fields.FindField(GetStringByName('COLUMN_NAME')); if fld = nil then Continue; fld.Required := True; fld.InPrimaryKey := True; end; end; end end; procedure TDAESampleConnection.DoGetForeignKeys( out ForeignKeys: TDADriverForeignKeyCollection); var lSupportedSchema : boolean; begin inherited; case fDriverType of dazMSSQL: MSSQL_DoGetForeignKeys(GetDatasetClass.Create(Self), ForeignKeys, fMSSQLSchemaEnabled); dazInterBase: IB_DoGetForeignKeys(GetDatasetClass.Create(Self), ForeignKeys); dazMySQL: MYSQL_DoGetForeignKeys(GetDatasetClass.Create(Self), ForeignKeys, fNativeConnection.fConnection.Catalog); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then MSSQL_DoGetForeignKeys(GetDatasetClass.Create(Self), ForeignKeys, fMSSQLSchemaEnabled) else begin lSupportedSchema := fNativeConnection.fConnection.DbcConnection.GetMetadata.SupportsSchemasInDataManipulation; with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetCrossReference(fNativeConnection.fConnection.Catalog, '', '', fNativeConnection.fConnection.Catalog, '', '') do while Next do with ForeignKeys.Add do begin if lSupportedSchema then begin PKTable := GetStringByName('PKTABLE_SCHEM') + '.' + GetStringByName('PKTABLE_NAME'); FKTable := GetStringByName('FKTABLE_SCHEM') + '.' + GetStringByName('FKTABLE_NAME'); end else begin PKTable := GetStringByName('PKTABLE_NAME'); FKTable := GetStringByName('FKTABLE_NAME'); end; PKField := GetStringByName('PKCOLUMN_NAME'); FKField := GetStringByName('FKCOLUMN_NAME'); end; end; end; end; function TDAESampleConnection.GetDatabaseNames: IROStrings; begin case fDriverType of dazMSSQL: Result := MSSQL_GetDatabaseNames(Self); dazMySQL: Result := MYSQL_GetDatabaseNames(GetDatasetClass.Create(Self)); dazPostgreSQL: Result := Postgres_GetDatabaseNames(Self); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then Result := MSSQL_GetDatabaseNames(Self) else begin Result := NewROStrings; with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetCatalogs do while Next do Result.Add(GetStringByName('TABLE_CAT')); end; end; end; function TDAESampleConnection.GetQuoteChars: TDAQuoteCharArray; var s : string; begin Result := inherited GetQuoteChars; case fDriverType of dazMSSQL: Result := MSSQL_GetQuoteChars; else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then Result := MSSQL_GetQuoteChars else begin s := fNativeConnection.fConnection.DbcConnection.GetMetadata.GetIdentifierQuoteString; if Length(s) = 1 then begin Result[0] := s[1]; Result[1] := s[1]; end else if Length(s) = 2 then begin Result[0] := s[1]; Result[1] := s[2]; end end; end; end; function TDAESampleConnection.IdentifierNeedsQuoting( const iIdentifier: string): boolean; var lList : TstringList; i : integer; begin Result:= inherited IdentifierNeedsQuoting(iIdentifier); if not result then case fDriverType of dazMSSQL: Result := MSSQL_IdentifierNeedsQuoting(iIdentifier); dazInterBase: Result := IB_IdentifierNeedsQuoting(iIdentifier, GetSQLDialect); dazMySQL: Result := MYSQL_IdentifierNeedsQuoting(iIdentifier); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then Result := MSSQL_IdentifierNeedsQuoting(iIdentifier) else begin lList := TStringList.Create; try lList.CommaText := fNativeConnection.fConnection.DbcConnection.GetMetadata.GetSQLKeywords + ',' + fNativeConnection.fConnection.DbcConnection.GetMetadata.GetNumericFunctions + ',' + fNativeConnection.fConnection.DbcConnection.GetMetadata.GetStringFunctions + ',' + fNativeConnection.fConnection.DbcConnection.GetMetadata.GetSystemFunctions + ',' + fNativeConnection.fConnection.DbcConnection.GetMetadata.GetTimeDateFunctions; for i := 0 to lList.Count - 1 do if CompareText(llist[i], iIdentifier) = 0 then begin Result := True; Exit; end; finally lList.Free; end end; end; end; function TDAESampleConnection.GetRole: string; begin Result := fNativeConnection.fConnection.Properties.Values['rolename']; end; function TDAESampleConnection.GetSQLDialect: integer; begin Result := StrToIntDef(fNativeConnection.fConnection.Properties.Values['dialect'], -1); if Result = -1 then begin if fDriverName = 'interbase-5' then Result := 1 else Result := 3; end; end; procedure TDAESampleConnection.SetRole(const Value: string); begin fNativeConnection.fConnection.Properties.Values['rolename'] := Value; end; procedure TDAESampleConnection.SetSQLDialect(Value: integer); begin fNativeConnection.fConnection.Properties.Values['dialect'] := IntToStr(Value); end; function TDAESampleConnection.GetCharset: string; begin Result := fNativeConnection.fConnection.Properties.Values['codepage']; end; procedure TDAESampleConnection.SetCharset(const Value: string); begin fNativeConnection.fConnection.Properties.Values['codepage'] := Value; end; procedure TDAESampleConnection.Commit; begin Self.DoCommitTransaction; end; procedure TDAESampleConnection.Rollback; begin Self.DoRollbackTransaction; end; function TDAESampleConnection.DoGetLastAutoInc( const GeneratorName: string): integer; begin Result := -1; case fDriverType of dazMSSQL: Result := MSSQL_DoGetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); dazInterBase: Result := IB_GetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); dazMySQL: Result := MySQL_GetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); dazOracle: Result := Oracle_DoGetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); dazPostgreSQL: Result := Postgres_DoGetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then Result := MSSQL_DoGetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)) else ; end; end; function TDAESampleConnection.GetNextAutoinc( const GeneratorName: string): integer; begin Result := -1; case fDriverType of dazInterBase: Result := IB_GetNextAutoinc(GeneratorName, GetDatasetClass.Create(Self)); dazOracle: Result := Oracle_GetNextAutoinc(GeneratorName, GetDatasetClass.Create(Self)); dazPostgreSQL: Result := Postgres_GetNextAutoInc(GeneratorName, GetDatasetClass.Create(Self)); end; end; procedure TDAESampleConnection.DoGetNames(AList: IROStrings; AObjectType: TDAObjecttype); var lTableTypes : TStringDynArray; lsupportSchema : Boolean; lprocname : string; i : integer; begin fNativeConnection.fConnection.Connect; lsupportSchema := fNativeConnection.fConnection.DbcConnection.GetMetadata.SupportsSchemasInDataManipulation; if AObjectType = dotProcedure then begin with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetProcedures(fNativeConnection.fConnection.Catalog, '', '') do while Next do begin lprocname := GetStringByName('PROCEDURE_NAME'); i := pos(';', lprocname); if i > 0 then lprocname := Copy(lprocname, 1, i - 1); if lsupportSchema then aList.Add(GetStringByName('PROCEDURE_SCHEM') + '.' + lprocname) else aList.Add(lprocname) end; end else begin SetLength(lTableTypes, 1); if AObjectType = dotTable then lTableTypes[0] := 'TABLE' else lTableTypes[0] := 'VIEW'; with fNativeConnection.fConnection.DbcConnection.GetMetadata.GetTables(fNativeConnection.fConnection.Catalog, '', '', lTableTypes) do while Next do if lsupportSchema then aList.Add(GetStringByName('TABLE_SCHEM') + '.' + GetStringByName('TABLE_NAME')) else aList.Add(GetStringByName('TABLE_NAME')) end; end; function TDAESampleConnection.GetSPSelectSyntax( HasArguments: Boolean): string; begin case fDriverType of dazMSSQL: Result := MSSQL_GetSPSelectSyntax(HasArguments); dazInterBase: Result := IB_GetSPSelectSyntax(HasArguments); dazOracle: Result := Oracle_GetSPSelectSyntax(HasArguments); else if (fDriverType = dazADO) and (fADOProviderType in [oledb_MSSQL, oledb_MSSQL2005]) then Result := MSSQL_GetSPSelectSyntax(HasArguments) else begin Result := inherited GetSPSelectSyntax(HasArguments); end; end; end; function TDAESampleConnection.GetCommandTimeout: Integer; begin Result := StrToIntDef(fNativeConnection.fConnection.Properties.Values['timeout'], 0); end; function TDAESampleConnection.GetProviderName: string; begin Result := fADOProviderName; end; function TDAESampleConnection.GetProviderType: TDAOleDBProviderType; begin Result := fADOProviderType; end; procedure TDAESampleConnection.SetCommandTimeout(const Value: Integer); begin fNativeConnection.fConnection.Properties.Values['timeout'] := InttoStr(Value); end; procedure TDAESampleConnection.DoGetStoredProcedureParams( const aStoredProcedureName: string; out Params: TDAParamCollection); begin case fDriverType of dazMySQL: MYSQL_DoGetStoredProcedureParams(aStoredProcedureName, GetDatasetClass.Create(Self), Params, fNativeConnection.fConnection.Catalog); else inherited; end; end; { TDAESampleDriver } procedure TDAESampleDriver.GetAuxDrivers(out List: IROStrings); var i, j : integer; lDrivers : IZCollection; Protocols : TStringDynArray; begin inherited; lDrivers := ZDbcIntfs.DriverManager.GetDrivers; for i := 0 to lDrivers.Count - 1 do begin Protocols := (lDrivers[I] as IZDriver).GetSupportedProtocols; for J := Low(Protocols) to High(Protocols) do List.Add(Protocols[J]); end; List.Sorted := True; end; procedure TDAESampleDriver.GetAuxParams(const AuxDriver: string; out List: IROStrings); var i : TDAOleDBProviderType; s : string; begin inherited; case ZEOSDriverIdToZEOSDriverType(AuxDriver) of dazADO: begin s := ''; for i := Low(TDAOleDBProviderType) to High(TDAOleDBProviderType) do if (i <> oledb_Unknown) {// Redundant but safe if I change the enum later...} then begin if s <> '' then s := s + ';'; s := s + OleDBProviders[i]; end; List.Add('Provider=(' + s + ')'); end; dazInterBase: AddIBAuxParams(List); end; if ZEOSDriverIdToZEOSDriverType(AuxDriver) <> dazAdo then List.Add('Port='); List.Add('timeout='); end; function TDAESampleDriver.GetAvailableDriverOptions: TDAAvailableDriverOptions; begin Result := [doAuxDriver, doServerName, doDatabaseName, doLogin, doCustom]; end; function TDAESampleDriver.GetConnectionClass: TDAEConnectionClass; begin result := TDAESampleConnection; end; function TDAESampleDriver.GetDefaultConnectionType( const AuxDriver: string): string; begin case ZEOSDriverIdToZEOSDriverType(AuxDriver) of dazADO: Result := ''; dazMySQL: Result := MySQL_DriverType; dazIBMDB2: Result:= DB2_DriverType; dazInterBase: Result := MSSQL_DriverType; dazMSSQL: Result := IB_DriverType; dazOracle: Result := Oracle_DriverType; dazPostgreSQL: Result := PostgreSQL_DriverType; dazSQLite : Result:= SQLite_DriverType; dazASA: Result:=ASA_DriverType; dazSybase: Result:=Sybase_DriverType; else Result:= inherited GetDefaultConnectionType(AuxDriver); end; end; function TDAESampleDriver.GetDescription: string; begin result := 'DataAbstact Zeos Driver'; end; function TDAESampleDriver.GetDriverID: string; begin result := 'ZEOS'; end; function TDAESampleDriver.GetProviderDefaultCustomParameters( Provider: string): string; begin Result := ''; case ZEOSDriverIdToZEOSDriverType(Provider) of dazADO: Result := 'Provider=;'; dazMySQL: Result := MYSQL_GetDefaultCustomParameters; end; end; { TDAESampleQuery } function TDAESampleQuery.CreateDataset(aConnection: TDAEConnection): TDataset; begin result := TZReadOnlyQuery.Create(nil); TZReadOnlyQuery(result).Connection := TDAESampleConnection(aConnection).fNativeConnection.fConnection; end; function TDAESampleQuery.DoGetSQL: string; begin result := TZReadOnlyQuery(Dataset).SQL.Text; end; procedure TDAESampleQuery.DoPrepare(Value: boolean); begin // nothing end; procedure TDAESampleQuery.DoSetSQL(const Value: string); begin TZReadOnlyQuery(Dataset).SQL.Text := Value; end; { TDAESampleStoredProcedure } function TDAESampleStoredProcedure.CreateDataset(aConnection: TDAEConnection): TDataset; begin result := TZStoredProc.Create(nil); TZStoredProc(result).Connection := TDAESampleConnection(aConnection).fNativeConnection.fConnection; end; function TDAESampleStoredProcedure.DoGetSQL: string; begin Result := ''; end; procedure TDAESampleStoredProcedure.DoPrepare(Value: boolean); begin // nothing end; procedure TDAESampleStoredProcedure.DoSetSQL(const Value: string); begin // end; function TDAESampleStoredProcedure.GetStoredProcedureName: string; begin Result := TZStoredProc(result).StoredProcName; end; procedure TDAESampleStoredProcedure.SetStoredProcedureName( const Name: string); begin TZStoredProc(Dataset).StoredProcName := Name; end; { TZEOSConnection } constructor TZEOSConnection.Create(AOwner: TComponent); begin inherited; fConnection := TZConnection.Create(self); fConnection.LoginPrompt := False; fMetaData := TZSQLMetaData.Create(Self); fMetaData.Connection := fConnection; end; function TZEOSConnection.GetConnected: Boolean; begin Result := fConnection.Connected; end; procedure TZEOSConnection.SetConnected(Value: boolean); begin fConnection.Connected := Value; end; exports GetDriverObject name func_GetDriverObject; initialization {$IFDEF FPC} {$I DataAbstract_ZeosDriver_Glyphs.lrs} {$ENDIF} _driver := nil; RegisterDriverProc(GetDriverObject); finalization UnregisterDriverProc(GetDriverObject); FreeAndNIL(_driver); end.