Re[12]: SQLite++ в многопоточном приложении
От: cppnick  
Дата: 05.02.12 07:22
Оценка:
Здравствуйте, PM, Вы писали:

PM>Здравствуйте, Gorilla, Вы писали:


G>>А можно добавить use биндеры для char* и wchar_t* ?


PM>Добавил пару перегруженных функций:

PM>
PM>use(utf8_char const* str)
PM>use(utf16_char const* str)
PM>

Ваши utf16_char дружат с char16_t из С++11 или жёстко "unsigned short int"?
Re[13]: SQLite++ в многопоточном приложении
От: PM  
Дата: 05.02.12 09:29
Оценка:
Здравствуйте, cppnick, Вы писали:

C>Ваши utf16_char дружат с char16_t из С++11 или жёстко "unsigned short int"?


В Visual C++ utf16_char это wchar_t, в GCC — unsigned short. Движения в сторону поддержки новшеств C++11 в SQLite++ еще не было.

Я вообще придерживаюсь мнения, что использование UTF-16 в SQLite необходимо в редких случаях.
Re: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 05.04.12 21:43
Оценка: 6 (1) :)
Нужна поддержка EXCLUSIVE и IMMEDIATE транзакций в классе sqlitepp::transaction. Патч с моим вариантом:

Index: sqlitepp/transaction.cpp
===================================================================
--- sqlitepp/transaction.cpp    (revision 13)
+++ sqlitepp/transaction.cpp    (working copy)
@@ -16,13 +16,14 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-transaction::transaction(session& s) : s_(s), do_rollback_(false)
+transaction::transaction(session& s, ttype type) : s_(s), do_rollback_(false)
 {
     if ( s_.active_txn() )
     {
         throw nested_txn_not_supported();
     }
-    s_ << utf(L"begin");
+    s_ << (type == deferred ? utf(L"begin deferred") : 
+           type == immediate ? utf(L"begin immediate") : utf(L"begin exclusive"));
     s_.active_txn_ = this;
     do_rollback_ = true;
 }
Index: sqlitepp/transaction.hpp
===================================================================
--- sqlitepp/transaction.hpp    (revision 13)
+++ sqlitepp/transaction.hpp    (working copy)
@@ -21,8 +21,10 @@
 class transaction
 {
 public:
+    enum ttype { deferred, immediate, exclusive };
+
     // Begin transaction in context of session.
-    transaction(session& s);
+    transaction(session& s, ttype type = deferred);
 
     // End transaction with rollback if it is not commited.
     ~transaction();
Re[2]: SQLite++ в многопоточном приложении
От: PM  
Дата: 07.04.12 03:31
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>Нужна поддержка EXCLUSIVE и IMMEDIATE транзакций в классе sqlitepp::transaction. Патч с моим вариантом:

[]

Ок, добавил в trunk
Re[2]: SQLite++ в многопоточном приложении
От: о_О
Дата: 09.05.12 09:20
Оценка:
Здравствуйте, PM, Вы писали:

Всё в UTF-8, LIKE не работает, 10 лет проекту... Пичаль
Re[3]: SQLite++ в многопоточном приложении
От: PM  
Дата: 09.05.12 17:16
Оценка:
Здравствуйте, о_О, Вы писали:

о_О>Всё в UTF-8, LIKE не работает, 10 лет проекту... Пичаль


Сочувствую вашей печали, но не понимаю о чем речь.
Re[2]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 15.05.12 10:02
Оценка:
Вопрос: какова область видимости блоба получаемого через into? Нужно ли как-то освобождать память под него?
Например:
sqlitepp::session db("test.db");
sqlitepp::blob    icon;

db << "SELECT data FROM incons WHERE id=1234", sqlitepp::into(icon);
// можно ли обращаться к icon.data? нужно ли освобождать память?


Далее: у меня есть класс производный от std:vector<unsigned char>, но into и use биндеры не принимают его напрямую, требуется некрасивое приведение типов. Можно ли заставить биндеры принимать любые производные вектора?
Еще одно пожелание: когда я отправляю селект через << на sqlitepp::session, мне часто требуется писать if (!db.last_exec()) throw std::runtime_error("no data selected"). Может можно сделать какую-нибудь опцию при открытии базы, или сделать какой-нибудь модификатор вроде db << "sql query", sqlitepp::throw(), или метод db.set_throw_if_no_data(true) который включает выбрасывание исключения если запрос имел into биндеры и не вернул никаких данных. Даже не знаю как лучше.

В добавок одно наблюдения от меня, которое сэкономит вам кучу времени и нервных клеток. Функция sqlite3_enable_shared_cache делает работу с БД потоконебезопасной!!! Shared caсhe у них баговый и может вызывать отказ при обработке параллельных запросов. В документации про это ничего не сказано, остерегайтесь использования этой функции.
Re[3]: SQLite++ в многопоточном приложении
От: ntp  
Дата: 15.05.12 12:59
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>Вопрос: какова область видимости блоба получаемого через into? Нужно ли как-то освобождать память под него?


The pointers returned are valid until a type conversion occurs as described above, or until sqlite3_step() or sqlite3_reset() or sqlite3_finalize() is called. The memory space used to hold strings and BLOBs is freed automatically. Do not pass the pointers returned sqlite3_column_blob(), sqlite3_column_text(), etc. into sqlite3_free().


G>// можно ли обращаться к icon.data? нужно ли освобождать память?

Нельзя, не нужно. Чтобы обратиться к полученным данным, нужно либо подержать объект sqlitepp::statement до момента обращения к данным, либо писать свой конвертер, чтобы управлять памятью по-своему.

G>Далее: у меня есть класс производный от std:vector<unsigned char>, но into и use биндеры не принимают его напрямую, требуется некрасивое приведение типов. Можно ли заставить биндеры принимать любые производные вектора?

Напишите конвертер с красивым приведением
Re: SQLite++ в многопоточном приложении
От: ntp  
Дата: 15.05.12 13:04
Оценка:
Добавлю свой вопрос.

Может ли запрос дождаться освобождения базы, а не вылетать с SQLITE_BUSY? Есть ли у sqlite встроенные средства для этого или надо организовывать самописную синхронизацию?
Тем более, что база может использоваться из разных приложений, к примеру.

Переходить на полноценные СУБД не хочется
Re[4]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 15.05.12 13:35
Оценка:
Здравствуйте, ntp, Вы писали:

ntp>Здравствуйте, Gorilla, Вы писали:


G>>Вопрос: какова область видимости блоба получаемого через into? Нужно ли как-то освобождать память под него?


ntp>

The pointers returned are valid until a type conversion occurs as described above, or until sqlite3_step() or sqlite3_reset() or sqlite3_finalize() is called. The memory space used to hold strings and BLOBs is freed automatically. Do not pass the pointers returned sqlite3_column_blob(), sqlite3_column_text(), etc. into sqlite3_free().


G>>// можно ли обращаться к icon.data? нужно ли освобождать память?

ntp>Нельзя, не нужно. Чтобы обратиться к полученным данным, нужно либо подержать объект sqlitepp::statement до момента обращения к данным, либо писать свой конвертер, чтобы управлять памятью по-своему.
Я так и предполагал, но на всякий случай спрашиваю, вдруг там statement живет до следующего запроса. Пофиг, буду грузить в вектор.

G>>Далее: у меня есть класс производный от std:vector<unsigned char>, но into и use биндеры не принимают его напрямую, требуется некрасивое приведение типов. Можно ли заставить биндеры принимать любые производные вектора?

ntp>Напишите конвертер с красивым приведением
К сожалению я не настолько продвинут в с++ чтобы лезть в такие дебри.

ntp>Может ли запрос дождаться освобождения базы, а не вылетать с SQLITE_BUSY? Есть ли у sqlite встроенные средства для этого или надо организовывать самописную синхронизацию?

ntp>Тем более, что база может использоваться из разных приложений, к примеру.
sqlite3_busy_timeout(database->impl(), 10*1000); — устанавливаем таймаут 10сек.
Re[5]: SQLite++ в многопоточном приложении
От: ntp  
Дата: 15.05.12 14:53
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>>>Далее: у меня есть класс производный от std:vector<unsigned char>, но into и use биндеры не принимают его напрямую, требуется некрасивое приведение типов. Можно ли заставить биндеры принимать любые производные вектора?

ntp>>Напишите конвертер с красивым приведением
G>К сожалению я не настолько продвинут в с++ чтобы лезть в такие дебри.
Если нельзя привести ваш класс к базовому (и уже его передать в into/use), то тогда вот пример, в который можно подставить любой объект, лишь бы его данные, захваченные blob'ом, можно было описать непрерывным куском памяти:

namespace sqlitepp {

template<typename T>
struct converter< std::vector<T> >
{
    typedef blob base_type;
    static std::vector<T> to(blob const& b)
    {
        T const* f = reinterpret_cast<T const*>(b.data);
        T const* l = f + b.size / sizeof(T);
        return std::vector<T>(f, l);
    }
    static blob from(std::vector<T> const& t)
    {
        blob b;
        b.data = t.empty()? 0 : &t[0];
        b.size = t.size() * sizeof(T);
        return b;
    }
};

}
Re[6]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 15.05.12 15:21
Оценка:
Здравствуйте, ntp, Вы писали:

ntp>Если нельзя привести ваш класс к базовому (и уже его передать в into/use)

Можно привести, я сейчас так и делаю. Но это некрасиво, хотелось бы избавиться от длинного приведения, чтобы оно делалось автоматом в конвертере, и чтобы работало для любого класса производного от vector. Такое возможно?
Re[7]: SQLite++ в многопоточном приложении
От: PM  
Дата: 16.05.12 07:21
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>Здравствуйте, ntp, Вы писали:


ntp>>Если нельзя привести ваш класс к базовому (и уже его передать в into/use)

G>Можно привести, я сейчас так и делаю. Но это некрасиво, хотелось бы избавиться от длинного приведения, чтобы оно делалось автоматом в конвертере, и чтобы работало для любого класса производного от vector. Такое возможно?

Если я правильно понял суть вопроса, то можно выкрутиться так:

#include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp>

// Конвертер для классов унаследованных от std::vector<T>. Тип VectorT должен обеспечить конструктор из диапазона итераторов:
//
//   template<typename T>
//   struct VectorT : public std::vector<T>
//   {
//       /// Конструктор из диапазона итераторов, в частном случае это может быть [value_type const* begin, value_type const* end) 
//       template<typename ForwardIterator>
//       VectorT(ForwardIterator begin, ForwardIterator end) : std::vector<T>(begin, end) {}
//   };
//
template<typename VectorT>
struct converter<VectorT,
    typename boost::enable_if<boost::is_base_of<std::vector<typename VectorT::value_type>, VectorT> >::type>
{
    typedef blob base_type;
    static VectorT to(blob const& b)
    {
        typename VectorT::value_type const* f = reinterpret_cast<typename VectorT::value_type const*>(b.data);
        typename VectorT::value_type const* l = f + b.size / sizeof(typename VectorT::value_type);
        return VectorT(f, l);
    }
    static blob from(VectorT const& t)
    {
        blob b;
        b.data = t.empty()? 0 : &t[0];
        b.size = t.size() * sizeof(typename VectorT::value_type);
        return b;
    }
};


И тогда такое будет работать:

template<typename T>
struct my_vector : public std::vector<T>
{
    my_vector() {}

    template<typename ForwardIt>
    my_vector(ForwardIt begin, ForwardIt end)
        : std::vector<T>(begin, end)
    {
    }
};

void test()
{
    my_vector<int> data, data2;
    data.push_back(1);
    data.push_back(11);

    using namespace sqlitepp;

    session se("test.db");
    se << utf(L"create table my_vector(val blob)");
    se << utf(L"insert into my_vector(val) values(:val)"), use(data);
    se << utf(L"select val from my_vector"), into(data2);
    ensure("my_vector", data2 == data);
}
Re[8]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 16.05.12 18:38
Оценка:
PM>Если я правильно понял суть вопроса, то можно выкрутиться так:
А можно то-же самое, но без boost? Одна из причин по которой я выбрал sqlitepp — это отсутствие зависимостей от boost.
Re[9]: SQLite++ в многопоточном приложении
От: PM  
Дата: 17.05.12 02:00
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>А можно то-же самое, но без boost? Одна из причин по которой я выбрал sqlitepp — это отсутствие зависимостей от boost.


В С++11 есть std::is_base_of и std::enable_if

Можно реализовать их самому, либо посмотреть как сделано в Boost и реализовать самому.
Re[10]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 17.05.12 13:45
Оценка:
Здравствуйте, PM, Вы писали:

PM>Здравствуйте, Gorilla, Вы писали:


G>>А можно то-же самое, но без boost? Одна из причин по которой я выбрал sqlitepp — это отсутствие зависимостей от boost.


PM>В С++11 есть std::is_base_of и std::enable_if

Тогда хорошо бы было добавить в проект соответствующий конвертор, поместив его внутри блока #if _MSC_VER >= 1600 / #endif
Кстати, в последней версии из svn возникает такой варнинг при компиляции:
cl : Command line warning D9030: '/Gm' is incompatible with multiprocessing; ignoring /MP switch

И еще хорошо бы было обновить sqlite до версии 3.7.12.
Re[11]: SQLite++ в многопоточном приложении
От: PM  
Дата: 17.05.12 17:05
Оценка: 6 (1)
Здравствуйте, Gorilla, Вы писали:

PM>>В С++11 есть std::is_base_of и std::enable_if

G>Тогда хорошо бы было добавить в проект соответствующий конвертор, поместив его внутри блока #if _MSC_VER >= 1600 / #endif

Не вижу в этом большой потребности, т.к. поддержка С++11 — отдельная тема. Вообще, поддержка наследников std::vector в конвертере данных это достаточно экзотический случай. Если вам необходимы конвертеры для собственных типов, сделайте в своем проекте специализацию sqlitepp::converter<> для них.

G>Кстати, в последней версии из svn возникает такой варнинг при компиляции:

G>
G>cl : Command line warning D9030: '/Gm' is incompatible with multiprocessing; ignoring /MP switch
G>

G>И еще хорошо бы было обновить sqlite до версии 3.7.12.

Предупржедение починил, обновлять SQLite пока некогда.
Re[2]: SQLite++ в многопоточном приложении
От: Gorilla  
Дата: 30.08.12 02:23
Оценка:
Вопрос к PM: не планируется ли портировать библиотеку под mysql? Несмотря на все ухищрения мой проект перерос sqlite, требуется взрослая база данных. Но я так привык к sqlite++, что другие обертки кажутся ужасными.
Re[3]: SQLite++ в многопоточном приложении
От: Centaur Россия  
Дата: 30.08.12 04:22
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>Вопрос к PM: не планируется ли портировать библиотеку под mysql? Несмотря на все ухищрения мой проект перерос sqlite, требуется взрослая база данных. Но я так привык к sqlite++, что другие обертки кажутся ужасными.


Довольно странно в качестве примера взрослой базы данных приводить mysql. А у Postgres’а есть вполне modern C++-style обёртка libpqxx.
Re[3]: SQLite++ в многопоточном приложении
От: PM  
Дата: 30.08.12 10:29
Оценка:
Здравствуйте, Gorilla, Вы писали:

G>Вопрос к PM: не планируется ли портировать библиотеку под mysql? Несмотря на все ухищрения мой проект перерос sqlite, требуется взрослая база данных. Но я так привык к sqlite++, что другие обертки кажутся ужасными.


Нет, я не планирую добавлять в SQlite++ поддержку других БД. По-моему, нет необъодимости в еще одной универсальной БД библиотеке

На вскидку могу вспомнить SOCI и CppDB (последнюю кстати я успешно использовал в одном проекте c MySQL)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.