Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Адаптация кода к 64 битному ИД #4115

Open
1 of 6 tasks
gsbelarus opened this issue Jan 16, 2019 · 1 comment
Open
1 of 6 tasks

Адаптация кода к 64 битному ИД #4115

gsbelarus opened this issue Jan 16, 2019 · 1 comment

Comments

@gsbelarus
Copy link
Member

gsbelarus commented Jan 16, 2019

Обработаны папки:

  • Addressbook
  • DirectoryGood
  • Wage

Проверены папки:

  • Addressbook
  • DirectoryGood
  • Wage
@gsbelarus
Copy link
Member Author

gsbelarus commented Jan 16, 2019

Суть проблемы

После перехода на 64 битный ИД:

  1. Переменные в коде должны быть типа Int64 вместо Integer.
  2. Надо использовать другие методы чтения\записи значений в полях и параметрах AsLargeInt вместо AsInteger.
  3. Надо использовать другую функцию преобразования из строки.
  4. Преобразования в Делфи5 в или из типа вариант будут неправильными.

Решение:

  1. Заводим специальный тип TID. Сейчас он будет TID = Integer, а в будущем переключим его на TID = Int64.
  2. Используем для идентификаторов, ссылок, ключей ТОЛЬКО тип TID.
  3. Создаем набор вспомогательных функций, которые выполняют операции преобразования, присваивания, сравнения и используем только их, вместо операторов присвоения и стандартных функций.

Функции преобразования и присваивания TID

Определены в gdcBaseInterface.pas:

  // функции для получения ИД из запроса, строки, варианта
  function GetTID(f: TIBXSQLVAR): TID; overload;
  function GetTID(f: TField): TID; overload;
  function GetTID(s: String): TID; overload;
  function GetTID(s: String; def: TID): TID; overload;
  function GetTID(v: Variant): TID; overload;

  // функции для присваивания и преобразования ИД
  function SetTID(f: TIBXSQLVAR; const ID: TID): TID; overload;
  function SetTID(f: TField; const ID: TID): TID; overload;
  function SetTID(f: TIBXSQLVAR; fld: TField): TID; overload;
  function TID2S(const ID: TID): String; overload;
  function TID2V(const ID: TID): variant; overload;
  function TID264(const ID: TID): Int64; overload;

  // функции для проверки ИД в 32битном диапазоне
  function Is32TID(const ID: TID): boolean;
  procedure Check32TID(const ID: TID);

Задача

  1. Методично просмотреть папку за папкой, файл за файлом весь код Гедымина. Выявить все места где используются идентификаторы и заменить на нужные типы и вызовы вспомогательных функций. Ниже приведены примеры.
  2. Вместе с делфи кодом меняем EXECUTE BLOCK, STORED PROCEDURE, TRIGGER, зашитый внутрь Гедымина. В коде SQL надо все переменные и параметры, которые работают с идентификаторами и объявлены как DECLARE VARIABLE v INTEGER менять на DECLARE VARIABLE v DFOREIGNKEY (или DECLARE VARIABLE v DINTKEY, если точно известно что переменная будет заполнена).
  3. После обработки файла в первой строчке ставится подпись с датой. Я ставлю \\ andreik, 15.01.2019, другие разработчики будут использовать свои инициалы.
  4. Файл должен быть еще раз просмотрен другим человеком на предмет того, не упущено ли что. Второй разработчик ставит свою подпись ниже первой. Файлы с двумя подписями будут считаться обработанными и проверенными.

Примеры обработки

Было:

var
  ID, Dep: Integer;

Стало:

var
  ID, Dep: TID;

Здесь всё понятно. Мы используем специальный тип для идентфикаторов вместо Integer. Он определен в gdcBaseInterface.pas.

Было:

gdcObject.FieldByName('wcompanykey').AsInteger

Стало:

GetTID(gdcObject.FieldByName('wcompanykey')

Используем специальную функцию для получения значения идентификатора из поля вместо прямого обращения к значению поля AsInteger.

Было:

Format('lb > (SELECT c.lb FROM gd_contact c WHERE c.id = %d) ' +
  'AND rb <= (SELECT c2.rb FROM gd_contact c2 WHERE c2.id = %d) ', [ID, ID]));

Стало:

Format('lb > (SELECT c.lb FROM gd_contact c WHERE c.id = %d) ' +
  'AND rb <= (SELECT c2.rb FROM gd_contact c2 WHERE c2.id = %d) ', [TID264(ID), TID264(ID)]));

Обратите внимание, заменили прямые значения переменных на преобразования через функцию.

Альтернативный вариант -- использовать строки:

Format('lb > (SELECT c.lb FROM gd_contact c WHERE c.id = %s) ' +
   'AND rb <= (SELECT c2.rb FROM gd_contact c2 WHERE c2.id = %s) ', [TID2S(ID), TID2S(ID)]));

Было:

gdcObject.FieldByName('parent').AsInteger := Dep;

Стало:

SetTID(gdcObject.FieldByName('parent'), Dep);

Выше было чтение через специальные функции, а здесь запись в значение поля.

Было:

gdcObject.ExecSingleQuery('UPDATE OR INSERT INTO gd_employee (contactkey) ' +
   'VALUES (' + IntToStr(gdcObject.ID) + ') MATCHING (contactkey)');

Стало:

gdcObject.ExecSingleQuery('UPDATE OR INSERT INTO gd_employee (contactkey) ' +
  'VALUES (' + TID2S(gdcObject.ID) + ') MATCHING (contactkey)');

Обратите внимание, используем свою функцию преобразования в строку вместо IntToStr.

Было:

if gdcObject.ParamByName('companykey').AsInteger <> ibcmbCompany.CurrentKeyInt then

Стало:

if GetTID(gdcObject.ParamByName('companykey')) <> ibcmbCompany.CurrentKeyInt then

Здесь обратите внимание, как мы используем функцию, чтобы получить значение из параметра. И обратите внимание, что свойство CurrentKeyInt компонента выпадающий список мы не трогаем, так как мы просто поменяем его объявление в коде с Integer на TID.

Это же касается свойства CurrentKey у выпадающего списка. Оно как было String, так и останется.

@gsbelarus gsbelarus pinned this issue Jan 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant