|
|
| Строка 1: |
Строка 1: |
| − | После каждого успешного обновления структуры БД заносится запись в таблицу [[FIN_VERSIONINFO]]. Таким образом, текущую версию структуры можно извлечь по максимальному идентификатору с помощью запроса:
| + | См. [[Модификация структуры базы данных]]. |
| − | | + | |
| − | SELECT FIRST 1 * FROM fin_versioninfo ORDER BY id DESC
| + | |
| − | | + | |
| − | Для изменения структуры БД разработчик создает процедуру типа [[gdModify.TProcAddr|TProcAddr]]. Как правило, на одно изменение создается одна процедура. Ниже приведен пример из файла [[mdf_ConvertBNStatementCommentToBlob]]:
| + | |
| − | | + | |
| − | <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 о новом номере версии структуры БД
| + | |
| − | # Комитится транзакция
| + | |
| − | # Если произошла ошибка, то сообщение помещается в лог и транзакция откатывается
| + | |
| − |
| + | |
| − | Все подобные процедуры вместе с номером версии структуры БД заносятся в глобальный массив [[mdf_proclist.cProcList|cProcList]]. При запуске Гедымина, после аутентификации пользователя и подключения к базе, номер текущей версии структуры БД сверяется с номером из последнего элемента массива. Если номер текущей версии меньше или равен номеру из последнего элемента, то создается объект типа [[gdModify.TgdModify|TgdModify]] и запускается процесс апгрейда.
| + | |
| − | | + | |
| − | В ходе обновления последовательно выполняются процедуры из массива [[mdf_proclist.cProcList|cProcList]], пока выполняется условие:
| + | |
| − | | + | |
| − | FDBVersion <= cProcList[I].ModifyVersion
| + | |
| − | | + | |
| − | где FDBVersion -- номер текущей версии структуры БД, cProcList[I].ModifyVersion -- номер версии, указанный для I-той процедуры.
| + | |
| − | | + | |
| − | [[Category:Школа системного администратора]]
| + | |