Начал использовать SQLite++ (http://sqlitepp.berlios.de/) в своем проекте, возникло несколько вопросов и предложений по развитию проекта.
1 — Проект еще жив? Последний коммит был в 2007 году.
2 — Можно ли использовать один объект sqlitepp::session из нескольких потоков? Если да, то какие ограничения на такое использование?
3 — Кровь из носу нужна возможность вызывать сишные sqlite функции для объекта sqlitepp::session, например никак невозможно обойтись без sqlite3_busy_timeout, иначе запросы к базе обламываются при параллельном доступе из другого объекта sqlitepp::session.
4 — Нужна возможность указывать флаги при открытии базы, например нужен флаг SQLITE_OPEN_SHAREDCACHE, он ускоряет одновременную работу нескольких сессий БД.
Можно ли все это сделать? И вопрос к автору: если я сам это сделаю, примет ли он патч?
Отвечал на личное сообещние, может не дошло
G>Начал использовать SQLite++ (http://sqlitepp.berlios.de/) в своем проекте, возникло несколько вопросов и предложений по развитию проекта. G>1 — Проект еще жив? Последний коммит был в 2007 году.
Эээ, проект есть. Последний коммит в trunk был 6 апреля 2011 г.
G>2 — Можно ли использовать один объект sqlitepp::session из нескольких потоков? Если да, то какие ограничения на такое использование?
Можно, если обеспечить синхронизацию доступа к экземпляру sqlitepp::session, т.к. класс session не потокобезопасен.
G>3 — Кровь из носу нужна возможность вызывать сишные sqlite функции для объекта sqlitepp::session, например никак невозможно обойтись без sqlite3_busy_timeout, иначе запросы к базе обламываются при параллельном доступе из другого объекта sqlitepp::session.
Можно добавить нужные функции в класс sqlitepp::session, или сделать доступным sqlite3* хранящийся в session. Мне кажется первый путь чуть безопаснее и функции session::last_changes(), session::total_changes() были так и добавлены.
G>4 — Нужна возможность указывать флаги при открытии базы, например нужен флаг SQLITE_OPEN_SHAREDCACHE, он ускоряет одновременную работу нескольких сессий БД.
Без проблем — можно добавить параметр для флагов в session::open()
G>Можно ли все это сделать? И вопрос к автору: если я сам это сделаю, примет ли он патч?
Здравствуйте, PM, Вы писали:
PM>Можно добавить нужные функции в класс sqlitepp::session, или сделать доступным sqlite3* хранящийся в session. Мне кажется первый путь чуть безопаснее и функции session::last_changes(), session::total_changes() были так и добавлены.
При нужде не очень хочется менять библиотечные заголовочные файлы, ведь они могут быть перезаписаны при обновлении. Наверное, для таких случаев лучше предоставить явный доступ к экземпляру sqlite3.
Даже не знал про такую штуку.
В свое время написал свою обёртку с datasource, datarow, всякими перегруженными операторами преобразования к интегральным типам и std::s/w string, с поддержкой prepared statment-ов, с поддержкой сессий, и возможностью инжектить самописные extensions (т.е. расширять набор функций SQL). Вот уже год как юзаем, никто пока не жаловался
Здравствуйте, PM, Вы писали:
PM>Здравствуйте, Gorilla, Вы писали:
PM>Эээ, проект есть. Последний коммит в trunk был 6 апреля 2011 г.
Cорри, смотрел по дате на главной странице сайта. Раз проект жив, то не помешало бы обновить версию sqlite до 3.7.10 и в солюшене для VC10 прописать x64 конфигурацию.
PM>Можно, если обеспечить синхронизацию доступа к экземпляру sqlitepp::session, т.к. класс session не потокобезопасен.
Тогда сужаю вопрос: конструкция
unsigned long count;
database << "SELECT COUNT(*) FROM table", sqlitepp::into(count);
потокобезопасна? В коде много таких конструкций, очень не хочется здесь городить синхронизацию. Пока без нее все работает.
PM>Можно добавить нужные функции в класс sqlitepp::session, или сделать доступным sqlite3* хранящийся в session. Мне кажется первый путь чуть безопаснее и функции session::last_changes(), session::total_changes() были так и добавлены.
Хорошо бы тогда добавить нужные функции плюс функцию get_impl() для прямого доступа к sqlite3*. Все возможности sqlite сразу не перекроешь, желательно оставлять пользователям библиотеки обходной вариант на свой страх и риск, чтобы не пришлось делать #define private public перед хедером.
PM>Без проблем — можно добавить параметр для флагов в session::open()
Флаги уже не нужны, почитав документацию я нашел функцию sqlite3_enable_shared_cache включающую разделяемый кэш глобально. Мне этого достаточно.
PM>Патч приму
Отлично, в ближайшее время будет.
Здравствуйте, nen777w, Вы писали:
N>Даже не знал про такую штуку. N>В свое время написал свою обёртку с datasource, datarow, всякими перегруженными операторами преобразования к интегральным типам и std::s/w string, с поддержкой prepared statment-ов, с поддержкой сессий, и возможностью инжектить самописные extensions (т.е. расширять набор функций SQL). Вот уже год как юзаем, никто пока не жаловался
Я делал эту обертку на идеях из SOCI, которая тогда поддерживала только Oracle. Есть еще одна похожая библиотека, CppDB, использовал ее в одном проекте для работы с MySQL.
Здравствуйте, Gorilla, Вы писали:
G>Здравствуйте, PM, Вы писали:
PM>>Здравствуйте, Gorilla, Вы писали:
PM>>Эээ, проект есть. Последний коммит в trunk был 6 апреля 2011 г. G>Cорри, смотрел по дате на главной странице сайта. Раз проект жив, то не помешало бы обновить версию sqlite до 3.7.10 и в солюшене для VC10 прописать x64 конфигурацию.
Это может быть когда-нибудь SQLite можно обновлять по необходимости — достаточно распаковывать файлы из SQLite amalagamation в каталог sqlite и пересобирать библиотеку. В плане поддержки обратной совместимости D. Richard Hipp делает все что можно.
PM>>Можно, если обеспечить синхронизацию доступа к экземпляру sqlitepp::session, т.к. класс session не потокобезопасен. G>Тогда сужаю вопрос: конструкция G>
G>unsigned long count;
G>database << "SELECT COUNT(*) FROM table", sqlitepp::into(count);
G>
G>потокобезопасна? В коде много таких конструкций, очень не хочется здесь городить синхронизацию. Пока без нее все работает.
Везет В экземпляре session хранятся 2 вспомогательны переменных — указатель на активную транзакцию и результат последнего вызова sqlite3_step(). Я думаю, если не обращаться к session::active_txn() и всем функциям session::last_*() то все будет в порядке (при условии что экземпляр session живет дольше любого из созданных в нем statement).
PM>>Можно добавить нужные функции в класс sqlitepp::session, или сделать доступным sqlite3* хранящийся в session. Мне кажется первый путь чуть безопаснее и функции session::last_changes(), session::total_changes() были так и добавлены. G>Хорошо бы тогда добавить нужные функции плюс функцию get_impl() для прямого доступа к sqlite3*. Все возможности sqlite сразу не перекроешь, желательно оставлять пользователям библиотеки обходной вариант на свой страх и риск, чтобы не пришлось делать #define private public перед хедером.
Ок, не вижу проблем добавить пару функций sqlite3* session::impl() const и sqlite3_stmt* statement::impl() const;
Здравствуйте, Gorilla, Вы писали:
G>3 — Кровь из носу нужна возможность вызывать сишные sqlite функции для объекта sqlitepp::session, например никак невозможно обойтись без sqlite3_busy_timeout, иначе запросы к базе обламываются при параллельном доступе из другого объекта sqlitepp::session.
Здравствуйте, PM, Вы писали:
PM>Здравствуйте, Gorilla, Вы писали:
G>>Я еще добавил вот такой патч:
PM>[здесь был патч]
PM>спасибо, применю. Только я думаю не добавлять третий конструктор session, а добавить к нему второму параметр:
PM>
PM>explicit session(string_t const& filename, int flags = 0);
PM>
Функция open_v2 есть только в utf8 варианте, это может стать проблемой.
PM>>explicit session(string_t const& filename, int flags = 0);
PM>>
G>Функция open_v2 есть только в utf8 варианте, это может стать проблемой.
Это не проблема В sqlitepp/string.hpp есть функция utf8() для конверсии строк в UTF-8
Закоммитил в trunk.
Вчера внезапно нашлось время для обновления SQLite до версии 3.7.10 Заодно добавил функции session::impl() и statement::impl() для прямого доступа к структурам SQLite. Также обновил Solution для Visual Studio 2010 — добавил конфигурацию для x64, переименовал targets сборки чтобы не было конфликтов при сборке Win32 или x64. Правда batch build не проходит. Но по отдельности все цели собираются и тесты проходят.
Еще небольшой список изменений которых не хватает для полного счасться:
Вот мои правки последней версии проекта, с ними он красивее компилируется и включена вся нужная в релизе оптимизация.
Еще наткнулся на баг студии с созданием пусорной директории "Debug", но не знаю как его обойти. Может быть стоит компилить исходники sqlite внутри проекта sqlitepp, а не в отдельном проекте?
Здравствуйте, Gorilla, Вы писали:
G>Еще небольшой список изменений которых не хватает для полного счасться:
G>Вот мои правки последней версии проекта, с ними он красивее компилируется и включена вся нужная в релизе оптимизация. G>Еще наткнулся на баг студии с созданием пусорной директории "Debug", но не знаю как его обойти. Может быть стоит компилить исходники sqlite внутри проекта sqlitepp, а не в отдельном проекте?
Применил, спасибо. Также подчистил немного код и настройки тестового проекта чтобы избавиться от предупреждений компилятора.
Насчет исходников SQLite внутри SQLite++ не уверен — я собираю sqltepp.so в Linux, и там почти всегда уже есть какая-то из более-менее свежих версий SQLite. Я думаю зависимости от SQLite на уровне библиотек вполне достаточно.
Здравствуйте, PM, Вы писали:
PM>Применил, спасибо. Также подчистил немного код и настройки тестового проекта чтобы избавиться от предупреждений компилятора.
А зачем удалил "<Filter Include="Source Files">..." из файлов .filters? Ведь именно в этом фича фильтров, чтобы показывало хедеры и сорсы отдельно.
Здравствуйте, Gorilla, Вы писали:
G>А зачем удалил "<Filter Include="Source Files">..." из файлов .filters? Ведь именно в этом фича фильтров, чтобы показывало хедеры и сорсы отдельно.
Никогда не понимал искусственное деление на Source/Header. Предпочитаю в своих проектах группировать файлы по подсистемам. На мой взгляд так удобнее и логичнее, когда заголовочный и исходный файлы отображаются рядом в Solution Explorer. И так быстрее между ними переключаться. В идеале, иерархия файлов в Solution Explorer и их размещение в файловой системе совпадают.
Под капотом вызывается sqlite3_bind_text(impl_, pos, str, -1, SQLITE_STATIC) или sqlite3_bind_text16 для utf16_char, т.е. преборазований в string_t и лишних копирований не происходит.