Страницы

21 декабря 2012 г.

ODBC, Quik. В указанном DSN архитектура драйвера и архитектура приложения не соответствуют друг- другу...

Доброго времени суток.
А вам попадалась такая ошибка:
"В указанном DSN архитектура драйвера и архитектура приложения не соответствуют друг- другу SQLSTATE = IM014 Код ошибки = 0" ?

       Мне попалась при попытке настроить выгрузку по ODBC из торговой системы Quik в базу PostgreSQL на ОС Windows 7 x64.

Итак, как это решить?

       Суть проблемы заключается в несоответствии разрядности ODBC-драйвера и приложения которое им может воспользоваться .Если у вас 64-разрядная система, то Вы наверняка скачали и установили 64-разрядный драйвер ODBC. Если у Вас приложение для которого требуется выгрузка по ODBC - 64-х битное, то проблем не должно было возникнуть впринцыпи (Троговой платформы Quik это не касается, на текущий момент она 32-разрадная). Если приложение 32-битное, тогда скачиваем 32-битный драйвер ODBC, ставим его в систему, и настраиваем при помощи приложения расположенного в папке "c:\windows\sysWOW64\odbcad32.exe".

       Если у Вас есть и 32-х и 64-х разрядные приложения работающие по ODBС, то ничто не мешает установить драйвера с ссответствующими разрядностями.

29 октября 2012 г.

PostgreSQL. Переменные внутри триггерных функций.

Доброго времени суток.

       Решил законспектировать некоторую информацию о данных доступных при написании триггеров PostgreSQL.
       Во время работы триггера, в контексте  функции автоматически создаются переменные которые содержат очень полезные данные данные:
  • NEW.  Тип - RECORD. Содержит значения стобцов ТЕКУЩЕЙ записи таблицы при выполнении операций INSERT/UPDATE;

  • OLD. Тип - RECORD. Содержит значения стобцов ТЕКУЩЕЙ записи таблицы при выполнении операций UPDATE/DELETE;

  • TG_NAME. Тип - NAME.Содержит имя запущенного триггера;

  • TG_WHEN. Тип - TEXT. Содержит строку "BEFORE" или "AFTER", в зависимости от режима срабатывания триггера;

  • TG_OP. Тип - TEXT. Содержит строку "INSERT", "UPDATE" или "DELETE", в зависимости от оператора который вызвал выполнение триггера;

  • TG_TABLE_NAME. Тип - NAME. Содержит имя таблицы к которой была применена операция вызвавщая текущий тириггер;

  • TG_TABLE_SCHEMA. Тип - NAME. Содержит имя схемы которой принадлежит таблица описанная в предидущем пункте;

Полный список переменных, описания, и примеры можно увидеть в официальном мануале.

16 октября 2012 г.

Delphi. Ошибка: Ancestor for 'Component' not found.

Доброго времени суток.
       При запуске приложения, и при построении формы, содержащей какой-либо фрейм, может появляться ошибка "Ancestor for 'Component' not found" (где Component - имя компонента).
Эта ошибка появляется если Вы переименовали компонент на фрейме, но в на форме, которая содержит фрейм компонент прописан со старым именем. Нужно просто указать одинаковые имена компонентов в родителе и наследнике.

P.S. Многократно видел в интернете обсуждение аналогичных проблем. Надеюсь кому-то пригодится данный пост.

9 октября 2012 г.

ZeosLib. Транзакции. Ошибка: invalid operation in non AutoCommit mode

Еще раз Здравствуйте.
       Наткнулся на ошибку "invalid operation in non AutoCommit mode" при выполнении ZConnection.StartTransaction.
       В zeos-компонентах управление транзакциями производится из объекта класса TZConnection. В этом классе есть свойство AutoCommit:boolean, а так же методы StartTransaction, Commit, Rollback.
       Я думал, что когда используется StartTransaction..Commit/Rollback, AutoCommit должен быть FALSE. Ибо если логически подумать, то зачем нам автоматический коммит, если мы управляем транзакциями вручную.
Оказывается немного не так... StartTransaction НЕ будет работать если AutoCommit = false.
       Если AutoCommit = true, тогда транзакции фиксируются после каждого корректно завершенного SQL-оператора, а StartTransaction позволяет отменить автоматическое фиксирование и управлять транзакцией вручную. При AutoCommit = false - изменения не будут фиксироваться в базу вообще, следовательно команду StartTransaction вызывать бесполезно.

p.s.
Код метода который генерирует указанное в сабже исключение:
procedure TZConnection.CheckAutoCommitMode;
begin
  if not FAutoCommit and (FExplicitTransactionCounter = 0) then
    raise EZDatabaseError.Create(SInvalidOpInNonAutoCommit);
end;

8 октября 2012 г.

PostgreSQL. Склеиваем дату и время в SQL запросе.

Hello World.
Сегодня понадобилось склеить дату и время находящиеся в разных столбцах вместе, и поместить в третий результирующий столбец.
Функций для этой операции я не нашел, поэтому пришлось экспериментировать.
Представим, что есть таблица с полями:
create table test (
field_date date, 
field_time time without time zone,
field_result timestamp without time zone) 

Предположим, что первые две колонки таблицы заполненны датами и значениями времени. Далее, чтобы заполнить третий столбец совмещенными значениями даты и времени из двух предидущих столбцов, пишем update:
update test set
field_result = (field_date::date||' '||field_time::time without time zone)::timestamp without time zone

Все, проверяем результат...

3 октября 2012 г.

Delphi XE2. FastReport. Fail с экспортом.

       Друзья мои, сразу после того как вы увидите в стандартной поставке Delphi XE2 копмоненты FastReport 4, и бесконечно обрадовавшись начнете ваять на их базе какую-нибудь серьезную подсистему отчетности - загляните по ссылке: http://www.fast-report.com/ru/products/fast-report4-editions-compare.html, и ознакомтесь с ограничениями Вашей версии!
Имеено для XE2 отсутствует экспорт в самые нужные форматы! Я об этом не прочел вовремя... и приплыл. Канешно, временное решение я нашел, но в скором будущем, похоже, стану клиентом FastReport.
Вот так бывает. :)

2 октября 2012 г.

pgAdmin. Резервное копирование и восстановление базы данных.

Доброго времени суток.
       Нашел на компе старое описание пошаговых действий при резервном копировании и восстановлении базы данных. Для чего делал и для кого делал - не помню, но не пропадать же добру, залью сюда. Может кому-то в чем-то пригодится :).

1 октября 2012 г.

Delphi XE2. Установка ZeosLib.

Приветствую Вас в своем блоге.

Сегодня я хотел бы описать процесс установки компонентов Zeos на Delphi XE2.

        Первое, что необходимо это конечно сами компоненты. Когда-то я качал их из официального SVN-а. Архив с тех пор сохранился, его можно взять ТУТ, если по каким-либо причинам Вы не можете скачать с SVN.
        Итак, компоненты загружены, сложены в отдельную папку, идем далее...
Выбираем "File - Open Project..."
 

27 сентября 2012 г.

pgScript. Работа с датами (представление значений в скрипте).

Доброго времени суток.

       pgScript во время выполнения подствляет вместо именованных переменных их значения, причем просто заметой имени на значения прямо в текста скрипта. Может быть для скриптовых языков (в общем случае) это не новость, но я столкнулся с этим впервые.
       На кануне мне довелось написать скрипток который выполняет запрос с фильтрацией по дате. Дата для фильтрации выбиралась в переменную скрипта, а позже использовалась в запросе.

Скрипт:
declare @SesRec,
 @i,
 @date_session;

begin
 set @SesRec = select to_char(session_begin, 'YYYY-MM-DD') from session order by session_begin;

 set @i = 0;
 while @SesRec[@i][0]
 begin
  set @date_session = @SesRec[@i][0];
  print @date_session;
  update "session" set
   id_session = @i
  where session_begin::date = '@date_session'::date;
   set @i = @i+1;
 end
end


Обратите внимание на запрос, а именно на способ подстановки переменной "@data_session":
update "session" set
 id_session = @i
where session_begin::date = '@date_session'::date;

pgScript интерпретировал такой запрос так:
[QUERY    ] 
update "session" set
 id_session = 0
where session_begin::date = '1900-01-01'::date
и выполнил его корректно!
Записи типа:
update "session" set
 id_session = @i
where session_begin::date = @date_session::date;
--**********************************************
update "session" set
 id_session = @i
where session_begin::date = ''||@date_session||''::date;
--**********************************************
update "session" set
 id_session = @i
where session_begin::date = quote_literal(@date_session)::date;

Работать не будут!

20 сентября 2012 г.

Вирусы атакуют!!! или Epic Fail! (humor)

Приветствую.
Уже не первый раз встречаю попытки "вылечить" мой компьютер от злостных вирусов...
И каждый раз меня это жутко веселит )))

Вы не поверите, система настолько продвинута, что даже нашла кучу вирусов:

13 сентября 2012 г.

Delphi XE2. FastReport. Ошибка: Cannot find class TfrxReport.

Доброго времени суток.
С Delphi XE2 поставляется генератор отчетов FastReport 4. При попытке им поспользоваться обнаружлся неприятный глюк. Если разместить компонент отчета (TfrxReport), на форме, открыть постоитель отчета, построить отчет, сохранить все построеное в файл *.fr3. То в случае перезапуска проекта и попытке открыть дизайнером frxReport сохраненный ранее файл *.fr3, то вылетит ошибка "Cannot find class TfrxReport", и отчет не откроется.
Разработчики пофиксили баг. (источник тут).

Чтобы убить баг, нужно:
  1. Закрыть Delphi XE2.
  2. Скачать архив исправленных модулей отсюда.
  3. Найти место куда встал FastReport (у меня это - "C:\Program Files\FastReports\")
  4. Скопировать файлы (с заменой) из скачанного архива (из папки "LibD16") а директорию "C:\Program Files\FastReports\LibD16\".
  5. Запустить Delphi XE2.


6 сентября 2012 г.

Основы С++. Видео лекция

Первая лекция! Остальное по ссылке внизу ролика.

Посмотреть видео на сайте Лекториума

Базы данных. Видео лекции

Решил просмотреть курс лекций по Базам Данных. Лектор - И.Тетерин.
Просмотрев первую лекцию (первые ~40 мин. видео, все остальное - "шум") принял решение продолжать просмотр и поделиться метериалами.
Все остальное по ссылке ниже ролика.


Посмотреть видео на сайте Лекториума

7 августа 2012 г.

Дизайн блога. Нужны рекомендации...

Доброго времени суток Вам, уважаемые. :)
       Со временем, относительно разных вещей в жизни, приходит понимание, что надо что-то менять.

       Обратил внимание на дизайн своего блога. В последнее время мне все больше кажется, что что-то нужно изменить. Никак не могу до конца определить что не так. Может все слишком темно и мрачно? Может цвета подобраны не так? Может нужно еще что-то добавить или убрать? А может вобще все изменить? Вобщем я не могу определиться как улучшить внешний вид и читабельность блога...

Что бы Вы поменяли в этом блоге, чтобы Вам было приятнее его читать?

Заранее благодарен за советы. :)

2 августа 2012 г.

PostgreSQL. Логирование исключений. Часть 2. Реализация.

Hello World! :)

       В данном посте мне хотелось бы продолжить тему разработки логирования исключений для PostgreSQL. В предыдущем посте я обозначил требования и способы реализации. Сейчас я хочу приступить непосредственно к реализации.

       Как я и говорил, этим хранилищем будет являтсья таблица. В соответствии с описанием в предыдущем посте, я определил все необходимые мне поля. Получился следующий скрипт:



CREATE TABLE sys.exception_log
(
  id_exception_log bigserial NOT NULL, -- идентификатор записи
  exception_time timestamp without time zone NOT NULL, --время исключения
  exception_code character varying NOT NULL DEFAULT 0, --код исключения
  exception_message character varying NOT NULL, --сообщение
  exception_query text NOT NULL, --текст запроса возбудившего исключение
  exception_label character varying, --метка
  usr_name character varying NOT NULL, --пользователь запустивший запрос
  server_version character varying NOT NULL, --версия сервера PostgreSQL
  db_location character varying NOT NULL, -- локация сервера
  client_location character varying NOT NULL, --локация удаленного клиента
  CONSTRAINT pk_exception_log_id_exception_log PRIMARY KEY (id_exception_log)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE sys.exception_log OWNER TO postgres;


PostgreSQL. Логирование исключений. Часть 1. Требования, тесты, поиски вариантов.

       Добро пожаловать в "Будни программиста".
       Сегодня я хотел бы начать освящать вопрос логирования исключительных ситуаций происходящих во время выполнения хранимых процедур. Не буду говорить о пользе такого функционала, ибо, думаю, это и так понятно. Скажу только, что из-за отсутствия такого функционала вчера пришлось потратить более часа на локализацию исключения возникающего у клиента, и чуть более минуты на устранение причины исключения.

Что нужно от логирования?

  1. Доступное хранилище лога исключений;
  2. Добавление в лог новых записей при возникновении исключений любого типа;
  3. Возможность хранения кода и текстового сообщения исключения;
  4. Необходимо хранить данные для локализации. В идеале SQL-запрос который вызвал исключение (в т.ч. имя хранимки (породившей исключение) с указанными значениями параметров); 
  5. Способ разметки областей хранимой процедуры для более точной локализации возникновения исключений.

1 августа 2012 г.

PostgreSQL. Методы проверки результатов выполнения запроса

Доброго времени суток.
       Я относительно недавно начал пользоваться PostgreSQL, и каждый день приносит мне новые открытия, которые я хотел бы законспектировать.

       Итак, в PostgreSQL есть способы проанализировать результаты выполенения запросов на предмет наличия возвращаемых данных. Ранее, я делал что-то типа:

if not exists(select null from table where rec_id = record_id) then
 insert... ;
else
 update... ;
end if;

Этот способ бесспорно работает, но PostgreSQL предоставлет более изящные решения, например: 

PostgreSQL. Полезные запросы к системным таблицам

Доброго времени суток.
Создаю очередную памятку полезных запросов, к которым время от времени приходится обращаться. Возможно настолько редко, что без памятки не обойтись.
Запросы будут как самописные так и взятые из различны источников (во избежание изобретения велосипедов).

Пост будет постоянно расширяться.

Запросы под катом.

5 июля 2012 г.

pgScript. Иллюстрация еще одного рабочего примера.

Доброго времени суток.
       Опыт изучения технической литературы показывает, что трудно уяснить теорию не закрепленную примерами. Да, я стараюсь везде выкладывать примеры использование тех или иных инструкций, но разница между "школьными" примерами и боевыми рабочими скриптами все таки колоссальна. Я буду стараться выгружать сюда как можно больше разнообразной практики, чтобы остальным было легче понять и разобраться в нюансах. И, может быть, сделать мне пару замечаний, ибо я все же еще новичок.
       Итак, вот собственно скрипт:

declare
 @SesNULLRec,
 @i,
 @max_prev_session;
begin
 /*Выгружаем все пропущенные сессиии в таблице security_price*/
 set @SesNULLRec = select distinct ses.id_session
  from session ses
  left join security_price sp on ses.id_session = sp.id_session
  where sp.id_session is null;

 --счетчик цикла (индекс значений в SesNULLRec)
 set @i = 0;
 while @SesNULLRec[@i][0] --пока значение есть...
 begin
  --пристваиваем отдельной пеерменной значение RECORD-переменной, ибо RECORD неправильно интерпретируется
  --select запросом
  set @max_prev_session = @SesNULLRec[@i][0]; -- строка i, столбец 0
  --выводим значение (для информативности)
  print @max_prev_session;

  /*Вставить в security_price записи из security_price с наибольшим идентификатором сессии который
  меньше чем указанный (указанный в данном случае - это тот который отсуствует в таблице security_price)
  Короче: Если в security_price нет записей за нужную сессию, копируем записи из ближайшей последней
  сессии подставляем идентификатор НУЖНОЙ, тем самым восполняя пробелы...*/
  insert into security_price (id_security, id_session, lot_size, cur_price)
  select
   id_security,
   @max_prev_session::bigint, -- нужной сессии
   lot_size,
   cur_price
  from 
   security_price
  where id_session in ( -- максимальный идентификатор предшествующей сессии
   select
    max(id_session)
   from security_price
   where id_session < @max_prev_session::bigint
   );

  --наращиваем счетчик цикла (индекс значений в SesNULLRec)
  set @i = @i+1;
 end
end

Думаю комментариев в данном скрипте достаточно и дополнительные объяснения будут лишними.

При написании данного скрипта я изредка поглядывал с статьи:
pgScript. Написание простых скриптов. Первый опыт.
pgScript. Использование типа RECORD

18 июня 2012 г.

PostgreSQL. Обработка исключений внутри функций.

Добро пожаловать в "Будни программиста"
       Сегодня вернулся к написанию хранимых процедур на plpgsql. После долгого периода некоторые моменты изрядно подзабылись. В том числе и синтаксис, да и вообще механизм обработки исключений. В связи с этим, хочу создать этот пост-пометку. Надеюсь он мне больше не понадобится, ибо если я забуду это еще раз, надо будет бежать к хирургу и просить вставить еще пару планок памяти :).

       Общий синтаксис функции с обработчиком исключений выглядит следующим образом:

[ DECLARE
 declarations ]
BEGIN
 statements
EXCEPTION
 WHEN condition [ OR condition ... ] THEN
  handler_statements
 [ WHEN condition [ OR condition ... ] THEN
  handler_statements
   ... ]

END;

16 июня 2012 г.

pgScript. Генераторы случайных последовательностей. Дата и время

       Приветствую Вас с своем скромном блоге.
       Сегодня мне хотелось бы продолжить ряд статей (который дополняется медленно, но верно :) ) посвященных генерации случайных последовательностей в pgScript. Далее пойдет речь о последовательностях типа Data, Time и Timestamp. 
Итак, начнем... Синтаксис определения генераторов всех выше указанных типов идентичен:
DATE(min, max, [sequence], [seed])
TIME(min, max, [sequence], [seed])
DATETIME(min, max, [sequence], [seed]) 
где,
min - Минимальная граница диапазона генерации значений;
max - Максимальная граница диапазона генерации значений;
[sequence] - необязательный параметр, устанавливает способ генерации. Различает только нулевое и ненулевое значение. 
[seed] - необязательный параметр, указывает функции номер значения в последовательности которое должна вернуть функция. Это целесообразно использовать в случаях когда необходимо генерировать одинаковое значение при нескольких обращениях к одному генератору, иначе (по умолчанию) при каждом обращении будет генерироваться произвольное значение.

7 июня 2012 г.

Регистрация COM сервера в системе

       Здравствуйте.
       Тем, кто уже работал с COM-серверами и успешно переносил их на другие машины - можно не читать.
       На начальном этапе программеров смущает тот факт, что при переносе на новую машину клиенты их COM-серверов (я работал только Out-precess) выдают ошибку "Interface not supported". Лично мой сервер является приложением, а не библиотекой. Где-то я вычитал что сервера-приложения сами себя регистрируют при запуске, что меня в конечном итоге и сбило с толку. При переносе на другую машину столкнулся с вышеописанной ошибкой. Все оказалось не так просто...
Итак, COM-сервера бывают 2-х видов:
  • В виде DLL;
  • В виде исполняемого файла.

4 июня 2012 г.

COM - объекты. Параметры фабрики классов.

Приветствую Вас в блоге "Будни программиста".

       Я заметил, что многие задают вопросы типа "А как сделать чтобы к одному Com-серверу можно было подключиться множеством клиентов?", "А как сделать чтоб для всех клиентов создавался один объект на сервере?" и т.д.
       Совсем недавно, немного познакомившись с технологией COM, я и сам искал ответы на эти вопросы. В этом посте я постараюсь подвести итог моих поисков.
Итак, имеется два параметра фабрики классов управляющие генерацией COM-объектов на сервере:
  • Instancing;
  • Threading Model;

3 июня 2012 г.

GRUB. Убираем дублирование вариантов загрузки ОСей.

       Доброго времени суток. Добро пожаловать в мой скромный блог.

       Речь пойдет и Linux Ubuntu и загрузчике GRUB который позволяет управлять вариантами загрузки системы (или систем если их несколько на ПК).
       Итак, в линуксе я относительно недавно и потому был очень удивлен, увидев что со временем вариантов загрузки системы становится все больше и больше. Варианты загрузки появляются при обновлении ядра Linux. Новое ядро прописывается в конфиг загрузчика, а старая версия не удаляется... Вот как раз 3 мин. назад установилось новое обновление, которое потребовало перезагрузки, сейчас ребутнусь, заодно и сделаю фото для наглядности. :)
Перезагрузка принесла нам фото, вот так это выглядит:


28 мая 2012 г.

pgScript. Генераторы случайных последовательностей. Числовые данные

Здравствуйте. Добро пожаловать в мой скромный блог.

       Сегодня я опишу генераторы случайных последовательностей числовых значений, которые используются в pgScript.

Целочисленные последовательности.

Следующая строка присвоит переменной "@Rec" значение генератора:

set @Rec = INTEGER ( Min, Max, [Sequence], [Seed] );
где,
Min - Минимальная граница генерации чисел.
Max - Максимальная граница генерации.
Sequence - Не обязательный параметр назначающий последовательность генерации чисел. (реакция генератора различна только на нулевое и ненулевое значение данного параметра).
Seed - Не обязательный параметр обозначающий индекс числа в последовательности. Т.е. если данный параметр установлен, то генератор будет возвращать не произвольное число, а число с указанным в данном параметре индексом, не зависимо от количества обращений.

21 мая 2012 г.

Написание callback-функций в C++ и COM

       Это быстрое описание того, как адаптировать Ваши указатели функции C-стиля, если Вы кодируете на C++. Эта статья написана для того, чтобы предоставить быстрое описание людям, пытающимся выяснять, как работают функции обратного вызова на всевозможных языках. Щелкните здесь для C#/.NET версии. Или щелкните здесь, если Вы хотите сделать делегат C#-стиля функций обратного вызова в C++.

       Проблема написания программы на C++ состоит в том, что работа с указателями функции реализована более сложно. В C все Ваши функции глобальны, и определить адрес функции можно в любой точке кода где это понадобится. Однако, в C ++ Ваши функции (если они не объявлены как статичные) связаны с объектами, и Вы должны оперировать объектом наряду со своим указателем функции.

17 мая 2012 г.

Delphi 2007. Сохранение библиотеки типов COM-сервера. Ошибка "Unable to rename 'my_TLB.tlb' to ' '"

Доброго времени суток.
       Внезапно понадобилось разработать свой маленький COM-сервер на Pascal-е  для реализации взаимодействия между приложениями. Воспроизводя все действия согласно мануалу я наткнулся на проблему не позволяющую мне сохранить проект. При открытой библиотеке типов IDE постоянно генерировало исключение "Unable to rename 'my_TLB.tlb' to '.'".
       Покопавшись по форумам я высянил,что такая проблема преследует только тех кто использует Delphi 2007 в совокупности с твикером. Твикер представляет собой исполняемый файл: "D2007Tweaks.exe". В инструкции к этой программе написано, что необходимо поставить галочки напротив пунктов 'Don't create local files', 'Don't create ~bpl files', 'Don't create history files', что я и сделал при установке Delphi.
       Как выяснилось именно эта настройка препятствует сохранению библиотеки типов COM - сервера. Если Снять вышеуказанные галочки, проект сохраниться нормально.

11 апреля 2012 г.

C++. Компилятор "VS 2005/2008". Ошибка LNK2019

Добрый день.

       Класс описанный в предыдущем посте я изначально писал с использованием IDE Code::Blocks 10.5 , Компилятор gcc. После этого функционал был отлажен, я перенес его в библиотеку которая компилится VC 2005/2008 на базе все того же Code::Blocks.
Попытался сделать билд и приплыл... Повалились ошибки:

w_registry.obj||error LNK2019: unresolved external symbol __imp__RegQueryValueExA@24 referenced in function "private: void __thiscall 
 win_reg::Registry::SysGetValue(char const *,unsigned char *,unsigned long *)" (?SysGetValue@Registry@win_reg@@AAEXPBDPAEPAK@Z)|
 

w_registry.obj||error LNK2019: unresolved external symbol __imp__RegSetValueExA@24 referenced in function "private: void __thiscall win_reg::Registry::SysSetValue(char const *,unsigned long,unsigned char const *,unsigned long)" (?SysSetValue@Registry@win_reg@@AAEXPBDKPBEK@Z)|
 

w_registry.obj||error LNK2019: unresolved external symbol __imp__RegOpenKeyExA@20 referenced in function "public: void __thiscall win_reg::Registry::OpenKey(struct HKEY__ * *,char const *,bool)" (?OpenKey@Registry@win_reg@@QAEXPAPAUHKEY__@@PBD_N@Z)|
 

w_registry.obj||error LNK2019: unresolved external symbol __imp__RegCreateKeyExA@36 referenced in function "public: void __thiscall win_reg::Registry::OpenKey(struct HKEY__ * *,char const *,bool)" (?OpenKey@Registry@win_reg@@QAEXPAPAUHKEY__@@PBD_N@Z)|
 

w_registry.obj||error LNK2019: unresolved external symbol __imp__RegCloseKey@4 referenced in function "public: void __thiscall win_reg::Registry::CloseKey(struct HKEY__ *)" (?CloseKey@Registry@win_reg@@QAEXPAUHKEY__@@@Z)|

C++. Работа с реестром Windows. Создание собственного класса.

       Доброго времени суток. Рад видеть Вас в своем блоге.
       Сегодня хотелось бы обсудить работу с реестром Windows. Да, эта тема далеко не новая, информации по ней в интернете куча. НО, я решил подойти к вопросу как новичок. Новичок, т.к. с недавнего времени заинтересовался C++ и на данном этапе стараюсь впитать как можно больше полезной и качественной инфы, чтобы пользоваться возможностями этого языка наиболее оптимально. Соответственно, касаемо работы с реестром "голый" Windows API я никогда не использовал.
       Вернемся к реестру... Я буду рассматривать работу с реестром Windows средствами Windows API. Возможно есть и другие способы, но я их не рассматривал.
       Как человек, несколько лет просидевший на паскале, я конечно же не мог не написать свой класс который будет иметь менее обширный интерфейс нежели голый API интерфейс описанных ниже функций. Об этом позже...

7 апреля 2012 г.

Metastock - TAutoTraderDLL. Впечатления после небольшого периода работы

       Доброго времени суток.
       Вот более недели я периодически ковыряюсь в метастоке и библиотеке (TAutoTraderDLL) с внешними функциями для взаимодействия с Quik. За это время я реализовал пару стратегий предоставленных мне финансовым аналитиком на работе. Я не могу сказать, что разобрался до конца в этой системе, но сейчас работать куда проще чем в начале и вопросов с каждым разом становится все меньше. Чтобы разобраться со всеми возможностями метастока необходимо намного больше временных ресурсов. Хотя мне как программисту, задача которого - техническая реализация стратегий роботов, знать там все вовсе не обязательно. :)


5 апреля 2012 г.

Округление числа. Когда нету Round()...

       Доброго времени суток в блоге "Будни программиста".
       Сегодня что-то стало скучно решил что-нибудь почитать. Взял в руки учебник по математике. :) Читал раздел про обыкновенные дроби, и десятичные дроби с бесконечной периодичностью.
       Сразу же вспомнилась простая операция округления чисел в большую сторону. А именно, заинтересовал вопрос, есть ли какая-либо математическая формула для преобразования числа к необходимой точности? Единой формулы я, к сожалению, не нашел. Конечно я далеко не математик, но навскидку накидал алгоритм преобразования:

1 апреля 2012 г.

pgScript. Генераторы случайных последовательностей. Строки.

Приветствую Вас в своем блоге.

       Сегодня пойдет речь о создании и использовании случайных последовательностей типа STRING в pgScript, а так же использование регулярных выражений.
       pgScript имеет функционал быстрого создания массивов рандомных последовательностей нескольких типов данных. Области применения таких последовательностей ограничиваются только фантазией разработчиков скриптов, но чаще всего их используют как генераторы случайных данных для тестирования различных единиц функционала базы данных, либо генерации уникальных ключей. Тут уже дело вкуса.
       Итак, генераторы последовательностей строк...
Строковая последовательность определяется следующим образом:

set @Gen = string(Min,Max,[Count], [Seed]);
где,
Min - Минимальное количество символов в одной единице последовательности.
Max - Максимальное количество символов  в одной последовательности.
Count - Количество возвращаемых последовательностей. Т.е. другими словами - количество слов в предложении. (не обязательный параметр, по умолчанию - "1").
Seed - Параметр фиксирующий последовательность созданную при инициализации переменной, и не позволяющий менять ее при последующем использовании.

28 марта 2012 г.

pgScript. Использование типа RECORD.

Здравствуйте поклонники PostgreSQL.
Добро пожаловать в мой блог.
       В предыдущем посте я описал свой первый опыт работы с pgScript. Там описан минимальный функционал, владея которым можно написать нечто простое. Но по некоторым пунктам хотелось бы конкретики... поэтому далее я опишу еще несколько постов с, наблюдениями и практикой связанной с pgScript.

Тип RECORD.

       Тип RECORD является двумерным массивом данным, доступ к элементам которого осуществляется через индексы элементов. Элементы нумеруются с нуля. Первый индекс массива указывает на строку, второй на столбец. Например:

MetaStock - TAutoTraderDLL. Первый осознанный биржевой робот.

Приветствую Вас в своем блоге.
       Параллельно с основной работой я периодически занимаюсь написанием торговых роботов с использованием Metastock. Аналитики мне дают алгоритмы, а я их реализовываю средствами построителя пользовательских индикторов.
       Целью создания этого поста является, прежде всего, отображение концепции разработки торговых роботов с использованием MetaStock и внешних функций, предоставляемых сторонними разработчиками. В статье пойдет речь о роботе написанном с использованием функций из библиотеки TAutoTraderDLL.

22 марта 2012 г.

pgScript. Написание простых скриптов. Первый опыт.


Приветствую Вас в блоге "Будни программиста".


      Сегодня впервые мне пришлось столкнуться с написанием скриптов на pgScript. Синтаксис написания скриптов на pgScript сильно отличается от синтаксиса написания тел хранимых процедур на plpgsql, что, честно говоря, в начале написания приводило к жуткой синтаксической путанице. :)


Итак, переходим непосредственно к изучению...

19 марта 2012 г.

Lazarus. TDBGrid + ZeosLib 7. Отображение дробных чисел.

Добрый день.
 
       Недавно столкнулся с проблемой отображения вещественных чисел. Дело в том что прога, в которой была замечена проблема работает с финансами, поэтому точность отображения играет ключевую роль, дабы не привести к инфаркту будущих пользователей - финансистов.
       Искажение отображения происходило следующим образом:
Есть исходное число: 1 400 940.05 - в таком виде оно хранилось в базе.
1 400 940 - в таком виде оно отображалось в DBGrid.
Вероятнее всего искажения происходили потому, что по умолчанию, DBGrid в совокупности с датасетом от Zeos отображает один символ после зщапятой. Т.е. число 123.4 - отобразится корректно, а число 123.04 - без дробной части.

Для обхода такого неприятного ограничения я написал процедуру:

procedure TZPostgresQuery.SetDisplayFormat;
var
  i:integer;
  fCount:integer;
begin
  i:=0;
  fCount:=0;
  if FQuery.Active then
  begin
    fCount:=FQuery.FieldCount;
    for i:=0 to fCount-1 do
      case FQuery.Fields[i].DataType of
        ftFloat:TFloatField(FQuery.Fields[i]).DisplayFormat := '#0.##';
        { TODO -odrmiller : Если формат указать как ",#.##", то числа будут отображаться с разделением по три,
        но на винде вместо разделителя пробела ставится символ "?". }
      end;
  end;
end;

       Это ее первая версия, т.к. при обнаружении глюков буду расширять пока еще одновариантный CASE.
Процедура выполняется всегда после открытия датасета.

       Если кто-то знает более оптимальный способ, просьба указать правильный путь. Спасибо :)

18 марта 2012 г.

Metastock... Автоматизация размещения заявок: Использование TAutoTraderDLL


На кануне выходных получил экземпляр библиотеки TAutoTraderDLL.
В комплект поставки входит пустая база данных, TAutoTrader.mdb, куда подгружаются из Quik данные по портфелям и состоянию счета. Reg-файл для регистрации в реестре настроечной информации для библиотеки, инструкции и несколько вспомогательных библиотек.

В данный момент занимаюсь настройкой системы для использования библиотеки. Забегая наперед скажу, что в справке все подробно и понятно описано. в идеальных условиях проблем с настройкой возникнуть не должно, но мои условия были не идеальными... :) При том что я не являюсь трейдером, и имею весьма скудный опыт общения с клиентским терминалом Quik, то настройки библиотеки TAutoTraderDLL для меня была не такой гладкой как хотелось бы.

Первое с чем пришлось столкнуться - это отсутствие пункта меню "Лимиты". Долго искал этот пункт, открывая все подряд по очереди, думая что пункт "переехал" куда-то в ходе развития программы, а нет... Все оказалось весьма интереснее. Пункт меню "Лимиты" отображается лишь тогда, когда трейдеру назначены лимиты... Иначе этот пункта просто нет. (хотя я бы просто заблокировал его, чтобы исключить замешательство заблудших программистов). В общем... RTFM.

Лимиты получили, таблицы настроили. Вперед!

13 марта 2012 г.

ZeosLib. Впечатления от использования в Lazarus

Пишу информационную систему на Free Pascal и PostgreSQL.
Изначально использовал стандартные компоненты (TPQConnection, TSQLQuery и т.д.).
Для того чтобы было проще рулить механизмами взаимодействия с БД - написал диспетчер компонентов.

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

Итак, Zeos*.
Стандартные компоненты хорошо справлялись с поставленными тривиальными задачами, но наступил момент когда нам понадобилась обратная связь с сервером БД. Обратная связь средствами исключений не годится по понятным, думаю, причинам.
Конкретно мне было необходимо автоматически обновлять датасет на клиенте при наступлении определенных событий в базе данных.

Помимо Zeos, такими способностями обладает PostgreDAС... Но он платный - неприемлемо.

Для того чтобы использовать Zeos в совокупности с PostgreSQL,  придется немного переделать исходники самого зеоса. Эта малая плата за бесплатность функционала который он предоставляет :).
Проблема в том что из-за синтаксических особенностей диалекта SQL который использует PostgreSQL, Zeos не всегда понимает, что выполняемый запрос синтаксически правильный. Придется подправить парсер следующим образом:
В модуле ZSQLStrings нужно заменить тело метода TZSQLStrings.RebuildAll:

12 марта 2012 г.

Линус Торвальдс посоветовал неумелым разработчикам средств безопасности застрелиться

Создатель операционной системы Linux Линус Торвальдс опубликовал на своей странице  в Google+ гневную тираду в адрес разработчиков дистрибутива OpenSUSE.
Торвальдс столкнулся с тем, что установленная на его ноутбуке система
OpenSUSE требует ввода пароля администратора для выполнения даже таких элементарных действий, как изменение часового пояса, добавление новой беспроводной сети или принтера. Изобретателей подобных «мер безопасности» Торвальдс назвал «дебилами» и посоветовал им поскорее застрелиться, ибо мир без них будет лучше.

Сотни комментаторов поддержали мнение создателя Linux о политике
безопасности в дистрибутиве OpenSUSE. Некоторые из них возразили против
употребления таких сильных выражений, но сам Торвальдс и многие другие
настаивают на своем. «Шутки часто бывают оскорбительными, — написал
Торвальдс. — Если вы на них обижаетесь, то проблема только в вас.
Подумайте об этом».

  Хотя подобные слова редко приходится слышать от известных людей,
нельзя не заметить, что чрезмерные меры безопасности раздражают
пользователей. Обильную критику вызвала в свое время, например, функция
контроля учетных записей в Windows Vista.

(С) http://www.osp.ru

11 марта 2012 г.

Доступ по сети к серверу PostgreSQL

Не мало где об этом написано, но все же, т.к. по PostgreSQL относительно мало русскоязычной информации, создам этот топик, как памятку.

ОС: Linux Ubuntu 10.04.

Для этого нам небходимо отредактировать два файла (необходимы права root).
Файл /etc/postgresql/8.3/main/postgresql.conf
Ищем секцию CONNECTIONS AND AUTHENTICATION и меняем строку
 #listen_addresses = 'localhost'
на
 listen_addresses = '*'
ВНИМАНИЕ!!!
Не забываем раскомментировать параметр, удалив символ # перед словом "listen_addresses"


Файл /etc/postgresql/8.3/main/pg_hba.conf
Идем в самый конец файла и ищем строки:
 # IPv4 local connections:
 host all all 127.0.0.1/32 md5

127.0.0.1/32 это маска разрешенной сети (32 - это число значащих бит в маске, т.е. в данном случае - все), добавляем строку с маской вашей сети, например:
 host all all 192.168.1.0/24 md5

, т.е. будут разрешены все соединения с адресов 192.168.1.1 и по 192.168.1.254. Или, для большей безопасности, добавляете конкретную машину:
 host all all 192.168.1.3/32 md5 
 
Для того, чтобы обеспечить доступ ЛЮБЫМ IP-адресам необходимо изменить параметр следующим образом:
 host all all 0.0.0.0/0 md5 

Перезапускаем службу:


sudo service postgresql start

sudo service postgresql stop
sudo service postgresql restart

После всех этих манипуляций можно проверять коннект по сети...

Откуда взял исходник для поста, не помню (лежал в архивах), как вспомню - обязательно напишу.

28 февраля 2012 г.

Metastock... Автоматизация размещения заявок: Выбор инструментария

Первое что нашлось в Google - это пара ссылок:
http://goldfishru.narod.ru/ - библиотека описанная тут на первый взгляд слабоватая...
http://stop-loss.ru/tautotraderdll - тут нечто посерьезнее.

Есть еще один вариант: "DLL Косинского", но взаимодействие с квиком в этой библиотеке реализовано через файы а не через API (trans2quik.dll), что подразумевает замедление, в общем, при наличии API, DLL предлагаемая Косинским - прошлый век. ИМХО.


Практика - критерий истины. :)

Это будет мой первый биржевой робот.

************************************************************************************

Просмотрел оба варианта...
В обоих случаях необходима библиотека trans2quik.dll. Без нее никак... она является дверью для транзакций в квик.
Буду использовать второй вариант (TAutoTrade.DLL), ибо он наиболее функционален, нежели библиотека представленная в первой ссылке. К тому же, GoldFish умеет выставлять одной заявкой только один лот... Хотя фраза "по умолчанию" меня смущает, наверняка есть способ сделать не "по умолчанию"... Пока ХЗ.

/*TAutoTrader.dll - платная библиотека. Покупается в разрезе торговых счетов. Пока разработчики отвечают на вопросы заюзаю пока для тестов то, что предлагалось в первой ссылке (GoldFish).*/

По пути нашлись нужные описания:
Описание функций Metastock
Наиболее полное описание



Ну чтож, после кратковременного исследования все же решил окончательно остановиться на платной версии (TAutoTrader.dll ). Т.к. GoldFish позволяет отправлять одной заявкой только один лот, а это очень серьезное ограничение, с которым можно лишь протестить как работает API Quik (trans2quik.dll). Как обойти это ограничение я не нашел, да и не думаю что это возможно. К тому же, от разработчика нет ответа уже неделю, это не приемлемо. В результате даже не стал заморачиваться...


to be continued...

p.s. Продолжение: Впечатления от использования TAutoTrader.dll

Разбирательство с Metastock... Начало.

Дня 4 назад поручили разбираться с метастоком... Metastock - это софт для проведения технического анализа результатов торговли на фондовой бирже.

Вобщем, все что надо - это научиться грузить в него данные из торговой платформы Quik в режиме реального времени, добывать/конвертировать/загружать данные с финама, ну и.. разобраться во встроенном языке программирования чтобы написать несложного робота, который будет генерить заявки на продаже в зависимости от изменений значений выходного графика в метастоке...

Первым делом, по относительно простому мануалу прикрутил его к квику. Все работает, данные грузятся, НО... при большом количестве бумаг и при тиковом интервале загрузки - валится куча варнингов с предупрежениями о том что поток данных слишком интенсивный, и данные могут теряться...
Данные нужны все...Надо расширять возможности сервака. Благо пока все крутится на виртуалке :)