3 Nisan 2018 Salı

SQLite C Api

Giriş
Kurulum sonrasında şuna benzer bir yapı elde ederiz.
SQLITE
  |___bin
  |___include
  |___lib
  |___share
  |
Şu dosya include edilir. Windows'ta sqlite3.lib ile linkleriz. Ayrıca sqlite3.dll path içinde mevcut olmalıdır. Linux'ta ise libsqlite3.so ile linkleriz.
#include <sqlite3.h>
sqlite3_bind_int metodu
Şöyle yaparız.
sqlite3_stmt* res = ...;
int id = ...;
int i  =  ...;
sqlite3_bind_int (res, i, id);
sqlite3_bind_parameter_count metodu
Şöyle yaparız.
sqlite3_stmt* res = ...;
int paramCnt = sqlite3_bind_parameter_count (res);
sqlite3_bind_parameter_index metodu
Şöyle yaparız.
sqlite3_stmt* res = ...;
int i = sqlite3_bind_parameter_index (res, "@id");
sqlite3_close metodu
Bağlantı şöyle kapatılır.
sqlite3_close(conn);
sqlite3_column_count metodu
Şöyle yaparız.
sqlite3_stmt * res = ...;
int columnCnt = sqlite3_column_count (res);
sqlite3_column_name metodu
Şöyle yaparız.
int i = 1;
if (strcmp("id", sqlite3_column_name(res, i)) == 0) {...}
sqlite3_column_int metodu
Şöyle yaparız.
int i = 1; 
int id = sqlite3_column_int (res,i);
sqlite3_config metodu
Uri şeklinde veritabanı dosya ismi kullanmak istemezsek şöyle yaparız.
sqlite3_config(SQLITE_CONFIG_URI, 0)
sqlite_err metodu
Hata olursa, hata kodunu yazar.
sqlite3 *db;
int  rc = sqlite3_open("idk.db", &db);
if( rc ){
  fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  exit(0);
}
sqlite3_exec metodu
İmzası şöylee
int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);
Tablo şöyle yaratılır
#define sql "CREATE TABLE IF NOT EXISTS TTC (...)"
char * sErrMsg = 0;
sqlite3_exec(conn, sql, NULL, NULL, &sErrMsg);
Insert şöyle yapılır
strng sql= "INSERT INTO login (name,username,password) VALUES ('...')"; 
error = sqlite3_exec(conn, sql_lite, 0, 0, 0);
Transaction şöyle yapılır.
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
...
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
Meıod sonuç olarka bir int değer döner. Hata olduğunu anlamak için SQLITE_OK ile karşılaştırılır. Şöyle yaparız
if (rc != SQLITE_OK) {...}
Bu metodun 3. parametresi callback'tir şöyle çağırırız.
sqlite3_exec(db, sql, callback, NULL, &sErrMsg);
Bu metodun 5. parametresi hata mesajının yazıldığı bellektir. Eğer çağrı sırasında null geçmezsek ve hata varsa bu belleği silmemiz gerekir.
sqlite3* db = ...;
char* zErr = NULL;

char* sql = "create table ...";
int rc = sqlite3_exec(db, sql, NULL, NULL, &zErr);
if (rc != SQLITE_OK)
{
  if (zErr != NULL)
  {
    fprintf(stderr, "SQL error: %s\n", zErr);
    sqlite3_free(zErr);
  }
}
Örnek - sqlite3_exec metodu için callback
callback her satır için ayrı ayrı çağrılır.
callback'in 1. parametresi "Data provided in the 4th argument of sqlite3_exec()" anlamına gelir
callback'in 2. parametresi sütun sayısıdır
callback'in 3. parametresi sütun değeridir. 
callback'in 4. parametresi sütun ismidir. 

Örnek
Sütun ismini ve değerini yazdırmak için şöyle yaparız.
int i;
for(i = 0; i < argc; i++) {
  cout << column[i] << ": " << argv[i] << endl;
}
Örnek
Sütun ismini ve değerini yazdırmak için şöyle yaparız. Bu sefer sütun değerinin NULL olması da dikkate alınıyor.
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");
}
Örnek
Şöyle yaparız.
char *zErrMsg = 0;
stringstream sql_query;

// assemble string
sql_query << "INSERT INTO Department1 (Date,Time,Accept) VALUES ('...')";
const char* str = sql_query.str().c_str();

// execute SQL statement
rc = sqlite3_exec(db, str, callback, 0, &zErrMsg);

if( rc != SQLITE_OK )
{
  fprintf(stderr, "SQL error: %s\n", zErrMsg);
  sqlite3_free(zErrMsg);
}
else
{
  fprintf(stdout, "Records created successfully\n");
}
sqlite3_close(db);

static int callback(void *db, int argc, char **argv, char **azColName)
{
  for(int i=0; i<argc; ++i)
  {
    cout << ("%s", argv[i] ? argv[i] : "NULL") << endl;
  }
  return 0;
}
sqlite3_finalize metodu
Result set şöyle kapatılır.
sqlite3_finalize(res);
Döngü ile şöyle kullanırız.
while (SQLITE_ROW == sqlite3_step(res)) {
  ...
}
sqlite3_finalize(res);
sqlite3_free metodu
sqlite3_exec gibi metodlar tarafından hata mesajı için ayrılan bellek alanını temizler.
Örnek
Şöyle yaparız.
char *zErrMsg = 0;
char * sql = "...";
int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){...;sqlite3_free(zErrMsg);}
sqlite3_mutex metodu
Şöyle yaparız.
sqlite3_open(“/data/…/MY_DATABASE_NAME”, &db);
sqlite3_mutex* mutex = sqlite3_db_mutex(db); 

sqlite3_mutex_enter(mutex); //DATABASE LOCKED, 

sqlite3_exec(db, ….)

sqlite3_mutex_leave(mutex);
sqlite3_close(db);
sqlite3_open metodu
Metodun imzası şöyledir. Açılan dosya sqlite3_close() ile kapatılmalıdır.
int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
Örnek
Dosya şöyle açılır
#define DATABASE "c:\\TTC_schedule_scheduleitem_10-27-2009.sqlite"
sqlite3 * db;
sqlite3_open(DATABASE, &db);
Örnek
Metod hata varsa 0'dan farklı bir değer döner.  Hata için dönen değer SQLITE_OK ile karşılaştırılabilir.
sqlite3 *conn;
int     error = 0;
error = sqlite3_open("data.dat", &conn);
if (error)
{
  printf("Can not open database");
}
Örnek
Şöyle yaparız.
sqlite3 *db;
int rc;
char db_name[] = "db_test.db";

rc = sqlite3_open(db_name, &db);

if( rc )
{
  fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
}
else
{
  fprintf(stdout, "Opened database successfully\n");
}
Örnek
Eğer istenirse veritabanı bellekte açılabilir. Bunun için dosya ismi yerine ":memory:" kullanılır.
sqlite3* mem_database;
if((SQLITE_OK == sqlite3_open(":memory:", &mem_database)){
  ...
}
sqlite3_close(mem_database);
sqlite3_open_v2 metodu
Şöyle yaparız.
string db = "...";
dbase_return=sqlite3_open_v2(db.c_str(),&db_handle,SQLITE_OPEN_READWRITE,NULL);
Veritabanı ismi şöyle olmalıdır.
file:///C:/Programs_C++/Project/Databases/dbase.db
sqlite3_prepare metodu
Metodun imzası şöyledir.
int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
sqlite3_prepare_v2 metodu
Result set almak için kullanılır. Bir statement tanımlanır.
sqlite3_stmt *res;
tail şöyledir.
const char     *tail;
Daha sonra sorgu gönderilir.
sqlite3_prepare_v2(conn, "SELECT * FROM login order by No",1000, &res, &tail);
sqlite3_reset metodu
Result set ile kullanılıyor ancak anlamadım.

sqlite3_step metodu
Result set şöyle dolaşılır. Result set içinde kaç tane sütun olduğunu nasıl buluruz bilmiyorum.
while (sqlite3_step(res) == SQLITE_ROW)
{
  printf("%d|", sqlite3_column_int(res, 0));
  printf("%s|", sqlite3_column_text(res, 1));
  printf("%s|", sqlite3_column_text(res, 2));
  printf("%s|", sqlite3_column_text(res, 3));
  printf("%u\n", sqlite3_column_int(res, 4));

}
64 bit inte' şöyle erişiriz.
sqlite3_column_int64(res, 1);
Sadece dolaşan bir örnek şöyle yazılır. Result set bitince SQLITE_DONE döndüğünü görebiliriz.
void Trial(sqlite3_stmt *stmt) {
  int ret;
  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) ;
  if (ret != SQLITE_DONE) {
    errx(1, "sqlite3_step: %d (%s)", ret, sqlite3_errstr(ret));
  }
  ret = sqlite3_reset(stmt);
  if (ret != SQLITE_OK) {
    errx(1, "sqlite3_reset: %d (%s)", ret, sqlite3_errstr(ret));
  }
}

Hiç yorum yok:

Yorum Gönder