LINUX.ORG.RU

C++ обертка для ODBC


0

0


хочется грамотную C++ обёртку для ODBC (точнее unixODBC). мне в принципе понравился mysql++, хочется чего-то схожего для ODBC. ессно должно без проблем собираться и жить с указанным unixODBC.

ps: можно конечно и самому написать, это не сложно, но есть подозрение, что тема избитая и уже давно реализованная.

// wbr

Ответ на: комментарий от mv

> otl вне конкуренции. otl.sf.net

если OTL == Oracle/ODBC Template Library == ~50k строк шаблонного кода на C++ *в одном* файле заголовка размером примерно 700kb, то я бы за такое руки отрывал без суда и следствия :-/ хотя конечно базовая идея забавная, спору нет.

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от kto_tama

> Изобретать велосипед наверно нет смысла В смысле самому писать драйвер - наверно это слишком круто Уже все написано

замечу, что мне не нужно писать драйвер ODBC для какой-то DS engine. мне нужна лишь обёртка - wrapper - на стороне клиента для стандартного ODBC C API для C++ :)

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

один из плюсов , который я могу привести в пользу OTL - это его переносимость
лет 7 назад я его использовал под офтопик

kto_tama ★★★★★
()
Ответ на: комментарий от klalafuda

> если OTL == Oracle/ODBC Template Library == ~50k строк шаблонного кода на C++ *в одном* файле заголовка размером примерно 700kb, то я бы за такое руки отрывал без суда и следствия :-/ хотя конечно базовая идея забавная, спору нет.

Тебе не пофиг ли, в каком виде оно реализовано (качество реализации у меня нареканий не вызвало, кстати)? Зато для true С++-ника работа с данными через потоки будет как кусок масла в кашу :)

mv ★★★★★
()
Ответ на: комментарий от mv

> Тебе не пофиг ли, в каком виде оно реализовано (качество реализации у меня нареканий не вызвало, кстати)?

а вот у меня почему-то вызвало :-/

$ grep private otlv4.h | wc -l
8
$ grep public otlv4.h | wc -l
148

все что можно и что нельзя без разбору валим в public? это IMHO мягко говоря неправильно с точки зрения дизайна :-/

*весь* код inline. причём даже для классов, которые к шаблонам/etc никакого отношения не имеют. нафига такой overhead :-?

вечный "using namsepace std" в общем заголовке - ну когда это кончится :-?

куча собственных велосипедов, которые давно есть в том же boost. IMHO можно было бы существенно сократить объем проекта.

про стиль форматирования, организацию проекта и тотальное отсутствие комментариев я умолчу... скажете, это не важно мол работает и нехай с ним? лично я так не считаю. всегда возникают ситуации, в которых приходится поддерживать и 3d party компоненты -> копаться руками во всем этом чуде...

в общем, было бы желание а поводов придраться в OTL предостаточно :-/

> Зато для true С++-ника работа с данными через потоки будет как кусок масла в кашу :)

ну по поводу самой концепции мнение пока что не сформировалось. смотрю, тестирую...

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda


с другой стороны, OTL вполне нормально работает с unixODBC/MySQL so будем считать, что внутрь никто не заглядывал. "у каждого есть свои недостатки" (c) один американский миллионер.

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

> куча собственных велосипедов, которые давно есть в том же boost. IMHO можно было бы существенно сократить объем проекта.

otl: This project started with my early experiments on the Oracle Call Interface back in 1994

boost: 1 Sep 1999

The category "Experimental" has been added to the library page. The integer library is the first entry.

> про стиль форматирования, организацию проекта и тотальное отсутствие комментариев я умолчу... скажете, это не важно мол работает и нехай с ним? лично я так не считаю. всегда возникают ситуации, в которых приходится поддерживать и 3d party компоненты -> копаться руками во всем этом чуде...

Ну я копался в поисках источника проблемы. Нашёл, у себя.

mv ★★★★★
()
Ответ на: комментарий от mv

> otl: This project started with my early experiments on the Oracle Call Interface back in 1994
> boost: 1 Sep 1999

да понятно, что как и у любого проекта с длинной историей у OTL хватает "хвостов", которые сегодня смотрятся несколько архаичными. то-же можно сказать и про ACE and so on но что-то революционно менять никто по всей видимости уже не будет. впрочем, что называется не очень то и хотелось. в конце-концов работает и ладно.

мне вот пока не понятно, почему, когда я создавая otl_stream и указываю buffer_size > 1 (N) то INSERT вставляет лишь каждую N-ю запись? i.e. если после каждого оператора "<<" звать flush() то все нормально но это очевидно сказывается на скорости вставки. если не flush() звать, то то-же всё нормально и ошибок нет, но вот в базе для N=10 я вижу лишь 1, 10, 20... записи :-/

клиент подключается к MySQL 5.0.41 на локальном хосте через пару unixODBC/2.2.12 + MyODBC/3.51. я что-то не понимаю на этом празднике жизни?

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от mv

> Ну я копался в поисках источника проблемы. Нашёл, у себя.

у себя не нашёл, но за конструкции вида:

class otl_stream { public : otl_stream_shell* shell; ..... otl_stream& operator>>(short& sh) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op=true; switch(shell->stream_type){ case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc=(*io)->eof(); #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(sh); #else (*io)->operator>><short,otl_var_short>(sh); #endif break; case otl_odbc_select_stream: last_eof_rc=(*ss)->eof(); #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(sh); #else (*ss)->operator>><short,otl_var_short>(sh); #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if((*this).is_null()) sh=OTL_SCAST(short int,OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif OTL_TRACE_WRITE(sh,"operator >>","short int&") inc_next_ov(); return *this; } ..... };

...в приличных домах лондОна по головке не гладят и g++ со мной полностью согласен на -Wall. и таких ляпов там к сожалению предостаточно.

OTL таки знатный претендент на суровый рефакторинг :-/

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

форматирование будь оно неладно :-/

class otl_stream{
public:
  otl_stream_shell* shell;
.....
 otl_stream& operator>>(short& sh)
   OTL_THROWS_OTL_EXCEPTION
 {
   last_oper_was_read_op=true;
   switch(shell->stream_type){
   case otl_odbc_no_stream:
     break;
   case otl_odbc_io_stream:
     last_eof_rc=(*io)->eof();
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
     (*io)->operator>>(sh);
#else
     (*io)->operator>><short,otl_var_short>(sh);
#endif
     break;
   case otl_odbc_select_stream:
     last_eof_rc=(*ss)->eof();
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
     (*ss)->operator>>(sh);
#else
     (*ss)->operator>><short,otl_var_short>(sh);
#endif
     break;
   }
.........

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

я щас раскопал свой исходник хрен знает какой давности
это прямой си-шный вызов оракловой процедуры
согласись , следующая конструкция довольно элегантна :
otl_stream ss(1,
"begin "
" pkg_test2.find_comp(\
:name_comp <char[100],in> , \
:comp_idd <int,out>);"
"end;",
db // connect object
);
ss.set_commit(0);
ss<<name_comp;
ss>>comp_idd;



kto_tama ★★★★★
()
Ответ на: комментарий от kto_tama

> согласись , следующая конструкция довольно элегантна : 

видимо, стоило уточнить  :)

нет, я не про элегантность конструкции потокового ввода/вывода.
как раз сама концепция в принципе достаточно элегантна и как
минимум имеет право на жизнь. почему нет? ни чуть не хуже чем
ручной prepare/bind/execute etc.

а вот с реализацией конечно же есть некоторые напряги. в примере с
оператором вывода:

odbc::otl_connect db;
odbc::otl_stream ds(1, "SELECT foo FROM abc WHERE id=:f<int>");
int value, id = 12345;
ds << id;
ds >> value;

в этом примере проблема в том, что после успешного исполнения
вывода в value его значение может быть запросто undefined :)

hint: присмотритесь к операторам ">>" для otl_stream: в каждом есть
switch и нет ни default ни обработки ошибок so вполне валидный код
пользователя может привести к непредсказуемым результатам :-/

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

Давайте определимся: у вас уже что-то не работает, или просто "за державу обидно"? Вы то сами, кстати, в своём софте все возможные варианты развития событий обрабатываете? :)

mv ★★★★★
()
Ответ на: комментарий от mv

> Давайте определимся: у вас уже что-то не работает, или просто "за державу обидно"?

1. не работает. точнее, не собирается со штатными -Wall -Werror. g++ 4.1.1 достаточно умен, чтобы отслеживать подобные ситуации и предупреждать об не инициализированных переменных. правда, к сожалению, не всегда и некоторые конструкции такого вида с операторами otl_stream собираются без предупреждений не смотря на "бомбу" :(

да, конечно, с вероятностью 99% или даже выше в реальном проекте при соблюдении определённых правил это не вызовет проблем. но оставшийся процент настораживает. а сколько ляпов я ещё не увидел? вопрос...

2. идея и реализация OTL мне вполне понравилась. тем паче жалко наблюдать подобные ляпы :(

> Вы то сами, кстати, в своём софте все возможные варианты развития событий обрабатываете? :)

да, всегда и везде. это закон и он пересмотру не подлежит.

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

> да, конечно, с вероятностью 99% или даже выше в реальном проекте при соблюдении определённых правил это не вызовет проблем. но оставшийся процент настораживает. а сколько ляпов я ещё не увидел? вопрос...

причём замечу, что я отнюдь не ставил себе целью аудит кода OTL. скорее это совершенно банальные вещи, которые автоматически вылезли сами собой при попытке нарисовать пару-тройку простейших тестовых приложений. IMHO их очень сложно не заметить и почему не было внесено соотв. изменений с целью повысить надёжность и предсказуемость библиотеки для меня загадка.

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

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

kto_tama ★★★★★
()
Ответ на: комментарий от klalafuda

> почему не было внесено соотв. изменений с целью повысить надёжность и предсказуемость библиотеки для меня загадка.

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

:/

tailgunner ★★★★★
()
Ответ на: комментарий от kto_tama

> не стоит делать перегиб в сторону клиента софт-то клиент-серверный

боюсь, к ситуации, когда "клиент" - это сам по себе сервер в некой распределённой системе обработки данных, такие допуски не применимы. все компоненты системы должны работать одинаково стабильно 24x7. у меня как правило именно такие ситуации.

// wbr

klalafuda ★☆☆
() автор топика
Ответ на: комментарий от klalafuda

А вы чейнджлоги самого unixODBC и планируемой к использованию базы данных почитайте :-D Да, багтреккер у gcc тоже почитайте :) "Как страшно жить..."

А ошибки в железе так вообще мрак, патч на кремний ведь не накатаешь ;-)

mv ★★★★★
()
Ответ на: комментарий от klalafuda

Да, кстати, fault tolerance - это именно обработка ошибок (куда ж без них), а не их отсутствие в продукте.

mv ★★★★★
()
Ответ на: комментарий от klalafuda

Сильно уж у Вас лицо на картинке серьезное. Имхо зазря :).

eXOR ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.