From: Enrique E. <the...@us...> - 2005-11-06 20:52:02
|
Update of /cvsroot/instantobjects/Source/Brokers/ZeosDBO In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28692/Brokers/ZeosDBO Modified Files: InstantZeosDBO.pas InstantZeosDBOCatalog.pas Log Message: Evolution support for SQLite of ZeosDBO broker Index: InstantZeosDBOCatalog.pas =================================================================== RCS file: /cvsroot/instantobjects/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** InstantZeosDBOCatalog.pas 18 Oct 2005 22:55:18 -0000 1.1 --- InstantZeosDBOCatalog.pas 6 Nov 2005 20:51:53 -0000 1.2 *************** *** 59,63 **** uses ! SysUtils, Classes, ZConnection, InstantConsts, InstantZeosDBO, TypInfo; procedure TInstantZeosDBOCatalog.AddFieldMetadatas( --- 59,63 ---- uses ! Types, SysUtils, Classes, ZConnection, InstantConsts, InstantZeosDBO, TypInfo; procedure TInstantZeosDBOCatalog.AddFieldMetadatas( *************** *** 72,77 **** TableMetadata.Name, ''); ! Fields.First; ! while not Fields.IsAfterLast do begin FieldMetadata := TableMetadata.FieldMetadatas.Add; --- 72,77 ---- TableMetadata.Name, ''); ! Fields.BeforeFirst; ! while Fields.Next do begin FieldMetadata := TableMetadata.FieldMetadatas.Add; *************** *** 82,86 **** FieldMetadata.AlternateDataTypes := AlternateDataTypes; FieldMetadata.Options := []; ! if Fields.GetBooleanByName('IS_NULLABLE') then FieldMetadata.Options := FieldMetadata.Options + [foRequired]; if TableMetadata.IndexMetadatas.IsFieldIndexed(FieldMetadata) then --- 82,86 ---- FieldMetadata.AlternateDataTypes := AlternateDataTypes; FieldMetadata.Options := []; ! if not Fields.GetBooleanByName('IS_NULLABLE') then FieldMetadata.Options := FieldMetadata.Options + [foRequired]; if TableMetadata.IndexMetadatas.IsFieldIndexed(FieldMetadata) then *************** *** 92,96 **** else FieldMetadata.Size := Fields.GetIntByName('COLUMN_SIZE'); - Fields.Next; end; end; --- 92,95 ---- *************** *** 108,128 **** TableMetadata.Name); ! PrimaryKeys.First; ! while not PrimaryKeys.IsAfterLast do begin ! IndexMetadata := TableMetadata.IndexMetadatas.Add; ! IndexMetadata.Name := PrimaryKeys.GetStringByName('PK_NAME'); ! IndexMetadata.Fields := PrimaryKeys.GetStringByName('COLUMN_NAME'); ! IndexMetadata.Options := [ixPrimary, ixUnique]; ! if PrimaryKeys.Next then ! while AnsiSameStr(IndexMetadata.Name, ! PrimaryKeys.GetStringByName('COLUMN_NAME')) do ! begin ! IndexMetadata.Fields := ';' + IndexMetadata.Fields + ! PrimaryKeys.GetStringByName('COLUMN_NAME'); ! PrimaryKeys.Next; ! end; end; - PrimaryKeys := nil; with Broker as TInstantZeosDBOBroker, Connector.Connection as TZConnection do --- 107,127 ---- TableMetadata.Name); ! IndexMetadata := nil; ! PrimaryKeys.BeforeFirst; ! while PrimaryKeys.Next do begin ! IndexName := PrimaryKeys.GetStringByName('PK_NAME'); ! if Assigned(IndexMetadata) and ! AnsiSameStr(IndexMetadata.Name, IndexName) then ! IndexMetadata.Fields := ';' + IndexMetadata.Fields + ! PrimaryKeys.GetStringByName('COLUMN_NAME') ! else ! begin ! IndexMetadata := TableMetadata.IndexMetadatas.Add; ! IndexMetadata.Name := IndexName; ! IndexMetadata.Fields := PrimaryKeys.GetStringByName('COLUMN_NAME'); ! IndexMetadata.Options := [ixPrimary, ixUnique]; ! end; end; with Broker as TInstantZeosDBOBroker, Connector.Connection as TZConnection do *************** *** 130,135 **** TableMetadata.Name, False, False); ! IndexInfo.First; ! while not IndexInfo.IsAfterLast do begin //Exclude primary keys --- 129,135 ---- TableMetadata.Name, False, False); ! IndexMetadata := nil; ! IndexInfo.BeforeFirst; ! while IndexInfo.Next do begin //Exclude primary keys *************** *** 139,161 **** (AnsiPos('PRI', IndexName) = 0) then begin ! IndexMetadata := TableMetadata.IndexMetadatas.Add; ! IndexMetadata.Name := IndexName; ! IndexMetadata.Fields := IndexInfo.GetStringByName('COLUMN_NAME'); ! IndexMetadata.Options := []; ! if not IndexInfo.GetBooleanByName('NON_UNIQUE') then ! IndexMetadata.Options := IndexMetadata.Options + [ixUnique]; ! if IndexInfo.GetStringByName('ASC_OR_DESC') = 'D' then ! IndexMetadata.Options := IndexMetadata.Options + [ixDescending]; ! if IndexInfo.Next then ! while AnsiSameStr(IndexMetadata.Name, ! IndexInfo.GetStringByName('COLUMN_NAME')) do ! begin ! IndexMetadata.Fields := ';' + IndexMetadata.Fields + ! IndexInfo.GetStringByName('COLUMN_NAME'); ! IndexInfo.Next; ! end; ! end ! else ! IndexInfo.Next; end; end; --- 139,157 ---- (AnsiPos('PRI', IndexName) = 0) then begin ! if Assigned(IndexMetadata) and ! AnsiSameStr(IndexMetadata.Name, IndexName) then ! IndexMetadata.Fields := ';' + IndexMetadata.Fields + ! IndexInfo.GetStringByName('COLUMN_NAME'); ! begin ! IndexMetadata := TableMetadata.IndexMetadatas.Add; ! IndexMetadata.Name := IndexName; ! IndexMetadata.Fields := IndexInfo.GetStringByName('COLUMN_NAME'); ! IndexMetadata.Options := []; ! if not IndexInfo.GetBooleanByName('NON_UNIQUE') then ! IndexMetadata.Options := IndexMetadata.Options + [ixUnique]; ! if IndexInfo.GetStringByName('ASC_OR_DESC') = 'D' then ! IndexMetadata.Options := IndexMetadata.Options + [ixDescending]; ! end; ! end; end; end; *************** *** 164,189 **** TableMetadatas: TInstantTableMetadatas); var TableMetadata: TInstantTableMetadata; Tables: IZResultSet; begin with Broker as TInstantZeosDBOBroker, Connector.Connection do begin if not Connector.Connected then Connector.Connect; ! Tables := DbcConnection.GetMetadata.GetTables(Catalog, '', '', nil); end; ! Tables.First; ! while not Tables.IsAfterLast do begin ! if AnsiSameStr(Tables.GetStringByName('TABLE_TYPE'), 'TABLE') then ! begin ! TableMetadata := TableMetadatas.Add; ! TableMetadata.Name := Tables.GetStringByName('TABLE_NAME'); ! // Call AddIndexMetadatas first, so that AddFieldMetadatas can see what ! // indexes are defined to correctly set the foIndexed option. ! AddIndexMetadatas(TableMetadata); ! AddFieldMetadatas(TableMetadata); ! end; ! Tables.Next; end; end; --- 160,185 ---- TableMetadatas: TInstantTableMetadatas); var + TableType: TStringDynArray; TableMetadata: TInstantTableMetadata; Tables: IZResultSet; begin + SetLength(TableType, 1); + TableType[0] := 'TABLE'; with Broker as TInstantZeosDBOBroker, Connector.Connection do begin if not Connector.Connected then Connector.Connect; ! DbcConnection.GetMetadata.ClearCache; ! Tables := DbcConnection.GetMetadata.GetTables(Catalog, '', '', TableType); end; ! Tables.BeforeFirst; ! while Tables.Next do begin ! TableMetadata := TableMetadatas.Add; ! TableMetadata.Name := Tables.GetStringByName('TABLE_NAME'); ! // Call AddIndexMetadatas first, so that AddFieldMetadatas can see what ! // indexes are defined to correctly set the foIndexed option. ! AddIndexMetadatas(TableMetadata); ! AddFieldMetadatas(TableMetadata); end; end; Index: InstantZeosDBO.pas =================================================================== RCS file: /cvsroot/instantobjects/Source/Brokers/ZeosDBO/InstantZeosDBO.pas,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** InstantZeosDBO.pas 23 Oct 2005 17:05:28 -0000 1.4 --- InstantZeosDBO.pas 6 Nov 2005 20:51:53 -0000 1.5 *************** *** 50,54 **** uses ! Classes, Db, InstantPersistence, InstantCommand, ZConnection; type --- 50,54 ---- uses ! Classes, Db, InstantPersistence, InstantCommand, InstantDBBuild, ZConnection; type *************** *** 147,151 **** TInstantZeosDBOResolver = class(TInstantSQLResolver) ! // Read an integer field and convert it to boolean expression protected function ReadBooleanField(DataSet: TDataSet; const FieldName: string): Boolean; override; --- 147,151 ---- TInstantZeosDBOResolver = class(TInstantSQLResolver) ! // Read an integer field and convert it to boolean expression protected function ReadBooleanField(DataSet: TDataSet; const FieldName: string): Boolean; override; *************** *** 153,157 **** TInstantZeosDBOTranslator = class(TInstantRelationalTranslator) ! // Translate boolean expressions to '0' or '1' protected function TranslateConstant(Constant: TInstantIQLConstant; Writer: TInstantIQLWriter): Boolean; override; --- 153,157 ---- TInstantZeosDBOTranslator = class(TInstantRelationalTranslator) ! // Translate boolean expressions to '0' or '1' protected function TranslateConstant(Constant: TInstantIQLConstant; Writer: TInstantIQLWriter): Boolean; override; *************** *** 218,222 **** TInstantZeosDBOMySQLBroker = class(TInstantZeosDBOBroker) protected ! function InternalDataTypeToColumnType(DataType: TInstantDataType): string; override; function UseBooleanFields: Boolean; override; end; --- 218,223 ---- TInstantZeosDBOMySQLBroker = class(TInstantZeosDBOBroker) protected ! function InternalDataTypeToColumnType(DataType: TInstantDataType): string; ! override; function UseBooleanFields: Boolean; override; end; *************** *** 226,233 **** --- 227,270 ---- {$IFDEF SQLITE_SUPPORT} + + //SQLite doesn´t support ALTER TABLE for supports ADD COLUMN, ALTER COLUMN and + //DROP COLUMN, is emulated with a couple of CREATE TEMP TABLE, INSERT INTO, + //DROP TABLE, CREATE TABLE, INSERT INTO and finally DROP TABLE + TInstantDBBuildSQLiteAlterTableSQLCommand = class(TInstantDBBuildSQLCommand) + private + FTmpTableMD: TInstantTableMetadata; + FOldTableMetadata: TInstantTableMetadata; + FNewTableMetadata: TInstantTableMetadata; + FScheme : TInstantScheme; + function GetNewTableMetadata: TInstantTableMetadata; + function GetOldTableMetadata: TInstantTableMetadata; + protected + procedure Rollback; virtual; + function GetDescription: string; override; + function GetSQLStatement(const Index: Integer): string; override; + function GetSQLStatementCount: Integer; override; + procedure InternalExecute; override; + public + destructor Destroy; override; + property OldTableMetadata: TInstantTableMetadata read GetOldTableMetadata; + property NewTableMetadata: TInstantTableMetadata read GetNewTableMetadata; + end; + + TInstantSQLiteGenerator = class(TInstantSQLGenerator) + protected + function InternalGenerateInsertFromSelectSQL(const SourceMetadata, TargetMetadata: TInstantTableMetadata): string; virtual; + function InternalGenerateCreateTempTableSQL(Metadata: TInstantTableMetadata): string; virtual; + public + function GenerateCreateTempTableSQL(Metadata: TInstantTableMetadata): string; + function GenerateInsertFromSelectSQL(const SourceMetadata, TargetMetadata: TInstantTableMetadata): string; + end; + TInstantZeosDBOSQLiteBroker = class(TInstantZeosDBOBroker) protected function InternalDataTypeToColumnType(DataType: TInstantDataType): string; override; function UseBooleanFields: Boolean; override; + public + class function GeneratorClass: TInstantSQLGeneratorClass; override; + function CreateDBBuildCommand(const CommandType: TInstantDBBuildCommandType): TInstantDBBuildCommand; override; end; {$ENDIF} *************** *** 238,246 **** uses ! SysUtils, {$IFDEF D7+}Types,{$ENDIF} Controls, InstantConsts, InstantClasses, ! InstantDBBuild, InstantZeosDBOConnectionDefEdit, InstantZeosDBOCatalog, ! InstantUtils, ZClasses, ZCompatibility, ZDbcIntfs, ZDataset; ! { Global routines } procedure AssignZeosDBOProtocols(Strings: TStrings); --- 275,288 ---- uses ! SysUtils, {$IFDEF D7+}Types, {$ENDIF}Controls, InstantConsts, InstantClasses, ! InstantZeosDBOConnectionDefEdit, InstantZeosDBOCatalog, InstantUtils, ZClasses, ! ZCompatibility, ZDbcIntfs, ZDataset; ! {$IFDEF SQLITE_SUPPORT} ! const ! STmpTableSuffix = '_XYZ_'; ! {$ENDIF} ! ! { Global routines } procedure AssignZeosDBOProtocols(Strings: TStrings); *************** *** 268,272 **** end; ! class function TInstantZeosDBOConnectionDef.ConnectorClass: TInstantConnectorClass; begin Result := TInstantZeosDBOConnector; --- 310,315 ---- end; ! class function TInstantZeosDBOConnectionDef.ConnectorClass: ! TInstantConnectorClass; begin Result := TInstantZeosDBOConnector; *************** *** 348,352 **** end; ! class function TInstantZeosDBOConnector.ConnectionDefClass: TInstantConnectionDefClass; begin Result := TInstantZeosDBOConnectionDef; --- 391,396 ---- end; ! class function TInstantZeosDBOConnector.ConnectionDefClass: ! TInstantConnectionDefClass; begin Result := TInstantZeosDBOConnectionDef; *************** *** 378,384 **** {$IFDEF IBFB_SUPPORT} if SameText(FConnection.Protocol, 'interbase-5') or ! SameText(FConnection.Protocol, 'interbase-6') or ! SameText(FConnection.Protocol, 'firebird-1.0') or ! SameText(FConnection.Protocol, 'firebird-1.5') then Result := TInstantZeosDBOIbFbBroker.Create(Self); {$ENDIF} --- 422,428 ---- {$IFDEF IBFB_SUPPORT} if SameText(FConnection.Protocol, 'interbase-5') or ! SameText(FConnection.Protocol, 'interbase-6') or ! SameText(FConnection.Protocol, 'firebird-1.0') or ! SameText(FConnection.Protocol, 'firebird-1.5') then Result := TInstantZeosDBOIbFbBroker.Create(Self); {$ENDIF} *************** *** 386,390 **** {$IFDEF ORACLE_SUPPORT} if SameText(FConnection.Protocol, 'oracle') or ! SameText(FConnection.Protocol, 'oracle-9i') then Result := TInstantZeosDBOOracleBroker.Create(Self); {$ENDIF} --- 430,434 ---- {$IFDEF ORACLE_SUPPORT} if SameText(FConnection.Protocol, 'oracle') or ! SameText(FConnection.Protocol, 'oracle-9i') then Result := TInstantZeosDBOOracleBroker.Create(Self); {$ENDIF} *************** *** 392,399 **** {$IFDEF PGSQL_SUPPORT} if SameText(FConnection.Protocol, 'postgresql') or ! SameText(FConnection.Protocol, 'postgresql-6.5') or ! SameText(FConnection.Protocol, 'postgresql-7.2') or ! SameText(FConnection.Protocol, 'postgresql-7.3') or ! SameText(FConnection.Protocol, 'postgresql-7.4') then Result := TInstantZeosDBOPgSQLBroker.Create(Self); {$ENDIF} --- 436,443 ---- {$IFDEF PGSQL_SUPPORT} if SameText(FConnection.Protocol, 'postgresql') or ! SameText(FConnection.Protocol, 'postgresql-6.5') or ! SameText(FConnection.Protocol, 'postgresql-7.2') or ! SameText(FConnection.Protocol, 'postgresql-7.3') or ! SameText(FConnection.Protocol, 'postgresql-7.4') then Result := TInstantZeosDBOPgSQLBroker.Create(Self); {$ENDIF} *************** *** 401,408 **** {$IFDEF MYSQL_SUPPORT} if SameText(FConnection.Protocol, 'mysql') or ! SameText(FConnection.Protocol, 'mysql-3.20') or ! SameText(FConnection.Protocol, 'mysql-3.23') or ! SameText(FConnection.Protocol, 'mysql-4.0') or ! SameText(FConnection.Protocol, 'mysql-4.1') then Result := TInstantZeosDBOMySQLBroker.Create(Self); {$ENDIF} --- 445,452 ---- {$IFDEF MYSQL_SUPPORT} if SameText(FConnection.Protocol, 'mysql') or ! SameText(FConnection.Protocol, 'mysql-3.20') or ! SameText(FConnection.Protocol, 'mysql-3.23') or ! SameText(FConnection.Protocol, 'mysql-4.0') or ! SameText(FConnection.Protocol, 'mysql-4.1') then Result := TInstantZeosDBOMySQLBroker.Create(Self); {$ENDIF} *************** *** 410,414 **** {$IFDEF SQLITE_SUPPORT} if SameText(FConnection.Protocol, 'sqlite') or ! SameText(FConnection.Protocol, 'sqlite-2.8') then Result := TInstantZeosDBOSQLiteBroker.Create(Self); {$ENDIF} --- 454,458 ---- {$IFDEF SQLITE_SUPPORT} if SameText(FConnection.Protocol, 'sqlite') or ! SameText(FConnection.Protocol, 'sqlite-2.8') then Result := TInstantZeosDBOSQLiteBroker.Create(Self); {$ENDIF} *************** *** 416,420 **** if Result = nil then raise EInstantError.CreateFmt('ZeosDBO protocol "%s" not supported', ! [FConnection.Protocol]); end; --- 460,464 ---- if Result = nil then raise EInstantError.CreateFmt('ZeosDBO protocol "%s" not supported', ! [FConnection.Protocol]); end; *************** *** 448,452 **** if not (csDesigning in ComponentState) then CheckConnection; ! Result := FConnection; end; --- 492,496 ---- if not (csDesigning in ComponentState) then CheckConnection; ! Result := FConnection; end; *************** *** 580,585 **** end; *) ! else ! TargetParam.Assign(SourceParam); end; end; --- 624,629 ---- end; *) ! else ! TargetParam.Assign(SourceParam); end; end; *************** *** 644,648 **** begin if Connector.Connected then ! Result := Connector.Connection.DbcConnection.GetMetadata.GetIdentifierQuoteString; { TODO : else? } end; --- 688,693 ---- begin if Connector.Connected then ! Result := ! Connector.Connection.DbcConnection.GetMetadata.GetIdentifierQuoteString; { TODO : else? } end; *************** *** 683,687 **** begin if Connector.Connected then ! Result := Connector.Connection.DbcConnection.GetMetadata.GetDatabaseProductName; { TODO : else? } end; --- 728,733 ---- begin if Connector.Connected then ! Result := ! Connector.Connection.DbcConnection.GetMetadata.GetDatabaseProductName; { TODO : else? } end; *************** *** 724,733 **** Writer.WriteChar('1'); Result := True; ! end else ! if SameText(Constant.Value, InstantFalseString) then begin Writer.WriteChar('0'); Result := True; ! end else Result := inherited TranslateConstant(Constant, Writer); end; --- 770,780 ---- Writer.WriteChar('1'); Result := True; ! end ! else if SameText(Constant.Value, InstantFalseString) then begin Writer.WriteChar('0'); Result := True; ! end ! else Result := inherited TranslateConstant(Constant, Writer); end; *************** *** 735,739 **** { TInstantZeosDBOQuery } ! class function TInstantZeosDBOQuery.TranslatorClass: TInstantRelationalTranslatorClass; begin Result := TInstantZeosDBOTranslator; --- 782,787 ---- { TInstantZeosDBOQuery } ! class function TInstantZeosDBOQuery.TranslatorClass: ! TInstantRelationalTranslatorClass; begin Result := TInstantZeosDBOTranslator; *************** *** 743,758 **** {$IFDEF SYBASE_SUPPORT} function TInstantZeosDBOSybaseBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'DOUBLE PRECISION', ! 'MONEY', ! 'TINYINT', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'IMAGE'); begin Result := Types[DataType]; --- 791,807 ---- {$IFDEF SYBASE_SUPPORT} + function TInstantZeosDBOSybaseBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'DOUBLE PRECISION', ! 'MONEY', ! 'TINYINT', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'IMAGE'); begin Result := Types[DataType]; *************** *** 768,783 **** {$IFDEF MSSQL_SUPPORT} function TInstantZeosDBOMSSQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'MONEY', ! 'BIT', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'IMAGE'); begin Result := Types[DataType]; --- 817,833 ---- {$IFDEF MSSQL_SUPPORT} + function TInstantZeosDBOMSSQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'MONEY', ! 'BIT', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'IMAGE'); begin Result := Types[DataType]; *************** *** 793,808 **** {$IFDEF IBFB_SUPPORT} function TInstantZeosDBOIbFbBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'DOUBLE PRECISION', ! 'DECIMAL(14,4)', ! 'SMALLINT', ! 'VARCHAR', ! 'BLOB SUB_TYPE 1', ! 'TIMESTAMP', ! 'BLOB'); begin Result := Types[DataType]; --- 843,859 ---- {$IFDEF IBFB_SUPPORT} + function TInstantZeosDBOIbFbBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'DOUBLE PRECISION', ! 'DECIMAL(14,4)', ! 'SMALLINT', ! 'VARCHAR', ! 'BLOB SUB_TYPE 1', ! 'TIMESTAMP', ! 'BLOB'); begin Result := Types[DataType]; *************** *** 818,833 **** {$IFDEF ORACLE_SUPPORT} function TInstantZeosDBOOracleBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'NUMBER(10)', ! 'FLOAT', ! 'NUMBER(14,4)', ! 'NUMBER(1)', ! 'VARCHAR2', ! 'CLOB', ! 'DATE', ! 'BLOB'); begin Result := Types[DataType]; --- 869,885 ---- {$IFDEF ORACLE_SUPPORT} + function TInstantZeosDBOOracleBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'NUMBER(10)', ! 'FLOAT', ! 'NUMBER(14,4)', ! 'NUMBER(1)', ! 'VARCHAR2', ! 'CLOB', ! 'DATE', ! 'BLOB'); begin Result := Types[DataType]; *************** *** 843,858 **** {$IFDEF PGSQL_SUPPORT} function TInstantZeosDBOPgSQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT8', ! 'DECIMAL(14,4)', ! 'BOOLEAN', ! 'VARCHAR', ! 'TEXT', ! 'TIMESTAMP', ! 'BYTEA'); begin Result := Types[DataType]; --- 895,911 ---- {$IFDEF PGSQL_SUPPORT} + function TInstantZeosDBOPgSQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT8', ! 'DECIMAL(14,4)', ! 'BOOLEAN', ! 'VARCHAR', ! 'TEXT', ! 'TIMESTAMP', ! 'BYTEA'); begin Result := Types[DataType]; *************** *** 868,883 **** {$IFDEF MYSQL_SUPPORT} function TInstantZeosDBOMySQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'DECIMAL(14,4)', ! 'BOOL', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'BLOB'); begin Result := Types[DataType]; --- 921,937 ---- {$IFDEF MYSQL_SUPPORT} + function TInstantZeosDBOMySQLBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'DECIMAL(14,4)', ! 'BOOL', ! 'VARCHAR', ! 'TEXT', ! 'DATETIME', ! 'BLOB'); begin Result := Types[DataType]; *************** *** 890,908 **** {$ENDIF} { TInstantZeosDBOSQLiteBroker } ! {$IFDEF SQLITE_SUPPORT} function TInstantZeosDBOSQLiteBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'NUMERIC(14,4)', ! 'BOOLEAN', ! 'VARCHAR', ! 'TEXT', ! 'TIMESTAMP', ! 'BLOB'); begin Result := Types[DataType]; --- 944,1164 ---- {$ENDIF} + {$IFDEF SQLITE_SUPPORT} + + { TInstantDBBuildAlterTableSQLCommand } + + destructor TInstantDBBuildSQLiteAlterTableSQLCommand.Destroy; + begin + FNewTableMetadata.Free; + FTmpTableMD.Free; + FScheme.Free; + inherited; + end; + + function TInstantDBBuildSQLiteAlterTableSQLCommand.GetDescription: string; + begin + with Broker.Generator do + case CommandType of + ctAddField: + Result := GenerateAddFieldSQL(NewMetadata as TInstantFieldMetadata); + ctAlterField: + Result := GenerateAlterFieldSQL(OldMetadata as TInstantFieldMetadata, + NewMetadata as TInstantFieldMetadata); + ctDropField: + Result := GenerateDropFieldSQL(OldMetadata as TInstantFieldMetadata); + end; + Result := Result + ' - emulated with multi-statement SQL.'; + end; + + function TInstantDBBuildSQLiteAlterTableSQLCommand.GetNewTableMetadata: TInstantTableMetadata; + begin + if not Assigned(FNewTableMetadata) then + begin + FNewTableMetadata := TInstantTableMetadata.Create(OldTableMetadata.Collection); + FNewTableMetadata.Assign(OldTableMetadata); + case CommandType of + ctAddField: + FNewTableMetadata.FieldMetadatas.Add.Assign(NewMetadata); + ctAlterField: + begin + with FNewTableMetadata.FieldMetadatas do + Remove(Find(OldMetadata.Name)); + FNewTableMetadata.FieldMetadatas.Add.Assign(NewMetadata); + end; + ctDropField: + with FNewTableMetadata.FieldMetadatas do + Remove(Find(OldMetadata.Name)); + end; + end; + Result := FNewTableMetadata; + end; + + function TInstantDBBuildSQLiteAlterTableSQLCommand.GetOldTableMetadata: TInstantTableMetadata; + var + FieldMetadata : TInstantFieldMetadata; + begin + if not Assigned(FOldTableMetadata) then + begin + //Force to read the table from database + FScheme := Broker.ReadDatabaseScheme; + + FieldMetadata := nil; + case CommandType of + ctDropField, ctAlterField: + FieldMetadata := TInstantFieldMetadata(OldMetadata); + ctAddField: + FieldMetadata := TInstantFieldMetadata(NewMetadata); + end; + + { TODO : This only works for case-insensitive object names! } + FOldTableMetadata := + FScheme.FindTableMetadata(AnsiUpperCase(FieldMetadata.TableMetadata.Name)); + end; + Result := FOldTableMetadata; + end; + + function TInstantDBBuildSQLiteAlterTableSQLCommand.GetSQLStatement( + const Index: Integer): string; + + function CreateTmpTableMetadata(TableMetadata: TInstantTableMetadata): + TInstantTableMetadata; + begin + Result := TInstantTableMetadata.Create(TableMetadata.Collection); + Result.Assign(TableMetadata); + Result.Name := TableMetadata.Name + STmpTableSuffix; + end; + + begin + Result := inherited GetSQLStatement(Index); + + if not Assigned(FTmpTableMD) then + FTmpTableMD := CreateTmpTableMetadata(OldTableMetadata); + + with TInstantSQLiteGenerator(Broker.Generator) do + case Index of + 0: Result := GenerateCreateTempTableSQL(FTmpTableMD); + + 1: Result := GenerateInsertFromSelectSQL(OldTableMetadata, FTmpTableMD); + + 2: Result := GenerateDropTableSQL(OldTableMetadata); + + 3: Result := GenerateCreateTableSQL(NewTableMetadata); + + 4: Result := GenerateInsertFromSelectSQL(FTmpTableMD, NewTableMetadata); + + 5: Result := GenerateDropTableSQL(FTmpTableMD); + end; + end; + + function TInstantDBBuildSQLiteAlterTableSQLCommand.GetSQLStatementCount: Integer; + begin + Result := 6; + end; + + procedure TInstantDBBuildSQLiteAlterTableSQLCommand.InternalExecute; + var + iStatement: Integer; + InTransaction: Boolean; + begin + InTransaction := false; + try + for iStatement := 0 to Pred(GetSQLStatementCount) do + begin + Broker.Execute(GetSQLStatement(iStatement)); + InTransaction := (iStatement > 2) and (iStatement < 5); + end; + except + if InTransaction then Rollback; + raise; + end; + end; + + procedure TInstantDBBuildSQLiteAlterTableSQLCommand.Rollback; + begin + { TODO : Some DBMS supports data definition within transactions, ZEOS known that and then the follow code are unnecessary! } + with Broker, TInstantSQLiteGenerator(Broker.Generator) do + begin + try + Execute(GenerateDropTableSQL(NewTableMetadata)); + except + //Safe if NewTable doesn´t exist + end; + Execute(GenerateCreateTableSQL(OldTableMetadata)); + Execute(GenerateInsertFromSelectSQL(FTmpTableMD, OldTableMetadata)); + Execute(GenerateDropTableSQL(FTmpTableMD)); + end; + end; + + { TInstantSQLiteGenerator } + + function TInstantSQLiteGenerator.GenerateCreateTempTableSQL( + Metadata: TInstantTableMetadata): string; + begin + Result := InternalGenerateCreateTempTableSQL(Metadata); + end; + + function TInstantSQLiteGenerator.GenerateInsertFromSelectSQL( + const SourceMetadata, TargetMetadata: TInstantTableMetadata): string; + begin + Result := InternalGenerateInsertFromSelectSQL(SourceMetadata, TargetMetadata); + end; + + function TInstantSQLiteGenerator.InternalGenerateCreateTempTableSQL( + Metadata: TInstantTableMetadata): string; + begin + Result := InternalGenerateCreateTableSQL(Metadata); + Insert('TEMP ', Result, Pos('TABLE', Result)); + end; + + function TInstantSQLiteGenerator.InternalGenerateInsertFromSelectSQL( + const SourceMetadata, TargetMetadata: TInstantTableMetadata): string; + var + i: Integer; + TargetField : TInstantFieldMetadata; + FieldList : string; + begin + for i := 0 to Pred(TargetMetadata.FieldMetadatas.Count) do + begin + TargetField := TargetMetadata.FieldMetadatas[i]; + { TODO : This only works for case-insensitive object names! } + if SourceMetadata.FieldMetadatas.IndexOf(AnsiUpperCase(TargetField.Name)) > -1 then + FieldList := FieldList + EmbraceField(TargetField.Name) + ', '; + end; + Delete(FieldList, Length(FieldList) - 1, 2); + Result := Format('INSERT INTO %s(%s) SELECT %s FROM %s', + [TargetMetadata.Name, FieldList, FieldList, SourceMetadata.Name]); + end; + { TInstantZeosDBOSQLiteBroker } ! function TInstantZeosDBOSQLiteBroker.CreateDBBuildCommand( ! const CommandType: TInstantDBBuildCommandType): TInstantDBBuildCommand; ! begin ! case CommandType of ! ctAddField, ctAlterField, ctDropField: ! Result := TInstantDBBuildSQLiteAlterTableSQLCommand.Create(CommandType, Connector) ! else ! Result := inherited CreateDBBuildCommand(CommandType); ! end; ! end; ! ! class function TInstantZeosDBOSQLiteBroker.GeneratorClass: ! TInstantSQLGeneratorClass; ! begin ! Result := TInstantSQLiteGenerator; ! end; ! function TInstantZeosDBOSQLiteBroker.InternalDataTypeToColumnType( DataType: TInstantDataType): string; const Types: array[TInstantDataType] of string = ( ! 'INTEGER', ! 'FLOAT', ! 'NUMERIC(14,4)', ! 'BOOLEAN', ! 'VARCHAR', ! 'TEXT', ! 'TIMESTAMP', ! 'BLOB'); begin Result := Types[DataType]; |