GdModify

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
Строка 1: Строка 1:
Модуль '''gdModify.pas''' содержит реализацию класса '''TgdModify''', который отвечает за инкрементное обновление структуры базы данных (апгрейд). После каждого успешного изменения заносится запись в таблицу [[FIN_VERSIONINFO]]. Таким образом, текущую версию структуры базы данных можно извлечь из этой таблицы по максимальному идентификатору.  
+
Модуль '''gdModify.pas''' содержит реализацию класса '''TgdModify''', который отвечает за инкрементное обновление структуры базы данных (апгрейд). После каждого успешного изменения заносится запись в таблицу [[FIN_VERSIONINFO]]. Таким образом, текущую версию структуры базы данных можно извлечь из этой таблицы по максимальному идентификатору с помощью запроса:
 +
 
 +
  SELECT FIRST 1 * FROM fin_versioninfo ORDER BY id DESC
 +
 
 +
Для изменения структуры БД разработчик создает процедуру типа [[gdModify.TProcAddr|TProcAddr]]. Как правило, на одно изменение создается одна процедура. Ниже приведен пример такой процедуры:
 +
 
 +
<syntaxhighlight lang="delphi">
 +
procedure ModifyRUIDProcedure(IBDB: TIBDatabase; Log: TModifyLog);
 +
var
 +
  FTransaction: TIBTransaction;
 +
  FIBSQL: TIBSQL;
 +
begin
 +
  FTransaction := TIBTransaction.Create(nil);
 +
  FIBSQL := TIBSQL.Create(nil);
 +
  try
 +
    FTransaction.DefaultDatabase := IBDB;
 +
    try
 +
      FTransaction.StartTransaction;
 +
      FIBSQL.Transaction := FTransaction;
 +
      FIBSQL.ParamCheck := False;
 +
 
 +
      FIBSQL.SQL.Text :=
 +
        'CREATE OR ALTER PROCEDURE GD_P_GETRUID(ID INTEGER) '#13#10 +
 +
        '  RETURNS (XID INTEGER, DBID INTEGER) '#13#10 +
 +
        'AS '#13#10 +
 +
        'BEGIN '#13#10 +
 +
        '  XID = NULL; '#13#10 +
 +
        '  DBID = NULL; '#13#10 +
 +
        ' '#13#10 +
 +
        '  IF (NOT :ID IS NULL) THEN '#13#10 +
 +
        '  BEGIN '#13#10 +
 +
        '    IF (:ID < 147000000) THEN '#13#10 +
 +
        '    BEGIN '#13#10 +
 +
        '      XID = :ID; '#13#10 +
 +
        '      DBID = 17; '#13#10 +
 +
        '    END ELSE '#13#10 +
 +
        '    BEGIN '#13#10 +
 +
        '      SELECT xid, dbid '#13#10 +
 +
        '      FROM gd_ruid '#13#10 +
 +
        '      WHERE id=:ID '#13#10 +
 +
        '      INTO :XID, :DBID; '#13#10 +
 +
        ' '#13#10 +
 +
        '      IF (XID IS NULL) THEN '#13#10 +
 +
        '      BEGIN '#13#10 +
 +
        '        XID = ID; '#13#10 +
 +
        '        DBID = GEN_ID(gd_g_dbid, 0); '#13#10 +
 +
        ' '#13#10 +
 +
        '        INSERT INTO gd_ruid(id, xid, dbid, modified, editorkey) '#13#10 +
 +
        '          VALUES(:ID, :XID, :DBID, CURRENT_TIMESTAMP, NULL); '#13#10 +
 +
        '      END '#13#10 +
 +
        '    END '#13#10 +
 +
        '  END '#13#10 +
 +
        ' '#13#10 +
 +
        '  SUSPEND; '#13#10 +
 +
        'END ';
 +
 
 +
      FIBSQL.ExecQuery;
 +
 
 +
      FIBSQL.SQL.Text :=
 +
        'UPDATE OR INSERT INTO fin_versioninfo ' +
 +
        '  VALUES (132, ''0000.0001.0000.0163'', ''28.03.2011'', ''Modify GD_P_GETRUID procedure.'') ' +
 +
        '  MATCHING (id)';
 +
      FIBSQL.ExecQuery;
 +
      FIBSQL.Close;
 +
 
 +
      FTransaction.Commit;
 +
    except
 +
      on E: Exception do
 +
      begin
 +
        Log('Произошла ошибка: ' + E.Message);
 +
        if FTransaction.InTransaction then
 +
          FTransaction.Rollback;
 +
        raise;
 +
      end;
 +
    end;
 +
  finally
 +
    FIBSQL.Free;
 +
    FTransaction.Free;
 +
  end;
 +
end;
 +
</syntaxhighlight>
 +
 
 +
В данном случае вносятся изменения в хранимую процедуру [[GD_P_GETRUID]]. Как видно, на вход передается конект к базе данных и объект логирования. В общем случае, внутри процедуры:
 +
 
 +
# Создаются и связываются объекты транзакции и SQL команды
 +
# Стартует транзакция
 +
# Делаются необходимые проверки
 +
# Выполняется одна или несколько SQL команд
 +
# Помещаются сообщения в лог о ходе процесса
 +
# Добавляется запись в fin_versioninfo о новом номере версии структуры БД
 +
# Комитится транзакция
 +
# Если произошла ошибка, то сообщение помещается в лог и транзакция откатывается
 +
 
{{UnitMembers_Template|member_type=Классы|unit={{PAGENAMEE}}|list=TgdModify}}
 
{{UnitMembers_Template|member_type=Классы|unit={{PAGENAMEE}}|list=TgdModify}}
 
{{LinkToSource_Template|full_name=Gedemin/Setup/gdModify.pas}}
 
{{LinkToSource_Template|full_name=Gedemin/Setup/gdModify.pas}}

Версия 14:32, 10 мая 2011

Модуль gdModify.pas содержит реализацию класса TgdModify, который отвечает за инкрементное обновление структуры базы данных (апгрейд). После каждого успешного изменения заносится запись в таблицу FIN_VERSIONINFO. Таким образом, текущую версию структуры базы данных можно извлечь из этой таблицы по максимальному идентификатору с помощью запроса:

 SELECT FIRST 1 * FROM fin_versioninfo ORDER BY id DESC

Для изменения структуры БД разработчик создает процедуру типа TProcAddr. Как правило, на одно изменение создается одна процедура. Ниже приведен пример такой процедуры:

procedure ModifyRUIDProcedure(IBDB: TIBDatabase; Log: TModifyLog);
var
  FTransaction: TIBTransaction;
  FIBSQL: TIBSQL;
begin
  FTransaction := TIBTransaction.Create(nil);
  FIBSQL := TIBSQL.Create(nil);
  try
    FTransaction.DefaultDatabase := IBDB;
    try
      FTransaction.StartTransaction;
      FIBSQL.Transaction := FTransaction;
      FIBSQL.ParamCheck := False;
 
      FIBSQL.SQL.Text :=
        'CREATE OR ALTER PROCEDURE GD_P_GETRUID(ID INTEGER) '#13#10 +
        '  RETURNS (XID INTEGER, DBID INTEGER) '#13#10 +
        'AS '#13#10 +
        'BEGIN '#13#10 +
        '  XID = NULL; '#13#10 +
        '  DBID = NULL; '#13#10 +
        ' '#13#10 +
        '  IF (NOT :ID IS NULL) THEN '#13#10 +
        '  BEGIN '#13#10 +
        '    IF (:ID < 147000000) THEN '#13#10 +
        '    BEGIN '#13#10 +
        '      XID = :ID; '#13#10 +
        '      DBID = 17; '#13#10 +
        '    END ELSE '#13#10 +
        '    BEGIN '#13#10 +
        '      SELECT xid, dbid '#13#10 +
        '      FROM gd_ruid '#13#10 +
        '      WHERE id=:ID '#13#10 +
        '      INTO :XID, :DBID; '#13#10 +
        ' '#13#10 +
        '      IF (XID IS NULL) THEN '#13#10 +
        '      BEGIN '#13#10 +
        '        XID = ID; '#13#10 +
        '        DBID = GEN_ID(gd_g_dbid, 0); '#13#10 +
        ' '#13#10 +
        '        INSERT INTO gd_ruid(id, xid, dbid, modified, editorkey) '#13#10 +
        '          VALUES(:ID, :XID, :DBID, CURRENT_TIMESTAMP, NULL); '#13#10 +
        '      END '#13#10 +
        '    END '#13#10 +
        '  END '#13#10 +
        ' '#13#10 +
        '  SUSPEND; '#13#10 +
        'END ';
 
      FIBSQL.ExecQuery;
 
      FIBSQL.SQL.Text :=
        'UPDATE OR INSERT INTO fin_versioninfo ' +
        '  VALUES (132, ''0000.0001.0000.0163'', ''28.03.2011'', ''Modify GD_P_GETRUID procedure.'') ' +
        '  MATCHING (id)';
      FIBSQL.ExecQuery;
      FIBSQL.Close;
 
      FTransaction.Commit;
    except
      on E: Exception do
      begin
        Log('Произошла ошибка: ' + E.Message);
        if FTransaction.InTransaction then
          FTransaction.Rollback;
        raise;
      end;
    end;
  finally
    FIBSQL.Free;
    FTransaction.Free;
  end;
end;

В данном случае вносятся изменения в хранимую процедуру GD_P_GETRUID. Как видно, на вход передается конект к базе данных и объект логирования. В общем случае, внутри процедуры:

  1. Создаются и связываются объекты транзакции и SQL команды
  2. Стартует транзакция
  3. Делаются необходимые проверки
  4. Выполняется одна или несколько SQL команд
  5. Помещаются сообщения в лог о ходе процесса
  6. Добавляется запись в fin_versioninfo о новом номере версии структуры БД
  7. Комитится транзакция
  8. Если произошла ошибка, то сообщение помещается в лог и транзакция откатывается


Классы

TgdModify Класс для инкрементного обновления структуры базы данных.

Исходный код

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты