Esempio n. 1
0
static int database_info_list_iterate_found_match(
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *zip_name
      )
{
   char db_crc[PATH_MAX_LENGTH]                = {0};
   char db_playlist_path[PATH_MAX_LENGTH]      = {0};
   char  db_playlist_base_str[PATH_MAX_LENGTH] = {0};
   char entry_path_str[PATH_MAX_LENGTH]        = {0};
   content_playlist_t   *playlist = NULL;
   settings_t           *settings = config_get_ptr();
   const char            *db_path = db_state->list->elems[db_state->list_index].data;
   const char         *entry_path = db ? db->list->elems[db->list_ptr].data : NULL;
   database_info_t *db_info_entry = &db_state->info->list[db_state->entry_index];

   fill_short_pathname_representation(db_playlist_base_str,
         db_path, sizeof(db_playlist_base_str));

   path_remove_extension(db_playlist_base_str);

   strlcat(db_playlist_base_str, ".lpl", sizeof(db_playlist_base_str));
   fill_pathname_join(db_playlist_path, settings->playlist_directory,
         db_playlist_base_str, sizeof(db_playlist_path));

   playlist = content_playlist_init(db_playlist_path, COLLECTION_SIZE);


   snprintf(db_crc, sizeof(db_crc), "%08X|crc", db_info_entry->crc32);

   strlcpy(entry_path_str, entry_path, sizeof(entry_path_str));

   if (zip_name && zip_name[0] != '\0')
      fill_pathname_join_delim(entry_path_str, entry_path_str, zip_name,
            '#', sizeof(entry_path_str));

#if 0
   RARCH_LOG("Found match in database !\n");

   RARCH_LOG("Path: %s\n", db_path);
   RARCH_LOG("CRC : %s\n", db_crc);
   RARCH_LOG("Playlist Path: %s\n", db_playlist_path);
   RARCH_LOG("Entry Path: %s\n", entry_path);
   RARCH_LOG("Playlist not NULL: %d\n", playlist != NULL);
   RARCH_LOG("ZIP entry: %s\n", zip_name);
   RARCH_LOG("entry path str: %s\n", entry_path_str);
#endif

   content_playlist_push(playlist, entry_path_str,
         db_info_entry->name, "DETECT", "DETECT", db_crc, db_playlist_base_str);

   content_playlist_write_file(playlist);
   content_playlist_free(playlist);

   database_info_list_free(db_state->info);
   db_state->info = NULL;
   db_state->crc  = 0;

   return 0;
}
Esempio n. 2
0
static int task_database_iterate_serial_lookup(
    database_state_handle_t *db_state,
    database_info_handle_t *db, const char *name)
{
    if (!db_state->list ||
            (unsigned)db_state->list_index == (unsigned)db_state->list->size)
        return database_info_list_iterate_end_no_match(db_state);

    if (db_state->entry_index == 0)
    {
        char query[50];
        char *serial_buf =
            bin_to_hex_alloc((uint8_t*)db_state->serial, 10 * sizeof(uint8_t));

        if (!serial_buf)
            return 1;

        query[0] = '\0';

        snprintf(query, sizeof(query), "{'serial': b'%s'}", serial_buf);
        database_info_list_iterate_new(db_state, query);

        free(serial_buf);
    }

    if (db_state->info)
    {
        database_info_t *db_info_entry = &db_state->info->list[
                                             db_state->entry_index];

        if (db_info_entry && db_info_entry->serial)
        {
#if 0
            RARCH_LOG("serial: %s , entry serial: %s (%s).\n",
                      db_state->serial, db_info_entry->serial,
                      db_info_entry->name);
#endif
            if (string_is_equal(db_state->serial, db_info_entry->serial))
                return database_info_list_iterate_found_match(db_state, db, NULL);
        }
    }

    db_state->entry_index++;

    if (db_state->info)
    {
        if (db_state->entry_index >= db_state->info->count)
            return database_info_list_iterate_next(db_state);
    }

    /* If we haven't reached the end of the database list yet,
     * continue iterating. */
    if (db_state->list_index < db_state->list->size)
        return 1;

    database_info_list_free(db_state->info);
    free(db_state->info);
    return 0;
}
Esempio n. 3
0
static int task_database_iterate_crc_lookup(
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *zip_entry)
{

   if (!db_state->list || 
         (unsigned)db_state->list_index == (unsigned)db_state->list->size)
      return database_info_list_iterate_end_no_match(db_state);

   if (db_state->entry_index == 0)
   {
      char query[50] = {0};
      snprintf(query, sizeof(query),
            "{crc:or(b\"%08X\",b\"%08X\")}",
            swap_if_big32(db_state->crc), swap_if_big32(db_state->zip_crc));

      database_info_list_iterate_new(db_state, query);
   }

   if (db_state->info)
   {
      database_info_t *db_info_entry = 
         &db_state->info->list[db_state->entry_index];

      if (db_info_entry && db_info_entry->crc32)
      {
#if 0
         RARCH_LOG("CRC32: 0x%08X , entry CRC32: 0x%08X (%s).\n",
               db_state->crc, db_info_entry->crc32, db_info_entry->name);
#endif
         if (db_state->zip_crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  db_state, db, NULL);
         if (db_state->crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  db_state, db, zip_entry);
      }
   }

   db_state->entry_index++;

   if (db_state->info)
   {
      if (db_state->entry_index >= db_state->info->count)
         return database_info_list_iterate_next(db_state);
   }

   /* If we haven't reached the end of the database list yet,
    * continue iterating. */
   if (db_state->list_index < db_state->list->size)
      return 1;

   database_info_list_free(db_state->info);
   return 0;
}
Esempio n. 4
0
database_info_list_t *database_info_list_new(
      const char *rdb_path, const char *query)
{
   libretrodb_t db;
   libretrodb_cursor_t cur;
   int ret                                  = 0;
   unsigned k                               = 0;
   database_info_t *database_info           = NULL;
   database_info_list_t *database_info_list = NULL;

   if ((database_cursor_open(&db, &cur, rdb_path, query) != 0))
      return NULL;

   database_info_list = (database_info_list_t*)
      calloc(1, sizeof(*database_info_list));

   if (!database_info_list)
      goto end;

   while (ret != -1)
   {
      database_info_t db_info = {0};
      ret = database_cursor_iterate(&cur, &db_info);

      if (ret == 0)
      {
         database_info_t *db_ptr = NULL;
         database_info = (database_info_t*)
            realloc(database_info, (k+1) * sizeof(database_info_t));

         if (!database_info)
         {
            database_info_list_free(database_info_list);
            database_info_list = NULL;
            goto end;
         }

         db_ptr = &database_info[k];

         if (!db_ptr)
            continue;

         memcpy(db_ptr, &db_info, sizeof(*db_ptr));

         k++;
      }
   } 

   database_info_list->list  = database_info;
   database_info_list->count = k;

end:
   database_cursor_close(&db, &cur);

   return database_info_list;
}
Esempio n. 5
0
/* End of entries in database info list and didn't find a 
 * match, go to the next database. */
static int database_info_list_iterate_next(
      database_state_handle_t *db_state
      )
{
   db_state->list_index++;
   db_state->entry_index = 0;

   database_info_list_free(db_state->info);
   db_state->info        = NULL;

   return 1;
}
Esempio n. 6
0
static int database_info_list_iterate_new(database_state_handle_t *db_state, const char *query)
{
   const char *new_database = db_state->list->elems[db_state->list_index].data;
#if 0
   RARCH_LOG("Check database [%d/%d] : %s\n", (unsigned)db_state->list_index, 
         (unsigned)db_state->list->size, new_database);
#endif
   if (db_state->info)
      database_info_list_free(db_state->info);
   db_state->info = database_info_list_new(new_database, query);
   return 0;
}
Esempio n. 7
0
static int database_info_list_iterate_new(database_state_handle_t *db_state,
      const char *query)
{
   const char *new_database = database_info_get_current_name(db_state);

#ifndef RARCH_INTERNAL
   fprintf(stderr, "Check database [%d/%d] : %s\n", (unsigned)db_state->list_index,
         (unsigned)db_state->list->size, new_database);
#endif
   if (db_state->info)
   {
      database_info_list_free(db_state->info);
      free(db_state->info);
   }
   db_state->info = database_info_list_new(new_database, query);
   return 0;
}
Esempio n. 8
0
static int database_info_iterate_serial_lookup(
      database_state_handle_t *db_state,
      database_info_handle_t *db, const char *name)
{
   if (!db_state->list || (unsigned)db_state->list_index == (unsigned)db_state->list->size)
      return database_info_list_iterate_end_no_match(db_state);

   if (db_state->entry_index == 0)
   {
      char query[50] = {0};
      snprintf(query, sizeof(query), "{'serial': '%s'}", db_state->serial);

      database_info_list_iterate_new(db_state, query);
   }

   if (db_state->info)
   {
      database_info_t *db_info_entry = &db_state->info->list[db_state->entry_index];

      if (db_info_entry && db_info_entry->serial)
      {
#if 1
         RARCH_LOG("serial: %s , entry serial: %s (%s).\n",
                   db_state->serial, db_info_entry->serial, db_info_entry->name);
#endif
         if (db_state->serial == db_info_entry->serial)
            database_info_list_iterate_found_match(db_state, db, NULL);
      }
   }

   db_state->entry_index++;

   if (db_state->entry_index >= db_state->info->count)
      return database_info_list_iterate_next(db_state);

   if (db_state->list_index < db_state->list->size)
   {
      /* Didn't reach the end of the database list yet,
       * continue iterating. */
      return 1;
   }

   if (db_state->info)
      database_info_list_free(db_state->info);
   return 0;
}
Esempio n. 9
0
static int task_database_iterate_crc_lookup(
      db_handle_t *_db,
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *name,
      const char *archive_entry)
{

   if (!db_state->list ||
         (unsigned)db_state->list_index == (unsigned)db_state->list->size)
      return database_info_list_iterate_end_no_match(db, db_state, name);

   if (db_state->entry_index == 0)
   {
      char query[50];

      query[0] = '\0';

      /* don't scan files that can't be in this database */
      if (!(path_contains_compressed_file(name) &&
         core_info_database_match_archive_member(
         db_state->list->elems[db_state->list_index].data)) &&
          !core_info_database_supports_content_path(
         db_state->list->elems[db_state->list_index].data, name))
         return database_info_list_iterate_next(db_state);

      snprintf(query, sizeof(query),
            "{crc:or(b\"%08X\",b\"%08X\")}",
            db_state->crc, db_state->archive_crc);

      database_info_list_iterate_new(db_state, query);
   }

   if (db_state->info)
   {
      database_info_t *db_info_entry =
         &db_state->info->list[db_state->entry_index];

      if (db_info_entry && db_info_entry->crc32)
      {
#if 0
         RARCH_LOG("CRC32: 0x%08X , entry CRC32: 0x%08X (%s).\n",
               db_state->crc, db_info_entry->crc32, db_info_entry->name);
#endif
         if (db_state->archive_crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  _db,
                  db_state, db, NULL);
         if (db_state->crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  _db,
                  db_state, db, archive_entry);
      }
   }

   db_state->entry_index++;

   if (db_state->info)
   {
      if (db_state->entry_index >= db_state->info->count)
         return database_info_list_iterate_next(db_state);
   }

   /* If we haven't reached the end of the database list yet,
    * continue iterating. */
   if (db_state->list_index < db_state->list->size)
      return 1;

   database_info_list_free(db_state->info);

   if (db_state->info)
      free(db_state->info);

   return 0;
}
Esempio n. 10
0
static int database_info_list_iterate_found_match(
      db_handle_t *_db,
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *archive_name
      )
{
   char *db_crc                   = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *db_playlist_base_str     = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *db_playlist_path         = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *entry_path_str           = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   playlist_t   *playlist         = NULL;
   const char         *db_path    =
      database_info_get_current_name(db_state);
   const char         *entry_path =
      database_info_get_current_element_name(db);
   database_info_t *db_info_entry =
      &db_state->info->list[db_state->entry_index];
   char *hash;

   db_crc[0]                      = '\0';
   db_playlist_path[0]            = '\0';
   db_playlist_base_str[0]        = '\0';
   entry_path_str[0]              = '\0';

   fill_short_pathname_representation_noext(db_playlist_base_str,
         db_path, PATH_MAX_LENGTH * sizeof(char));

   strlcat(db_playlist_base_str,
         file_path_str(FILE_PATH_LPL_EXTENSION),
         PATH_MAX_LENGTH * sizeof(char));

   if (!string_is_empty(_db->playlist_directory))
      fill_pathname_join(db_playlist_path, _db->playlist_directory,
            db_playlist_base_str, PATH_MAX_LENGTH * sizeof(char));

   playlist = playlist_init(db_playlist_path, COLLECTION_SIZE);

   snprintf(db_crc, PATH_MAX_LENGTH * sizeof(char),
         "%08X|crc", db_info_entry->crc32);

   if (entry_path)
      strlcpy(entry_path_str, entry_path, PATH_MAX_LENGTH * sizeof(char));

   if (!string_is_empty(archive_name))
      fill_pathname_join_delim(entry_path_str,
            entry_path_str, archive_name,
            '#', PATH_MAX_LENGTH * sizeof(char));

   if (core_info_database_match_archive_member(
         db_state->list->elems[db_state->list_index].data) &&
       (hash = strchr(entry_path_str, '#')))
       *hash = '\0';

#if defined(RARCH_INTERNAL)
#if 0
   RARCH_LOG("Found match in database !\n");

   RARCH_LOG("Path: %s\n", db_path);
   RARCH_LOG("CRC : %s\n", db_crc);
   RARCH_LOG("Playlist Path: %s\n", db_playlist_path);
   RARCH_LOG("Entry Path: %s\n", entry_path);
   RARCH_LOG("Playlist not NULL: %d\n", playlist != NULL);
   RARCH_LOG("ZIP entry: %s\n", archive_name);
   RARCH_LOG("entry path str: %s\n", entry_path_str);
#endif
#else
   fprintf(stderr, "Found match in database !\n");

   fprintf(stderr, "Path: %s\n", db_path);
   fprintf(stderr, "CRC : %s\n", db_crc);
   fprintf(stderr, "Playlist Path: %s\n", db_playlist_path);
   fprintf(stderr, "Entry Path: %s\n", entry_path);
   fprintf(stderr, "Playlist not NULL: %d\n", playlist != NULL);
   fprintf(stderr, "ZIP entry: %s\n", archive_name);
   fprintf(stderr, "entry path str: %s\n", entry_path_str);
#endif

   if(!playlist_entry_exists(playlist, entry_path_str, db_crc))
   {
      playlist_push(playlist, entry_path_str,
            db_info_entry->name,
            file_path_str(FILE_PATH_DETECT),
            file_path_str(FILE_PATH_DETECT),
            db_crc, db_playlist_base_str);
   }

   playlist_write_file(playlist);
   playlist_free(playlist);

   database_info_list_free(db_state->info);
   free(db_state->info);

   db_state->info = NULL;
   db_state->crc  = 0;

   free(entry_path_str);
   free(db_playlist_path);
   free(db_playlist_base_str);
   free(db_crc);

   /* Move database to start since we are likely to match against it
      again */
   if (db_state->list_index != 0)
   {
      struct string_list_elem entry = db_state->list->elems[db_state->list_index];
      memmove(&db_state->list->elems[1],
              &db_state->list->elems[0],
              sizeof(entry) * db_state->list_index);
      db_state->list->elems[0] = entry;
   }

   return 0;
}
Esempio n. 11
0
database_info_list_t *database_info_list_new(
      const char *rdb_path, const char *query)
{
   int ret                                  = 0;
   unsigned k                               = 0;
   database_info_t *database_info           = NULL;
   database_info_list_t *database_info_list = NULL;
   libretrodb_t *db                         = libretrodb_new();
   libretrodb_cursor_t *cur                 = libretrodb_cursor_new();

   if (!db || !cur)
      goto end;

   if ((database_cursor_open(db, cur, rdb_path, query) != 0))
      goto end;

   database_info_list = (database_info_list_t*)
      malloc(sizeof(*database_info_list));

   if (!database_info_list)
      goto end;

   database_info_list->count  = 0;
   database_info_list->list   = NULL;

   while (ret != -1)
   {
      database_info_t db_info = {0};
      ret = database_cursor_iterate(cur, &db_info);

      if (ret == 0)
      {
         database_info_t *db_ptr  = NULL;
         database_info_t *new_ptr = (database_info_t*)
            realloc(database_info, (k+1) * sizeof(database_info_t));

         if (!new_ptr)
         {
            if (db_info.bbfc_rating)
               free(db_info.bbfc_rating);
            if (db_info.cero_rating)
               free(db_info.cero_rating);
            if (db_info.description)
               free(db_info.description);
            if (db_info.edge_magazine_review)
               free(db_info.edge_magazine_review);
            if (db_info.elspa_rating)
               free(db_info.elspa_rating);
            if (db_info.enhancement_hw)
               free(db_info.enhancement_hw);
            if (db_info.esrb_rating)
               free(db_info.esrb_rating);
            if (db_info.franchise)
               free(db_info.franchise);
            if (db_info.genre)
               free(db_info.genre);
            if (db_info.name)
               free(db_info.name);
            if (db_info.origin)
               free(db_info.origin);
            if (db_info.pegi_rating)
               free(db_info.pegi_rating);
            if (db_info.publisher)
               free(db_info.publisher);
            if (db_info.rom_name)
               free(db_info.rom_name);
            if (db_info.serial)
               free(db_info.serial);
            database_info_list_free(database_info_list);
            free(database_info);
            free(database_info_list);
            database_info_list = NULL;
            goto end;
         }

         database_info = new_ptr;
         db_ptr        = &database_info[k];

         memcpy(db_ptr, &db_info, sizeof(*db_ptr));

         k++;
      }
   }

   database_info_list->list  = database_info;
   database_info_list->count = k;

end:
   if (db)
   {
      database_cursor_close(db, cur);
      libretrodb_free(db);
   }
   if (cur)
      libretrodb_cursor_free(cur);

   return database_info_list;
}
Esempio n. 12
0
static int database_info_list_iterate_found_match(
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *zip_name
      )
{
   char db_crc[PATH_MAX_LENGTH]                = {0};
   char db_playlist_path[PATH_MAX_LENGTH]      = {0};
   char  db_playlist_base_str[PATH_MAX_LENGTH] = {0};
   char entry_path_str[PATH_MAX_LENGTH]        = {0};
   playlist_t   *playlist                      = NULL;
   settings_t           *settings              = config_get_ptr();
   const char            *db_path              = 
      db_state->list->elems[db_state->list_index].data;
   const char         *entry_path              = db ? 
      db->list->elems[db->list_ptr].data : NULL;
   database_info_t *db_info_entry              = 
      &db_state->info->list[db_state->entry_index];

   fill_short_pathname_representation_noext(db_playlist_base_str,
         db_path, sizeof(db_playlist_base_str));

   strlcat(db_playlist_base_str,
         file_path_str(FILE_PATH_LPL_EXTENSION),
         sizeof(db_playlist_base_str));
   fill_pathname_join(db_playlist_path, settings->directory.playlist,
         db_playlist_base_str, sizeof(db_playlist_path));

   playlist = playlist_init(db_playlist_path, COLLECTION_SIZE);


   snprintf(db_crc, sizeof(db_crc), "%08X|crc", db_info_entry->crc32);

   if (entry_path)
      strlcpy(entry_path_str, entry_path, sizeof(entry_path_str));

   if (!string_is_empty(zip_name))
      fill_pathname_join_delim(entry_path_str, entry_path_str, zip_name,
            '#', sizeof(entry_path_str));

#if 0
   RARCH_LOG("Found match in database !\n");

   RARCH_LOG("Path: %s\n", db_path);
   RARCH_LOG("CRC : %s\n", db_crc);
   RARCH_LOG("Playlist Path: %s\n", db_playlist_path);
   RARCH_LOG("Entry Path: %s\n", entry_path);
   RARCH_LOG("Playlist not NULL: %d\n", playlist != NULL);
   RARCH_LOG("ZIP entry: %s\n", zip_name);
   RARCH_LOG("entry path str: %s\n", entry_path_str);
#endif

   if(!playlist_entry_exists(playlist, entry_path_str, db_crc))
   {
      playlist_push(playlist, entry_path_str,
            db_info_entry->name,
            file_path_str(FILE_PATH_DETECT),
            file_path_str(FILE_PATH_DETECT),
            db_crc, db_playlist_base_str);
   }

   playlist_write_file(playlist);
   playlist_free(playlist);

   database_info_list_free(db_state->info);

   db_state->info = NULL;
   db_state->crc  = 0;

   return 0;
}
Esempio n. 13
0
static int database_info_list_iterate_found_match(
      db_handle_t *_db,
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *archive_name
      )
{
   char *db_crc                   = (char*)malloc(128 * sizeof(char));
   char *db_playlist_base_str     = (char*)malloc(128 * sizeof(char));
   char *db_playlist_path         = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *entry_path_str           = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   playlist_t   *playlist         = NULL;
   const char         *db_path    =
      database_info_get_current_name(db_state);
   const char         *entry_path =
      database_info_get_current_element_name(db);
   database_info_t *db_info_entry =
      &db_state->info->list[db_state->entry_index];

   db_crc[0] = '\0';
   db_playlist_path[0] = '\0';
   db_playlist_base_str[0] = '\0';
   entry_path_str[0] = '\0';

   fill_short_pathname_representation_noext(db_playlist_base_str,
         db_path, 128 * sizeof(char));

   strlcat(db_playlist_base_str,
         file_path_str(FILE_PATH_LPL_EXTENSION),
         128 * sizeof(char));
   fill_pathname_join(db_playlist_path, _db->playlist_directory,
         db_playlist_base_str, PATH_MAX_LENGTH * sizeof(char));

   playlist = playlist_init(db_playlist_path, COLLECTION_SIZE);

   snprintf(db_crc, 128 * sizeof(char),
         "%08X|crc", db_info_entry->crc32);

   if (entry_path)
      strlcpy(entry_path_str, entry_path, 128 * sizeof(char));

   if (!string_is_empty(archive_name))
      fill_pathname_join_delim(entry_path_str,
            entry_path_str, archive_name,
            '#', 128 * sizeof(char));

#if 0
   RARCH_LOG("Found match in database !\n");

   RARCH_LOG("Path: %s\n", db_path);
   RARCH_LOG("CRC : %s\n", db_crc);
   RARCH_LOG("Playlist Path: %s\n", db_playlist_path);
   RARCH_LOG("Entry Path: %s\n", entry_path);
   RARCH_LOG("Playlist not NULL: %d\n", playlist != NULL);
   RARCH_LOG("ZIP entry: %s\n", archive_name);
   RARCH_LOG("entry path str: %s\n", entry_path_str);
#endif

   if(!playlist_entry_exists(playlist, entry_path_str, db_crc))
   {
      playlist_push(playlist, entry_path_str,
            db_info_entry->name,
            file_path_str(FILE_PATH_DETECT),
            file_path_str(FILE_PATH_DETECT),
            db_crc, db_playlist_base_str);
   }

   playlist_write_file(playlist);
   playlist_free(playlist);

   database_info_list_free(db_state->info);
   free(db_state->info);

   db_state->info = NULL;
   db_state->crc  = 0;

   free(entry_path_str);
   free(db_playlist_path);
   free(db_playlist_base_str);
   free(db_crc);

   return 0;
}
Esempio n. 14
0
database_info_list_t *database_info_list_new(
      const char *rdb_path, const char *query)
{
   int ret                                  = 0;
   unsigned k                               = 0;
   database_info_t *database_info           = NULL;
   database_info_list_t *database_info_list = NULL;
   libretrodb_t *db                         = libretrodb_new();
   libretrodb_cursor_t *cur                 = libretrodb_cursor_new();

   if (!db || !cur)
      goto end;

   if ((database_cursor_open(db, cur, rdb_path, query) != 0))
      goto end;

   database_info_list = (database_info_list_t*)
      calloc(1, sizeof(*database_info_list));

   if (!database_info_list)
      goto end;

   while (ret != -1)
   {
      database_info_t db_info = {0};
      ret = database_cursor_iterate(cur, &db_info);

      if (ret == 0)
      {
         database_info_t *db_ptr  = NULL;
         database_info_t *new_ptr = (database_info_t*)
            realloc(database_info, (k+1) * sizeof(database_info_t));

         if (!new_ptr)
         {
            database_info_list_free(database_info_list);
            free(database_info);
            free(database_info_list);
            database_info_list = NULL;
            goto end;
         }

         database_info = new_ptr;
         db_ptr        = &database_info[k];

         memcpy(db_ptr, &db_info, sizeof(*db_ptr));

         k++;
      }
   }

   database_info_list->list  = database_info;
   database_info_list->count = k;

end:
   if (db)
   {
      database_cursor_close(db, cur);
      libretrodb_free(db);
   }
   if (cur)
      libretrodb_cursor_free(cur);

   return database_info_list;
}