Федеральное Агентство Связи регулярно обновляет размещённый в открытом доступе план нумерации. Если вы используете этот план для определения региона или провайдера абонента в своём диалплане, то скорее всего заинтересованы в актуальности этой информации. На первый взгляд нет ничего сложного в том, чтобы написать приложение, которое загрузит, обработает и отправит данные в БД, однако приступив к реализации, вы неизбежно наткнётесь на подводные камни, о которых я сейчас расскажу.
План набора состоит из четырёх табличных файлов в формате csv:
rossvyaz.ru/data/ABC-3xx.csv
rossvyaz.ru/data/ABC-4xx.csv
rossvyaz.ru/data/ABC-8xx.csv
rossvyaz.ru/data/DEF-9xx.csv
URL'ы иногда меняются.
Структура всех таблиц одинакова:
В поле Регион у некоторых провайдеров есть лишние точки с запятой:
Чтобы избежать ошибки во время чтения таблицы вашим приложением, нужно отключить проверку на ожидаемое количество полей или заменить ошибочную запись на корректную.
Мы собираемся записать данные в таблицу со следующей структурой:
Большинство регионов в таблицах можно однозначно определить по вхождению подстроки. К примеру, все записи для Саратовской области содержат подстроку Сарат.
Для тех регионов, которые нельзя однозначно определить, нужна дополнительная логика, о ней ниже.
Пример 1:
Ямало-Ненецкий автономный округ входит в состав Тюменской области, а Ненецкий автономный округ — в состав Архангельской. Проблема определения числового кода региона заключается в том, что подстрока Ненецкий АО полностью входит в Ямало-Ненецкий АО. Это значит, что содержащим подстроку Ненецкий АО записям будут соответствовать два региона.
Чтобы решить эту проблему, нужно добавить проверку на отсутствие подстроки (исключающую подстроку). Другими словами Ямало-Ненецкий АО будем определять по вхождению Ямало, а Ненецкий АО по вхождению Ненец и отсутствию Ямало.
Пример 2:
Пример неопознанных регионов. Таких записей в таблицах Россвязи много. Поисковик помогает выяснить, что г.о. Красногорск — Московкая область, г. Лянтор — Ханты-Мансийский автономный округ, а п. Парца — республика Мордовия. Решение простое, искомая подстрока преобразуется в массив строк, а проверять вхождение будем в цикле. Исключающую подстроку тоже преобразуем в массив.
Пример 3:
В этом примере нет возможности однозначно определить регион. Вы можете выбрать самый населённый из перечисленных, или присвоить особый код таким записям. На самом деле, все записи, которым соответствуют несколько регионов — это номера 8-80[0-9], федеральные номера, за звонки на которые не взимается плата. Я присвоил таким записям коды в диапазоне от 200 до 210. Не думаю, что они мне когда-нибудь пригодятся.
Код приложения можно посмотреть тут.
Исполняемые файлы для платформ linux, macos и windows находятся в каталоге bin (работу приложения на платформе windows я не тестировал).
Конфигурационный файл config.yml должен находиться в том же каталоге, откуда запускается исполняемый файл. Если есть желание, можете реализовать в приложении поддержку флагов, чтобы указывать путь к конфигу в аргументах коммандной строки, pull-request'ы приветствуются.
Поле data_source содержит пути до табличных файлов Россвязи. Если путь начинается с http, приложение загрузит таблицу с помощью встроенного веб-клиента, в противном случае попытается найти таблицу в файловой системе.
Обратите внимание на закомментированные строки. Это пути до табличных файлов Россвязи, сохранённых в репозитории. Если у вас не самое быстрое интернет-соединение, каждый запуск приложения будет загружать эти файлы заново. Для более быстрой работы приложения раскомментируйте эти строки и закомментируйте гиперссылки. Возможно приложение потребуется запускать чаще, чем вы думаете, позднее на примере объясню почему.
Поля exceptions и regions содержат пути до файлов с исправлениями и описанием регионов. О них чуть позднее.
В разделе db описаны параметры подключения к СУБД MySQL. Для использования другой СУБД нужно заменить драйвер в коде и шаблон строки подключения в конструкторе структуры Service
Впрочем, нет ничего сложного в том, чтобы добавить поле с типом СУБД в конфиг и добавить поддержку этих типов в приложение, pull-request'ы вновь приветствуются.
Файл exceptions.yml содержит список исправлений. Все совпадения подстрок в exceptions.yml до двоеточия, найденные в табличных файлов Россвязи, будут заменены на подстроки, следующие после двоеточия.
Файл regions.yml содержит список числовых кодов регионов с массивами вхождений и исключающих подстрок, используемых для определения конкретного региона. Если для какой-либо записи не будет найдено соответствие ни одному региону или соответствий будет два и более, то эта запись попадёт в БД, но поле region будет содержать значение 0 (регион не определён).
Перед запуском приложения, создайте базу данных с именем, указанным в db.name и убедитесь, что у пользователя, указанного в db.user, есть права на чтение и запись.
Итак, мы всё настроили, самое время запустить приложение.
Обратите внимание, что во время запуска таблица, указанная в поле db.table конфигурационного файла будет очищена, будьте осторожны.
Отчёт содержит несколько разделов.
unknown_regions — список записей, которым не соответствует регионы, или их количество больше одного;
wrong_records — список некорректных записей в таблице Россвязи;
warnings — список предупреждений, возникших во время работы приложения;
Отчёт под последним спойлером я получил во время запуска приложения приблизительно через месяц после последних правок regions.yml.
Чтобы избавиться от предупреждений и получить коды регионов для всех записей, нужно отредактировать regions.yml.
В качестве вишенки на торте предлагаю макрос диалплана Asterisk для определения региона по номеру абонента:
Для этих же целей можно использовать Lua скрипт:
Впрочем, подойдёт любой инструмент, поддерживающий SELECT запросы к MySQL.
Приятного вам администрирования.
План набора состоит из четырёх табличных файлов в формате csv:
rossvyaz.ru/data/ABC-3xx.csv
rossvyaz.ru/data/ABC-4xx.csv
rossvyaz.ru/data/ABC-8xx.csv
rossvyaz.ru/data/DEF-9xx.csv
URL'ы иногда меняются.
Структура всех таблиц одинакова:
АВС/ DEF;От;До;Емкость;Оператор;Регион
В поле Регион у некоторых провайдеров есть лишние точки с запятой:
Московская область; Москва|Московская область; Москва
Чтобы избежать ошибки во время чтения таблицы вашим приложением, нужно отключить проверку на ожидаемое количество полей или заменить ошибочную запись на корректную.
Мы собираемся записать данные в таблицу со следующей структурой:
first BIGINT PRIMARY KEY NOT NULL // начало диапазона last BIGINT UNIQUE NOT NULL // конец диапазона provider TEXT // провайдер source_region TEXT // текстовое значение поля Регион из плана набора Россвязи region INT NOT NULL // числовой код региона
Большинство регионов в таблицах можно однозначно определить по вхождению подстроки. К примеру, все записи для Саратовской области содержат подстроку Сарат.
Для тех регионов, которые нельзя однозначно определить, нужна дополнительная логика, о ней ниже.
Пример 1:
- Ямало-Ненецкий АО
- Ненецкий АО
Ямало-Ненецкий автономный округ входит в состав Тюменской области, а Ненецкий автономный округ — в состав Архангельской. Проблема определения числового кода региона заключается в том, что подстрока Ненецкий АО полностью входит в Ямало-Ненецкий АО. Это значит, что содержащим подстроку Ненецкий АО записям будут соответствовать два региона.
Чтобы решить эту проблему, нужно добавить проверку на отсутствие подстроки (исключающую подстроку). Другими словами Ямало-Ненецкий АО будем определять по вхождению Ямало, а Ненецкий АО по вхождению Ненец и отсутствию Ямало.
Пример 2:
- г.о. Красногорск
- г. Лянтор
- п. Парца
Пример неопознанных регионов. Таких записей в таблицах Россвязи много. Поисковик помогает выяснить, что г.о. Красногорск — Московкая область, г. Лянтор — Ханты-Мансийский автономный округ, а п. Парца — республика Мордовия. Решение простое, искомая подстрока преобразуется в массив строк, а проверять вхождение будем в цикле. Исключающую подстроку тоже преобразуем в массив.
Пример 3:
- Сибирский федеральный округ, Дальневосточный федеральный округ
- Красноярский край, Республика Хакасия, г. Москва, г. Санкт-Петербург
- Российская Федерация
В этом примере нет возможности однозначно определить регион. Вы можете выбрать самый населённый из перечисленных, или присвоить особый код таким записям. На самом деле, все записи, которым соответствуют несколько регионов — это номера 8-80[0-9], федеральные номера, за звонки на которые не взимается плата. Я присвоил таким записям коды в диапазоне от 200 до 210. Не думаю, что они мне когда-нибудь пригодятся.
Код приложения можно посмотреть тут.
Исполняемые файлы для платформ linux, macos и windows находятся в каталоге bin (работу приложения на платформе windows я не тестировал).
Конфигурационный файл config.yml должен находиться в том же каталоге, откуда запускается исполняемый файл. Если есть желание, можете реализовать в приложении поддержку флагов, чтобы указывать путь к конфигу в аргументах коммандной строки, pull-request'ы приветствуются.
Конфигурационный файл
data_source: - https://rossvyaz.ru/data/ABC-3xx.csv - https://rossvyaz.ru/data/ABC-4xx.csv - https://rossvyaz.ru/data/ABC-8xx.csv - https://rossvyaz.ru/data/DEF-9xx.csv # - ../service/testdata/ABC-3xx.csv # - ../service/testdata/ABC-4xx.csv # - ../service/testdata/ABC-8xx.csv # - ../service/testdata/DEF-9xx.csv exceptions: exceptions.yml regions: regions.yml db: host: localhost name: asterisk table: codes user: asterisk password: asterisk
Поле data_source содержит пути до табличных файлов Россвязи. Если путь начинается с http, приложение загрузит таблицу с помощью встроенного веб-клиента, в противном случае попытается найти таблицу в файловой системе.
Обратите внимание на закомментированные строки. Это пути до табличных файлов Россвязи, сохранённых в репозитории. Если у вас не самое быстрое интернет-соединение, каждый запуск приложения будет загружать эти файлы заново. Для более быстрой работы приложения раскомментируйте эти строки и закомментируйте гиперссылки. Возможно приложение потребуется запускать чаще, чем вы думаете, позднее на примере объясню почему.
Поля exceptions и regions содержат пути до файлов с исправлениями и описанием регионов. О них чуть позднее.
В разделе db описаны параметры подключения к СУБД MySQL. Для использования другой СУБД нужно заменить драйвер в коде и шаблон строки подключения в конструкторе структуры Service
db, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", c.DB.User, c.DB.Password, c.DB.Host, c.DB.Name), nil)
Впрочем, нет ничего сложного в том, чтобы добавить поле с типом СУБД в конфиг и добавить поддержку этих типов в приложение, pull-request'ы вновь приветствуются.
Файл exceptions.yml содержит список исправлений. Все совпадения подстрок в exceptions.yml до двоеточия, найденные в табличных файлов Россвязи, будут заменены на подстроки, следующие после двоеточия.
Файл regions.yml содержит список числовых кодов регионов с массивами вхождений и исключающих подстрок, используемых для определения конкретного региона. Если для какой-либо записи не будет найдено соответствие ни одному региону или соответствий будет два и более, то эта запись попадёт в БД, но поле region будет содержать значение 0 (регион не определён).
Пример описания региона
78: name: Санкт-Петербург contain: - Ленинградская - Санкт - г.п. Никольское not_contain: - Красноярский
Перед запуском приложения, создайте базу данных с именем, указанным в db.name и убедитесь, что у пользователя, указанного в db.user, есть права на чтение и запись.
Итак, мы всё настроили, самое время запустить приложение.
Обратите внимание, что во время запуска таблица, указанная в поле db.table конфигурационного файла будет очищена, будьте осторожны.
./def2sql
Если ошибок и предупреждений нет, вы увидите похожий вывод
correct records amount: 372324 inserted 372324 records
В противном случае вы увидите отчёт с ошибками и предупреждениями
correct records amount: 372324 inserted 372324 records { "unknown_regions": [ { "First": 3424333950, "Last": 3424333999, "Range": 50, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Красновишерск", "Region": 0 }, { "First": 3424820000, "Last": 3424820049, "Range": 50, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Губаха", "Region": 0 }, { "First": 3425425000, "Last": 3425425049, "Range": 50, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Верещагино", "Region": 0 }, { "First": 3425620000, "Last": 3425620049, "Range": 50, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Чусовой", "Region": 0 }, { "First": 3426050000, "Last": 3426050050, "Range": 51, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Кудымкар", "Region": 0 }, { "First": 3427399950, "Last": 3427399999, "Range": 50, "Provider": "ООО \"КОКОБРИ\"", "SourceRegion": "г.о. Краснокамск", "Region": 0 }, { "First": 4217523500, "Last": 4217523999, "Range": 500, "Provider": "ПАО \"Компания \"Сухой\"", "SourceRegion": "АО Ленинский", "Region": 0 }, { "First": 4217526000, "Last": 4217526999, "Range": 1000, "Provider": "ПАО \"Компания \"Сухой\"", "SourceRegion": "АО Ленинский", "Region": 0 }, { "First": 8003550000, "Last": 8003559999, "Range": 10000, "Provider": "ООО \"ТК Телезон\" (ИНН 2460087999)", "SourceRegion": "Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург", "Region": 0 }, { "First": 8003810000, "Last": 8003819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8013810000, "Last": 8013819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8023810000, "Last": 8023819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8031010000, "Last": 8031019999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Уральский федеральный округ * Приволжский федеральный округ", "Region": 0 }, { "First": 8033550000, "Last": 8033559999, "Range": 10000, "Provider": "ООО \"ТК Телезон\" (ИНН 2460087999)", "SourceRegion": "Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург", "Region": 0 }, { "First": 8033810000, "Last": 8033819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8041010000, "Last": 8041019999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Уральский федеральный округ * Приволжский федеральный округ", "Region": 0 }, { "First": 8043810000, "Last": 8043819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8051010000, "Last": 8051019999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Уральский федеральный округ * Приволжский федеральный округ", "Region": 0 }, { "First": 8053810000, "Last": 8053819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8063810000, "Last": 8063819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8073810000, "Last": 8073819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8083810000, "Last": 8083819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 8091010000, "Last": 8091019999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Уральский федеральный округ * Приволжский федеральный округ", "Region": 0 }, { "First": 8093550000, "Last": 8093559999, "Range": 10000, "Provider": "ООО \"ТК Телезон\" (ИНН 2460087999)", "SourceRegion": "Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург", "Region": 0 }, { "First": 8093810000, "Last": 8093819999, "Range": 10000, "Provider": "ПАО \"Ростелеком\"", "SourceRegion": "Сибирский федеральный округ * Дальневосточный федеральный округ", "Region": 0 }, { "First": 9512780000, "Last": 9512789999, "Range": 10000, "Provider": "ООО \"Т2 Мобайл\"", "SourceRegion": "Абзелиловский район * Белорецкий район|Абзелиловский район * Белорецкий район", "Region": 0 }, { "First": 9963000000, "Last": 9963029999, "Range": 30000, "Provider": "ООО \"Т2 Мобайл\"", "SourceRegion": "Абзелиловский район * Белорецкий район|Абзелиловский район * Белорецкий район", "Region": 0 } ], "warnings": [ "couldn't find region for record (3424333950-3424333999; ООО \"КОКОБРИ\", г.о. Красновишерск)", "couldn't find region for record (3424820000-3424820049; ООО \"КОКОБРИ\", г.о. Губаха)", "couldn't find region for record (3425425000-3425425049; ООО \"КОКОБРИ\", г.о. Верещагино)", "couldn't find region for record (3425620000-3425620049; ООО \"КОКОБРИ\", г.о. Чусовой)", "couldn't find region for record (3426050000-3426050050; ООО \"КОКОБРИ\", г.о. Кудымкар)", "couldn't find region for record (3427399950-3427399999; ООО \"КОКОБРИ\", г.о. Краснокамск)", "couldn't find region for record (4217523500-4217523999; ПАО \"Компания \"Сухой\", АО Ленинский)", "couldn't find region for record (4217526000-4217526999; ПАО \"Компания \"Сухой\", АО Ленинский)", "couldn't find region for record (8003550000-8003559999; ООО \"ТК Телезон\" (ИНН 2460087999), Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург)", initial commit "couldn't find region for record (8003810000-8003819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8013810000-8013819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8023810000-8023819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8031010000-8031019999; ПАО \"Ростелеком\", Уральский федеральный округ * Приволжский федеральный округ)", "couldn't find region for record (8033550000-8033559999; ООО \"ТК Телезон\" (ИНН 2460087999), Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург)", "couldn't find region for record (8033810000-8033819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8041010000-8041019999; ПАО \"Ростелеком\", Уральский федеральный округ * Приволжский федеральный округ)", "couldn't find region for record (8043810000-8043819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8051010000-8051019999; ПАО \"Ростелеком\", Уральский федеральный округ * Приволжский федеральный округ)", "couldn't find region for record (8053810000-8053819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8063810000-8063819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8073810000-8073819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8083810000-8083819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (8091010000-8091019999; ПАО \"Ростелеком\", Уральский федеральный округ * Приволжский федеральный округ)", "couldn't find region for record (8093550000-8093559999; ООО \"ТК Телезон\" (ИНН 2460087999), Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург)", "couldn't find region for record (8093810000-8093819999; ПАО \"Ростелеком\", Сибирский федеральный округ * Дальневосточный федеральный округ)", "couldn't find region for record (9512780000-9512789999; ООО \"Т2 Мобайл\", Абзелиловский район * Белорецкий район|Абзелиловский район * Белорецкий район)", "couldn't find region for record (9963000000-9963029999; ООО \"Т2 Мобайл\", Абзелиловский район * Белорецкий район|Абзелиловский район * Белорецкий район)" ] }
Отчёт содержит несколько разделов.
unknown_regions — список записей, которым не соответствует регионы, или их количество больше одного;
wrong_records — список некорректных записей в таблице Россвязи;
warnings — список предупреждений, возникших во время работы приложения;
Отчёт под последним спойлером я получил во время запуска приложения приблизительно через месяц после последних правок regions.yml.
Неактуальная версия regions.yml
1: name: Республика Адыгея (Адыгея) contain: - Адыгея 2: name: Республика Башкортостан contain: - Башкортостан - Абзелиловский и Белорецкий 3: name: Республика Бурятия contain: - Бурятия 4: name: Республика Алтай contain: - Республика Алтай 5: name: Республика Дагестан contain: - Дагестан 6: name: Республика Ингушетия contain: - Ингушетия 7: name: Кабардино-Балкарская Республика contain: - Кабардино-Балкарская 8: name: Республика Калмыкия contain: - Калмыкия 9: name: Карачаево-Черкесская Республика contain: - Карачаево 10: name: Республика Карелия contain: - Карелия - г.п. Сортавала 11: name: Республика Коми contain: - Коми 12: name: Республика Марий Эл contain: - Марий 13: name: Республика Мордовия contain: - Мордовия - п. Парца 14: name: Республика Саха (Якутия) contain: - Якутия - Нерюнгри 15: name: Республика Северная Осетия - Алания contain: - Осетия 16: name: Республика Татарстан (Татарстан) contain: - Татарстан - Казань - Челны 17: name: Республика Тыва contain: - Тыва 18: name: Удмуртская Республика contain: - Удмурт - пгт. Ува 19: name: Республика Хакасия contain: - Хакасия not_contain: - Красноярский 20: name: Чеченская Республика contain: - Чеченская Республика - Чечня - Республика Чеченская 21: name: Чувашская Республика - Чувашия contain: - Чувашская Республика - Чувашия 22: name: Алтайский край contain: - Алтайский край 23: name: Краснодарский край contain: - Краснодарский 24: name: Красноярский край contain: - Красноярский край not_contain: - Москва 25: name: Приморский край contain: - Приморский край 26: name: Ставропольский край contain: - Ставропольский край 27: name: Хабаровский край contain: - Хабаровский 28: name: Амурская область contain: - Амурская 29: name: Архангельская область contain: - Архангельская - Ненецкий not_contain: - Ямало - Красноярск 30: name: Астраханская область contain: - Астраханская 31: name: Белгородская область contain: - Белгородская 32: name: Брянская область contain: - Брянская 33: name: Владимирская область contain: - Владимирская 34: name: Волгоградская область contain: - Волгоградская 35: name: Вологодская область contain: - Вологодская 36: name: Воронежская область contain: - Воронежская - г.о. Борисоглебский 37: name: Ивановская область contain: - Ивановская - г.о. Иваново - г.о. Кинешма 38: name: Иркутская область contain: - Иркутская 39: name: Калининградская область contain: - Калининградская 40: name: Калужская область contain: - Калужская 41: name: Камчатский край contain: - Камчатский 42: name: Кемеровская область contain: - Кемеровская 43: name: Кировская область contain: - Кировская 44: name: Костромская область contain: - Костромская 45: name: Курганская область contain: - Курганская 46: name: Курская область contain: - Курская #47: # name: Ленинградская область # contain: # - Ленинградская 48: name: Липецкая область contain: - Липецкая 49: name: Магаданская область contain: - Магаданская #50: # name: Московская область # contain: # - Московская 51: name: Мурманская область contain: - Мурманская 52: name: Нижегородская область contain: - Нижегородская 53: name: Новгородская область contain: - Новгородская 54: name: Новосибирская область contain: - Новосибирская - г. Инская 55: name: Омская область contain: - Омская - АО. Ленинский 56: name: Оренбургская область contain: - Оренбургская 57: name: Орловская область contain: - Орловская 58: name: Пензенская область contain: - Пензенская 59: name: Пермский край contain: - Пермский - г.о. Соликамский - Лысьвенский р-н - р-н Чайковский 60: name: Псковская область contain: - Псковская 61: name: Ростовская область contain: - Ростовская 62: name: Рязанская область contain: - Рязанская 63: name: Самарская область contain: - Самарская 64: name: Саратовская область contain: - Саратовская 65: name: Сахалинская область contain: - Сахалинская 66: name: Свердловская область contain: - Свердловская 67: name: Смоленская область contain: - Смоленская 68: name: Тамбовская область contain: - Тамбовская 69: name: Тверская область contain: - Тверская 70: name: Томская область contain: - Томская 71: name: Тульская область contain: - Тульская 72: name: Тюменская область contain: - Тюменская 73: name: Ульяновская область contain: - Ульяновская 74: name: Челябинская область contain: - Челябинская - г.о. Златоустовский - г.о. Магнитогорский 75: name: Забайкальский край contain: - Забайкальский 76: name: Ярославская область contain: - Ярославская 77: name: г. Москва contain: - Московская - Москва - Люберцы - Мытищи - г.о. Красногорск - г.о. Солнечногорск - с.п. Пышлицкое - г.о. Озёры - с.п. Луневское - Рузский Санаторий Русь УПАТС - г.о. Клин - г.о. Щелково - г.о. Егорьевск - ЗАТО п. Восход - п. Федюково not_contain: - Красноярский 78: name: Санкт-Петербург contain: - Ленинградская - Санкт - г.п. Никольское not_contain: - Красноярский 79: name: Еврейская автономная область contain: - Еврейская #83: # name: Ненецкий автономный округ # contain: # - Ненецкий 86: name: Ханты-Мансийский автономный округ - Югра contain: - Ханты - Сургут - Нефтеюганск - Лянтор - Когалым - г. Радужный not_contain: - Владимирская 87: name: Чукотский автономный округ contain: - Чукотский 89: name: Ямало-Ненецкий автономный округ contain: - Ямало-Ненецкий 91: name: Республика Крым contain: - Республика Крым - Симферополь - Севастополь #92: # name: Севастополь # contain: # - Севастополь 99: name: Иные территории, включая город и космодром Байконур contain: - Байконур 200: name: Российская Федерация contain: - Российская 201: name: Дальневосточный федеральный округ contain: - Дальневосточный федеральный округ not_contain: - Сибирский федеральный округ 202: name: Сибирский федеральный округ contain: - Сибирский федеральный округ not_contain: - Дальневосточный федеральный округ 203: name: Центральный федеральный округ contain: - Центральный федеральный округ 204: name: Уральский федеральный округ contain: - Уральский федеральный округ not_contain: - Приволжский федеральный округ 205: name: Приволжский федеральный округ contain: - Приволжский федеральный округ not_contain: - Уральский федеральный округ 206: name: Северо-Западный федеральный округ contain: - Северо-Западный федеральный округ 207: name: Сибирский федеральный округ, Дальневосточный федеральный округ contain: - Сибирский федеральный округ, Дальневосточный федеральный округ 208: name: Уральский федеральный округ, Приволжский федеральный округ contain: - Уральский федеральный округ, Приволжский федеральный округ 209: name: Красноярский край, Республика Хакасия, г. Москва, г. Санкт-Петербург contain: - Красноярский край, Республика Хакасия, г. Москва, г. Санкт-Петербург
Чтобы избавиться от предупреждений и получить коды регионов для всех записей, нужно отредактировать regions.yml.
diff версий regions.yml
10d9 < - Абзелиловский район 245d243 < - АО Ленинский 265,270d262 < - г.о. Красновишерск < - г.о. Губаха < - г.о. Верещагино < - г.о. Чусовой < - г.о. Кудымкар < - г.о. Краснокамск 452d443 < - Сибирский федеральный округ * Дальневосточный федеральный округ 457d447 < - Уральский федеральный округ * Приволжский федеральный округ 461,462c451 < - Красноярский край, Республика Хакасия, г. Москва, г. Санкт-Петербург < - Красноярский край * Республика Хакасия * г. Москва * г. Санкт-Петербург \ No newline at end of file --- > - Красноярский край, Республика Хакасия, г. Москва, г. Санкт-Петербург \ No newline at end of file
Вуаля
correct records amount: 372324 inserted 372324 records
В качестве вишенки на торте предлагаю макрос диалплана Asterisk для определения региона по номеру абонента:
[macro-get-region] exten => s,1,MYSQL(Connect conn localhost user password dbname) exten => s,n,MYSQL(Query result ${conn} SELECT region FROM codes WHERE ${ARG1} BETWEEN first AND last LIMIT 1) exten => s,n,MYSQL(Fetch region ${result} region_num) exten => s,n,MYSQL(Clear ${result}) exten => s,n,MYSQL(Disconnect ${conn})
Для этих же целей можно использовать Lua скрипт:
local driver = require("luasql.mysql") local env = assert (driver.mysql()) local con = assert (env:connect("dbname", "user", "password")) local cur = assert (con:execute(string.format("select region from codes where %s between first and last limit 1", arg[1]))) row = cur:fetch ({}, "a") if row ~= nil then print(row.region) else print(0) end cur:close() con:close() env:close(
Впрочем, подойдёт любой инструмент, поддерживающий SELECT запросы к MySQL.
Приятного вам администрирования.
