15 июн. 2016 г.
Чем хороши радикальные изменения законодательства -- в офис наведываются давние и очень давние пользователи наших программ. На днях заглянул Евгений Александрович Кучерявенко, один из первых покупателей, пользователь Анжелики, а затем и Гедымина с 1996 года!
Стараниями Евгения Александровича все хозяйства Ивановского района систему полной автоматизации учета с/х предприятия, включая животноводство и растениеводство.
8 июн. 2016 г.
Несколько простых правил одновременной работы над проектом в гит
-
Как можно чаще выполнять git pull для загрузки себе изменений, произведенных другими разработчиками.
При работе в отдельной ветви, из которой позже изменения будут переданы в основную, регулярно выполнять git fetch, затем git merge master.
При возникновении конфликтов принимаем чужие изменения (Accept theirs -- в Tortoise Git) и вносим в них свои правки.
Если автоматический merge не прошел из-за конфликта, то, после его разрешения, на комите, будет показан список измененных файлов как нами, так и другими разработчиками. Если мы работаем с Tortoise Git ни в коем случае нельзя снимать галки с файлов (даже если лично мы их не меняли), иначе изменения других людей пропадут и в репозиторий запишется файл в том состоянии, в котором он был у нас на диске до merge.
Labels:
Git
7 июн. 2016 г.
Ветви Cash & Check
Две ветви добавлены в репозиторий gedemin-apps для текущей разработки проектов POSitive:Cash и POSitive:Check. Здесь будут находиться новейшие версии. После тестирования изменения будут скидываться в ветку master из которой у нас сейчас еженочно формируются дистрибутивы.
Посмотреть какие ветки присутствуют локально на компьютере:
git branch
Добавить и переключиться на локальную ветку cash, связать ее с веткой в центральном репозитории:
git checkout -b cash --track origin/cash
Переключиться на ветку master:
git checkout master
Переключиться на ветку cash:
git checkout cash
Получить изменения с сервера в локальную базу данных. Файлы изменены не будут!
git fetch
Применить полученные изменения из удаленной ветки к локальным файлам в текущей ветке:
git merge
Два предыдущих действия одной командой:
git pull
Если ругнется, что локальная ветка не привязана к ветке в удаленном репозитории, то:
git branch --set-upstream-to=origin/cash cash
После чего делаем pull.
Мы в ветке cash. Принимаем изменения из ветки master:
git merge master
ВАЖНО! При возникновении конфликтов принять изменения другой стороны и внести свои коррективы.
Изменили некоторые файлы. Сохраняем изменения в локальном хранилище:
git commit -a -m "some changes were made"
Отправляем изменения в центральный репозиторий:
git push
После того, как изменения в ветке cash протестированы, отправляем их в ветку master:
git checkout master
git merge cash
git commit -a -m "New cash version"
git push
Labels:
исходный код,
Git
14 мая 2016 г.
True UTF-8 encoding
XML файл в кодировке UTF-8 можно сформировать используя только ASCII и кодируя все национальные символы через � последовательности. Дешево и сердито. Например, такой подход предложен здесь.
Но, если мы хотим, чтобы XML файл красиво отображался в текстовом редакторе, системе контроля версий и т.п., надо сохранить его в настоящей кодировке UTF-8. Для этого мы добавили в платформу функции WIN1251ToUTF8 и UTF8ToWIN1251, которые принимают на вход два потока и перекодируют данные между ними. В дополнение к ним идут функции ReplaceXMLTags и ExpandXMLTags.
Пример использования см. здесь.
Labels:
полезное,
documentation,
vbscript,
XML
12 мая 2016 г.
Деноминация 2016. Технические аспекты
Мы подготовили инструкцию для наших клиентов по деноминированию базы данных. Технически нет возможности хранить в рамках одной базы данных суммы в старых и новых рублях. Поэтому в определенный момент времени база должна быть деноминирована, т.е. с помощью специальной утилиты все денежные значения в базе данных должны быть разделены на 10 000. С этого момента, все суммы, вне зависимости от периода времени к которому они относятся, будут храниться в деноминированных рублях.
В отличие от конкурирующих решений наш подход сохраняет всю историю, весь документооборот предприятия до 1 июля.
Первая проблема, которая возникает, это возможная потеря точности. Платформа использует тип Currency, который позволяет обрабатывать денежные величины с точностью до 4-го знака после запятой. После деноминации 0.0001 в новых деньгах будет соответствовать 1-му старому рублю. Все что меньше рубля потеряется (округлится по правилам математического округления). Хотя 1 неденоминированный рубль очень маленькая величина (коробок спичек сейчас стоит 400 рублей) можно представить базу данных, где мелкий товар учитывается поштучно и цена единицы содержит копейки -- пуговицы, швейные иголки, болты, гайки и т.п. Мы рекомендуем в таком случае провести на 30 июня 2016 г. переоценку товара, округлив учетные цены до целых рублей.
Вторая проблема -- округление до целого числа в скрипт-функциях и отчетных формах через вызов функций Round, Int, Fix, CLng, CInt или обращение к полю через свойство AsInteger. Мы внесем исправления в типовые прикладные решения, но решить задачу в общем случае, анализируя программный код и автоматически заменяя вызовы функций нам не представляется возможным. Единственный путь -- заранее создать копию рабочей базы данных, деноминировать ее и затем тестировать на ней все режимы работы и устранять выявленные проблемы.
Третья проблема заключается в том, что бухгалтерия предприятия до 20 июля производит закрытие июня и второго квартала. При этом вносятся и/или корректируются документы прошлых периодов, закрываются транзитные счета, выполняется трансформация баланса, рассчитываются промежуточные показатели и налоги. Согласно методическим разъяснениям налоговые декларации за июнь подаются в неденоминированных рублях.
Мы видим такое решение данной проблемы: предприятие продолжает после 1 июля вести учет в неденоминированных рублях при этом, непосредственно в печатных формах товарных накладных, денежные величины делятся на 10 000; суммы, поступающие из системы банк-клиент умножаются на 10 000, соответственно, суммы, уходящие в банк-клиент, делятся на 10 000; входящие накладные умножаются на 10 000 и т.д. После того, как налоговые декларации будут сданы можно будет проводить деноминацию базы данных и переходить на учет в деноминированных рублях.
Малое предприятие, при надлежащей подготовке в июне месяце, вполне может выполнить закрытие в самых первых числах июля и, таким образом, избежать промежуточного периода учета в старых и новых рублях.
Деноминация базы данных производится с помощью отдельной утилиты dnmn.exe, которая предоставляется клиентам на абонентском обслуживании. Мы обработали несколько десятков баз данных и сформировали список полей для деноминации. Если на вашем предприятии используются частные решения, то перед запуском процесса следует добавить нужные поля в список деноминируемых.
Labels:
база данных,
утилиты
9 мая 2016 г.
Прямой доступ к DBF файлам
Устав бороться с "тормозами" и ошибками стандартных ODBC драйверов для доступа к DBF файлам мы включили компонент TDBF в исходный код Гедымина. Пример использования можно посмотреть тут.
Точных замеров и сравнений не проводили, но "на глаз" переход на встроенный компонент ускорил у одного из наших клиентов обработку больших массивов данных раза в три.
Labels:
база данных,
оптимизация,
полезное,
производительность
26 апр. 2016 г.
Сохранить имя пользователя и пароль в Git
При работе с приватными репозиториями github, при выполнении операция pull/push git будет постоянно запрашивать имя пользователя и пароль. Заставить систему запомнить введенные один раз значения можно следующим образом:
1. Переходим в окно командной строки, в папку с исходниками
2. Выполняем:
git config credential.helper store
git pull
Username: type your username
Password: type your password
При последующих операциях имя пользователя и пароль вводить уже не надо.
Labels:
Git
24 апр. 2016 г.
Задание на неделю #1. Firebird 3
На этой неделе произошло событие, которого мы с нетерпением ждали шесть долгих лет -- вышла третья версия сервера Firebird. В двух словах предыстория такова: Interbase, от которого в 2000-м году отпочковался Firebird, был задуман в те времена, когда многопроцессорные системы с десятками гигабайт оперативной памяти встречались разве что в фантастических рассказах. Когда же научно-технический прогресс догнал и перегнал самые смелые фантазии, именно внутренняя архитектура сервера стала основным тормозом. По сути, в многопользовательском сценарии у системного администратора было два выбора: или использовать оперативную память для кэширования данных, но тогда запросы из всех подключений будут выполняться только на одном процессоре/ядре (архитектура SuperServer), или задействовать все процессоры/ядра, но тогда не будет общего кэша и скорость будет зависеть от производительности дисковой подсистемы (архитектура Classic). Тот случай, когда хрен редьки не слаще.
Изменения в архитектуре SuperServer движка Firebird 3 теперь позволяют последнему выполнять запросы сетевых клиентов параллельно на разных процессорах/ядрах, при доступе к общему кэшу, что теоретически делает SuperServer выбором по умолчанию при развертывании системы на предприятии. Как оно получится на практике -- зависит от надежности тройки. В начале 2000-х мы перевели всех клиентов с SuperServer на Classic по двум причинам: падение процесса SuperServer означает обрыв всех коннектов и потерю данных во всех открытых транзакциях у сетевых пользователей; выполнение тяжелого запроса одним из клиентов практически парализует работу всех остальных.
У одного нашего клиента база данных имеет размер 50 Гб, количество одновременных подключений 50-60, на сервере 128 Гб оперативной памяти и 20 физических ядер. План: использовать SuperServer, установить кэш размером 50 Гб и выделить под буфер сортировки 32 Гб. Учитывая, что дисковая подсистема построена на RAID контроллере с 2 Гб энергонезависимой памяти, теоретически, это позволит вообще исключить прямое обращение к дискам. Т.е. производительность сервера базы данных будет определяться процессором, памятью и скоростью обмена с RAID контроллером.
Напомним, что именно производительность дисковой подсистемы всегда возглавляла список факторов, влияющих на общую производительность СУБД. Мы ожидаем ускорения выполнения запросов минимум на порядок. О достигнутых результатах напишем в этом блоге.
Практически все нововведения из третьей версии найдут применение в Гедымине:
-
Передача НУЛЛ значений по сети битовой маской.
Сейчас каждое поле с НУЛЛ значением занимает при передаче 4 байта + длина поля. Например, в таблице с бухгалтерскими проводками у нас десятки полей-аналитических признаков, которые могут быть не заполнены. Экономия может достигать нескольких сотен байт на каждую запись.
Возможность увеличить TCP буфер до 32 Кб и применить компрессию данных при передаче.
В интернете есть свидетельства о том, что скорость возрастает десятикратно при подключении по сетям с большой латентностью. Например, к серверу в удаленном офисе по VPN каналу.
Шифрование файла базы данных. Теперь злоумышленник не сможет получить доступ к конфиденциальной информации просто переписав файл на сервер с чистой установкой Firebird и известным паролем к учетной записи SYSDBA.
Window функции в SQL запросах позволяют объединять вместе данные и агрегатные значения по заданным группам этих данных. До Firebird 3 такую задачу можно было решить либо подзапросами (крайне медленно, так как подзапрос будет выполняться для каждой записи), либо выполнением в цикле отдельных запросов для каждой группы и объединением их результатов в единый набор данных с помощью EXECUTE BLOCK или STORED PROCEDURE, либо алгоритмической обработкой на клиенте (например, внутри Fast Report при построении отчета).
“Linger” Database Closure for Superserver -- период времени, в течение которого сервер сохраняет в памяти все ресурсы, после закрытия последнего подключения к базе данных -- позволит ускорить загрузку пакета пространств имен, так как переподключение к базе данных выполняется после каждого ПИ, содержащего метаданные.
DDL триггеры позволят отказаться от выполнения процедуры at_p_sync при старте системы для синхронизации информации о структуре базы данных с содержимым AT_ таблиц.
Другие изменения и улучшения, на которых мы подробнее остановимся в следующих выпусках.
Labels:
безопасность,
идеи,
Firebird,
SQL,
Weekly
27 янв. 2016 г.
Поиск кольцевых ссылок в реляционной базе данных рекурсивным SQL запросом
Наш предыдущий подход к поиску кольцевых ссылок, изложенный тут, заключался в том, чтобы дать рекурсивному запросу возможность зациклиться и контролировать количество итераций. При достаточно большом их числе мы могли сказать, что скорее всего в данных присутствует цилическая связь. Само число следовало подбирать эмпирически, анализируя данные конкретной задачи.
Между тем, существует способ однозначного выявления циклов без "наматывания" кругов по графу. Рассмотрим граф, показанный на рисунке ниже:
В базе данных он хранится в виде матрицы смежностей в таблице t:
CREATE TABLE t (
a INTEGER,
b INTEGER
)
Соответственно, исходные данные:
INSERT INTO t VALUES (1, 2); INSERT INTO t VALUES (2, 3); INSERT INTO t VALUES (3, 4); INSERT INTO t VALUES (3, 5); INSERT INTO t VALUES (3, 6); INSERT INTO t VALUES (2, 7); INSERT INTO t VALUES (6, 1);Для поиска кольцевых ссылок напишем запрос:
with recursive tree as
(
select distinct
a as initial, a, b, -1 as prev
from
t
union all
select
iif(tr.initial <> tt.a, tr.initial, -1) as initial,
tt.a,
tt.b,
tr.a as prev
from
t tt JOIN tree tr ON
tr.b = tt.a and tr.initial > 0
)
select
*
from
tree
where
initial = -1
Запрос покажет все первые сегменты A - B (и предыдущие, т.е. сегменты непосредственно приведшие к циклу, PREV - A), всех возможных циклов в заданных данных. В нашем случае:
INITIAL A B PREV -1 1 2 6 -1 2 3 1 -1 2 7 1 -1 3 4 2 -1 3 5 2 -1 3 6 2 -1 6 1 3При необходимости проверить не входит ли в кольцо конкретный узел, следует прописать его ИД в первом запросе рекурсивного CTE:
with recursive tree as
(
select distinct
a as initial, a, b, -1 as prev
from
t
where
a = _some_id_
union all
select
iif(tr.initial <> tt.a, tr.initial, -1) as initial,
tt.a,
tt.b,
tr.a as prev
from
t tt JOIN tree tr ON
tr.b = tt.a and tr.initial > 0
)
select
*
from
tree
where
initial = -1
8 янв. 2016 г.
Конвертация параметров складских документов
Параметры складских документов изначально хранились в двоичном поле OPTIONS, в таблице GD_DOCUMENTTYPE.
При наследовании типов документов параметры должны наследоваться. Причем, если мы что-то исправляем в родителе, то изменения должны распространиться на наследника. В обратную сторону распространение работать не должно -- изменили в наследнике, родителя это никак не затрагивает. Реализовать наследование параметров для двоичного формата, во-первых, трудоемко, во-вторых, потребует одномоментной замены всех gedemin.exe на предприятии. Причем минусы в виде непрозрачности данных никуда не денутся.
Новая версия gedemin.exe хранит параметры в реляционном виде в таблице GD_DOCUMENTTYPE_OPTION. Один параметр -- одна запись, связанная с GD_DOCUMENTTYPE.
Для просмотра параметров добавлен грид в окно со списком типов документов.
Правильный порядок конвертации такой:
-
К эталонной БД, на которой идет разработка, однократно подключаемся из командной строки с параметром /cdo:
gedemin.exe /cdo
Произойдет автоматическая конвертация опций после чего следует сохранить измененные ПИ.
Грузим обновленные ПИ на базы, где используются складские документы.
-
gedemin.exe /cdo на базе ETALON и сохраняем с нее ПИ.
gedemin.exe /cdo на базе ETALON_RESTORAN и ЗАГРУЖАЕМ на неё общие ПИ с базы ETALON.
Только после загрузки сохраняем ПИ с базы ETALON_RESTORAN.
Labels:
полезное
13 дек. 2015 г.
Выполнение скрипт-функции по расписанию
Как организовать выполнение скрипт-функции по расписанию?
Автозадачи решают данную проблему, но требуют постоянно загруженного gedemin.exe и открытого коннекта к базе данных. Начиная с версии 2.9.2 можно использовать планировщик операционной системы и два новых параметра командной строки:
gedemin.exe /run 147000555_256456378
Выполняет скрипт-функцию с заданным РУИДом после загрузки платформы, инициализации подсистемы автозадач и выполнения всех автозадач, назначенных на старт системы (если таковые имеются).
gedemin.exe /run 147000555_256456378 /exit
То же, что и выше, но после выполнения скрипт-функции программа будет завершена.
gedemin.exe /exit
Завершение выполнения gedemin.exe сразу после загрузки, подключения к базе данных, инициализации подсистемы автозадач и выполнения всех автозадач, назначенных на старт системы.
Указанные параметры могут использоваться вместе с параметрами подключения к базе данных.
Labels:
безопасность,
документация,
полезное,
совет,
справочная система,
vbscript
14 нояб. 2015 г.
Перезапуск платформы по расписанию
В идеальном мире, где идеальные люди запускают идеальные программы, ошибкам просто нет места. Но в реальной жизни shit, к сожалению, happens. Когда сроки истекли еще вчера, а технические требования заказчик меняет каждый раз, когда видит очередную версию, приходится действовать по методике "run and fire". И, если ошибки на экране в худшем случае заставят пользователя произнести несколько нецензурных слов, то неявные утечки памяти и редкие баги в серверном коде, способны свести с ума даже закаленного аса разработки и отладки.
Здесь на помощь приходит "quick and dirty" решение в виде автоматического перезапуска платформы по расписанию:
На приведенном выше скриншоте показаны настройки автозадачи для перезапуска платформы каждые 10 минут. Стоит сделать замечание, что перезапуск не произойдет, если на экране открыто диалоговое окно в модальном режиме.
Здесь на помощь приходит "quick and dirty" решение в виде автоматического перезапуска платформы по расписанию:
На приведенном выше скриншоте показаны настройки автозадачи для перезапуска платформы каждые 10 минут. Стоит сделать замечание, что перезапуск не произойдет, если на экране открыто диалоговое окно в модальном режиме.
Labels:
документация,
полезное,
проблема
Подписаться на:
Сообщения (Atom)


