unit uDAMySQLInterfaces; {----------------------------------------------------------------------------} { Data Abstract Library - Core Library } { } { compiler: Delphi 6 and up, Kylix 3 and up } { platform: Win32, Linux } { } { (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 SysUtils, uDAInterfaces, uDAEngine, uROClasses; type { IDAMySQLConnection For identification purposes Implemented by all MySQL connections } IDAMySQLConnection = interface(IDAConnection) ['{EB62495C-E922-45B3-B8DC-5DFCD787D3C8}'] end; TDAMySQLDriver = class(TDAEDriver) protected function GetAvailableDriverOptions: TDAAvailableDriverOptions; override; safecall; procedure GetAuxParams(const AuxDriver: string; out List: IROStrings); override; function GetDefaultCustomParameters: string; override; safecall; public end; TDAMySQLConnection = class(TDAEConnection, IDAMySQLConnection, IDACanQueryDatabaseNames) private protected function GetTableSchema: string; virtual; function useUnicode:Boolean; virtual; protected function DoGetLastAutoInc(const GeneratorName: string): integer; override; procedure DoGetStoredProcedureNames(out List: IROStrings); override; function GetDatabaseNames: IROStrings; procedure DoGetTableNames(out List: IROStrings); override; procedure DoGetViewNames(out List: IROStrings); override; procedure DoGetForeignKeys(out ForeignKeys: TDADriverForeignKeyCollection); override; procedure DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); override; procedure DoGetStoredProcedureParams(const aStoredProcedureName: string; out Params: TDAParamCollection); override; function IdentifierNeedsQuoting(const iIdentifier: string): boolean; override; safecall; public end; function MySQL_GetLastAutoInc(const GeneratorName: string; Query: IDADataset): integer; function MYSQL_GetDefaultCustomParameters: string; procedure MYSQL_GetAuxParams(List: IROStrings); function MYSQL_GetDatabaseNames(Query: IDADataset): IROStrings; procedure MYSQL_DoGetNames(Query: IDADataset; AList: IROStrings; AObjectType: TDAObjecttype; aSchema: string); procedure MYSQL_DoGetForeignKeys(Query: IDADataset; ForeignKeys: TDADriverForeignKeyCollection; aSchema: string); procedure MYSQL_DoGetTableFields(const aTableName: string; Query: IDADataset; out Fields: TDAFieldCollection; aSchema: string; useUnicode: Boolean=False); procedure MYSQL_DoGetStoredProcedureParams(const aStoredProcedureName: string; Query: IDADataset; out Params: TDAParamCollection; aSchema: string); function MYSQL_IdentifierNeedsQuoting(const iIdentifier: string): boolean; const MySQL_DriverType = 'MySQL'; implementation uses uDAUtils, StrUtils; var mysql_reservedwords : array of string; function MySQL_GetLastAutoInc(const GeneratorName: string; Query: IDADataset): integer; begin try Query.SQL := 'SELECT LAST_INSERT_ID()'; Query.Open; Result := Query.Fields[0].AsInteger; finally Query := nil; end; end; function MYSQL_GetDefaultCustomParameters: string; begin Result := 'Port=3306;'; end; procedure MYSQL_GetAuxParams(List: IROStrings); begin List.Add('Port='); end; { TDAMySQLDriver } procedure TDAMySQLDriver.GetAuxParams(const AuxDriver: string; out List: IROStrings); begin inherited; MYSQL_GetAuxParams(List); end; function TDAMySQLDriver.GetAvailableDriverOptions: TDAAvailableDriverOptions; begin result := [doServerName, doDatabaseName, doLogin, doCustom]; end; function TDAMySQLDriver.GetDefaultCustomParameters: string; begin Result := MYSQL_GetDefaultCustomParameters; end; function MYSQL_GetDatabaseNames(Query: IDADataset): IROStrings; begin Result := NewROStrings; try Query.SQL := 'SHOW DATABASES'; Query.Open; while not Query.Eof do begin Result.Add(Query.Fields[0].AsString); Query.Next; end; finally Query := nil; end; end; procedure MYSQL_DoGetNames(Query: IDADataset; AList: IROStrings; AObjectType: TDAObjecttype; aSchema: string); const sDoGetTableNames = 'SELECT TABLE_NAME ' + 'FROM INFORMATION_SCHEMA.TABLES ' + 'WHERE TABLE_TYPE = ''%s'' AND TABLE_SCHEMA = ''%s'''; sDOGetProcedures = 'SELECT ROUTINE_NAME ' + 'FROM INFORMATION_SCHEMA.ROUTINES ' + 'WHERE ROUTINE_TYPE = ''PROCEDURE'' AND ROUTINE_SCHEMA = ''%s'''; begin try case AObjectType of dotTable: Query.SQL := Format(sDoGetTableNames, ['BASE TABLE', aSchema]); dotView: Query.SQL := Format(sDoGetTableNames, ['VIEW', aSchema]); dotProcedure: Query.SQL := Format(sDOGetProcedures, [aSchema]); end; Query.Open; while not Query.Eof do begin Alist.Add(Query.Fields[0].AsString); Query.Next; end; finally Query := nil; end; end; procedure MYSQL_DoGetForeignKeys(Query: IDADataset; ForeignKeys: TDADriverForeignKeyCollection; aSchema: string); var lCurrConstraint : string; lCurrFK : TDADriverForeignKey; const sFK_SQL = 'SELECT ' + 'TABLE_NAME, REFERENCED_TABLE_NAME, COLUMN_NAME, REFERENCED_COLUMN_NAME ' + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' + 'WHERE CONSTRAINT_SCHEMA=''%s'' AND REFERENCED_TABLE_NAME IS NOT NULL'; begin lCurrConstraint := ''; lCurrFK := nil; try Query.SQL := Format(sFK_SQL, [aSchema]); Query.Open; ForeignKeys.Clear; while (not Query.EOF) do begin if lCurrConstraint <> Query.Fields[0].AsString + '|' + Query.Fields[1].AsString then begin lCurrConstraint := Query.Fields[0].AsString + '|' + Query.Fields[1].AsString; lCurrFK := ForeignKeys.Add(); with lCurrFK do begin PKTable := TrimRight(Query.Fields[0].AsString); FKTable := TrimRight(Query.Fields[1].AsString); PKField := TrimRight(Query.Fields[2].AsString); FKField := TrimRight(Query.Fields[3].AsString); end; end else begin with lCurrFK do begin PKField := PKField + ';' + TrimRight(Query.Fields[2].AsString); FKField := FKField + ';' + TrimRight(Query.Fields[3].AsString); end; end; Query.Next; end; finally Query := nil; end; end; function MySQLDataTypeToDA(aDataType: string; Unicode, AutoInc, Unsigned: boolean): TDADataType; begin aDataType := LowerCase(aDataType); if (aDAtaType = 'char') or (aDAtaType = 'varchar') or (aDAtaType = 'binary') or (aDAtaType = 'varbinary') or (aDataType = 'enum') or (aDataType = 'set') then begin if Unicode then Result := datWideString else Result := datString; end else if (aDataType = 'text') or (aDataType = 'longtext') or (aDataType = 'tinytext') or (aDataType = 'mediumtext') then begin if Unicode then Result := datWideMemo else Result := datMemo; end else if (aDataType = 'blob') or (aDataType = 'tinyblob') or (aDataType = 'mediumblob') or (aDataType = 'longblob') then Result := datBlob else if (aDataType = 'date') or (aDataType = 'time') or (aDataType = 'datetime') or (aDataType = 'timestamp') then result := datDateTime else if (aDataType = 'bit') then Result := datLargeUInt else if (aDataType = 'tinyint') then begin if Unsigned then result := datByte else result := datShortInt end else if (aDataType = 'smallint') then begin if Unsigned then Result := datWord else Result := datSmallInt end else if (aDataType = 'year') then Result := datWord else if (aDataType = 'mediumint') or (aDataType = 'int') or (aDataType = 'integer') then begin if AutoInc then Result := datAutoInc else if Unsigned then Result := datCardinal else result := datInteger end else if (aDataType = 'bigint') then begin if AutoInc then Result := datLargeAutoInc else if Unsigned then Result := datLargeUInt else result := datLargeInt end else if (aDataType = 'float') then begin Result := datSingleFloat end else if (aDataType = 'double') then begin Result := datFloat end else if (aDataType = 'decimal') then result := datDecimal else result := datUnknown; end; procedure MYSQL_DoGetTableFields(const aTableName: string; Query: IDADataset; out Fields: TDAFieldCollection; aSchema: string; useUnicode: Boolean); const sGetTableFields = 'SELECT ' + //TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE, COLUMN_KEY, EXTRA, PRIVILEGES, COLUMN_COMMENT 'COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, CHARACTER_MAXIMUM_LENGTH, CHARACTER_SET_NAME, COLUMN_KEY, COLUMN_COMMENT, EXTRA, COLUMN_TYPE ' + 'FROM INFORMATION_SCHEMA.COLUMNS ' + 'WHERE ' + '(TABLE_SCHEMA = ''%s'') AND (TABLE_NAME = ''%s'') ' + 'ORDER BY ORDINAL_POSITION'; var fld : TDAField; begin try Query.SQL := Format(sGetTableFields, [aSchema, aTableName]); Query.Open; Fields := TDAFieldCollection.Create(nil); while not Query.Eof do begin fld := Fields.Add; fld.Name := Query.Fields[0].AsString; fld.Required := Query.Fields[2].AsString <> 'YES'; if not Query.Fields[3].IsNull then fld.DefaultValue := Query.Fields[3].AsString; fld.Size := Query.Fields[4].AsInteger; fld.InPrimaryKey := SameText(Query.Fields[6].AsString, 'PRI'); fld.Description := Query.Fields[7].AsString; fld.DataType := MysqlDataTypeToDA(Query.Fields[1].asString, useUnicode and ( sametext(Query.Fields[5].AsString, 'utf8') or sametext(Query.Fields[5].AsString, 'ucs2')), SameText(Query.Fields[8].AsString, 'auto_increment'), pos(' unsigned',LowerCase(Query.Fields[9].AsString))>0); if fld.DefaultValue <> '' then begin if not TestDefaultValue(fld.DefaultValue, fld.DataType) then fld.DefaultValue := ''; end; Query.Next; end; finally Query := nil; end; end; procedure MYSQL_DoGetStoredProcedureParams(const aStoredProcedureName: string; Query: IDADataset; out Params: TDAParamCollection; aSchema: string); const sSQL = 'SELECT PARAM_LIST FROM MYSQL.PROC WHERE DB = ''%s'' AND NAME = ''%s'''; sError = 'Can''t parse procedures params'; aValidChars = ['A'..'Z', 'a'..'z', '0'..'9','_']; var par : TDAParam; s, s1 : string; p, p1 : pchar; begin try Query.SQL := Format(sSQL, [aSchema, aStoredProcedureName]); Query.Open; Params := TDAParamCollection.Create(nil); if (not Query.Eof) and (not Query.Fields[0].IsNull) then begin s := Query.Fields[0].AsString; p := Pchar(s); repeat while p^ = ',' do inc(p); while p^ = ' ' do inc(p); if p^ = #0 then Exit; par := Params.Add; p1 := p; while p1^ in aValidChars do inc(p1); if p1^ = #0 then exit; SetString(s1, p, p1 - p); s1 := Lowercase(s1); if s1 = 'in' then par.ParamType := daptInput else if s1 = 'out' then par.ParamType := daptOutput else if s1 = 'inout' then par.ParamType := daptInputOutput; if par.ParamType <> daptUnknown then begin while p1^ = ' ' do inc(p1); p := p1; while p1^ in aValidChars do inc(p1); if p1^ = #0 then exit; SetString(s1, p, p1 - p); end else begin par.ParamType := daptInput; end; par.Name := s1; while p1^ = ' ' do inc(p1); p := p1; while p1^ in aValidChars do inc(p1); SetString(s1, p, p1 - p); par.DataType := MysqlDataTypeToDA(s1, sametext(s1, 'utf8') or sametext(s1, 'ucs2'), False, pos(' unsigned',s1)>0); if p1^ = #0 then exit; while p1^ = ' ' do inc(p1); p := p1; until p^ <> ','; end; finally Query := nil; end; end; function MYSQL_IdentifierNeedsQuoting(const iIdentifier: string): boolean; var L,H,I, r: Integer; begin result := False; l := 0; h := Length(mysql_reservedwords) -1; while l <= h do begin i := (L + H) shr 1; r := CompareText(iIdentifier, mysql_reservedwords[i]); if r < 0 then h := i - 1 else if r > 0 then l := i + 1 else begin result := true; exit; end; end; end; { TDAMySQLConnection } procedure TDAMySQLConnection.DoGetForeignKeys( out ForeignKeys: TDADriverForeignKeyCollection); begin inherited; MYSQL_DoGetForeignKeys(GetDatasetClass.Create(Self), ForeignKeys, GetTableSchema); end; function TDAMySQLConnection.DoGetLastAutoInc( const GeneratorName: string): integer; begin Result := MySQL_GetLastAutoInc(GeneratorName, GetDatasetClass.Create(Self)); end; procedure TDAMySQLConnection.DoGetStoredProcedureNames( out List: IROStrings); begin inherited; MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotProcedure, GetTableSchema); end; procedure TDAMySQLConnection.DoGetStoredProcedureParams( const aStoredProcedureName: string; out Params: TDAParamCollection); begin MYSQL_DoGetStoredProcedureParams(aStoredProcedureName, GetDatasetClass.Create(Self), Params, GetTableSchema); end; procedure TDAMySQLConnection.DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); begin MYSQL_DoGetTableFields(QuoteIdentifierIfNeeded(aTableName), GetDatasetClass.Create(Self), Fields, GetTableSchema,useUnicode); end; procedure TDAMySQLConnection.DoGetTableNames(out List: IROStrings); begin inherited; MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotTable, GetTableSchema); end; procedure TDAMySQLConnection.DoGetViewNames(out List: IROStrings); begin inherited; MYSQL_DoGetNames(GetDatasetClass.Create(Self), List, dotView, GetTableSchema); end; function TDAMySQLConnection.GetDatabaseNames: IROStrings; begin Result := MYSQL_GetDatabaseNames(GetDatasetClass.Create(Self)); end; function TDAMySQLConnection.GetTableSchema: string; begin with TDAConnectionStringParser.Create(GetConnectionString) do try Result := Database; finally Free; end; end; procedure MYSQL_InitializeReservedWords; begin SetLength(mysql_reservedwords, 229); mysql_reservedwords[0] := 'ACTION'; mysql_reservedwords[1] := 'ADD'; mysql_reservedwords[2] := 'ALL'; mysql_reservedwords[3] := 'ALTER'; mysql_reservedwords[4] := 'ANALYZE'; mysql_reservedwords[5] := 'AND'; mysql_reservedwords[6] := 'AS'; mysql_reservedwords[7] := 'ASC'; mysql_reservedwords[8] := 'ASENSITIVE'; mysql_reservedwords[9] := 'BEFORE'; mysql_reservedwords[10] := 'BETWEEN'; mysql_reservedwords[11] := 'BIGINT'; mysql_reservedwords[12] := 'BINARY'; mysql_reservedwords[13] := 'BIT'; mysql_reservedwords[14] := 'BLOB'; mysql_reservedwords[15] := 'BOTH'; mysql_reservedwords[16] := 'BY'; mysql_reservedwords[17] := 'CALL'; mysql_reservedwords[18] := 'CASCADE'; mysql_reservedwords[19] := 'CASE'; mysql_reservedwords[20] := 'CHANGE'; mysql_reservedwords[21] := 'CHAR'; mysql_reservedwords[22] := 'CHARACTER'; mysql_reservedwords[23] := 'CHECK'; mysql_reservedwords[24] := 'COLLATE'; mysql_reservedwords[25] := 'COLUMN'; mysql_reservedwords[26] := 'CONDITION'; mysql_reservedwords[27] := 'CONSTRAINT'; mysql_reservedwords[28] := 'CONTINUE'; mysql_reservedwords[29] := 'CONVERT'; mysql_reservedwords[30] := 'CREATE'; mysql_reservedwords[31] := 'CROSS'; mysql_reservedwords[32] := 'CURRENT_DATE'; mysql_reservedwords[33] := 'CURRENT_TIME'; mysql_reservedwords[34] := 'CURRENT_TIMESTAMP'; mysql_reservedwords[35] := 'CURRENT_USER'; mysql_reservedwords[36] := 'CURSOR'; mysql_reservedwords[37] := 'DATABASE'; mysql_reservedwords[38] := 'DATABASES'; mysql_reservedwords[39] := 'DATE'; mysql_reservedwords[40] := 'DAY_HOUR'; mysql_reservedwords[41] := 'DAY_MICROSECOND'; mysql_reservedwords[42] := 'DAY_MINUTE'; mysql_reservedwords[43] := 'DAY_SECOND'; mysql_reservedwords[44] := 'DEC'; mysql_reservedwords[45] := 'DECIMAL'; mysql_reservedwords[46] := 'DECLARE'; mysql_reservedwords[47] := 'DEFAULT'; mysql_reservedwords[48] := 'DELAYED'; mysql_reservedwords[49] := 'DELETE'; mysql_reservedwords[50] := 'DESC'; mysql_reservedwords[51] := 'DESCRIBE'; mysql_reservedwords[52] := 'DETERMINISTIC'; mysql_reservedwords[53] := 'DISTINCT'; mysql_reservedwords[54] := 'DISTINCTROW'; mysql_reservedwords[55] := 'DIV'; mysql_reservedwords[56] := 'DOUBLE'; mysql_reservedwords[57] := 'DROP'; mysql_reservedwords[58] := 'DUAL'; mysql_reservedwords[59] := 'EACH'; mysql_reservedwords[60] := 'ELSE'; mysql_reservedwords[61] := 'ELSEIF'; mysql_reservedwords[62] := 'ENCLOSED'; mysql_reservedwords[63] := 'ENUM'; mysql_reservedwords[64] := 'ESCAPED'; mysql_reservedwords[65] := 'EXISTS'; mysql_reservedwords[66] := 'EXIT'; mysql_reservedwords[67] := 'EXPLAIN'; mysql_reservedwords[68] := 'FALSE'; mysql_reservedwords[69] := 'FETCH'; mysql_reservedwords[70] := 'FLOAT'; mysql_reservedwords[71] := 'FLOAT4'; mysql_reservedwords[72] := 'FLOAT8'; mysql_reservedwords[73] := 'FOR'; mysql_reservedwords[74] := 'FORCE'; mysql_reservedwords[75] := 'FOREIGN'; mysql_reservedwords[76] := 'FROM'; mysql_reservedwords[77] := 'FULLTEXT'; mysql_reservedwords[78] := 'GRANT'; mysql_reservedwords[79] := 'GROUP'; mysql_reservedwords[80] := 'HAVING'; mysql_reservedwords[81] := 'HIGH_PRIORITY'; mysql_reservedwords[82] := 'HOUR_MICROSECOND'; mysql_reservedwords[83] := 'HOUR_MINUTE'; mysql_reservedwords[84] := 'HOUR_SECOND'; mysql_reservedwords[85] := 'IF'; mysql_reservedwords[86] := 'IGNORE'; mysql_reservedwords[87] := 'IN'; mysql_reservedwords[88] := 'INDEX'; mysql_reservedwords[89] := 'INFILE'; mysql_reservedwords[90] := 'INNER'; mysql_reservedwords[91] := 'INOUT'; mysql_reservedwords[92] := 'INSENSITIVE'; mysql_reservedwords[93] := 'INSERT'; mysql_reservedwords[94] := 'INT'; mysql_reservedwords[95] := 'INT1'; mysql_reservedwords[96] := 'INT2'; mysql_reservedwords[97] := 'INT3'; mysql_reservedwords[98] := 'INT4'; mysql_reservedwords[99] := 'INT8'; mysql_reservedwords[100] := 'INTEGER'; mysql_reservedwords[101] := 'INTERVAL'; mysql_reservedwords[102] := 'INTO'; mysql_reservedwords[103] := 'IS'; mysql_reservedwords[104] := 'ITERATE'; mysql_reservedwords[105] := 'JOIN'; mysql_reservedwords[106] := 'KEY'; mysql_reservedwords[107] := 'KEYS'; mysql_reservedwords[108] := 'KILL'; mysql_reservedwords[109] := 'LEADING'; mysql_reservedwords[110] := 'LEAVE'; mysql_reservedwords[111] := 'LEFT'; mysql_reservedwords[112] := 'LIKE'; mysql_reservedwords[113] := 'LIMIT'; mysql_reservedwords[114] := 'LINES'; mysql_reservedwords[115] := 'LOAD'; mysql_reservedwords[116] := 'LOCALTIME'; mysql_reservedwords[117] := 'LOCALTIMESTAMP'; mysql_reservedwords[118] := 'LOCK'; mysql_reservedwords[119] := 'LONG'; mysql_reservedwords[120] := 'LONGBLOB'; mysql_reservedwords[121] := 'LONGTEXT'; mysql_reservedwords[122] := 'LOOP'; mysql_reservedwords[123] := 'LOW_PRIORITY'; mysql_reservedwords[124] := 'MATCH'; mysql_reservedwords[125] := 'MEDIUMBLOB'; mysql_reservedwords[126] := 'MEDIUMINT'; mysql_reservedwords[127] := 'MEDIUMTEXT'; mysql_reservedwords[128] := 'MIDDLEINT'; mysql_reservedwords[129] := 'MINUTE_MICROSECOND'; mysql_reservedwords[130] := 'MINUTE_SECOND'; mysql_reservedwords[131] := 'MOD'; mysql_reservedwords[132] := 'MODIFIES'; mysql_reservedwords[133] := 'NATURAL'; mysql_reservedwords[134] := 'NO'; mysql_reservedwords[135] := 'NO_WRITE_TO_BINLOG'; mysql_reservedwords[136] := 'NOT'; mysql_reservedwords[137] := 'NULL'; mysql_reservedwords[138] := 'NUMERIC'; mysql_reservedwords[139] := 'ON'; mysql_reservedwords[140] := 'OPTIMIZE'; mysql_reservedwords[141] := 'OPTION'; mysql_reservedwords[142] := 'OPTIONALLY'; mysql_reservedwords[143] := 'OR'; mysql_reservedwords[144] := 'ORDER'; mysql_reservedwords[145] := 'OUT'; mysql_reservedwords[146] := 'OUTER'; mysql_reservedwords[147] := 'OUTFILE'; mysql_reservedwords[148] := 'PRECISION'; mysql_reservedwords[149] := 'PRIMARY'; mysql_reservedwords[150] := 'PROCEDURE'; mysql_reservedwords[151] := 'PURGE'; mysql_reservedwords[152] := 'RAID0'; mysql_reservedwords[153] := 'READ'; mysql_reservedwords[154] := 'READS'; mysql_reservedwords[155] := 'REAL'; mysql_reservedwords[156] := 'REFERENCES'; mysql_reservedwords[157] := 'REGEXP'; mysql_reservedwords[158] := 'RELEASE'; mysql_reservedwords[159] := 'RENAME'; mysql_reservedwords[160] := 'REPEAT'; mysql_reservedwords[161] := 'REPLACE'; mysql_reservedwords[162] := 'REQUIRE'; mysql_reservedwords[163] := 'RESTRICT'; mysql_reservedwords[164] := 'RETURN'; mysql_reservedwords[165] := 'REVOKE'; mysql_reservedwords[166] := 'RIGHT'; mysql_reservedwords[167] := 'RLIKE'; mysql_reservedwords[168] := 'SCHEMA'; mysql_reservedwords[169] := 'SCHEMAS'; mysql_reservedwords[170] := 'SECOND_MICROSECOND'; mysql_reservedwords[171] := 'SELECT'; mysql_reservedwords[172] := 'SENSITIVE'; mysql_reservedwords[173] := 'SEPARATOR'; mysql_reservedwords[174] := 'SET'; mysql_reservedwords[175] := 'SHOW'; mysql_reservedwords[176] := 'SMALLINT'; mysql_reservedwords[177] := 'SONAME'; mysql_reservedwords[178] := 'SPATIAL'; mysql_reservedwords[179] := 'SPECIFIC'; mysql_reservedwords[180] := 'SQL'; mysql_reservedwords[181] := 'SQL_BIG_RESULT'; mysql_reservedwords[182] := 'SQL_CALC_FOUND_ROWS'; mysql_reservedwords[183] := 'SQL_SMALL_RESULT'; mysql_reservedwords[184] := 'SQLEXCEPTION'; mysql_reservedwords[185] := 'SQLSTATE'; mysql_reservedwords[186] := 'SQLWARNING'; mysql_reservedwords[187] := 'SSL'; mysql_reservedwords[188] := 'STARTING'; mysql_reservedwords[189] := 'STRAIGHT_JOIN'; mysql_reservedwords[190] := 'TABLE'; mysql_reservedwords[191] := 'TERMINATED'; mysql_reservedwords[192] := 'TEXT'; mysql_reservedwords[193] := 'THEN'; mysql_reservedwords[194] := 'TIME'; mysql_reservedwords[195] := 'TIMESTAMP'; mysql_reservedwords[196] := 'TINYBLOB'; mysql_reservedwords[197] := 'TINYINT'; mysql_reservedwords[198] := 'TINYTEXT'; mysql_reservedwords[199] := 'TO'; mysql_reservedwords[200] := 'TRAILING'; mysql_reservedwords[201] := 'TRIGGER'; mysql_reservedwords[202] := 'TRUE'; mysql_reservedwords[203] := 'UNDO'; mysql_reservedwords[204] := 'UNION'; mysql_reservedwords[205] := 'UNIQUE'; mysql_reservedwords[206] := 'UNLOCK'; mysql_reservedwords[207] := 'UNSIGNED'; mysql_reservedwords[208] := 'UPDATE'; mysql_reservedwords[209] := 'USAGE'; mysql_reservedwords[210] := 'USE'; mysql_reservedwords[211] := 'USING'; mysql_reservedwords[212] := 'UTC_DATE'; mysql_reservedwords[213] := 'UTC_TIME'; mysql_reservedwords[214] := 'UTC_TIMESTAMP'; mysql_reservedwords[215] := 'VALUES'; mysql_reservedwords[216] := 'VARBINARY'; mysql_reservedwords[217] := 'VARCHAR'; mysql_reservedwords[218] := 'VARCHARACTER'; mysql_reservedwords[219] := 'VARYING'; mysql_reservedwords[220] := 'WHEN'; mysql_reservedwords[221] := 'WHERE'; mysql_reservedwords[222] := 'WHILE'; mysql_reservedwords[223] := 'WITH'; mysql_reservedwords[224] := 'WRITE'; mysql_reservedwords[225] := 'X509'; mysql_reservedwords[226] := 'XOR'; mysql_reservedwords[227] := 'YEAR_MONTH'; mysql_reservedwords[228] := 'ZEROFILL'; end; function TDAMySQLConnection.IdentifierNeedsQuoting( const iIdentifier: string): boolean; begin Result := inherited IdentifierNeedsQuoting(iIdentifier) or MYSQL_IdentifierNeedsQuoting(iIdentifier); end; function TDAMySQLConnection.useUnicode: Boolean; begin Result:=False; end; initialization mysql_InitializeReservedWords; finalization mysql_reservedwords := nil; end.