1 {*********************************************************}
3 { Zeos Database Objects }
4 { Ado metadata information }
6 { Originally written by Janos Fegyverneki }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
59 Types, Classes, SysUtils, ZSysUtils, ZClasses, ZDbcIntfs, ZDbcMetadata,
60 ZDbcResultSet, ZDbcCachedResultSet, ZDbcResultsetMetadata, ZURL,
61 ZCompatibility, ZGenericSqlAnalyser, ZPlainAdo, ZDbcConnection;
64 // technobot 2008-06-27 - methods moved as is from TZAdoDatabaseMetadata:
65 {** Implements Ado Database Information. }
66 TZAdoDatabaseInfo = class(TZAbstractDatabaseInfo)
68 constructor Create(const Metadata: TZAbstractDatabaseMetadata);
70 // database/driver/server info:
71 function GetDatabaseProductName: string; override;
72 function GetDatabaseProductVersion: string; override;
73 function GetDriverName: string; override;
74 // function GetDriverVersion: string; override; -> Same as parent
75 function GetDriverMajorVersion: Integer; override;
76 function GetDriverMinorVersion: Integer; override;
77 // function GetServerVersion: string; -> Not implemented
79 // capabilities (what it can/cannot do):
80 // function AllProceduresAreCallable: Boolean; override; -> Not implemented
81 // function AllTablesAreSelectable: Boolean; override; -> Not implemented
82 function SupportsMixedCaseIdentifiers: Boolean; override;
83 function SupportsMixedCaseQuotedIdentifiers: Boolean; override;
84 // function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented
85 // function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented
86 // function SupportsColumnAliasing: Boolean; override; -> Not implemented
87 // function SupportsConvert: Boolean; override; -> Not implemented
88 // function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):
89 // Boolean; override; -> Not implemented
90 // function SupportsTableCorrelationNames: Boolean; override; -> Not implemented
91 // function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented
92 function SupportsExpressionsInOrderBy: Boolean; override;
93 function SupportsOrderByUnrelated: Boolean; override;
94 function SupportsGroupBy: Boolean; override;
95 function SupportsGroupByUnrelated: Boolean; override;
96 function SupportsGroupByBeyondSelect: Boolean; override;
97 // function SupportsLikeEscapeClause: Boolean; override; -> Not implemented
98 // function SupportsMultipleResultSets: Boolean; override; -> Not implemented
99 // function SupportsMultipleTransactions: Boolean; override; -> Not implemented
100 // function SupportsNonNullableColumns: Boolean; override; -> Not implemented
101 // function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented
102 // function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented
103 // function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented
104 // function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented
105 // function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented
106 // function SupportsANSI92FullSQL: Boolean; override; -> Not implemented
107 function SupportsIntegrityEnhancementFacility: Boolean; override;
108 // function SupportsOuterJoins: Boolean; override; -> Not implemented
109 // function SupportsFullOuterJoins: Boolean; override; -> Not implemented
110 // function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented
111 function SupportsSchemasInDataManipulation: Boolean; override;
112 function SupportsSchemasInProcedureCalls: Boolean; override;
113 function SupportsSchemasInTableDefinitions: Boolean; override;
114 function SupportsSchemasInIndexDefinitions: Boolean; override;
115 function SupportsSchemasInPrivilegeDefinitions: Boolean; override;
116 function SupportsCatalogsInDataManipulation: Boolean; override;
117 function SupportsCatalogsInProcedureCalls: Boolean; override;
118 function SupportsCatalogsInTableDefinitions: Boolean; override;
119 function SupportsCatalogsInIndexDefinitions: Boolean; override;
120 function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;
121 function SupportsOverloadPrefixInStoredProcedureName: Boolean; override;
122 function SupportsPositionedDelete: Boolean; override;
123 function SupportsPositionedUpdate: Boolean; override;
124 function SupportsSelectForUpdate: Boolean; override;
125 function SupportsStoredProcedures: Boolean; override;
126 function SupportsSubqueriesInComparisons: Boolean; override;
127 function SupportsSubqueriesInExists: Boolean; override;
128 function SupportsSubqueriesInIns: Boolean; override;
129 function SupportsSubqueriesInQuantifieds: Boolean; override;
130 function SupportsCorrelatedSubqueries: Boolean; override;
131 function SupportsUnion: Boolean; override;
132 function SupportsUnionAll: Boolean; override;
133 function SupportsOpenCursorsAcrossCommit: Boolean; override;
134 function SupportsOpenCursorsAcrossRollback: Boolean; override;
135 function SupportsOpenStatementsAcrossCommit: Boolean; override;
136 function SupportsOpenStatementsAcrossRollback: Boolean; override;
137 function SupportsTransactions: Boolean; override;
138 function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):
140 function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;
141 function SupportsDataManipulationTransactionsOnly: Boolean; override;
142 function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;
143 function SupportsResultSetConcurrency(_Type: TZResultSetType;
144 Concurrency: TZResultSetConcurrency): Boolean; override;
145 // function SupportsBatchUpdates: Boolean; override; -> Not implemented
146 function SupportsNonEscapedSearchStrings: Boolean; override;
147 function SupportsUpdateAutoIncrementFields: Boolean; override;
150 function GetMaxBinaryLiteralLength: Integer; override;
151 function GetMaxCharLiteralLength: Integer; override;
152 function GetMaxColumnNameLength: Integer; override;
153 function GetMaxColumnsInGroupBy: Integer; override;
154 function GetMaxColumnsInIndex: Integer; override;
155 function GetMaxColumnsInOrderBy: Integer; override;
156 function GetMaxColumnsInSelect: Integer; override;
157 function GetMaxColumnsInTable: Integer; override;
158 function GetMaxConnections: Integer; override;
159 function GetMaxCursorNameLength: Integer; override;
160 function GetMaxIndexLength: Integer; override;
161 function GetMaxSchemaNameLength: Integer; override;
162 function GetMaxProcedureNameLength: Integer; override;
163 function GetMaxCatalogNameLength: Integer; override;
164 function GetMaxRowSize: Integer; override;
165 function GetMaxStatementLength: Integer; override;
166 function GetMaxStatements: Integer; override;
167 function GetMaxTableNameLength: Integer; override;
168 function GetMaxTablesInSelect: Integer; override;
169 function GetMaxUserNameLength: Integer; override;
171 // policies (how are various data and operations handled):
172 // function IsReadOnly: Boolean; override; -> Not implemented
173 // function IsCatalogAtStart: Boolean; override; -> Not implemented
174 function DoesMaxRowSizeIncludeBlobs: Boolean; override;
175 // function NullsAreSortedHigh: Boolean; override; -> Not implemented
176 // function NullsAreSortedLow: Boolean; override; -> Not implemented
177 // function NullsAreSortedAtStart: Boolean; override; -> Not implemented
178 // function NullsAreSortedAtEnd: Boolean; override; -> Not implemented
179 // function NullPlusNonNullIsNull: Boolean; override; -> Not implemented
180 // function UsesLocalFiles: Boolean; override; -> Not implemented
181 function UsesLocalFilePerTable: Boolean; override;
182 function StoresUpperCaseIdentifiers: Boolean; override;
183 function StoresLowerCaseIdentifiers: Boolean; override;
184 function StoresMixedCaseIdentifiers: Boolean; override;
185 function StoresUpperCaseQuotedIdentifiers: Boolean; override;
186 function StoresLowerCaseQuotedIdentifiers: Boolean; override;
187 function StoresMixedCaseQuotedIdentifiers: Boolean; override;
188 function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;
189 function DataDefinitionCausesTransactionCommit: Boolean; override;
190 function DataDefinitionIgnoredInTransactions: Boolean; override;
192 // interface details (terms, keywords, etc):
193 function GetSchemaTerm: string; override;
194 function GetProcedureTerm: string; override;
195 function GetCatalogTerm: string; override;
196 function GetCatalogSeparator: string; override;
197 function GetSQLKeywords: string; override;
198 function GetNumericFunctions: string; override;
199 function GetStringFunctions: string; override;
200 function GetSystemFunctions: string; override;
201 function GetTimeDateFunctions: string; override;
202 function GetSearchStringEscape: string; override;
203 function GetExtraNameCharacters: string; override;
206 {** Implements Ado Metadata. }
207 TZAdoDatabaseMetadata = class(TZAbstractDatabaseMetadata)
209 FAdoConnection: ZPlainAdo.Connection;
210 FSupportedSchemasInitialized: Boolean;
211 function AdoOpenSchema(Schema: Integer; const Args: array of const): ZPlainAdo.RecordSet;
212 procedure InitializeSchemas;
213 function SchemaSupported(SchemaId: Integer): Boolean; // (technobot) should be moved to TZAdoDatabaseInfo?
214 function FindSchema(SchemaId: Integer): Integer;
215 function BuildRestrictions(SchemaId: Integer; const Args: array of const): Variant;
217 function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-27
218 function DecomposeObjectString(const S: String): String; override;
220 function UncachedGetTables(const Catalog: string; const SchemaPattern: string;
221 const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;
222 function UncachedGetSchemas: IZResultSet; override;
223 function UncachedGetCatalogs: IZResultSet; override;
224 function UncachedGetTableTypes: IZResultSet; override;
225 function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;
226 const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;
227 function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;
228 const TableNamePattern: string): IZResultSet; override;
229 function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;
230 const Table: string; const ColumnNamePattern: string): IZResultSet; override;
231 function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;
232 const Table: string): IZResultSet; override;
233 function UncachedGetImportedKeys(const Catalog: string; const Schema: string;
234 const Table: string): IZResultSet; override;
235 function UncachedGetExportedKeys(const Catalog: string; const Schema: string;
236 const Table: string): IZResultSet; override;
237 function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;
238 const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
239 const ForeignTable: string): IZResultSet; override;
240 function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;
241 Unique: Boolean; Approximate: Boolean): IZResultSet; override;
242 // function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;
243 // const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented
244 function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;
245 const ProcedureNamePattern: string): IZResultSet; override;
246 function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;
247 const ProcedureNamePattern: string; const ColumnNamePattern: string):
248 IZResultSet; override;
249 function UncachedGetVersionColumns(const Catalog: string; const Schema: string;
250 const Table: string): IZResultSet; override;
251 function UncachedGetTypeInfo: IZResultSet; override;
252 function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
253 const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;
255 constructor Create(Connection: TZAbstractConnection; const Url: TZURL); override;
256 destructor Destroy; override;
258 // function GetTokenizer: IZTokenizer; override;
267 Math, ZDbcUtils, ZCollections, ZGenericSqlToken, ZDbcAdoUtils, ZDbcAdo,
268 OleDB, ZDbcAdoResultSet;
271 TSuppSchemaRec = record
273 SupportedRestrictions: Integer;
274 AdoSchemaId: Integer;
277 IDBSchemaRowset = interface(IUnknown)
278 ['{0c733a7b-2a1c-11ce-ade5-00aa0044773d}']
280 pUnkOuter : IUnknown;
281 const rguidSchema : TGUID;
282 cRestrictions : Integer;
283 var rgRestrictions : PVariant;{!!was: const VARIANT __RPC_FAR rgRestrictions[ ],}
284 const riid : IUnknown;
285 cPropertySets : Integer;
286 var rgPropertySets : TDBPROPSET;
287 var ppRowset : IUnknown) : HResult; stdcall;
289 var pcSchemas : Integer;
290 var prgSchemas : PGUID;
291 var prgRestrictionSupport : PInteger) : HResult; stdcall;
295 SupportedSchemas: array of TSuppSchemaRec;
297 { TZAdoDatabaseInfo }
300 Constructs this object.
301 @param Metadata the interface of the correpsonding database metadata object
302 @param IdentifierQuotes the default Quotes for Identifiers used by the driver
304 constructor TZAdoDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);
306 inherited Create(MetaData, '[]');
309 //----------------------------------------------------------------------
310 // First, a variety of minor information about the target database.
313 What's the name of this database product?
314 @return database product name
316 function TZAdoDatabaseInfo.GetDatabaseProductName: string;
322 What's the version of this database product?
323 @return database version
325 function TZAdoDatabaseInfo.GetDatabaseProductVersion: string;
327 Result := (Metadata.GetConnection as IZAdoConnection).GetAdoConnection.Version;
331 What's the name of this JDBC driver?
332 @return JDBC driver name
334 function TZAdoDatabaseInfo.GetDriverName: string;
336 Result := 'Zeos Database Connectivity Driver for Microsoft ADO';
340 What's this JDBC driver's major version number?
341 @return JDBC driver major version
343 function TZAdoDatabaseInfo.GetDriverMajorVersion: Integer;
349 What's this JDBC driver's minor version number?
350 @return JDBC driver minor version number
352 function TZAdoDatabaseInfo.GetDriverMinorVersion: Integer;
358 Does the database use a file for each table?
359 @return true if the database uses a local file for each table
361 function TZAdoDatabaseInfo.UsesLocalFilePerTable: Boolean;
367 Does the database treat mixed case unquoted SQL identifiers as
368 case sensitive and as a result store them in mixed case?
369 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will
371 @return <code>true</code> if so; <code>false</code> otherwise
373 function TZAdoDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;
379 Does the database treat mixed case unquoted SQL identifiers as
380 case insensitive and store them in upper case?
381 @return <code>true</code> if so; <code>false</code> otherwise
383 function TZAdoDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;
389 Does the database treat mixed case unquoted SQL identifiers as
390 case insensitive and store them in lower case?
391 @return <code>true</code> if so; <code>false</code> otherwise
393 function TZAdoDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;
399 Does the database treat mixed case unquoted SQL identifiers as
400 case insensitive and store them in mixed case?
401 @return <code>true</code> if so; <code>false</code> otherwise
403 function TZAdoDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;
409 Does the database treat mixed case quoted SQL identifiers as
410 case sensitive and as a result store them in mixed case?
411 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.
412 @return <code>true</code> if so; <code>false</code> otherwise
414 function TZAdoDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;
420 Does the database treat mixed case quoted SQL identifiers as
421 case insensitive and store them in upper case?
422 @return <code>true</code> if so; <code>false</code> otherwise
424 function TZAdoDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;
430 Does the database treat mixed case quoted SQL identifiers as
431 case insensitive and store them in lower case?
432 @return <code>true</code> if so; <code>false</code> otherwise
434 function TZAdoDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;
440 Does the database treat mixed case quoted SQL identifiers as
441 case insensitive and store them in mixed case?
442 @return <code>true</code> if so; <code>false</code> otherwise
444 function TZAdoDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;
450 Gets a comma-separated list of all a database's SQL keywords
451 that are NOT also SQL92 keywords.
454 function TZAdoDatabaseInfo.GetSQLKeywords: string;
456 { TODO -ofjanos -cAPI : SQL Keywords that are not SQL92 compliant }
461 Gets a comma-separated list of math functions. These are the
462 X/Open CLI math function names used in the JDBC function escape
466 function TZAdoDatabaseInfo.GetNumericFunctions: string;
468 Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,'+
469 'PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQUARE,SQRT,TAN';
473 Gets a comma-separated list of string functions. These are the
474 X/Open CLI string function names used in the JDBC function escape
478 function TZAdoDatabaseInfo.GetStringFunctions: string;
480 Result := 'ASCII,CHAR,CHARINDEX,DIFFERENCE,LEFT,LEN,LOWER,LTRIM,NCHAR,PATINDEX,'+
481 'REPLACE,QUOTENAME,REPLICATE,REVERSE,RIGHT,RTRIM,SOUNDEX,SPACE,STR,'+
482 'STUFF,SUBSTRING,UNICODE,UPPER';
486 Gets a comma-separated list of system functions. These are the
487 X/Open CLI system function names used in the JDBC function escape
491 function TZAdoDatabaseInfo.GetSystemFunctions: string;
493 Result := 'APP_NAME,CASE,CAST,CONVERT,COALESCE,CURRENT_TIMESTAMP,CURRENT_USER,'+
494 'DATALENGTH,@@ERROR,FORMATMESSAGE,GETANSINULL,HOST_ID,HOST_NAME,'+
495 'IDENT_INCR,IDENT_SEED,@@IDENTITY,IDENTITY,ISDATE,ISNULL,ISNUMERIC,'+
496 'NEWID,NULLIF,PARSENAME,PERMISSIONS,@@ROWCOUNT,SESSION_USER,STATS_DATE,'+
497 'SYSTEM_USER,@@TRANCOUNT,USER_NAME';
501 Gets a comma-separated list of time and date functions.
504 function TZAdoDatabaseInfo.GetTimeDateFunctions: string;
506 Result := 'DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,GETDATE,MONTH,YEAR';
510 Gets the string that can be used to escape wildcard characters.
511 This is the string that can be used to escape '_' or '%' in
512 the string pattern style catalog search parameters.
514 <P>The '_' character represents any single character.
515 <P>The '%' character represents any sequence of zero or
518 @return the string used to escape wildcard characters
520 function TZAdoDatabaseInfo.GetSearchStringEscape: string;
522 { TODO -ofjanos -cgeneral :
523 In sql server this must be specified as the parameter of like.
524 example: WHERE ColumnA LIKE '%5/%%' ESCAPE '/' }
529 Gets all the "extra" characters that can be used in unquoted
530 identifier names (those beyond a-z, A-Z, 0-9 and _).
531 @return the string containing the extra characters
533 function TZAdoDatabaseInfo.GetExtraNameCharacters: string;
538 //--------------------------------------------------------------------
539 // Functions describing which features are supported.
542 Are expressions in "ORDER BY" lists supported?
543 @return <code>true</code> if so; <code>false</code> otherwise
545 function TZAdoDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;
551 Can an "ORDER BY" clause use columns not in the SELECT statement?
552 @return <code>true</code> if so; <code>false</code> otherwise
554 function TZAdoDatabaseInfo.SupportsOrderByUnrelated: Boolean;
560 Is some form of "GROUP BY" clause supported?
561 @return <code>true</code> if so; <code>false</code> otherwise
563 function TZAdoDatabaseInfo.SupportsGroupBy: Boolean;
569 Can a "GROUP BY" clause use columns not in the SELECT?
570 @return <code>true</code> if so; <code>false</code> otherwise
572 function TZAdoDatabaseInfo.SupportsGroupByUnrelated: Boolean;
578 Can a "GROUP BY" clause add columns not in the SELECT
579 provided it specifies all the columns in the SELECT?
580 @return <code>true</code> if so; <code>false</code> otherwise
582 function TZAdoDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;
588 Is the SQL Integrity Enhancement Facility supported?
589 @return <code>true</code> if so; <code>false</code> otherwise
591 function TZAdoDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;
597 What's the database vendor's preferred term for "schema"?
598 @return the vendor term
600 function TZAdoDatabaseInfo.GetSchemaTerm: string;
606 What's the database vendor's preferred term for "procedure"?
607 @return the vendor term
609 function TZAdoDatabaseInfo.GetProcedureTerm: string;
611 Result := 'procedure';
615 What's the database vendor's preferred term for "catalog"?
616 @return the vendor term
618 function TZAdoDatabaseInfo.GetCatalogTerm: string;
620 Result := 'database';
624 What's the separator between catalog and table name?
625 @return the separator string
627 function TZAdoDatabaseInfo.GetCatalogSeparator: string;
633 Can a schema name be used in a data manipulation statement?
634 @return <code>true</code> if so; <code>false</code> otherwise
636 function TZAdoDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;
642 Can a schema name be used in a procedure call statement?
643 @return <code>true</code> if so; <code>false</code> otherwise
645 function TZAdoDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;
651 Can a schema name be used in a table definition statement?
652 @return <code>true</code> if so; <code>false</code> otherwise
654 function TZAdoDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;
660 Can a schema name be used in an index definition statement?
661 @return <code>true</code> if so; <code>false</code> otherwise
663 function TZAdoDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;
669 Can a schema name be used in a privilege definition statement?
670 @return <code>true</code> if so; <code>false</code> otherwise
672 function TZAdoDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;
678 Can a catalog name be used in a data manipulation statement?
679 @return <code>true</code> if so; <code>false</code> otherwise
681 function TZAdoDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;
687 Can a catalog name be used in a procedure call statement?
688 @return <code>true</code> if so; <code>false</code> otherwise
690 function TZAdoDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;
696 Can a catalog name be used in a table definition statement?
697 @return <code>true</code> if so; <code>false</code> otherwise
699 function TZAdoDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;
705 Can a catalog name be used in an index definition statement?
706 @return <code>true</code> if so; <code>false</code> otherwise
708 function TZAdoDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;
714 Can a catalog name be used in a privilege definition statement?
715 @return <code>true</code> if so; <code>false</code> otherwise
717 function TZAdoDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;
723 Can a stored procedure have an additional overload suffix?
724 @return <code>true</code> if so; <code>false</code> otherwise
726 function TZAdoDatabaseInfo.SupportsOverloadPrefixInStoredProcedureName: Boolean;
732 Is positioned DELETE supported?
733 @return <code>true</code> if so; <code>false</code> otherwise
735 function TZAdoDatabaseInfo.SupportsPositionedDelete: Boolean;
738 //Specifies that the DELETE is done at the current position of the specified cursor.
743 Is positioned UPDATE supported?
744 @return <code>true</code> if so; <code>false</code> otherwise
746 function TZAdoDatabaseInfo.SupportsPositionedUpdate: Boolean;
752 Is SELECT for UPDATE supported?
753 @return <code>true</code> if so; <code>false</code> otherwise
755 function TZAdoDatabaseInfo.SupportsSelectForUpdate: Boolean;
761 Are stored procedure calls using the stored procedure escape
763 @return <code>true</code> if so; <code>false</code> otherwise
765 function TZAdoDatabaseInfo.SupportsStoredProcedures: Boolean;
771 Are subqueries in comparison expressions supported?
772 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
773 @return <code>true</code> if so; <code>false</code> otherwise
775 function TZAdoDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;
781 Are subqueries in 'exists' expressions supported?
782 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
783 @return <code>true</code> if so; <code>false</code> otherwise
785 function TZAdoDatabaseInfo.SupportsSubqueriesInExists: Boolean;
791 Are subqueries in 'in' statements supported?
792 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
793 @return <code>true</code> if so; <code>false</code> otherwise
795 function TZAdoDatabaseInfo.SupportsSubqueriesInIns: Boolean;
801 Are subqueries in quantified expressions supported?
802 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
803 @return <code>true</code> if so; <code>false</code> otherwise
805 function TZAdoDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;
811 Are correlated subqueries supported?
812 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
813 @return <code>true</code> if so; <code>false</code> otherwise
815 function TZAdoDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;
821 Is SQL UNION supported?
822 @return <code>true</code> if so; <code>false</code> otherwise
824 function TZAdoDatabaseInfo.SupportsUnion: Boolean;
830 Is SQL UNION ALL supported?
831 @return <code>true</code> if so; <code>false</code> otherwise
833 function TZAdoDatabaseInfo.SupportsUnionAll: Boolean;
839 Can cursors remain open across commits?
840 @return <code>true</code> if cursors always remain open;
841 <code>false</code> if they might not remain open
843 function TZAdoDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;
849 Can cursors remain open across rollbacks?
850 @return <code>true</code> if cursors always remain open;
851 <code>false</code> if they might not remain open
853 function TZAdoDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;
859 Can statements remain open across commits?
860 @return <code>true</code> if statements always remain open;
861 <code>false</code> if they might not remain open
863 function TZAdoDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;
869 Can statements remain open across rollbacks?
870 @return <code>true</code> if statements always remain open;
871 <code>false</code> if they might not remain open
873 function TZAdoDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;
878 //----------------------------------------------------------------------
879 // The following group of methods exposes various limitations
880 // based on the target database with the current driver.
881 // Unless otherwise specified, a result of zero means there is no
882 // limit, or the limit is not known.
885 How many hex characters can you have in an inline binary literal?
886 @return max binary literal length in hex characters;
887 a result of zero means that there is no limit or the limit is not known
889 function TZAdoDatabaseInfo.GetMaxBinaryLiteralLength: Integer;
895 What's the max length for a character literal?
896 @return max literal length;
897 a result of zero means that there is no limit or the limit is not known
899 function TZAdoDatabaseInfo.GetMaxCharLiteralLength: Integer;
905 What's the limit on column name length?
906 @return max column name length;
907 a result of zero means that there is no limit or the limit is not known
909 function TZAdoDatabaseInfo.GetMaxColumnNameLength: Integer;
915 What's the maximum number of columns in a "GROUP BY" clause?
916 @return max number of columns;
917 a result of zero means that there is no limit or the limit is not known
919 function TZAdoDatabaseInfo.GetMaxColumnsInGroupBy: Integer;
925 What's the maximum number of columns allowed in an index?
926 @return max number of columns;
927 a result of zero means that there is no limit or the limit is not known
929 function TZAdoDatabaseInfo.GetMaxColumnsInIndex: Integer;
935 What's the maximum number of columns in an "ORDER BY" clause?
936 @return max number of columns;
937 a result of zero means that there is no limit or the limit is not known
939 function TZAdoDatabaseInfo.GetMaxColumnsInOrderBy: Integer;
945 What's the maximum number of columns in a "SELECT" list?
946 @return max number of columns;
947 a result of zero means that there is no limit or the limit is not known
949 function TZAdoDatabaseInfo.GetMaxColumnsInSelect: Integer;
955 What's the maximum number of columns in a table?
956 @return max number of columns;
957 a result of zero means that there is no limit or the limit is not known
959 function TZAdoDatabaseInfo.GetMaxColumnsInTable: Integer;
965 How many active connections can we have at a time to this database?
966 @return max number of active connections;
967 a result of zero means that there is no limit or the limit is not known
969 function TZAdoDatabaseInfo.GetMaxConnections: Integer;
975 What's the maximum cursor name length?
976 @return max cursor name length in bytes;
977 a result of zero means that there is no limit or the limit is not known
979 function TZAdoDatabaseInfo.GetMaxCursorNameLength: Integer;
985 Retrieves the maximum number of bytes for an index, including all
986 of the parts of the index.
987 @return max index length in bytes, which includes the composite of all
988 the constituent parts of the index;
989 a result of zero means that there is no limit or the limit is not known
991 function TZAdoDatabaseInfo.GetMaxIndexLength: Integer;
997 What's the maximum length allowed for a schema name?
998 @return max name length in bytes;
999 a result of zero means that there is no limit or the limit is not known
1001 function TZAdoDatabaseInfo.GetMaxSchemaNameLength: Integer;
1007 What's the maximum length of a procedure name?
1008 @return max name length in bytes;
1009 a result of zero means that there is no limit or the limit is not known
1011 function TZAdoDatabaseInfo.GetMaxProcedureNameLength: Integer;
1017 What's the maximum length of a catalog name?
1018 @return max name length in bytes;
1019 a result of zero means that there is no limit or the limit is not known
1021 function TZAdoDatabaseInfo.GetMaxCatalogNameLength: Integer;
1027 What's the maximum length of a single row?
1028 @return max row size in bytes;
1029 a result of zero means that there is no limit or the limit is not known
1031 function TZAdoDatabaseInfo.GetMaxRowSize: Integer;
1037 Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1039 @return <code>true</code> if so; <code>false</code> otherwise
1041 function TZAdoDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;
1047 What's the maximum length of an SQL statement?
1048 @return max length in bytes;
1049 a result of zero means that there is no limit or the limit is not known
1051 function TZAdoDatabaseInfo.GetMaxStatementLength: Integer;
1057 How many active statements can we have open at one time to this
1059 @return the maximum number of statements that can be open at one time;
1060 a result of zero means that there is no limit or the limit is not known
1062 function TZAdoDatabaseInfo.GetMaxStatements: Integer;
1068 What's the maximum length of a table name?
1069 @return max name length in bytes;
1070 a result of zero means that there is no limit or the limit is not known
1072 function TZAdoDatabaseInfo.GetMaxTableNameLength: Integer;
1078 What's the maximum number of tables in a SELECT statement?
1079 @return the maximum number of tables allowed in a SELECT statement;
1080 a result of zero means that there is no limit or the limit is not known
1082 function TZAdoDatabaseInfo.GetMaxTablesInSelect: Integer;
1088 What's the maximum length of a user name?
1089 @return max user name length in bytes;
1090 a result of zero means that there is no limit or the limit is not known
1092 function TZAdoDatabaseInfo.GetMaxUserNameLength: Integer;
1097 //----------------------------------------------------------------------
1100 What's the database's default transaction isolation level? The
1101 values are defined in <code>java.sql.Connection</code>.
1102 @return the default isolation level
1105 function TZAdoDatabaseInfo.GetDefaultTransactionIsolation:
1106 TZTransactIsolationLevel;
1108 Result := tiReadCommitted;
1112 Are transactions supported? If not, invoking the method
1113 <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.
1114 @return <code>true</code> if transactions are supported; <code>false</code> otherwise
1116 function TZAdoDatabaseInfo.SupportsTransactions: Boolean;
1122 Does this database support the given transaction isolation level?
1123 @param level the values are defined in <code>java.sql.Connection</code>
1124 @return <code>true</code> if so; <code>false</code> otherwise
1127 function TZAdoDatabaseInfo.SupportsTransactionIsolationLevel(
1128 Level: TZTransactIsolationLevel): Boolean;
1134 Are both data definition and data manipulation statements
1135 within a transaction supported?
1136 @return <code>true</code> if so; <code>false</code> otherwise
1138 function TZAdoDatabaseInfo.
1139 SupportsDataDefinitionAndDataManipulationTransactions: Boolean;
1145 Are only data manipulation statements within a transaction
1147 @return <code>true</code> if so; <code>false</code> otherwise
1149 function TZAdoDatabaseInfo.
1150 SupportsDataManipulationTransactionsOnly: Boolean;
1156 Does a data definition statement within a transaction force the
1157 transaction to commit?
1158 @return <code>true</code> if so; <code>false</code> otherwise
1160 function TZAdoDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;
1166 Is a data definition statement within a transaction ignored?
1167 @return <code>true</code> if so; <code>false</code> otherwise
1169 function TZAdoDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;
1175 Does the database support the given result set type?
1176 @param type defined in <code>java.sql.ResultSet</code>
1177 @return <code>true</code> if so; <code>false</code> otherwise
1179 function TZAdoDatabaseInfo.SupportsResultSetType(
1180 _Type: TZResultSetType): Boolean;
1186 Does the database support the concurrency type in combination
1187 with the given result set type?
1189 @param type defined in <code>java.sql.ResultSet</code>
1190 @param concurrency type defined in <code>java.sql.ResultSet</code>
1191 @return <code>true</code> if so; <code>false</code> otherwise
1193 function TZAdoDatabaseInfo.SupportsResultSetConcurrency(
1194 _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;
1200 Does the Database or Actual Version understand non escaped search strings?
1201 @return <code>true</code> if the DataBase does understand non escaped
1204 function TZAdoDatabaseInfo.SupportsNonEscapedSearchStrings: Boolean;
1210 Does the Database support updating auto incremental fields?
1211 @return <code>true</code> if the DataBase allows it.
1213 function TZAdoDatabaseInfo.SupportsUpdateAutoIncrementFields: Boolean;
1218 { TZAdoDatabaseMetadata }
1222 Constructs this object and assignes the main properties.
1223 @param Connection a database connection object.
1224 @param Url a database connection url string.
1225 @param Info an extra connection properties.
1227 constructor TZAdoDatabaseMetadata.Create(Connection: TZAbstractConnection;
1230 inherited Create(Connection, Url);
1231 FAdoConnection := nil;
1235 Destroys this object and cleanups the memory.
1237 destructor TZAdoDatabaseMetadata.Destroy;
1243 Constructs a database information object and returns the interface to it. Used
1244 internally by the constructor.
1245 @return the database information object interface
1247 function TZAdoDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;
1249 Result := TZAdoDatabaseInfo.Create(Self);
1252 function TZAdoDatabaseMetadata.DecomposeObjectString(const S: String): String;
1257 if IC.IsQuoted(S) then
1258 Result := IC.ExtractQuote(S)
1263 Gets a description of the stored procedures available in a
1266 <P>Only procedure descriptions matching the schema and
1267 procedure name criteria are returned. They are ordered by
1268 PROCEDURE_SCHEM, and PROCEDURE_NAME.
1270 <P>Each procedure description has the the following columns:
1272 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1273 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1274 <LI><B>PROCEDURE_NAME</B> String => procedure name
1275 <LI> reserved for future use
1276 <LI> reserved for future use
1277 <LI> reserved for future use
1278 <LI><B>REMARKS</B> String => explanatory comment on the procedure
1279 <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1281 <LI> procedureResultUnknown - May return a result
1282 <LI> procedureNoResult - Does not return a result
1283 <LI> procedureReturnsResult - Returns a result
1287 @param catalog a catalog name; "" retrieves those without a
1288 catalog; null means drop catalog name from the selection criteria
1289 @param schemaPattern a schema name pattern; "" retrieves those
1291 @param procedureNamePattern a procedure name pattern
1292 @return <code>ResultSet</code> - each row is a procedure description
1293 @see #getSearchStringEscape
1295 function TZAdoDatabaseMetadata.UncachedGetProcedures(const Catalog: string;
1296 const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;
1298 AdoRecordSet: ZPlainAdo.RecordSet;
1300 Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);
1302 AdoRecordSet := AdoOpenSchema(adSchemaProcedures,
1303 [Catalog, SchemaPattern, ProcedureNamePattern, '']);
1304 if Assigned(AdoRecordSet) then
1306 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1310 Result.MoveToInsertRow;
1311 Result.UpdateStringByName('PROCEDURE_CAT',
1312 GetStringByName('PROCEDURE_CATALOG'));
1313 Result.UpdateStringByName('PROCEDURE_SCHEM',
1314 GetStringByName('PROCEDURE_SCHEMA'));
1315 Result.UpdateStringByName('PROCEDURE_NAME',
1316 GetStringByName('PROCEDURE_NAME'));
1317 Result.UpdateStringByName('REMARKS',
1318 GetStringByName('DESCRIPTION'));
1319 Result.UpdateShortByName('PROCEDURE_TYPE',
1320 GetShortByName('PROCEDURE_TYPE') - 1);
1330 Gets a description of a catalog's stored procedure parameters
1333 <P>Only descriptions matching the schema, procedure and
1334 parameter name criteria are returned. They are ordered by
1335 PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1336 if any, is first. Next are the parameter descriptions in call
1337 order. The column descriptions follow in column number order.
1339 <P>Each row in the <code>ResultSet</code> is a parameter description or
1340 column description with the following fields:
1342 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1343 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1344 <LI><B>PROCEDURE_NAME</B> String => procedure name
1345 <LI><B>COLUMN_NAME</B> String => column/parameter name
1346 <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1348 <LI> procedureColumnUnknown - nobody knows
1349 <LI> procedureColumnIn - IN parameter
1350 <LI> procedureColumnInOut - INOUT parameter
1351 <LI> procedureColumnOut - OUT parameter
1352 <LI> procedureColumnReturn - procedure return value
1353 <LI> procedureColumnResult - result column in <code>ResultSet</code>
1355 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1356 <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
1357 type name is fully qualified
1358 <LI><B>PRECISION</B> int => precision
1359 <LI><B>LENGTH</B> int => length in bytes of data
1360 <LI><B>SCALE</B> short => scale
1361 <LI><B>RADIX</B> short => radix
1362 <LI><B>NULLABLE</B> short => can it contain NULL?
1364 <LI> procedureNoNulls - does not allow NULL values
1365 <LI> procedureNullable - allows NULL values
1366 <LI> procedureNullableUnknown - nullability unknown
1368 <LI><B>REMARKS</B> String => comment describing parameter/column
1371 <P><B>Note:</B> Some databases may not return the column
1372 descriptions for a procedure. Additional columns beyond
1373 REMARKS can be defined by the database.
1375 @param catalog a catalog name; "" retrieves those without a
1376 catalog; null means drop catalog name from the selection criteria
1377 @param schemaPattern a schema name pattern; "" retrieves those
1379 @param procedureNamePattern a procedure name pattern
1380 @param columnNamePattern a column name pattern
1381 @return <code>ResultSet</code> - each row describes a stored procedure parameter or
1383 @see #getSearchStringEscape
1385 function TZAdoDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;
1386 const SchemaPattern: string; const ProcedureNamePattern: string;
1387 const ColumnNamePattern: string): IZResultSet;
1389 AdoRecordSet: ZPlainAdo.RecordSet;
1391 Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);
1393 AdoRecordSet := AdoOpenSchema(adSchemaProcedureParameters,
1394 [Catalog, SchemaPattern, ProcedureNamePattern]);
1395 if Assigned(AdoRecordSet) then
1397 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1401 Result.MoveToInsertRow;
1402 Result.UpdateStringByName('PROCEDURE_CAT',
1403 GetStringByName('PROCEDURE_CATALOG'));
1404 Result.UpdateStringByName('PROCEDURE_SCHEM',
1405 GetStringByName('PROCEDURE_SCHEMA'));
1406 Result.UpdateStringByName('PROCEDURE_NAME',
1407 GetStringByName('PROCEDURE_NAME'));
1408 Result.UpdateStringByName('COLUMN_NAME',
1409 GetStringByName('PARAMETER_NAME'));
1410 case GetShortByName('PARAMETER_TYPE') of
1411 1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));
1412 2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));
1413 3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctOut));
1414 4: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));
1416 Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));
1418 Result.UpdateShortByName('DATA_TYPE',
1419 Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),
1420 ConSettings.CPType)));
1421 Result.UpdateStringByName('TYPE_NAME',
1422 GetStringByName('TYPE_NAME'));
1423 Result.UpdateIntByName('PRECISION',
1424 GetIntByName('NUMERIC_PRECISION'));
1425 Result.UpdateIntByName('LENGTH',
1426 GetIntByName('CHARACTER_OCTET_LENGTH'));
1427 Result.UpdateShortByName('SCALE',
1428 GetShortByName('NUMERIC_SCALE'));
1429 // Result.UpdateShortByName('RADIX', GetShortByName('RADIX'));
1430 Result.UpdateShortByName('NULLABLE', 2);
1431 if GetStringByName('IS_NULLABLE') = 'NO' then
1432 Result.UpdateShortByName('NULLABLE', 0);
1433 if GetStringByName('IS_NULLABLE') = 'YES' then
1434 Result.UpdateShortByName('NULLABLE', 1);
1435 Result.UpdateStringByName('REMARKS',
1436 GetStringByName('DESCRIPTION'));
1446 Gets a description of tables available in a catalog.
1448 <P>Only table descriptions matching the catalog, schema, table
1449 name and type criteria are returned. They are ordered by
1450 TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1452 <P>Each table description has the following columns:
1454 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1455 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1456 <LI><B>TABLE_NAME</B> String => table name
1457 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1458 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1459 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1460 <LI><B>REMARKS</B> String => explanatory comment on the table
1463 <P><B>Note:</B> Some databases may not return information for
1466 @param catalog a catalog name; "" retrieves those without a
1467 catalog; null means drop catalog name from the selection criteria
1468 @param schemaPattern a schema name pattern; "" retrieves those
1470 @param tableNamePattern a table name pattern
1471 @param types a list of table types to include; null returns all types
1472 @return <code>ResultSet</code> - each row is a table description
1473 @see #getSearchStringEscape
1475 function TZAdoDatabaseMetadata.UncachedGetTables(const Catalog: string;
1476 const SchemaPattern: string; const TableNamePattern: string;
1477 const Types: TStringDynArray): IZResultSet;
1481 AdoRecordSet: ZPlainAdo.RecordSet;
1483 Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);
1485 for I := Low(Types) to High(Types) do
1487 if Length(TableTypes) > 0 then
1488 TableTypes := TableTypes + ',';
1489 TableTypes := TableTypes + Types[I];
1492 AdoRecordSet := AdoOpenSchema(adSchemaTables,
1493 [Catalog, SchemaPattern, TableNamePattern, TableTypes]);
1494 if Assigned(AdoRecordSet) then
1496 with TZAdoResultSet.Create(GetStatement, '', AdoRecordset) do
1500 Result.MoveToInsertRow;
1501 Result.UpdateStringByName('TABLE_CAT',
1502 GetStringByName('TABLE_CATALOG'));
1503 Result.UpdateStringByName('TABLE_SCHEM',
1504 GetStringByName('TABLE_SCHEMA'));
1505 Result.UpdateStringByName('TABLE_NAME',
1506 GetStringByName('TABLE_NAME'));
1507 Result.UpdateStringByName('TABLE_TYPE',
1508 GetStringByName('TABLE_TYPE'));
1509 Result.UpdateStringByName('REMARKS',
1510 GetStringByName('DESCRIPTION'));
1520 Gets the schema names available in this database. The results
1521 are ordered by schema name.
1523 <P>The schema column is:
1525 <LI><B>TABLE_SCHEM</B> String => schema name
1528 @return <code>ResultSet</code> - each row has a single String column that is a
1531 function TZAdoDatabaseMetadata.UncachedGetSchemas: IZResultSet;
1533 AdoRecordSet: ZPlainAdo.RecordSet;
1535 Result:=inherited UncachedGetSchemas;
1537 AdoRecordSet := AdoOpenSchema(adSchemaSchemata, []);
1538 if Assigned(AdoRecordSet) then
1540 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1544 Result.MoveToInsertRow;
1545 Result.UpdateStringByName('TABLE_SCHEM',
1546 GetStringByName('SCHEMA_NAME'));
1556 Gets the catalog names available in this database. The results
1557 are ordered by catalog name.
1559 <P>The catalog column is:
1561 <LI><B>TABLE_CAT</B> String => catalog name
1564 @return <code>ResultSet</code> - each row has a single String column that is a
1567 function TZAdoDatabaseMetadata.UncachedGetCatalogs: IZResultSet;
1569 AdoRecordSet: ZPlainAdo.RecordSet;
1571 Result:=inherited UncachedGetCatalogs;
1573 AdoRecordSet := AdoOpenSchema(adSchemaCatalogs, []);
1574 if Assigned(AdoRecordSet) then
1576 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1580 Result.MoveToInsertRow;
1581 Result.UpdateStringByName('TABLE_CAT',
1582 GetStringByName('CATALOG_NAME'));
1592 Gets the table types available in this database. The results
1593 are ordered by table type.
1595 <P>The table type is:
1597 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1598 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1599 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1602 @return <code>ResultSet</code> - each row has a single String column that is a
1605 function TZAdoDatabaseMetadata.UncachedGetTableTypes: IZResultSet;
1607 TableTypes: array[0..7] of string = (
1608 'ALIAS', 'TABLE', 'SYNONYM', 'SYSTEM TABLE', 'VIEW',
1609 'GLOBAL TEMPORARY', 'LOCAL TEMPORARY', 'SYSTEM VIEW'
1614 Result:=inherited UncachedGetTableTypes;
1618 Result.MoveToInsertRow;
1619 Result.UpdateStringByName('TABLE_TYPE', TableTypes[I]);
1625 Gets a description of table columns available in
1626 the specified catalog.
1628 <P>Only column descriptions matching the catalog, schema, table
1629 and column name criteria are returned. They are ordered by
1630 TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1632 <P>Each column description has the following columns:
1634 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1635 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1636 <LI><B>TABLE_NAME</B> String => table name
1637 <LI><B>COLUMN_NAME</B> String => column name
1638 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1639 <LI><B>TYPE_NAME</B> String => Data source dependent type name,
1640 for a UDT the type name is fully qualified
1641 <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1642 types this is the maximum number of characters, for numeric or
1643 decimal types this is precision.
1644 <LI><B>BUFFER_LENGTH</B> is not used.
1645 <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1646 <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1647 <LI><B>NULLABLE</B> int => is NULL allowed?
1649 <LI> columnNoNulls - might not allow NULL values
1650 <LI> columnNullable - definitely allows NULL values
1651 <LI> columnNullableUnknown - nullability unknown
1653 <LI><B>REMARKS</B> String => comment describing column (may be null)
1654 <LI><B>COLUMN_DEF</B> String => default value (may be null)
1655 <LI><B>SQL_DATA_TYPE</B> int => unused
1656 <LI><B>SQL_DATETIME_SUB</B> int => unused
1657 <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1658 maximum number of bytes in the column
1659 <LI><B>ORDINAL_POSITION</B> int => index of column in table
1661 <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1662 does not allow NULL values; "YES" means the column might
1663 allow NULL values. An empty string means nobody knows.
1666 @param catalog a catalog name; "" retrieves those without a
1667 catalog; null means drop catalog name from the selection criteria
1668 @param schemaPattern a schema name pattern; "" retrieves those
1670 @param tableNamePattern a table name pattern
1671 @param columnNamePattern a column name pattern
1672 @return <code>ResultSet</code> - each row is a column description
1673 @see #getSearchStringEscape
1675 function TZAdoDatabaseMetadata.UncachedGetColumns(const Catalog: string;
1676 const SchemaPattern: string; const TableNamePattern: string;
1677 const ColumnNamePattern: string): IZResultSet;
1679 AdoRecordSet: ZPlainAdo.RecordSet;
1683 Result:=inherited UncachedGetColumns(Catalog, SchemaPattern,
1684 TableNamePattern, ColumnNamePattern);
1686 AdoRecordSet := AdoOpenSchema(adSchemaColumns,
1687 [DecomposeObjectString(Catalog), DecomposeObjectString(SchemaPattern),
1688 DecomposeObjectString(TableNamePattern), DecomposeObjectString(ColumnNamePattern)]);
1689 if Assigned(AdoRecordSet) then
1691 AdoRecordSet.Sort := 'ORDINAL_POSITION';
1692 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1696 Result.MoveToInsertRow;
1697 Result.UpdateStringByName('TABLE_CAT',
1698 GetStringByName('TABLE_CATALOG'));
1699 Result.UpdateStringByName('TABLE_SCHEM',
1700 GetStringByName('TABLE_SCHEMA'));
1701 Result.UpdateStringByName('TABLE_NAME',
1702 GetStringByName('TABLE_NAME'));
1703 Result.UpdateStringByName('COLUMN_NAME',
1704 GetStringByName('COLUMN_NAME'));
1706 SQLType := ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),
1707 ConSettings.CPType);
1708 Flags := GetIntByName('COLUMN_FLAGS');
1709 //!!!If the field type is long then this is the only way to know it because it just returns string type
1710 if ((Flags and DBCOLUMNFLAGS_ISLONG) <> 0 ) and (SQLType in [stBytes, stString, stUnicodeString]) then
1712 stBytes: SQLType := stBinaryStream;
1713 stString: SQLType := stAsciiStream;
1714 stUnicodeString: SQLType := stUnicodeStream;
1716 Result.UpdateShortByName('DATA_TYPE', Ord(SQLType));
1717 Result.UpdateIntByName('COLUMN_SIZE',
1718 GetIntByName('CHARACTER_MAXIMUM_LENGTH'));
1719 Result.UpdateIntByName('BUFFER_LENGTH',
1720 GetIntByName('CHARACTER_MAXIMUM_LENGTH'));
1721 Result.UpdateIntByName('DECIMAL_DIGITS',
1722 GetIntByName('NUMERIC_SCALE'));
1723 Result.UpdateIntByName('NUM_PREC_RADIX',
1724 GetShortByName('NUMERIC_PRECISION'));
1725 if GetBooleanByName('IS_NULLABLE') then
1726 Result.UpdateShortByName('NULLABLE', 1)
1728 Result.UpdateShortByName('NULLABLE', 0);
1729 Result.UpdateStringByName('REMARKS',
1730 GetStringByName('DESCRIPTION'));
1731 Result.UpdateStringByName('COLUMN_DEF',
1732 GetStringByName('COLUMN_DEFAULT'));
1733 Result.UpdateShortByName('SQL_DATETIME_SUB',
1734 GetShortByName('DATETIME_PRECISION'));
1735 Result.UpdateIntByName('CHAR_OCTET_LENGTH',
1736 GetIntByName('CHARACTER_OCTET_LENGTH'));
1737 Result.UpdateIntByName('ORDINAL_POSITION',
1738 GetIntByName('ORDINAL_POSITION'));
1739 if UpperCase(GetStringByName('IS_NULLABLE')) = 'FALSE' then
1740 Result.UpdateStringByName('IS_NULLABLE', 'NO')
1742 Result.UpdateStringByName('IS_NULLABLE', 'YES');
1744 Result.UpdateBooleanByName('WRITABLE',
1745 (Flags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) <> 0));
1747 Result.UpdateBooleanByName('DEFINITELYWRITABLE',
1748 (Flags and (DBCOLUMNFLAGS_WRITE) <> 0));
1749 Result.UpdateBooleanByName('READONLY',
1750 (Flags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) = 0));
1751 Result.UpdateBooleanByName('SEARCHABLE',
1752 (Flags and (DBCOLUMNFLAGS_ISLONG) = 0));
1753 Result.UpdateNullByName('AUTO_INCREMENT');
1763 Gets a description of the access rights for a table's columns.
1765 <P>Only privileges matching the column name criteria are
1766 returned. They are ordered by COLUMN_NAME and PRIVILEGE.
1768 <P>Each privilige description has the following columns:
1770 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1771 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1772 <LI><B>TABLE_NAME</B> String => table name
1773 <LI><B>COLUMN_NAME</B> String => column name
1774 <LI><B>GRANTOR</B> => grantor of access (may be null)
1775 <LI><B>GRANTEE</B> String => grantee of access
1776 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1777 INSERT, UPDATE, REFRENCES, ...)
1778 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1779 to grant to others; "NO" if not; null if unknown
1782 @param catalog a catalog name; "" retrieves those without a
1783 catalog; null means drop catalog name from the selection criteria
1784 @param schema a schema name; "" retrieves those without a schema
1785 @param table a table name
1786 @param columnNamePattern a column name pattern
1787 @return <code>ResultSet</code> - each row is a column privilege description
1788 @see #getSearchStringEscape
1790 function TZAdoDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;
1791 const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;
1793 AdoRecordSet: ZPlainAdo.RecordSet;
1795 Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);
1797 AdoRecordSet := AdoOpenSchema(adSchemaColumnPrivileges,
1798 [Catalog, Schema, Table, ColumnNamePattern]);
1799 if Assigned(AdoRecordSet) then
1801 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1805 Result.MoveToInsertRow;
1806 Result.UpdateStringByName('TABLE_CAT',
1807 GetStringByName('TABLE_CATALOG'));
1808 Result.UpdateStringByName('TABLE_SCHEM',
1809 GetStringByName('TABLE_SCHEMA'));
1810 Result.UpdateStringByName('TABLE_NAME',
1811 GetStringByName('TABLE_NAME'));
1812 Result.UpdateStringByName('COLUMN_NAME',
1813 GetStringByName('COLUMN_NAME'));
1814 Result.UpdateStringByName('GRANTOR',
1815 GetStringByName('GRANTOR'));
1816 Result.UpdateStringByName('GRANTEE',
1817 GetStringByName('GRANTEE'));
1818 Result.UpdateStringByName('PRIVILEGE',
1819 GetStringByName('PRIVILEGE_TYPE'));
1820 if GetBooleanByName('IS_GRANTABLE') then
1821 Result.UpdateStringByName('IS_GRANTABLE', 'YES')
1823 Result.UpdateStringByName('IS_GRANTABLE', 'NO');
1833 Gets a description of the access rights for each table available
1834 in a catalog. Note that a table privilege applies to one or
1835 more columns in the table. It would be wrong to assume that
1836 this priviledge applies to all columns (this may be true for
1837 some systems but is not true for all.)
1839 <P>Only privileges matching the schema and table name
1840 criteria are returned. They are ordered by TABLE_SCHEM,
1841 TABLE_NAME, and PRIVILEGE.
1843 <P>Each privilige description has the following columns:
1845 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1846 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1847 <LI><B>TABLE_NAME</B> String => table name
1848 <LI><B>GRANTOR</B> => grantor of access (may be null)
1849 <LI><B>GRANTEE</B> String => grantee of access
1850 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1851 INSERT, UPDATE, REFRENCES, ...)
1852 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1853 to grant to others; "NO" if not; null if unknown
1856 @param catalog a catalog name; "" retrieves those without a
1857 catalog; null means drop catalog name from the selection criteria
1858 @param schemaPattern a schema name pattern; "" retrieves those
1860 @param tableNamePattern a table name pattern
1861 @return <code>ResultSet</code> - each row is a table privilege description
1862 @see #getSearchStringEscape
1864 function TZAdoDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;
1865 const SchemaPattern: string; const TableNamePattern: string): IZResultSet;
1867 AdoRecordSet: ZPlainAdo.RecordSet;
1869 Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);
1871 AdoRecordSet := AdoOpenSchema(adSchemaTablePrivileges,
1872 [Catalog, SchemaPattern, TableNamePattern]);
1873 if Assigned(AdoRecordSet) then
1875 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1879 Result.MoveToInsertRow;
1880 Result.UpdateStringByName('TABLE_CAT',
1881 GetStringByName('TABLE_CATALOG'));
1882 Result.UpdateStringByName('TABLE_SCHEM',
1883 GetStringByName('TABLE_SCHEMA'));
1884 Result.UpdateStringByName('TABLE_NAME',
1885 GetStringByName('TABLE_NAME'));
1886 Result.UpdateStringByName('GRANTOR',
1887 GetStringByName('GRANTOR'));
1888 Result.UpdateStringByName('GRANTEE',
1889 GetStringByName('GRANTEE'));
1890 Result.UpdateStringByName('PRIVILEGE',
1891 GetStringByName('PRIVILEGE_TYPE'));
1892 if GetBooleanByName('IS_GRANTABLE') then
1893 Result.UpdateStringByName('IS_GRANTABLE', 'YES')
1894 else Result.UpdateStringByName('IS_GRANTABLE', 'NO');
1904 Gets a description of a table's columns that are automatically
1905 updated when any value in a row is updated. They are
1908 <P>Each column description has the following columns:
1910 <LI><B>SCOPE</B> short => is not used
1911 <LI><B>COLUMN_NAME</B> String => column name
1912 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
1913 <LI><B>TYPE_NAME</B> String => Data source dependent type name
1914 <LI><B>COLUMN_SIZE</B> int => precision
1915 <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
1916 <LI><B>DECIMAL_DIGITS</B> short => scale
1917 <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
1918 like an Oracle ROWID
1920 <LI> versionColumnUnknown - may or may not be pseudo column
1921 <LI> versionColumnNotPseudo - is NOT a pseudo column
1922 <LI> versionColumnPseudo - is a pseudo column
1926 @param catalog a catalog name; "" retrieves those without a
1927 catalog; null means drop catalog name from the selection criteria
1928 @param schema a schema name; "" retrieves those without a schema
1929 @param table a table name
1930 @return <code>ResultSet</code> - each row is a column description
1931 @exception SQLException if a database access error occurs
1933 function TZAdoDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;
1934 const Schema: string; const Table: string): IZResultSet;
1936 DBCOLUMNFLAGS_ISROWVER = $00000200;
1938 AdoRecordSet: ZPlainAdo.RecordSet;
1940 Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);
1942 AdoRecordSet := AdoOpenSchema(adSchemaColumns, [Catalog, Schema, Table]);
1943 if Assigned(AdoRecordSet) then
1945 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
1949 if (GetIntByName('COLUMN_FLAGS')
1950 and DBCOLUMNFLAGS_ISROWVER) = 0 then
1952 Result.MoveToInsertRow;
1953 Result.UpdateShortByName('SCOPE', 0);
1954 Result.UpdateStringByName('COLUMN_NAME',
1955 GetStringByName('COLUMN_NAME'));
1956 Result.UpdateShortByName('DATA_TYPE',
1957 Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),
1958 ConSettings.CPType)));
1959 Result.UpdateStringByName('TYPE_NAME',
1960 GetStringByName('TYPE_NAME'));
1961 Result.UpdateIntByName('COLUMN_SIZE',
1962 GetIntByName('CHARACTER_OCTET_LENGTH'));
1963 Result.UpdateIntByName('BUFFER_LENGTH',
1964 GetIntByName('CHARACTER_OCTET_LENGTH'));
1965 Result.UpdateIntByName('DECIMAL_DIGITS',
1966 GetIntByName('NUMERIC_SCALE'));
1967 Result.UpdateShortByName('PSEUDO_COLUMN', 0);
1977 Gets a description of a table's primary key columns. They
1978 are ordered by COLUMN_NAME.
1980 <P>Each primary key column description has the following columns:
1982 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1983 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1984 <LI><B>TABLE_NAME</B> String => table name
1985 <LI><B>COLUMN_NAME</B> String => column name
1986 <LI><B>KEY_SEQ</B> short => sequence number within primary key
1987 <LI><B>PK_NAME</B> String => primary key name (may be null)
1990 @param catalog a catalog name; "" retrieves those without a
1991 catalog; null means drop catalog name from the selection criteria
1992 @param schema a schema name; "" retrieves those
1994 @param table a table name
1995 @return <code>ResultSet</code> - each row is a primary key column description
1996 @exception SQLException if a database access error occurs
1998 function TZAdoDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;
1999 const Schema: string; const Table: string): IZResultSet;
2001 AdoRecordSet: ZPlainAdo.RecordSet;
2003 Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);
2005 AdoRecordSet := AdoOpenSchema(adSchemaPrimaryKeys,
2006 [Catalog, Schema, Table]);
2007 if Assigned(AdoRecordSet) then
2009 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
2013 Result.MoveToInsertRow;
2014 Result.UpdateStringByName('TABLE_CAT',
2015 GetStringByName('TABLE_CATALOG'));
2016 Result.UpdateStringByName('TABLE_SCHEM',
2017 GetStringByName('TABLE_SCHEMA'));
2018 Result.UpdateStringByName('TABLE_NAME',
2019 GetStringByName('TABLE_NAME'));
2020 Result.UpdateStringByName('COLUMN_NAME',
2021 GetStringByName('COLUMN_NAME'));
2022 Result.UpdateShortByName('KEY_SEQ',
2023 GetShortByName('ORDINAL'));
2024 if FindColumn('PK_NAME') >= 1 then
2026 Result.UpdateStringByName('PK_NAME',
2027 GetStringByName('PK_NAME'));
2038 Gets a description of the primary key columns that are
2039 referenced by a table's foreign key columns (the primary keys
2040 imported by a table). They are ordered by PKTABLE_CAT,
2041 PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
2043 <P>Each primary key column description has the following columns:
2045 <LI><B>PKTABLE_CAT</B> String => primary key table catalog
2046 being imported (may be null)
2047 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
2048 being imported (may be null)
2049 <LI><B>PKTABLE_NAME</B> String => primary key table name
2051 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2053 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2054 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2055 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2056 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2057 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2058 <LI><B>UPDATE_RULE</B> short => What happens to
2059 foreign key when primary is updated:
2061 <LI> importedNoAction - do not allow update of primary
2062 key if it has been imported
2063 <LI> importedKeyCascade - change imported key to agree
2064 with primary key update
2065 <LI> importedKeySetNull - change imported key to NULL if
2066 its primary key has been updated
2067 <LI> importedKeySetDefault - change imported key to default values
2068 if its primary key has been updated
2069 <LI> importedKeyRestrict - same as importedKeyNoAction
2070 (for ODBC 2.x compatibility)
2072 <LI><B>DELETE_RULE</B> short => What happens to
2073 the foreign key when primary is deleted.
2075 <LI> importedKeyNoAction - do not allow delete of primary
2076 key if it has been imported
2077 <LI> importedKeyCascade - delete rows that import a deleted key
2078 <LI> importedKeySetNull - change imported key to NULL if
2079 its primary key has been deleted
2080 <LI> importedKeyRestrict - same as importedKeyNoAction
2081 (for ODBC 2.x compatibility)
2082 <LI> importedKeySetDefault - change imported key to default if
2083 its primary key has been deleted
2085 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2086 <LI><B>PK_NAME</B> String => primary key name (may be null)
2087 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2088 constraints be deferred until commit
2090 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2091 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2092 <LI> importedKeyNotDeferrable - see SQL92 for definition
2096 @param catalog a catalog name; "" retrieves those without a
2097 catalog; null means drop catalog name from the selection criteria
2098 @param schema a schema name; "" retrieves those
2100 @param table a table name
2101 @return <code>ResultSet</code> - each row is a primary key column description
2102 @see #getExportedKeys
2104 function TZAdoDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;
2105 const Schema: string; const Table: string): IZResultSet;
2107 Result := UncachedGetCrossReference('', '', '', Catalog, Schema, Table);
2111 Gets a description of the foreign key columns that reference a
2112 table's primary key columns (the foreign keys exported by a
2113 table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2114 FKTABLE_NAME, and KEY_SEQ.
2116 <P>Each foreign key column description has the following columns:
2118 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2119 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2120 <LI><B>PKTABLE_NAME</B> String => primary key table name
2121 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2122 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2123 being exported (may be null)
2124 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2125 being exported (may be null)
2126 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2128 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2130 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2131 <LI><B>UPDATE_RULE</B> short => What happens to
2132 foreign key when primary is updated:
2134 <LI> importedNoAction - do not allow update of primary
2135 key if it has been imported
2136 <LI> importedKeyCascade - change imported key to agree
2137 with primary key update
2138 <LI> importedKeySetNull - change imported key to NULL if
2139 its primary key has been updated
2140 <LI> importedKeySetDefault - change imported key to default values
2141 if its primary key has been updated
2142 <LI> importedKeyRestrict - same as importedKeyNoAction
2143 (for ODBC 2.x compatibility)
2145 <LI><B>DELETE_RULE</B> short => What happens to
2146 the foreign key when primary is deleted.
2148 <LI> importedKeyNoAction - do not allow delete of primary
2149 key if it has been imported
2150 <LI> importedKeyCascade - delete rows that import a deleted key
2151 <LI> importedKeySetNull - change imported key to NULL if
2152 its primary key has been deleted
2153 <LI> importedKeyRestrict - same as importedKeyNoAction
2154 (for ODBC 2.x compatibility)
2155 <LI> importedKeySetDefault - change imported key to default if
2156 its primary key has been deleted
2158 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2159 <LI><B>PK_NAME</B> String => primary key name (may be null)
2160 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2161 constraints be deferred until commit
2163 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2164 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2165 <LI> importedKeyNotDeferrable - see SQL92 for definition
2169 @param catalog a catalog name; "" retrieves those without a
2170 catalog; null means drop catalog name from the selection criteria
2171 @param schema a schema name; "" retrieves those
2173 @param table a table name
2174 @return <code>ResultSet</code> - each row is a foreign key column description
2175 @see #getImportedKeys
2177 function TZAdoDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;
2178 const Schema: string; const Table: string): IZResultSet;
2180 Result := UncachedGetCrossReference(Catalog, Schema, Table, '', '', '');
2184 Gets a description of the foreign key columns in the foreign key
2185 table that reference the primary key columns of the primary key
2186 table (describe how one table imports another's key.) This
2187 should normally return a single foreign key/primary key pair
2188 (most tables only import a foreign key from a table once.) They
2189 are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2192 <P>Each foreign key column description has the following columns:
2194 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2195 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2196 <LI><B>PKTABLE_NAME</B> String => primary key table name
2197 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2198 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2199 being exported (may be null)
2200 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2201 being exported (may be null)
2202 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2204 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2206 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2207 <LI><B>UPDATE_RULE</B> short => What happens to
2208 foreign key when primary is updated:
2210 <LI> importedNoAction - do not allow update of primary
2211 key if it has been imported
2212 <LI> importedKeyCascade - change imported key to agree
2213 with primary key update
2214 <LI> importedKeySetNull - change imported key to NULL if
2215 its primary key has been updated
2216 <LI> importedKeySetDefault - change imported key to default values
2217 if its primary key has been updated
2218 <LI> importedKeyRestrict - same as importedKeyNoAction
2219 (for ODBC 2.x compatibility)
2221 <LI><B>DELETE_RULE</B> short => What happens to
2222 the foreign key when primary is deleted.
2224 <LI> importedKeyNoAction - do not allow delete of primary
2225 key if it has been imported
2226 <LI> importedKeyCascade - delete rows that import a deleted key
2227 <LI> importedKeySetNull - change imported key to NULL if
2228 its primary key has been deleted
2229 <LI> importedKeyRestrict - same as importedKeyNoAction
2230 (for ODBC 2.x compatibility)
2231 <LI> importedKeySetDefault - change imported key to default if
2232 its primary key has been deleted
2234 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2235 <LI><B>PK_NAME</B> String => primary key name (may be null)
2236 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2237 constraints be deferred until commit
2239 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2240 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2241 <LI> importedKeyNotDeferrable - see SQL92 for definition
2245 @param primaryCatalog a catalog name; "" retrieves those without a
2246 catalog; null means drop catalog name from the selection criteria
2247 @param primarySchema a schema name; "" retrieves those
2249 @param primaryTable the table name that exports the key
2250 @param foreignCatalog a catalog name; "" retrieves those without a
2251 catalog; null means drop catalog name from the selection criteria
2252 @param foreignSchema a schema name; "" retrieves those
2254 @param foreignTable the table name that imports the key
2255 @return <code>ResultSet</code> - each row is a foreign key column description
2256 @see #getImportedKeys
2258 function TZAdoDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;
2259 const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;
2260 const ForeignSchema: string; const ForeignTable: string): IZResultSet;
2262 AdoRecordSet: ZPlainAdo.RecordSet;
2264 function GetRuleType(const Rule: String): TZImportedKey;
2266 if Rule = 'RESTRICT' then
2267 Result := ikRestrict
2268 else if Rule = 'NO ACTION' then
2269 Result := ikNoAction
2270 else if Rule = 'CASCADE' then
2272 else if Rule = 'SET DEFAULT' then
2273 Result := ikSetDefault
2274 else if Rule = 'SET NULL' then
2277 Result := ikNotDeferrable; //impossible!
2280 Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,
2281 ForeignCatalog, ForeignSchema, ForeignTable);
2283 AdoRecordSet := AdoOpenSchema(adSchemaForeignKeys,
2284 [PrimaryCatalog, PrimarySchema, PrimaryTable,
2285 ForeignCatalog, ForeignSchema, ForeignTable]);
2286 if Assigned(AdoRecordSet) then
2288 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
2292 Result.MoveToInsertRow;
2293 Result.UpdateStringByName('PKTABLE_CAT',
2294 GetStringByName('PK_TABLE_CATALOG'));
2295 Result.UpdateStringByName('PKTABLE_SCHEM',
2296 GetStringByName('PK_TABLE_SCHEMA'));
2297 Result.UpdateStringByName('PKTABLE_NAME',
2298 GetStringByName('PK_TABLE_NAME'));
2299 Result.UpdateStringByName('PKCOLUMN_NAME',
2300 GetStringByName('PK_COLUMN_NAME'));
2301 Result.UpdateStringByName('FKTABLE_CAT',
2302 GetStringByName('FK_TABLE_CATALOG'));
2303 Result.UpdateStringByName('FKTABLE_SCHEM',
2304 GetStringByName('FK_TABLE_SCHEMA'));
2305 Result.UpdateStringByName('FKTABLE_NAME',
2306 GetStringByName('FK_TABLE_NAME'));
2307 Result.UpdateStringByName('FKCOLUMN_NAME',
2308 GetStringByName('FK_COLUMN_NAME'));
2309 Result.UpdateShortByName('KEY_SEQ',
2310 GetShortByName('ORDINAL'));
2311 Result.UpdateShortByName('UPDATE_RULE',
2312 Ord(GetRuleType(GetStringByName('UPDATE_RULE'))));
2313 Result.UpdateShortByName('DELETE_RULE',
2314 Ord(GetRuleType(GetStringByName('DELETE_RULE'))));
2315 Result.UpdateStringByName('FK_NAME',
2316 GetStringByName('FK_NAME'));
2317 Result.UpdateStringByName('PK_NAME',
2318 GetStringByName('PK_NAME'));
2319 Result.UpdateIntByName('DEFERRABILITY',
2320 GetShortByName('DEFERRABILITY'));
2330 Gets a description of all the standard SQL types supported by
2331 this database. They are ordered by DATA_TYPE and then by how
2332 closely the data type maps to the corresponding JDBC SQL type.
2334 <P>Each type description has the following columns:
2336 <LI><B>TYPE_NAME</B> String => Type name
2337 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2338 <LI><B>PRECISION</B> int => maximum precision
2339 <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2341 <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2343 <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2344 the type (may be null)
2345 <LI><B>NULLABLE</B> short => can you use NULL for this type?
2347 <LI> typeNoNulls - does not allow NULL values
2348 <LI> typeNullable - allows NULL values
2349 <LI> typeNullableUnknown - nullability unknown
2351 <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2352 <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2354 <LI> typePredNone - No support
2355 <LI> typePredChar - Only supported with WHERE .. LIKE
2356 <LI> typePredBasic - Supported except for WHERE .. LIKE
2357 <LI> typeSearchable - Supported for all WHERE ..
2359 <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2360 <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2361 <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2362 auto-increment value?
2363 <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2365 <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2366 <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2367 <LI><B>SQL_DATA_TYPE</B> int => unused
2368 <LI><B>SQL_DATETIME_SUB</B> int => unused
2369 <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2372 @return <code>ResultSet</code> - each row is an SQL type description
2374 function TZAdoDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;
2376 AdoRecordSet: ZPlainAdo.RecordSet;
2378 Result:=inherited UncachedGetTypeInfo;
2380 AdoRecordSet := AdoOpenSchema(adSchemaProviderTypes, []);
2381 if Assigned(AdoRecordSet) then
2383 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
2387 Result.MoveToInsertRow;
2388 Result.UpdateStringByName('TYPE_NAME',
2389 GetStringByName('TYPE_NAME'));
2390 Result.UpdateShortByName('DATA_TYPE',
2391 Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),
2392 ConSettings.CPType)));
2393 Result.UpdateIntByName('PRECISION',
2394 0);//GetIntByName('PRECISION'));
2395 Result.UpdateStringByName('LITERAL_PREFIX',
2396 GetStringByName('LITERAL_PREFIX'));
2397 Result.UpdateStringByName('LITERAL_SUFFIX',
2398 GetStringByName('LITERAL_SUFFIX'));
2399 Result.UpdateStringByName('CREATE_PARAMS',
2400 GetStringByName('CREATE_PARAMS'));
2401 if GetBooleanByName('IS_NULLABLE') then
2402 Result.UpdateShortByName('NULLABLE', 1)
2404 Result.UpdateShortByName('NULLABLE', 0);
2405 Result.UpdateBooleanByName('CASE_SENSITIVE',
2406 GetBooleanByName('CASE_SENSITIVE'));
2407 Result.UpdateShortByName('SEARCHABLE',
2408 GetShortByName('SEARCHABLE'));
2409 Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',
2410 GetBooleanByName('UNSIGNED_ATTRIBUTE'));
2411 Result.UpdateBooleanByName('FIXED_PREC_SCALE',
2412 GetBooleanByName('FIXED_PREC_SCALE'));
2413 Result.UpdateBooleanByName('AUTO_INCREMENT', False);
2414 Result.UpdateStringByName('LOCAL_TYPE_NAME',
2415 GetStringByName('LOCAL_TYPE_NAME'));
2416 Result.UpdateShortByName('MINIMUM_SCALE',
2417 GetShortByName('MINIMUM_SCALE'));
2418 Result.UpdateShortByName('MAXIMUM_SCALE',
2419 GetShortByName('MAXIMUM_SCALE'));
2420 // Result.UpdateShortByName('SQL_DATA_TYPE',
2421 // GetShortByName('SQL_DATA_TYPE'));
2422 // Result.UpdateShortByName('SQL_DATETIME_SUB',
2423 // GetShortByName('SQL_DATETIME_SUB'));
2424 // Result.UpdateShortByName('NUM_PREC_RADIX',
2425 // GetShortByName('NUM_PREC_RADIX'));
2435 Gets a description of a table's indices and statistics. They are
2436 ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2438 <P>Each index column description has the following columns:
2440 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2441 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2442 <LI><B>TABLE_NAME</B> String => table name
2443 <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2444 false when TYPE is tableIndexStatistic
2445 <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2446 null when TYPE is tableIndexStatistic
2447 <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2449 <LI><B>TYPE</B> short => index type:
2451 <LI> tableIndexStatistic - this identifies table statistics that are
2452 returned in conjuction with a table's index descriptions
2453 <LI> tableIndexClustered - this is a clustered index
2454 <LI> tableIndexHashed - this is a hashed index
2455 <LI> tableIndexOther - this is some other style of index
2457 <LI><B>ORDINAL_POSITION</B> short => column sequence number
2458 within index; zero when TYPE is tableIndexStatistic
2459 <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2461 <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2462 "D" => descending, may be null if sort sequence is not supported;
2463 null when TYPE is tableIndexStatistic
2464 <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2465 this is the number of rows in the table; otherwise, it is the
2466 number of unique values in the index.
2467 <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
2468 this is the number of pages used for the table, otherwise it
2469 is the number of pages used for the current index.
2470 <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2474 @param catalog a catalog name; "" retrieves those without a
2475 catalog; null means drop catalog name from the selection criteria
2476 @param schema a schema name; "" retrieves those without a schema
2477 @param table a table name
2478 @param unique when true, return only indices for unique values;
2479 when false, return indices regardless of whether unique or not
2480 @param approximate when true, result is allowed to reflect approximate
2481 or out of data values; when false, results are requested to be
2483 @return <code>ResultSet</code> - each row is an index column description
2485 function TZAdoDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;
2486 const Schema: string; const Table: string; Unique: Boolean;
2487 Approximate: Boolean): IZResultSet;
2489 AdoRecordSet: ZPlainAdo.RecordSet;
2491 Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);
2493 AdoRecordSet := AdoOpenSchema(adSchemaIndexes,
2494 [Catalog, Schema, '', '', Table]);
2495 if Assigned(AdoRecordSet) then
2497 with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do
2501 Result.MoveToInsertRow;
2502 Result.UpdateStringByName('TABLE_CAT',
2503 GetStringByName('TABLE_CATALOG'));
2504 Result.UpdateStringByName('TABLE_SCHEM',
2505 GetStringByName('TABLE_SCHEMA'));
2506 Result.UpdateStringByName('TABLE_NAME',
2507 GetStringByName('TABLE_NAME'));
2508 Result.UpdateBooleanByName('NON_UNIQUE',
2509 not GetBooleanByName('UNIQUE'));
2510 Result.UpdateStringByName('INDEX_QUALIFIER',
2511 GetStringByName('INDEX_CATALOG'));
2512 Result.UpdateStringByName('INDEX_NAME',
2513 GetStringByName('INDEX_NAME'));
2514 Result.UpdateShortByName('TYPE',
2515 GetShortByName('TYPE'));
2516 Result.UpdateShortByName('ORDINAL_POSITION',
2517 GetShortByName('ORDINAL_POSITION'));
2518 Result.UpdateStringByName('COLUMN_NAME',
2519 GetStringByName('COLUMN_NAME'));
2520 //!!! Result.UpdateStringByName('ASC_OR_DESC',
2521 // GetStringByName('COLLATION'));
2522 Result.UpdateIntByName('CARDINALITY',
2523 GetIntByName('CARDINALITY'));
2524 Result.UpdateIntByName('PAGES',
2525 GetIntByName('PAGES'));
2526 Result.UpdateStringByName('FILTER_CONDITION',
2527 GetStringByName('FILTER_CONDITION'));
2538 Gets a description of the user-defined types defined in a particular
2539 schema. Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,
2542 <P>Only types matching the catalog, schema, type name and type
2543 criteria are returned. They are ordered by DATA_TYPE, TYPE_SCHEM
2544 and TYPE_NAME. The type name parameter may be a fully-qualified
2545 name. In this case, the catalog and schemaPattern parameters are
2548 <P>Each type description has the following columns:
2550 <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
2551 <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
2552 <LI><B>TYPE_NAME</B> String => type name
2553 <LI><B>CLASS_NAME</B> String => Java class name
2554 <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.
2555 One of JAVA_OBJECT, STRUCT, or DISTINCT
2556 <LI><B>REMARKS</B> String => explanatory comment on the type
2559 <P><B>Note:</B> If the driver does not support UDTs, an empty
2560 result set is returned.
2562 @param catalog a catalog name; "" retrieves those without a
2563 catalog; null means drop catalog name from the selection criteria
2564 @param schemaPattern a schema name pattern; "" retrieves those
2566 @param typeNamePattern a type name pattern; may be a fully-qualified name
2567 @param types a list of user-named types to include (JAVA_OBJECT,
2568 STRUCT, or DISTINCT); null returns all types
2569 @return <code>ResultSet</code> - each row is a type description
2571 function TZAdoDatabaseMetadata.UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
2572 const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet;
2575 Result:=inherited UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);
2577 // AdoRecordSet := AdoOpenSchema(adSchemaIndexes, Restrictions);
2578 // if Assigned(AdoRecordSet) then
2579 // with GetStatement.ExecuteQuery(
2580 // Format('select TYPE_CAT = db_name(), TYPE_SCHEM = user_name(uid),'
2581 // + ' TYPE_NAME = st.name, DATA_TYPE from master.dbo.spt_datatype_info'
2582 // + ' sti left outer join systypes st on (sti.ss_dtype = st.xtype)'
2583 // + ' where st.xusertype > 255 and user_name(uid) like %s and st.name'
2584 // + ' like %s', [SchemaPattern, TypeNamePattern])) do
2587 // Result.MoveToInsertRow;
2588 // Result.UpdateString('TYPE_CAT', GetString('TYPE_CAT'));
2589 // Result.UpdateString('TYPE_SCHEM', GetString('TYPE_SCHEM'));
2590 // Result.UpdateString('TYPE_NAME', GetString('TYPE_NAME'));
2591 // Result.UpdateNull('JAVA_CLASS');
2592 // Result.UpdateShort('DATA_TYPE', GetShort('DATA_TYPE'));
2593 // Result.UpdateNull('REMARKS');
2594 // Result.InsertRow;
2600 Open a schema rowset from ado
2602 @Schema Ado identifier
2603 @Args Variant array with restrictions
2604 @return ADO recordset with the schemas; nil if the schema is not supported
2606 function TZAdoDatabaseMetadata.AdoOpenSchema(Schema: Integer; const Args: array of const): ZPlainAdo.RecordSet;
2608 Restrictions: Variant;
2611 if not FSupportedSchemasInitialized then
2613 if not SchemaSupported(Schema) then
2616 Restrictions := BuildRestrictions(Schema, Args);
2617 Result := (GetConnection as IZAdoConnection).GetAdoConnection.
2618 OpenSchema(Schema, Restrictions, EmptyParam);
2625 Initialize supported schemas and restrictions from the OleDB provider
2627 procedure TZAdoDatabaseMetadata.InitializeSchemas;
2629 AdoConnection: IZAdoConnection;
2630 OleDBSession: IUnknown;
2631 SchemaRS: IDBSchemaRowset;
2632 PG, OriginalPG: PGUID;
2637 if not FSupportedSchemasInitialized then
2639 if not Assigned(FAdoConnection) then
2641 GetConnection.QueryInterface(IZAdoConnection, AdoConnection);
2642 FAdoConnection := AdoConnection.GetAdoConnection;
2644 (FAdoConnection as ADOConnectionConstruction).Get_Session(OleDBSession);
2645 if Assigned(OleDBSession) then
2647 OleDBSession.QueryInterface(IDBSchemaRowset, SchemaRS);
2648 if Assigned(SchemaRS) then
2650 SchemaRS.GetSchemas(Nr, PG, PInteger(IA));
2652 SetLength(SupportedSchemas, Nr);
2653 for I := 0 to Nr - 1 do
2655 SupportedSchemas[I].SchemaGuid := PG^;
2656 SupportedSchemas[I].SupportedRestrictions := IA^[I];
2657 SupportedSchemas[I].AdoSchemaId := ConvertOleDBToAdoSchema(PG^);
2658 Inc({$IFDEF DELPHI16_UP}NativeInt{$ELSE}Integer{$ENDIF}(PG), SizeOf(TGuid)); //M.A. Inc(Integer(PG), SizeOf(TGuid));
2660 FSupportedSchemasInitialized := True;
2661 if Assigned(OriginalPG) then ZAdoMalloc.Free(OriginalPG);
2662 if Assigned(IA) then ZAdoMalloc.Free(IA);
2669 Find the Schema Id in the supported schemas
2671 @SchemaId Ado identifier
2672 @return Index of the schema in the supported schemas array
2674 function TZAdoDatabaseMetadata.FindSchema(SchemaId: Integer): Integer;
2679 for I := 0 to Length(SupportedSchemas) - 1 do
2680 if SupportedSchemas[I].AdoSchemaId = SchemaId then
2688 Is the schema supported by the OleDB provider?
2690 @SchemaId Ado identifier
2691 @return True if the schema is supported
2693 function TZAdoDatabaseMetadata.SchemaSupported(SchemaId: Integer): Boolean;
2695 Result := FindSchema(SchemaId) > -1;
2699 Build a variant array from the provided parameters based on the supported restrictions
2701 @SchemaId Ado identifier
2703 @return Variant array of restrictions
2705 function TZAdoDatabaseMetadata.BuildRestrictions(SchemaId: Integer;
2706 const Args: array of const): Variant;
2708 SchemaIndex: Integer;
2712 if High(Args) = -1 then
2714 SchemaIndex := FindSchema(SchemaId);
2715 if SchemaIndex = -1 then
2718 Result := VarArrayCreate([0, High(Args)], varVariant);
2719 for I := 0 to High(Args) do
2721 if (SupportedSchemas[SchemaIndex].SupportedRestrictions
2722 and (1 shl I)) <> 0 then
2725 Result[I] := string(Args[I].VPWideChar);
2726 if (Args[I].VType = VtUnicodeString) then
2727 if string(Args[I].VPWideChar) = '' then
2729 Result[I] := string(Args[I].VAnsiString);
2730 if (Args[I].VType = vtAnsiString) then
2731 if string(Args[I].VAnsiString) = '' then
2733 Result[I] := UnAssigned;
2735 Result[I] := UnAssigned;