예제 #1
0
/* print error message of database */
static void dberrprint(KCDB* db, int32_t line, const char* func) {
    char* path;
    const char* emsg;
    int32_t ecode;
    path = kcdbpath(db);
    ecode = kcdbecode(db);
    emsg = kcdbemsg(db);
    oprintf("%s: %d: %s: %s: %d: %s: %s\n",
            g_progname, line, func, path ? path : "-", ecode, kcecodename(ecode), emsg);
    kcfree(path);
}
extern CAMLprim
value kc_abort_tran(value caml_db)
{
  CAMLparam1(caml_db);
  
  KCDB* db = get_db(caml_db);
  if (! kcdbendtran(db, 0)) {
     const char *error = kcdbemsg(db);
     RAISE(error);
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_begin_tran_sync(value caml_db)
{
  CAMLparam1(caml_db);
  
  KCDB* db = get_db(caml_db);
  if (! kcdbbegintran(db, 1)) {
     const char *error = kcdbemsg(db);
     RAISE(error);
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_set(value caml_db, value key, value val)
{
  CAMLparam3(caml_db, key, val);
  
  KCDB* db = get_db(caml_db);
  if (! kcdbset(db,
    String_val(key), caml_string_length(key),
    String_val(val), caml_string_length(val)
  )) {
     RAISE(kcdbemsg(db));
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_open(value path, value options)
{
  CAMLparam2(path, options);

  KCDB* db = kcdbnew();
  if (! kcdbopen(db, String_val(path), decode_flags(options, OPEN_FLAGS))) {
     const char *error = kcdbemsg(db);
     kcdbdel(db);
     RAISE(error);
  }

  value caml_db = alloc_small(1, Abstract_tag);
  KCDB_val(caml_db) = db;
  CAMLreturn(caml_db);
}
extern CAMLprim
value kc_remove(value caml_db, value key)
{
  CAMLparam2(caml_db, key);

  KCDB* db = get_db(caml_db);
  if (! kcdbremove(db,
    String_val(key), caml_string_length(key)
  )) {
     if (kcdbecode(db) != KCENOREC) {
       RAISE(kcdbemsg(db));
     }
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_exists(value caml_db, value key)
{
  CAMLparam2(caml_db, key);
  CAMLlocal1(val);

  KCDB* db = get_db(caml_db);
  if (! kcdbaccept(db,
    String_val(key), caml_string_length(key),
    exists_some_value, exists_no_value, &val, 0
  )) {
     RAISE(kcdbemsg(db));
  }
  
  CAMLreturn(val);
}
extern CAMLprim
value kc_replace(value caml_db, value key, value val)
{
  CAMLparam3(caml_db, key, val);
  
  KCDB* db = get_db(caml_db);
  if (! kcdbreplace(db,
    String_val(key), caml_string_length(key),
    String_val(val), caml_string_length(val)
  )) {
     if (kcdbecode(db) == KCENOREC) raise_not_found();
     else RAISE(kcdbemsg(db));
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_add(value caml_db, value key, value val)
{
  CAMLparam3(caml_db, key, val);
  
  KCDB* db = get_db(caml_db);
  if (! kcdbadd(db,
    String_val(key), caml_string_length(key),
    String_val(val), caml_string_length(val)
  )) {
     if (kcdbecode(db) == KCEDUPREC) caml_invalid_argument("Entry already exists");
     else RAISE(kcdbemsg(db));
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_find(value caml_db, value key)
{
  CAMLparam2(caml_db, key);
  CAMLlocal1(val);

  KCDB* db = get_db(caml_db);
  if (! kcdbaccept(db,
    String_val(key), caml_string_length(key),
    get_the_value, found_no_value, &val, 0
  )) {
     RAISE(kcdbemsg(db));
  }
  
  if ((char*)val == NULL) raise_not_found();
  CAMLreturn(val);
}
extern CAMLprim
value kc_close(value caml_db)
{
  CAMLparam1(caml_db);
  
  KCDB* db = KCDB_val(caml_db);
  if (db) {
    if (! kcdbclose(db)) {
       const char *error = kcdbemsg(db);
       RAISE(error);
    }

    kcdbdel(db);
    KCDB_val(caml_db) = NULL;
  }

  CAMLreturn(Val_unit);
}
extern CAMLprim
value kc_status(value caml_db)
{
  CAMLparam1(caml_db);
  CAMLlocal1(val);

  KCDB* db = get_db(caml_db);
  const char* status = kcdbstatus(db);
  if (! status) {
     const char *error = kcdbemsg(db);
     RAISE(error);
  }

  val = caml_copy_string(status);
  kcfree((void*) status);
  
  CAMLreturn(val);
}
extern CAMLprim
value kc_path(value caml_db)
{
  CAMLparam1(caml_db);
  CAMLlocal1(val);

  KCDB* db = get_db(caml_db);
  const char* path = kcdbpath(db);
  if (! path) {
     const char *error = kcdbemsg(db);
     RAISE(error);
  }

  val = caml_copy_string(path);
  kcfree((void*) path);
  
  CAMLreturn(val);
}