Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
1

SQLite Блокровка/разблокировка

05.07.2013, 22:09. Показов 3074. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть код: таймер периодически создает/запускает поток, поток получает данные ( через интернет) открывает БД (sqlite3_open() ) и добавляет туда новые данные закрывает БД ( sqlite3_close(db); ) поток завершается.

При первом создании потока все проходит нормально данные вставляются ошибок- нет, при втором при попытке
выполнить INSERT пишет что база блокирована, данные не занеслись.

Период между созданиями потоком значительный, так что первый поток успевает завершится до создания второго.

Вопрос : как правильно закрыть БД что бы она разблокировалась ? Или что могло повлиять на такую работу ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.07.2013, 22:09
Ответы с готовыми решениями:

Одновременная блокировка/разблокировка функционала программы
Прошу прощения за столь изворотливый заголовок темы. Опишу суть проблемы. Разрабатываю программу...

Блокировка/разблокировка клавиши впоследствии нажатия комбинации клавиш
Здравствуйте! Есть задачка: нужно сделать программу, которая блокирует некую клавишу (например...

Sqlite в c++ под linux, как правильно подключить sqlite?
Добрый день. Подскажите пожалуйста, как подключить sqlite к c++? Пишу приложение без сред...

События сессии пользователя (вход/выход/блокировка/разблокировка/сон/выход из сна/выключение/перезапуск)
Добрый день. Мне нужно слушать эти события (указаны в заголовке) в реальном времени для...

18
Заблокирован
05.07.2013, 23:01 2
Дебагом посмотреть что возвращает sqlite3_close итд если данные на месте и файла журнала нету.
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.07.2013, 23:16  [ТС] 3
Возвращает :
unable to close due to unfinalized statements or unfinished backups
Добавлено через 2 минуты
Что-то не могу понять где ошибка

Код класса обвертки ( код С++Builder)
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//---------------------------------------------------------------------------
namespace My{
//---------------------------------------------------------------------------
class SQLite
{
   String FError;
   String FResult;
   char *error;
 
   bool   FOpen;
   sqlite3 *db;
 
   public:
    SQLite():FError(""),FOpen(0),error(0),db(0){};
    ~SQLite();
 
    bool Open(String Path);
    bool Exists(String SiteId);
    bool Insert(const My::Subject& Subject);
 
    bool View(TStringGrid* SG);
 
    bool  IsOpen() { return FOpen;  }
    String Error() { return FError; };
    String Result(){ return FResult;};
    bool Close();
};
//-----------------------------End My:: -------------------------------------
}
//---------------------------------------------------------------------------


Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//---------------------------------------------------------------------------
bool My::SQLite::Open(String Path)
{
  if(FOpen) return false;
 
  int res = sqlite3_open(UTF8String(Path).c_str(), &db);
  if( res )
    {
      FError= UTF8String(sqlite3_errmsg(db));
      sqlite3_close(db);
      return false;
    }
  else  FOpen= true;
 
return  true;
}
//---------------------------------------------------------------------------
bool My::SQLite::Insert(const My::Subject& Subject)
{
  UTF8String Query=
    L"INSERT INTO \"main\".\"Subjects\" \
   (Id,SiteId,Subject,Author,Reference)\
    VALUES (NULL,'"+Subject.SiteId    +L"','"+
                    Subject.Name      +L"','"+
                    Subject.Author    +L"','"+
                    Subject.Reference +L"')";
 
  int res = sqlite3_exec(db,Query.c_str(),0, 0, &error);
 
  if( res!=SQLITE_OK )
    {
      FError= UTF8String(error);
      sqlite3_free(error);
      return false;
    }
 
return  true;
}
//---------------------------------------------------------------------------
bool My::SQLite::Exists(String SiteId)
{
  sqlite3_stmt *statement;
 
  UTF8String Query=
      L"SELECT  EXISTS(SELECT * FROM  Subjects WHERE SiteId ='"+SiteId+L"')";
 
  int res = sqlite3_prepare(db, Query.c_str(), -1, &statement,0);
  if( res!=SQLITE_OK )
    {
      //FError= UTF8String(error);
      //sqlite3_free(error);
      FError= UTF8String(sqlite3_errmsg(db));
      return false;
    }
 
  sqlite3_step(statement);
  FResult = (char*)sqlite3_column_text(statement,0);
 
return  true;
}
//---------------------------------------------------------------------------
bool My::SQLite::View(TStringGrid* SG)
{
  sqlite3_stmt *statement;
 
  UTF8String Query=
      L"SELECT * FROM Subjects  ORDER BY Id LIMIT 100";
 
  int res = sqlite3_prepare(db, Query.c_str(), -1, &statement,0);
  if( res!=SQLITE_OK )
    {
      FError= UTF8String(sqlite3_errmsg(db));
      return false;
    }
 
  for(int r=0; r<100; ++r)
    {
      if( sqlite3_step(statement)==SQLITE_DONE) break;
 
      String Text;
 
      int col_count= sqlite3_column_count(statement);
      for(int c=0; c<col_count; ++c)
        {
          if(c>=2 && c<=4)
            {
              Text+= UTF8String((char*)sqlite3_column_text(statement,c));
              SG->Cells[2][r+1] = Text;
              Text+="\n";
            }
          else
            if(c<2)
              SG->Cells[c][r+1] = UTF8String((char*)sqlite3_column_text(statement,c));
           //   else
           //     SG->Cells[3][r+1] = UTF8String((char*)sqlite3_column_text(statement,c));
        }
    }
 
  sqlite3_finalize(statement);
 
return  true;
}
//---------------------------------------------------------------------------
bool My::SQLite::Close()
{
  int res= sqlite3_close(db);
  if( res!=SQLITE_OK )
    {
      FError= UTF8String(sqlite3_errmsg(db));
      return false;
    }
return true;
}
//---------------------------------------------------------------------------
My::SQLite::~SQLite()
{
  //if(FOpen) sqlite3_close(db);
};
//---------------------------------------------------------------------------


Добавлено через 5 минут
Вроде нашел ошибку в методе Exists забыл выполнить sqlite3_finalize()

C++
1
2
3
sqlite3_step(statement);
FResult = (char*)sqlite3_column_text(statement,0);
sqlite3_finalize(statement);
0
Заблокирован
05.07.2013, 23:38 4
Ну если код такой простой тебе вообще это нафиг не нужно, а в критичных местах можно вообще делать тупо exec begin transaction;&&amp;commit;
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.07.2013, 23:42  [ТС] 5
Не совсем понял, что не надо ?

Как бы только начал разбираться с библиотекой, а в доке находил только простые примеры.
0
Заблокирован
06.07.2013, 00:29 6
В простых вещах prepared queries не нужны, фильтровать лучше у себя учиться если именно про обучение.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 00:30  [ТС] 7
Цитата Сообщение от Dr_Quake Посмотреть сообщение
В простых вещах prepared queries не нужны, фильтровать лучше у себя учиться если именно про обучение.
А как данные вытягивать ?

Я так и не понял как правильно это делать через колбеки: sqlite3
0
Заблокирован
06.07.2013, 00:32 8
Напрямую sql в sqlite3_exec, но опять же это только для обучения важно пройти. CALLBACK в sqlite нафиг не нужен на мой взгляд, не те масштабы чтобы так издеваться над файловой БД, но тут мало ли для чего пригодится, ты callback правильный фактически в нормальном виде на размере данных небольшом и не увидишь нормально, максимум 1-2 раза, но тут уже я не работал с этим почти, весь смысл sqlite - быстрая локальная небольшая база, а по правильному - ещё и memtable, это его основное назначение.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 00:36  [ТС] 9
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Напрямую sql в sqlite3_exec, но опять же это только для обучения важно пройти.
Не понял что вы имеете ввиду "под напрямую"? sqlite3_exec() использует колбек для получения результата запроса
0
Заблокирован
06.07.2013, 00:41 10
К тому, что там prepare/exec не нужен по сути. Prepared Statements для скорости и автоматизации escaping'a нужны.

http://stackoverflow.com/quest... erformance
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
06.07.2013, 16:05 11
Applications should finalize all prepared statements, close all BLOB handles, and finish all sqlite3_backup objects associated with the sqlite3 object prior to attempting to close the object.
Думаю не хватает sqlite3_finalize(statement); в My::SQLite::Exists()

Добавлено через 4 минуты
Пардон, не заметил что эту ошибку ты уже нашел...
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 16:09  [ТС] 12
Цитата Сообщение от Avazart Посмотреть сообщение
Я так и не понял как правильно это делать через колбеки: sqlite3
Это актуально ...
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
06.07.2013, 16:15 13
Цитата Сообщение от Avazart Посмотреть сообщение
Я так и не понял как правильно это делать через колбеки: sqlite3
Я делаю так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include "../sqlite/sqlite3.h"
 
static int callback( void *NotUsed, int argc, char **argv, char **azColName )
{
    for ( int i = 0; i < argc; i++ ) {
        printf( "%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL" );
    }
    printf( "\n" );
    return 0;
}
 
int main( int narg, char **arg )
{
    int         r;
    sqlite3 *   db = 0;
    char *      err_msg = 0;
 
    if ( narg != 2 ) {
        fprintf( stderr, "%s \"REQUEST\"\n", arg[0] );
        return 1;
    }
 
    r = sqlite3_open( "test_db", &db );
    if ( !r ) {
        r = sqlite3_exec( db, arg[1], callback, 0, &err_msg );
        if ( r == SQLITE_OK ) {
            fprintf( stderr, "sqlite3_exec(): ok\n" );
        } else {
            fprintf( stderr, "sqlite3_exec(): %s\n", err_msg );
            sqlite3_free( err_msg );
        }
    } else {
        fprintf( stderr, "sqlite3_open(): error %s\n", sqlite3_errmsg( db ) );
    }
 
    if ( db ) {
        r = sqlite3_close( db );
        fprintf( stderr, "sqlite3_close(): %s\n", r == SQLITE_OK ? "ok" : "fail" );
    }
 
    return 0;
}
Добавлено через 1 минуту
Пример результата запроса "SELECT * FROM my_table" уже созданной БД:
id = 1
name = John
text = aaa

id = 2
name = Ben
text = bbb

id = 3
name = CCC
text = c

id = 4
name = DDD
text = d

id = 5
name = EEE
text = ee

id = 6
name = FFF
text = fff
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 16:17  [ТС] 14
Смотри ссылку sqlite3 ...

Меня интересует как занести, к примеру, данные таблицы в двумерный массив ...
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
06.07.2013, 16:22 15
callback предоставляет тебе эти (запрошенные) данные. Бери и заноси, в чем проблема? Ты не знаешь как создать двумерный массив?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 16:25  [ТС] 16
C++
1
2
3
4
5
6
7
8
static int callback( void *NotUsed, int argc, char **argv, char **azColName )
{
    for ( int i = 0; i < argc; i++ ) {
        printf( "%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL" );
    }
    printf( "\n" );
    return 0;
}
char **argv - одномерный массив строк, где тут колонки, а где столбцы ?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
06.07.2013, 16:30 17
Цитата Сообщение от Avazart Посмотреть сообщение
где тут колонки, а где столбцы ?
Колонки и столбцы в запросе.

Я не специалист по БД но представляю себе это так:
1. Например, есть БД, в ней таблица, в ней 3 столбца ( id, name, age ).
2. Мне нужно заполнить массив именами (name).
3. Делаем запрос: "SELECT name FROM my_table"
4. callback выдает тебе список имен (argv[i] - одно имя), ты их заносишь.

Что я сказал не так?
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.07.2013, 16:39  [ТС] 18
Зайду иначе ..

Имеем вывод
id = 1
name = John
text = aaa

id = 2
name = Ben
text = bbb

id = 3
name = CCC
text = c

id = 4
name = DDD
text = d

id = 5
name = EEE
text = ee

id = 6
name = FFF
text = fff
А мне надо
id name text
-- ------- -----
1 John aaa
2 Ben bbb
3 CCC cccc
5 DDD ddd
6 ...
Добавлено через 3 минуты
Блин написал пост, и само дошло что calback может вызываться несколько раз при выполнении одного запроса. .... на то он и колбек...
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
06.07.2013, 16:44 19
Цитата Сообщение от Avazart Посмотреть сообщение
А мне надо
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static int callback( void *NotUsed, int argc, char **argv, char **azColName )
{
    static int first = 1;
 
    if ( first ) {
        for ( int i = 0; i < argc; i++ ) {
            printf( "\t%s", azColName[i] ); // выводим имена столбцов
        }
        first = 0;
        printf( "\n" );
    }
 
    for ( int i = 0; i < argc; i++ ) {
        printf( "\t%s", argv[i] ? argv[i] : "NULL" ); // выводим информацию под столбцами
    }
    printf( "\n" );
 
    return 0;
}
id name text
1 John aaa
2 Ben bbb
3 CCC c
4 DDD d
5 EEE ee
6 FFF fff
1
06.07.2013, 16:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.07.2013, 16:44
Помогаю со студенческими работами здесь

Как написать формулы в sqlite или отказаться от использования sqlite вовсе
Доброго времени суток. Друзья, пишу справочник по физике, недавно столкнулся с проблемой - как...

Файл cookies.sqlite не sqlite на самом деле, или как его открыть
хочу прочитать куки браузеров (это не противозаконно) оперу сделал, хром сделал, у хрома как раз...

Редактирование связанных объектов через EF в SQLite, C#, EF 6.2, SQLite, C# Winforms
Здравствуйте. Суть: используя вышеперечисленные технологии, при чтении из базы данных связанных...

SQLite for Excel или как выгрузить данные в SQLite
Здравствуйте! Мне необходимо написать макрос для выгрузки данных из excel в sqlite. Нашла проект...

SQLite не найден SQLite.Interop,dll
работаю на виртуальной машине windows 7 x86. Установлен Visual Studio 2013. Через NuGet установил...

Разблокировка
Всем привет! Обращаюсь к вам с такой проблемой. Брат &quot;балбес&quot; залез на какой то сайт не знаю что он...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru