diff options
Diffstat (limited to 'libglusterfs/src/gfdb/gfdb_sqlite3_helper.c')
| -rw-r--r-- | libglusterfs/src/gfdb/gfdb_sqlite3_helper.c | 197 | 
1 files changed, 159 insertions, 38 deletions
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c index 426fab0333e..e0a8b9c9803 100644 --- a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c +++ b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c @@ -1106,84 +1106,205 @@ gf_sql_query_function (sqlite3_stmt              *prep_stmt,                        gf_query_callback_t       query_callback,                        void                      *_query_cbk_args)  { -        int ret = -1; -        gfdb_query_record_t *gfdb_query_record = NULL; -        char *text_column = NULL; -        sqlite3 *db_conn = NULL; +        int ret                                         = -1; +        gfdb_query_record_t *query_record               = NULL; +        char *text_column                               = NULL; +        sqlite3 *db_conn                                = NULL; +        uuid_t  prev_gfid                               = {0}; +        uuid_t  curr_gfid                               = {0}; +        uuid_t  pgfid                                   = {0}; +        char *base_name                                 = NULL; +        gf_boolean_t is_first_record                    = _gf_true; +        gf_boolean_t is_query_empty                     = _gf_true;          GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, prep_stmt, out);          GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, query_callback, out);          db_conn = sqlite3_db_handle(prep_stmt); -        gfdb_query_record = gfdb_query_record_init (); -        if (!gfdb_query_record) { -                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, -                                LG_MSG_CREATE_FAILED, "Failed to create " -                                "gfdb_query_record"); -                                goto out; -        } - -        /*Loop to access queried rows*/ +        /* +         * Loop to access queried rows +         * Each db record will have 3 columns +         * GFID, PGFID, FILE_NAME +         * +         * For file with multiple hard links we will get multiple query rows +         * with the same GFID, but different PGID and FILE_NAME Combination +         * For Example if a file with +         *         GFID = 00000000-0000-0000-0000-000000000006 +         * has 3 hardlinks file1, file2 and file3 in 3 different folder +         * with GFID's +         * 00000000-0000-0000-0000-0000EFC00001, +         * 00000000-0000-0000-0000-00000ABC0001 and +         * 00000000-0000-0000-0000-00000ABC00CD +         * Then there will be 3 records +         *         GFID         : 00000000-0000-0000-0000-000000000006 +         *         PGFID        : 00000000-0000-0000-0000-0000EFC00001 +         *         FILE_NAME    : file1 +         * +         *         GFID         : 00000000-0000-0000-0000-000000000006 +         *         PGFID        : 00000000-0000-0000-0000-00000ABC0001 +         *         FILE_NAME    : file2 +         * +         *         GFID         : 00000000-0000-0000-0000-000000000006 +         *         PGFID        : 00000000-0000-0000-0000-00000ABC00CD +         *         FILE_NAME    : file3 +         * +         * This is retrieved and added to a single query_record +         * +         * query_record->gfid = 00000000-0000-0000-0000-000000000006 +         *                  ->link_info = {00000000-0000-0000-0000-0000EFC00001, +         *                                 "file1"} +         *                                  | +         *                                  V +         *             link_info = {00000000-0000-0000-0000-00000ABC0001, +         *                                 "file2"} +         *                                  | +         *                                  V +         *             link_info = {00000000-0000-0000-0000-00000ABC0001, +         *                                 "file3", +         *                                 list} +         * +         * This query record is sent to the registered query_callback() +         * +         * */          while ((ret = sqlite3_step (prep_stmt)) == SQLITE_ROW) { -                /*Clear the query record*/ -                memset (gfdb_query_record, 0, sizeof(*gfdb_query_record)); -                  if (sqlite3_column_count(prep_stmt) > 0) { -                        /*Retriving GFID - column index is 0*/ +                        is_query_empty = _gf_false; + +                        /*Retrieving GFID - column index is 0*/                          text_column = (char *)sqlite3_column_text                                                          (prep_stmt, 0);                          if (!text_column) {                                  gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, -                                        LG_MSG_GET_ID_FAILED, "Failed " -                                        "retriving GF_ID"); +                                        LG_MSG_GET_ID_FAILED, "Failed to" +                                        "retrieve GFID"); +                                goto out; +                        } +                        ret = gf_uuid_parse (text_column, curr_gfid); +                        if (ret) { +                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, +                                        LG_MSG_PARSE_FAILED, "Failed to parse " +                                        "GFID"); +                                goto out; +                        } + +                        /* +                         * if the previous record was not of the current gfid +                         * call the call_back function and send the +                         * query record, which will have all the link_info +                         * objects associated with this gfid +                         * +                         * */ +                        if (gf_uuid_compare (curr_gfid, prev_gfid) != 0) { + +                                /* If this is not the first record */ +                                if (!is_first_record) { +                                        /*Call the call_back function provided*/ +                                        ret = query_callback (query_record, +                                                        _query_cbk_args); +                                        if (ret) { +                                                gf_msg (GFDB_STR_SQLITE3, +                                                        GF_LOG_ERROR, 0, +                                                LG_MSG_QUERY_CALL_BACK_FAILED, +                                                        "Query call back " +                                                        "failed"); +                                                goto out; +                                        } + +                                } + +                                /*Clear the query record*/ +                                gfdb_query_record_free (query_record); +                                query_record = NULL; +                                query_record = gfdb_query_record_new (); +                                if (!query_record) { +                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                                0, LG_MSG_CREATE_FAILED, +                                                "Failed to create " +                                                "query_record"); +                                        goto out; +                                } + +                                gf_uuid_copy(query_record->gfid, +                                                                curr_gfid); +                                gf_uuid_copy(prev_gfid, curr_gfid); + +                        } + +                        /* Get PGFID */ +                        text_column = (char *)sqlite3_column_text +                                                        (prep_stmt, 1); +                        if (!text_column) { +                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, +                                        LG_MSG_GET_ID_FAILED, "Failed to" +                                        " retrieve GF_ID");                                  goto out;                          } -                        ret = gf_uuid_parse (text_column, gfdb_query_record->gfid); +                        ret = gf_uuid_parse (text_column, pgfid);                          if (ret) {                                  gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, -                                        LG_MSG_PARSE_FAILED, "Failed parsing " +                                        LG_MSG_PARSE_FAILED, "Failed to parse "                                          "GF_ID");                                  goto out;                          } -                        /*Retrive Link Buffer - column index 1*/ +                        /* Get Base name */                          text_column = (char *)sqlite3_column_text -                                                (prep_stmt, 1); -                        /* Get link string. Do shallow copy here -                         * query_callback function should do a -                         * deep copy and then do operations on this field*/ -                        gfdb_query_record->_link_info_str = text_column; -                        gfdb_query_record->link_info_size = strlen -                                                                (text_column); - -                        /* Call the call back function provided*/ -                        ret = query_callback (gfdb_query_record, -                                                        _query_cbk_args); +                                                        (prep_stmt, 2); +                        if (!text_column) { +                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, +                                        LG_MSG_GET_ID_FAILED, "Failed to" +                                        " retrieve GF_ID"); +                                goto out; +                        } +                        base_name = text_column; + + +                        /* Add link info to the list */ +                        ret = gfdb_add_link_to_query_record (query_record, +                                                         pgfid, base_name);                          if (ret) {                                  gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, -                                        LG_MSG_QUERY_CALL_BACK_FAILED, -                                        "Query Call back failed!"); +                                        LG_MSG_GET_ID_FAILED, "Failed to" +                                        " add link info to query record");                                  goto out;                          } +                        is_first_record = _gf_false; +                  }          }          if (ret != SQLITE_DONE) {                  gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, -                        LG_MSG_GET_RECORD_FAILED, "Failed retriving records " +                        LG_MSG_GET_RECORD_FAILED, "Failed to retrieve records "                          "from db : %s", sqlite3_errmsg (db_conn));                  ret = -1;                  goto out;          } + +        if (!is_query_empty) { +                /* +                 * Call the call_back function for the last record from the +                 * Database +                 * */ +                ret = query_callback (query_record, _query_cbk_args); +                if (ret) { +                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, +                                LG_MSG_QUERY_CALL_BACK_FAILED, +                                "Query call back failed"); +                        goto out; +                } +        } +          ret = 0;  out: -        gfdb_query_record_fini (&gfdb_query_record); +        gfdb_query_record_free (query_record); +        query_record = NULL;          return ret;  } @@ -1207,7 +1328,7 @@ gf_sql_clear_counters (gf_sql_connection_t *sql_conn)                                  &sql_strerror);          if (ret != SQLITE_OK) {                  gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED, -                        "Failed executing: %s : %s", +                        "Failed to execute: %s : %s",                          query_str, sql_strerror);                  sqlite3_free (sql_strerror);                          ret = -1;  | 
