Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Avazart
Эксперт С++
7586 / 5571 / 330
Регистрация: 10.12.2010
Сообщений: 24,999
Записей в блоге: 17
#1

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

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

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

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

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

Вопрос : как правильно закрыть БД что бы она разблокировалась ? Или что могло повлиять на такую работу ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.07.2013, 22:09
Я подобрал для вас темы с готовыми решениями и ответами на вопрос SQLite Блокровка/разблокировка (C++):

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

Работа с SQLite - C++
Хочу начать работать с SQLite, вот попробовал, но появилась ошибка, подскажите в чем проблема и как исправить, или посоветуйте другие...

Неправильная кодировка в SQLite - C++
Помогите, не правильная кодировка когда я с помощью SQLite получаю данные из файла "Login Data" (Chrome). LVITEM lvi; lvi.mask =...

Vector и Select SQLite - C++
Здравствуйте. Столкнулся с двумя проблемами и не знаю в чём дело. Есть метод класса: std::vector< std::vector<char*> >...

Начать работать с SQLite - C++
Помогите новичку! Пишу консольную программу под Win на С++ Компилирую этим (BAT-файлом): g++.exe %prj%_main_win.cpp %prj%src\*.cpp -o...

Vector allocator SQLite - C++
Гуру, помогите новичку! Столкнулся с проблемой, и даже не понимаю в чем она... Надо: сделать список(вектор) для хранения ссылок...

18
Dr_Quake
Заблокирован
05.07.2013, 23:01 #2
Дебагом посмотреть что возвращает sqlite3_close итд если данные на месте и файла журнала нету.
1
Avazart
Эксперт С++
7586 / 5571 / 330
Регистрация: 10.12.2010
Сообщений: 24,999
Записей в блоге: 17
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
Dr_Quake
Заблокирован
05.07.2013, 23:38 #4
Ну если код такой простой тебе вообще это нафиг не нужно, а в критичных местах можно вообще делать тупо exec begin transaction;&&amp;commit;
0
Avazart
Эксперт С++
7586 / 5571 / 330
Регистрация: 10.12.2010
Сообщений: 24,999
Записей в блоге: 17
05.07.2013, 23:42  [ТС] #5
Не совсем понял, что не надо ?

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

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

http://stackoverflow.com/questions/1...ve-performance
0
castaway
Эксперт С++
4926 / 3033 / 372
Регистрация: 10.11.2010
Сообщений: 11,084
Записей в блоге: 10
Завершенные тесты: 1
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
Avazart
Эксперт С++
7586 / 5571 / 330
Регистрация: 10.12.2010
Сообщений: 24,999
Записей в блоге: 17
06.07.2013, 16:09  [ТС] #12
Цитата Сообщение от Avazart Посмотреть сообщение
Я так и не понял как правильно это делать через колбеки: sqlite3
Это актуально ...
0
castaway
Эксперт С++
4926 / 3033 / 372
Регистрация: 10.11.2010
Сообщений: 11,084
Записей в блоге: 10
Завершенные тесты: 1
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
Avazart
Эксперт С++
7586 / 5571 / 330
Регистрация: 10.12.2010
Сообщений: 24,999
Записей в блоге: 17
06.07.2013, 16:17  [ТС] #14
Смотри ссылку sqlite3 ...

Меня интересует как занести, к примеру, данные таблицы в двумерный массив ...
0
castaway
Эксперт С++
4926 / 3033 / 372
Регистрация: 10.11.2010
Сообщений: 11,084
Записей в блоге: 10
Завершенные тесты: 1
06.07.2013, 16:22 #15
callback предоставляет тебе эти (запрошенные) данные. Бери и заноси, в чем проблема? Ты не знаешь как создать двумерный массив?
0
06.07.2013, 16:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2013, 16:22
Привет! Вот еще темы с ответами:

Работа с БД SQLite 3: чтение, запись - C++
есть бд SQLite 3, раньше с SQLite не работал, подскажите как от туда считать данные и записать их туда

Не могу удалить таблицы в БД SQLite - C++
К программе подключена либа SQLite для реализации небольшого хранилища данных. Иногда это хранилище надо очищать. Так вот, я столкнулся с...

Скорость выполнения запросов в SQLite - C++
Здравствуйте! Собственно, мне нужно осуществлять динамическую запись в журнал происходящих в программе изменений. Делаю это с помощью...

Как собрать приложение С++ которое содержит исходники SQLite - C++
Доброе времени суток, уважаемые форумчани. Столкнулся со следующей проблемой пишу приложение на с++ для хранения данных решил выбрать базу...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru