?

Log in

No account? Create an account

Previous Entry | Next Entry

Я уже упоминал в предыдущем посте о задаче написать редактор IP диапазонов сотовых операторов (кстати, кому интересно - открытая база есть вот здесь ).

Сама по себе задача тривиальная - в БД есть две таблицы, в одной из которых перечислены (помимо различной вспомогательной информации) начальный и конечный IP диапазона и id сотового оператора, к которому относится этот диапазон. Во второй перечислены операторы с их id.

Однако, есть очень важный ньюанс. Допустим, поступила информация о новом диапазоне - стало известно, что он относится, скажем, к МТС. Конечно можно просто добавить еще одну строчку в базу, но это будет некорректно, т.к. вполне может оказаться, что там уже есть диапазон, с которым новый совпадёт или, того хуже, частично пересечётся. Даже более того - этот старый диапазон мог в прошлом быть отнесен к другому оператору (скажем, по ошибке). Также есть опасность случайно ошибиться цифрой при вводе IP и затереть таким образом половину базы. Все эти нередкие ситуации надо анализировать и обрабатывать.

В итоге я сделал примерно так:

Вызываем на сервере сервис RangeService.addRangePreview, который получает через метод checkRangeIntersect() список всех IP диапазонов, с которыми пересекается добавляемый:

SELECT ... FROM ... WHERE ... AND
(
    :ip_start BETWEEN start AND finish
    OR
    :ip_finish BETWEEN start AND finish
    OR
    start BETWEEN :ip_start AND :ip_finish
    OR
    finish BETWEEN :ip_start AND :ip_finish
)
AND NOT
( start = :ip_start AND finish = :ip_finish )


этот, полученный в виде ассоциативного массива, список диапазонов скармливается методу getRangeFutureList() , который смотрит, каким именно образом на каждый из них повлияет добавляемый диапазон.

Возможные ситуации при добавлении нового диапазонаВариантов не так много:
  • будет создан, поскольку задан как новый и с другими не пересекается
  • совпадает с новым, будет обновлён
  • полностью поглощается новым, поэтому будет удален
  • будет создан (слева), в связи с попаданием нового диапазона внутрь существующего
  • будет создан (справа), в связи с попаданием нового диапазона внутрь существующего
  • будет удален, в связи с попаданием внутрь него нового диапазона (и созданием вместо него двух новых)
  • будет урезан слева, поскольку имеет общую часть с новым диапазоном
  • будет урезан справа, поскольку имеет общую часть с новым диапазоном
  • будет создан, поскольку задан как новый и с другими не пересекается
  • будет создан, поскольку задан как новый

Таким образом, метод getRangeFutureList() возвращает массив операций, которые надо совершить и параметры удаляемых/создаваемых/изменяемых диапазонов.

Массивы пересечений и планируемых изменений возвращаются во Flex клиент, где демонстрируются наглядно в виде диаграммы и таблицы - см. рис. в начале поста. Кстати, полоски сделаны не через graphics.drawRect(), а через new Button(), чтобы можно было легко навесить на каждую полоску toolTip и сделать её кликабельной (для выдачи дополнительной информации по клику).

Далее, если пользователь согласен и нажимает "Accept", вызывается RangeService.addRangeModify и по массиву с изменениями последовательно выполняются необходимые INSERT / DELETE / UPDATE.

Tags: