ERROR: database is locked. Sqlite - problem z ponownym otwarciem bazy.

0

Witam,

mam program, który najpierw sprawdza czy baza danych ma jakieś wiersze w tabeli. Jeśli nie ma to wykonuje się zapis informacji do bazy, jednak po wcześniejszym odczytaniu liczby wierszy z bazy baza nie chce się otworzyć na nowo. Wyświetla się error: database is locked.

trochę tego kodu mam, więc funkcja otw_bazy() odpowiada za pierwsze otwarcie bazy, następnie w ifie w main następuje ponowne otwarcie bazy przez szu.calosc();

w metodzie calosc() jest metoda do_bazy() i to ona powoduje drugie otwarcie bazy danych.

Proszę o pomoc.

kod:

#include <stdio.h>
//#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
//#include <boost/foreach.hpp> 
#include <fstream>
#include <ctime>
#include <curl/curl.h>
//#include <curl/types.h>
//#include <curl/easy.h>
#include <string>
#include <iostream>
#include <sstream>
#include "sqlite3.h"

using namespace std;
using namespace boost;

//######################################### ---- SCIAGANIE KODU ZRODLOWEGO ---- ####################################

class kod_zrodlowy{

private:

	struct FtpFile 
	{
	  const char *filename;
	  FILE *stream;
	}ftpfile[2];
public:
	int sezon_poczatkowy;
public:
	kod_zrodlowy(char *plik1, char *plik2);
	void pobierz_kod();
	void sciaganie(struct FtpFile plik, string link);
	static size_t zapis_do_pilku(void *buffer, size_t size, size_t nmemb, void *stream);
	~kod_zrodlowy(){};
};
 
kod_zrodlowy::kod_zrodlowy(char *pl1, char *pl2)
{
	ftpfile[0].filename=pl1;
	ftpfile[0].stream=NULL;	
	ftpfile[1].filename=pl2;
	ftpfile[1].stream=NULL;	
}

void kod_zrodlowy::pobierz_kod()
{
	string linki[2];

	SYSTEMTIME st;
	 GetSystemTime(&st);
	 
     int rok=st.wYear;

	string link="http://www.premiership-football.co.uk/Premiership-Matches-Results-0000-0000.php";

	
   
	string cos2;
	int cos=rok-3;
	sezon_poczatkowy=cos;
	for(int i=0; i<2; i++)
	{
		for(int j=0; j<2; j++)
		{

		
		cos+=j;
		//cout << "cos: " << cos << endl;
		cos2=cos;
		
		stringstream out;
		out << cos;
		cos2 = out.str();
	
		const regex pattern("0000");
   
  
		string replacer = cos2;

		match_flag_type fonly = format_first_only;

   
		link = regex_replace(link, pattern, replacer, fonly);
		linki[i]=link;
		}
		cos=rok-2;
		link="http://www.premiership-football.co.uk/Premiership-Matches-Results-0000-0000.php";
	}

	

	
	for(int i=0; i < 2; i++)
	{
		sciaganie(ftpfile[i], linki[i]);
	}

}

void kod_zrodlowy::sciaganie(struct FtpFile plik, string link)
{
	CURL *curl;
  CURLcode res;
  cout << link << endl;

	char * cstr;
	cstr = new char [link.size()+1];
	strcpy (cstr, link.c_str());

  curl_global_init(CURL_GLOBAL_DEFAULT);
 
  curl = curl_easy_init();
  if(curl) {
 
    curl_easy_setopt(curl, CURLOPT_URL, cstr);
    
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, zapis_do_pilku);
    
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &plik);
 
    
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
 
    res = curl_easy_perform(curl);
 
    
    curl_easy_cleanup(curl);
 
    if(CURLE_OK != res) {
      
      fprintf(stderr, "curl told us %d\n", res);
    }
  }
 
  if(plik.stream)
    fclose(plik.stream);
 
  curl_global_cleanup();


}

size_t kod_zrodlowy::zapis_do_pilku(void *buffer, size_t size, size_t nmemb, void *stream)
{
	
	
  struct FtpFile *out=(struct FtpFile *)stream;
  if(out && !out->stream) {
    
    out->stream=fopen(out->filename, "wb");
    if(!out->stream)
      return -1;  
  }

  
  return fwrite(buffer, size, nmemb, out->stream);
  
}
 

//######################################### ---- KONIEC ---- ####################################



//######################################### ---- WYDOBYWANIE INFORMACJI Z KODU ---- ####################################


class wyrazenia_regularne{

protected:

	char *nazwa_pliku1[2];
	char *nazwa_pliku2;
	string kod[2];


	string wyrazenia[2][2000];
	int liczba_wyr[2];
public:

	wyrazenia_regularne(char *pl1, char *pl2);
	
	void czyszczenie(string& item);
	void odczyt_z_pliku(char *nazwa_pliku,string &kod_zrodlowy);
	void wyszukiwanie(string &kod_zrodlowy,int licznik);
	void to();
};

void wyrazenia_regularne::to()
{
	
		for(int i=0; i<2; i++)
		{
			for(int j=0; j< liczba_wyr[i]; j++)
				cout << wyrazenia[i][j] << endl;
		}
	
}

wyrazenia_regularne::wyrazenia_regularne(char *pl1, char *pl2)
{
	nazwa_pliku1[0] = new char[strlen(pl1)+1];
	strcpy(nazwa_pliku1[0], pl1);
	nazwa_pliku1[1] = new char[strlen(pl2)+1];
	strcpy(nazwa_pliku1[1], pl2);

	
}


void wyrazenia_regularne::odczyt_z_pliku(char *nazwa_pliku, string &kod_zrodlowy)
{
	//string kod;
	ifstream plik;

	plik.open(nazwa_pliku, ios::out);

	if(plik.is_open())
	{
		while(!plik.eof())
			{

			kod_zrodlowy.push_back(plik.get());

			}
	}
	else cout << "blad otwarcia pliku\n";

	plik.close();

	
}

void wyrazenia_regularne::wyszukiwanie(string &kod_zrodlowy, int licznik)
{
	
	const static regex wzor("(>[^>([:space:])|(&nbsp;)|([:punct:])<].*?<)");

	//string *tab= new string[10000];
	int a=0;
	long int pozycja=0;
	size_t found;

	found = kod_zrodlowy.find("tab_albastru");

	if (found!=string::npos)
	{
		found=kod_zrodlowy.find("</table>",found);
		//cout<< "pozycja: " << found << endl;
		kod_zrodlowy.length();
		pozycja=kod_zrodlowy.length()-found;
	}

	string wy;

	const sregex_token_iterator end;
	for (sregex_token_iterator i(kod_zrodlowy.begin()+=kod_zrodlowy.find("tab_albastru"), kod_zrodlowy.end()-=pozycja, wzor); i != end; ++i)
	{
		wy=*i;
		czyszczenie(wy);
		wyrazenia[licznik][a]=wy;
		a++;	  
	}
	liczba_wyr[licznik]=a;
	
}

void wyrazenia_regularne::czyszczenie(string& item)
{
   
   const regex pattern("\\s(?=\\s|<)|(>)|(<)");
   
  
   string replacer = "";

   
   match_flag_type fonly = format_all;

   
   item = regex_replace(item, pattern, replacer, fonly);
}


//######################################### ---- KONIEC ---- ####################################



//######################################### ---- TRANSPORT DO BAZY ---- ####################################


class baza_danych : public wyrazenia_regularne
{
private:

	int sezon_poczatkowy;

public:

	baza_danych(char *pl1, char *pl2, int sezon): wyrazenia_regularne(pl1, pl2){
	sezon_poczatkowy=sezon;
	};
	void do_bazy(int licznik);
	static int callback(void *NotUsed, int argc, char **argv, char **azColName);
	void calosc();
	void spr();
};

int baza_danych::callback(void *NotUsed, int argc, char **argv, char **azColName)
{
  int i;
  for(i=0; i<argc; i++)
  {
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

void baza_danych::calosc()
{
	for(int i=0; i<2; i++)
	{
		odczyt_z_pliku(nazwa_pliku1[i],kod[i]);
		wyszukiwanie(kod[i],i);
		do_bazy(i);
	}
}

void baza_danych::do_bazy(int licznik)
{
	sqlite3 *db;

	char *zErrMsg = 0;
	int rc;
	const static regex wzor1("[0-9]*\-[0-9]*\-[0-9]*");

	rc = sqlite3_open ("scores2.sqlite", &db);

	if( rc ){

	fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
	}
	else
	{

	fprintf(stderr, "Baza danych otwarta!:)\n");

	
	string rezultat;
	stringstream  *ss= new stringstream[10000]; 
	int j=0;
	int b,indeks_bazy=0;

	while(j<5)
	{
		if(regex_match(wyrazenia[licznik][j], wzor1))
		{
			b=j;
			j++;
		};
		while((!(regex_match(wyrazenia[licznik][j], wzor1))) && (j<liczba_wyr[licznik]))
		{
			
			if(wyrazenia[licznik][j+1]>wyrazenia[licznik][j+3]) 
			{
					rezultat=wyrazenia[licznik][j];
			}
			else
			{
				if(wyrazenia[licznik][j+1]<wyrazenia[licznik][j+3])
				{
					rezultat=wyrazenia[licznik][j+2];
				}
				else
				{
					if(wyrazenia[licznik][j+1]==wyrazenia[licznik][j+3])
					{
						rezultat="Remis";
					}
				}
			}
		
			ss[indeks_bazy]<<"insert into Scores (Id, Sezon, Data, Druzyna1, Wynik1, Druzyna2, Wynik2, Rezultat) values ('"<<indeks_bazy<<"','"<<sezon_poczatkowy+licznik<<"','"<<wyrazenia[licznik][b]<<"','"<<wyrazenia[licznik][j]<<"','"<<wyrazenia[licznik][j+1]<<"','"<<wyrazenia[licznik][j+2]<<"','"<<wyrazenia[licznik][j+3]<<"','"<<rezultat<<"')"; 

			indeks_bazy++;
			j+=4;
		}
	}


	


	for(int i = 0; i <= indeks_bazy; i++)
		{
			rc = sqlite3_exec(db, (ss[i].str().c_str()), callback, 0, &zErrMsg);
			if( rc!=SQLITE_OK )
			{
				fprintf(stderr, "SQL error: %s\n", zErrMsg);
				sqlite3_free(zErrMsg);
				break; 
			}
		}
	 cout << "koniec";
	 
}
	sqlite3_close(db);



}



void baza_danych::spr()
{
	sqlite3 *db;
	string rezultat;
	stringstream  *ss= new stringstream[10000]; 
	char *zErrMsg = 0;
	int rc;
	
	const char *pSQL[6];

	int indeks_bazy=0;
	rc = sqlite3_open ("scores.sqlite", &db);

	if( rc ){

	fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
	}
	else
	{

	fprintf(stderr, "Baza danych otwarta!:)\n");

	
	
	
			pSQL[indeks_bazy]="insert into scores (Sezon, Data, Druzyna1, Wynik1, Druzyna2, Wynik2, Rezultat) values (1,2,3,4,5,6,7)"; 
			indeks_bazy++;
	
	
		
			pSQL[indeks_bazy]="SELECT (*) FROM Scores"; 


			
	
	}


	


	for(int i = 0; i < indeks_bazy; i++)
		{
			rc = sqlite3_exec(db, pSQL[i], callback, 0, &zErrMsg);
			if( rc!=SQLITE_OK )
			{
				fprintf(stderr, "SQL error: %s\n", zErrMsg);
				sqlite3_free(zErrMsg);
				break; 
			}
		}
	 cout << "koniec"<< endl;

}

static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
	string cos;
	int i;
  for(i=0; i<argc; i++)
  {
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
	cos=argv[i];
	//cout << "-----" << endl;
	//cout << argv[i] << endl;
  }
  printf("\n");
  return 0;
}

void otw_bazy(int &cos)
{
	sqlite3 *db;
	unsigned const char* _name;
	int wartosc;
	stringstream  odp;

	char *zErrMsg = 0;

	int rc, col;
	
	
	rc = sqlite3_open ("scores2.sqlite", &db);

	if( rc ){

	fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
	
	}
	else
	{

	fprintf(stderr, "Baza danych otwarta!:)\n");
	sqlite3_stmt  *select_stmt;
	
	
	
			//pSQL[indeks_bazy]="insert into scores (Sezon, Data, Druzyna1, Wynik1, Druzyna2, Wynik2, Rezultat) values (1,2,3,4,5,6,7)"; 
			//indeks_bazy++;
	
	
		
			//odp<<"SELECT Sezon, Data, Druzyna1, Wynik1, Druzyna2, Wynik2, Rezultat FROM Scores"; 
			//char *sql[]={"SELECT * FROM Scores ORDER BY ID DESC limit 1 "
			char *sql[]={"SELECT count(*) FROM scores ;"
				
			};
			


		for (int i=0; i<sizeof(sql)/sizeof(sql[0]); i++)
    {	
			if (sqlite3_prepare(db, sql[i], -1, &select_stmt, NULL))
        {
            printf("Error: %s\n", sqlite3_errmsg(db));
            sqlite3_finalize(select_stmt);
            sqlite3_close(db);
            system("pause");
            exit(1);
        }
			col = sqlite3_column_count(select_stmt);
	

	if((rc = sqlite3_step(select_stmt)) == SQLITE_ROW)
        {

            col = sqlite3_data_count(select_stmt);

            cos=sqlite3_column_int(select_stmt, 0);
			
            cout<<cos<<endl; //1
			
        }
		
	}
		
		
	}
	sqlite3_close(db);
}

int main(int argc, char* argv[])
{
	int cos;
	otw_bazy(cos);
	if(cos==0)
	{
	char *plik1="scores1.txt", *plik2="scores2.txt";
	
	class kod_zrodlowy moc(plik1,plik2);

	moc.pobierz_kod();
  
	int sezon = moc.sezon_poczatkowy;
	
	
	class baza_danych szu(plik1,plik2,sezon);
	szu.calosc();
	}
	else
	{
		cout << "nie udalo sie" << endl;
	}
	


	 cout << "koniec"<< endl;
	 
 system("pause");
  return 0;
}
0

Bazę należy otworzyć tylko raz, ewentualnie poprawnie zamknąć i wtedy otworzyć raz jeszcze.
Sprawdź czy poprawnie zamykasz, czy zamykasz wszystkie zapytania, np to z odczytaniem ilości rekordów.

0

dzięki, nie dodałem sqlite3_finalize(select_stmt); na końcu w funkcji otw_bazy();

1 użytkowników online, w tym zalogowanych: 0, gości: 1