GdModify
Материал из GedeminWiki
(Различия между версиями)
SYSDBA (обсуждение | вклад) |
SYSDBA (обсуждение | вклад) |
||
| Строка 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. Как видно, на вход передается конект к базе данных и объект логирования. В общем случае, внутри процедуры:
- Создаются и связываются объекты транзакции и SQL команды
- Стартует транзакция
- Делаются необходимые проверки
- Выполняется одна или несколько SQL команд
- Помещаются сообщения в лог о ходе процесса
- Добавляется запись в fin_versioninfo о новом номере версии структуры БД
- Комитится транзакция
- Если произошла ошибка, то сообщение помещается в лог и транзакция откатывается
Классы
| TgdModify | Класс для инкрементного обновления структуры базы данных. |