Ejemplo n.º 1
0
      bool kdb_bucket::start(int bucket_number)
      {
        bool ret = true;
        const char* data_dir = TBSYS_CONFIG.getString(TAIRKDB_SECTION, KDB_DATA_DIR, KDB_DEFAULT_DATA_DIR);
        if (data_dir == NULL) {
          log_error("kdb data dir not config, item: %s.%s", TAIRKDB_SECTION, KDB_DATA_DIR);
          ret  = false;
        }

        if (ret) {
          snprintf(filename, PATH_MAX_LENGTH, "%s/tair_kdb_%06d.dat", data_dir, bucket_number);
          uint64_t map_size = TBSYS_CONFIG.getInt(TAIRKDB_SECTION, KDB_MAP_SIZE, KDB_MAP_SIZE_DEFAULT);
          uint64_t bucket_size = TBSYS_CONFIG.getInt(TAIRKDB_SECTION, KDB_BUCKET_SIZE, KDB_BUCKET_SIZE_DEFAULT);
          uint64_t record_align = TBSYS_CONFIG.getInt(TAIRKDB_SECTION, KDB_RECORD_ALIGN, KDB_RECORD_ALIGN_DEFAULT);

          ret = db.tune_map(map_size);
          if (!ret ) {
            print_db_error("set mmap size failed");
          }

          if (ret) {
            ret = db.tune_alignment(record_align);
            if (!ret) {
              print_db_error("set record alignment failed");
            }
          }

          if (ret) {
            ret = db.tune_options(kyotocabinet::HashDB::TLINEAR);
            if (!ret) {
              print_db_error("set option failed");
            }
          }

          if (ret) {
            ret = db.tune_buckets(bucket_size);
            if (!ret) {
              print_db_error("set bucket size failed");
            }
          }

          if (ret) {
            uint32_t mode = kyotocabinet::HashDB::OWRITER | kyotocabinet::HashDB::OCREATE |kyotocabinet::HashDB::ONOREPAIR;
            ret = db.open(filename, mode);
            if (!ret) {
              print_db_error("open kdb failed");
            }
          }
        }

        if (ret) {
          stat_mgr.start(bucket_number, data_dir);
          log_info("kdb [%d] opened", bucket_number);
        }

        return ret;
      }
Ejemplo n.º 2
0
/**
 * Returns the file_id for the specified file.
 * @param database is the structure that contains everything that is
 *        related to the database (it's connexion for instance).
 * @param meta is the file's metadata that we want to insert into the
 *        cache.
 * @returns a file_row_t structure filed with values returned by the
 *          database.
 */
static file_row_t *get_file_id(db_t *database, meta_data_t *meta)
{
    file_row_t *row = NULL;
    char *error_message = NULL;
    gchar *sql_command = NULL;
    int db_result = 0;

    row = new_file_row_t();

    sql_command = g_strdup_printf("SELECT file_id from files WHERE inode=%" G_GUINT64_FORMAT " AND name='%s' AND type=%d AND uid=%d AND gid=%d AND ctime=%" G_GUINT64_FORMAT " AND mtime=%" G_GUINT64_FORMAT " AND mode=%d AND size=%" G_GUINT64_FORMAT ";", meta->inode, meta->name, meta->file_type, meta->uid, meta->gid, meta->ctime, meta->mtime, meta->mode, meta->size);

    db_result = sqlite3_exec(database->db, sql_command, get_file_callback, row, &error_message);

    free_variable(sql_command);

    if (db_result == SQLITE_OK)
        {
           return row;
        }
    else
        {
            print_db_error(database->db, _("(%d) Error while searching into the table 'files': %s\n"), db_result, error_message);
            return NULL; /* to avoid a compilation warning as we exited with failure in print_db_error */
        }
}
Ejemplo n.º 3
0
/**
 * Returns a database connexion or NULL.
 * @param database_name is the filename of the file that contains the
 *        database
 * @result returns a db_t * filled with the database connexion or NULL
 *         in case of an error.
 */
db_t *open_database(gchar *database_name)
{
    db_t *database = NULL;
    sqlite3 *db = NULL;
    int result = 0;

    database = (db_t *) g_malloc0(sizeof(db_t));

    result = sqlite3_open(database_name, &db);

    if (result != SQLITE_OK)
        {
            print_db_error(db, _("(%d) Error while trying to open %s database: %s\n"), result, database_name, sqlite3_errmsg(db));
            free_variable(database);
            sqlite3_close(db);

            return NULL;
        }
    else
        {
            database->db = db;
            sqlite3_extended_result_codes(db, 1);
            verify_if_tables_exists(database);

            return database;
        }
}
Ejemplo n.º 4
0
/**
 * Prints out an error message if an sqlite function just made one.
 * @param db is the concerned sqlite database
 * @param result is the result of the sqlite function
 * @param infos is a gchar * containing some context to help understanding
 *        the error.
 * @note sqlite3_errstr needs at least sqlite 3.7.15
 */
static void print_on_db_error(sqlite3 *db, int result, const gchar *infos)
{
    const char *message = NULL;
    int errcode = 0;

    if (result == SQLITE_ERROR)
        {
            errcode = sqlite3_extended_errcode(db);
            message = sqlite3_errstr(errcode);
            print_db_error(db, _("sqlite error (%d - %d) on %s: %s\n"), result, errcode, infos, message);
        }
}
Ejemplo n.º 5
0
/**
 * Prints out an error message if an sqlite function just made one.
 * @param db is the concerned sqlite database
 * @param result is the result of the sqlite function
 * @param infos is a gchar * containing some context to help understanding
 *        the error.
 * @note sqlite3_errstr needs at least sqlite 3.7.15
 */
static void print_on_db_error(sqlite3 *db, int result, const gchar *infos)
{
    const char *message = NULL;
    int errcode = 0;

    if (result == SQLITE_ERROR && db != NULL)
        {
            /** @note sqlite3_errstr needs at least sqlite 3.7.15 */
            errcode = sqlite3_extended_errcode(db);
            message = sqlite3_errstr(errcode);
            print_db_error(_("sqlite error (%d - %d) on %s: %s\n"), result, errcode, infos, message);
        }
}
Ejemplo n.º 6
0
      int kdb_bucket::remove(common::data_entry& key, bool version_care)
      {
        int rc = TAIR_RETURN_SUCCESS;

        int stat_data_size = 0;

        int li = util::string_util::mur_mur_hash(key.get_data(), key.get_size()) % LOCKER_SIZE;
        if(!locks->lock(li, true)) {
          log_error("acquire lock failed");
          return TAIR_RETURN_FAILED;
        }

        if (rc == TAIR_RETURN_SUCCESS) {
          size_t val_size = 0;
          char* old_value = db.get(key.get_data(), key.get_size(), &val_size);
          if (old_value == NULL) {
            rc = TAIR_RETURN_DATA_NOT_EXIST;
          } else {
            kdb_item item;
            item.full_value = old_value;
            item.full_value_size = val_size;
            stat_data_size = val_size + key.get_size();
            item.decode();

            if (version_care && key.data_meta.version != 0
                && key.data_meta.version != item.meta.version) {
              rc = TAIR_RETURN_VERSION_ERROR;
            }

            delete [] old_value;
          }
        }

        if (rc == TAIR_RETURN_SUCCESS) {
          int dc = db.remove(key.get_data(), key.get_size());
          if (dc < 0) {
            print_db_error("remove item failed");
            rc = TAIR_RETURN_FAILED;
          }

          if (rc == TAIR_RETURN_SUCCESS) {
            stat_mgr.stat_sub(key.area, stat_data_size, stat_data_size);
          }
        }

        locks->unlock(li);

        return rc;
      }
Ejemplo n.º 7
0
/**
 * Executes the SQL command onto the database without any callback
 * @param database : the db_t * structure that contains the database connexion
 * @param sql_cmd : a gchar * SQL command to be executed onto the database
 * @param format_message : a gchar * format message to be used in case of an error
 */
static void exec_sql_cmd(db_t *database, gchar *sql_cmd, gchar *format_message)
{
    char *error_message = NULL;
    const char *message = NULL;
    int result = 0;

    result = sqlite3_exec(database->db, sql_cmd, NULL, 0, &error_message);

    if (result != SQLITE_OK)
        {
            result = sqlite3_extended_errcode(database->db);
            /* sqlite3_errstr needs at least sqlite 3.7.15 */
            message = sqlite3_errstr(result);
            print_db_error(database->db, format_message, result, message);
        }
}
Ejemplo n.º 8
0
      bool kdb_bucket::begin_scan() {
        if (cursor != NULL) {
          delete cursor;
        }

        cursor = db.cursor(); // open the cursor
        bool ret = cursor->jump(); // jump to the first record
        if (ret == false) {
          const kyotocabinet::BasicDB::Error& err = db.error();
          if (err == kyotocabinet::BasicDB::Error::NOREC) {
            ret = true;
          } else {
            print_db_error("begin scan error");
          }
        }
        return ret;
      }
Ejemplo n.º 9
0
/**
 * Returns a database connexion or NULL.
 * @param dirname is the name of the directory where the database is
 *        located.
 * @param filename is the filename of the file that contains the
 *        database
 * @result returns a db_t * filled with the database connexion or NULL
 *         in case of an error.
 */
db_t *open_database(gchar *dirname, gchar *filename)
{
    gchar *database_name = NULL;
    db_t *database = NULL;
    sqlite3 *db = NULL;
    int result = 0;

    if (dirname != NULL && filename != NULL)
        {
            create_directory(dirname);
            database_name = g_build_filename(dirname, filename, NULL);
            result = sqlite3_open(database_name, &db);

            if (result != SQLITE_OK)
                {
                    print_db_error(_("(%d) Error while trying to open %s database: %s\n"), result, database_name, sqlite3_errmsg(db));
                    sqlite3_close(db);
                    free_variable(database_name);

                    return NULL;
                }
            else
                {
                    database = (db_t *) g_malloc0(sizeof(db_t));
                    g_assert_nonnull(database);

                    database->version_filename = g_strdup_printf("%s.version", database_name);
                    database->db = db;
                    sqlite3_extended_result_codes(db, 1);

                    verify_if_tables_exists(database);
                    database->stmts = new_stmts(db);
                    database->version = get_database_version(database->version_filename, KN_CLIENT_DATABASE);
                    migrate_schema_if_needed(database);

                    free_variable(database_name);

                    return database;
                }
        }
    else
        {
            return NULL;
        }
}
Ejemplo n.º 10
0
/**
 * Executes the SQL command onto the database without any callback
 * @param database : the db_t * structure that contains the database connexion
 * @param sql_cmd : a gchar * SQL command to be executed onto the database
 * @param format_message : a gchar * format message to be used in case of an error
 */
static int exec_sql_cmd(db_t *database, gchar *sql_cmd, gchar *format_message)
{
    char *error_message = NULL;
    const char *message = NULL;
    int result = 0;
    int errcode = 0;

    if (database != NULL && database->db != NULL)
        {
            result = sqlite3_exec(database->db, sql_cmd, NULL, 0, &error_message);

            if (result != SQLITE_OK)
                {
                    /** @note sqlite3_errstr needs at least sqlite 3.7.15 */
                    errcode = sqlite3_extended_errcode(database->db);
                    message = sqlite3_errstr(result);
                    print_db_error(format_message, result, errcode, message);
                }
        }

    return result;
}
Ejemplo n.º 11
0
/**
 * Migrates or does changes on sql schema where needed
 * @param database is the structure that contains everything that is
 *        related to the database (it's connexion for instance).
 */
static void migrate_schema_if_needed(db_t *database)
{
    if (database != NULL && database->version == 1)
        {
            /* First version is OK and there is nothing to do with that */
        }
    else if (database != NULL && database->version >= 1 && database->version < DATABASE_SCHEMA_VERSION)
        {
            fprintf(stdout, _("Warning database version is not correct: %ld but expected: %d\n"), database->version, DATABASE_SCHEMA_VERSION);
            fprintf(stdout, _("Now trying to migrate from %ld to %d\n"), database->version, DATABASE_SCHEMA_VERSION);

            /* Here should go the code to migrate from on version to another one
             * in an incremental way.
             */

            exit(EXIT_FAILURE);
        }
    else if (database != NULL)
        {
            print_db_error(_("Error database version is not correct: %ld but expected between 2 and %d\n"), database->version, DATABASE_SCHEMA_VERSION);
            exit(EXIT_FAILURE);
        }
}
Ejemplo n.º 12
0
 void kdb_bucket::stop()
 {
   if (!db.close()) {
     print_db_error("close kdb failed");
   }
 }
Ejemplo n.º 13
0
      int kdb_bucket::put(common::data_entry& key, common::data_entry& value, bool version_care, uint32_t expire_time)
      {
        kdb_item item;

        int cdate = 0;
        int mdate = 0;
        int edate = 0;
        int stat_data_size = 0;

        if(key.data_meta.cdate == 0 || version_care) {
          cdate = time(NULL);
          mdate = cdate;
          if(expire_time > 0)
            edate = expire_time > static_cast<uint32_t>(mdate) ? expire_time : mdate + expire_time;
        } else {
          cdate = key.data_meta.cdate;
          mdate = key.data_meta.mdate;
          edate = key.data_meta.edate;
        }

        int rc = TAIR_RETURN_SUCCESS;

        int li = util::string_util::mur_mur_hash(key.get_data(), key.get_size()) % LOCKER_SIZE;
        if(!locks->lock(li, true)) {
          log_error("acquire lock failed");
          return TAIR_RETURN_FAILED;
        }

        size_t val_size = 0;
        char* old_value = db.get(key.get_data(), key.get_size(), &val_size);
        if (old_value != NULL) {
          // key already exist
          item.full_value = old_value;
          item.full_value_size = val_size;
          item.decode();
          cdate = item.meta.cdate; // set back the create time

          if (item.is_expired()) {
            item.meta.version = 0;
          } else if (version_care) {
            // item is not expired & care version, check version
            if (key.data_meta.version != 0
                && key.data_meta.version != item.meta.version) {
              rc = TAIR_RETURN_VERSION_ERROR;
            }
          }
          item.full_value = NULL;
          item.full_value_size = 0;

          if (rc == TAIR_RETURN_SUCCESS) {
            stat_data_size -= val_size + key.get_size();
          }
        }

        if (old_value != NULL) {
          // free the memory ASAP
          delete [] old_value;
        }

        if (rc == TAIR_RETURN_SUCCESS) {
          item.meta.flag = value.data_meta.flag;
          item.meta.cdate = cdate;
          item.meta.mdate = mdate;
          item.meta.edate = edate;
          if (version_care) {
            item.meta.version++;
          } else {
            item.meta.version = key.data_meta.version;
          }

          item.value = value.get_data();
          item.value_size = value.get_size();

          item.encode();
          stat_data_size += item.full_value_size + key.get_size();
          
          int dc = db.set(key.get_data(), key.get_size(), item.full_value, item.full_value_size);
          item.free_full_value(); // free encoded value
            
          //update key's meta info
          key.data_meta.flag = item.meta.flag;
          key.data_meta.cdate = item.meta.cdate;
          key.data_meta.edate = item.meta.edate;
          key.data_meta.mdate = item.meta.mdate;
          key.data_meta.version = item.meta.version;
          key.data_meta.keysize = key.get_size();
          key.data_meta.valsize = item.value_size;
 
          if (dc < 0) {
            print_db_error("update item failed");
            rc = TAIR_RETURN_FAILED;
          }

          if (rc == TAIR_RETURN_SUCCESS) {
            stat_mgr.stat_add(key.area, stat_data_size, stat_data_size);
          }
        }

        locks->unlock(li);

        return rc;
      }