diff options
Diffstat (limited to 'libglusterfs/src/gfdb/gfdb_sqlite3_helper.c')
| -rw-r--r-- | libglusterfs/src/gfdb/gfdb_sqlite3_helper.c | 1128 | 
1 files changed, 1128 insertions, 0 deletions
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c new file mode 100644 index 00000000000..50504181d26 --- /dev/null +++ b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c @@ -0,0 +1,1128 @@ +/* +   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ + +#include "gfdb_sqlite3_helper.h" + +/***************************************************************************** + * + *                 Helper function to execute actual sql queries + * + * + * ****************************************************************************/ + +static inline int +gf_sql_delete_all (gf_sql_connection_t *sql_conn, +                  char              *gfid) +{ +        int ret = -1; +        sqlite3_stmt *delete_file_stmt = NULL; +        sqlite3_stmt *delete_link_stmt = NULL; +        char *delete_link_str = "DELETE FROM " +                           GF_FILE_LINK_TABLE +                           " WHERE GF_ID = ? ;"; +        char *delete_file_str = "DELETE FROM " +                           GF_FILE_TABLE +                           " WHERE GF_ID = ? ;"; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); + +        /* +         * Delete all links associated with this GFID +         * +         * */ +        /*Prepare statement for delete all links*/ +        ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, delete_link_str, -1, +                                &delete_link_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing delete statment %s : %s", +                        delete_link_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (delete_link_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + +        /*Execute the prepare statement*/ +        if (sqlite3_step (delete_link_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        delete_link_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + +        /* +         * Delete entry from file table associated with this GFID +         * +         * */ +        /*Prepare statement for delete all links*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_file_str, -1, +                                &delete_file_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing delete statment %s : %s", +                        delete_file_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (delete_file_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step (delete_file_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        delete_file_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +out: +        /*Free prepared statement*/ +        sqlite3_finalize (delete_file_stmt); +        sqlite3_finalize (delete_link_stmt); +        return ret; +} + +static inline int +gf_sql_delete_link (gf_sql_connection_t  *sql_conn, +                   char                 *gfid, +                   char                 *pargfid, +                   char                 *basename) +{ +        int ret = -1; +        sqlite3_stmt *delete_stmt = NULL; +        char *delete_str = "DELETE FROM " +                           GF_FILE_LINK_TABLE +                           " WHERE GF_ID = ? AND GF_PID = ?" +                           " AND FNAME = ?;"; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out); + +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_str, -1, +                                &delete_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing delete statment %s : %s", delete_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (delete_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind pargfid*/ +        ret = sqlite3_bind_text (delete_stmt, 2, pargfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent gfid %s : %s", pargfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind basename*/ +        ret = sqlite3_bind_text (delete_stmt, 3, basename, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basename %s : %s", basename, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step(delete_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        delete_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (delete_stmt); +        return ret; +} + + + +static inline int +gf_sql_update_link_flags (gf_sql_connection_t  *sql_conn, +                   char                 *gfid, +                   char                 *pargfid, +                   char                 *basename, +                   int                  update_flag, +                   gf_boolean_t         is_update_or_delete) +{ +        int ret = -1; +        sqlite3_stmt *update_stmt = NULL; +        char *update_column = NULL; +        char update_str[1024] = ""; + + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out); + +        update_column = (is_update_or_delete) ? "LINK_UPDATE" : "W_DEL_FLAG"; + +        sprintf (update_str, "UPDATE " +                            GF_FILE_LINK_TABLE +                            " SET %s = ?" +                            " WHERE GF_ID = ? AND GF_PID = ? AND FNAME = ?;", +                            update_column); + +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1, +                                &update_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing update statment %s : %s", update_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + +        /*Bind link_update*/ +        ret = sqlite3_bind_int (update_stmt, 1, update_flag); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding update_flag %d : %s", update_flag, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (update_stmt, 2, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind pargfid*/ +        ret = sqlite3_bind_text (update_stmt, 3, pargfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent gfid %s : %s", pargfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind basename*/ +        ret = sqlite3_bind_text (update_stmt, 4, basename, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basename %s : %s", basename, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + +        /*Execute the prepare statement*/ +        if (sqlite3_step(update_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        update_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (update_stmt); +        return ret; +} + + +static inline int +gf_sql_insert_link (gf_sql_connection_t  *sql_conn, +                   char                 *gfid, +                   char                 *pargfid, +                   char                 *basename, +                   char                 *basepath) +{ +        int ret = -1; +        sqlite3_stmt *insert_stmt = NULL; +        char *insert_str = "INSERT INTO " +                           GF_FILE_LINK_TABLE +                           " (GF_ID, GF_PID, FNAME, FPATH," +                           " W_DEL_FLAG, LINK_UPDATE) " +                           " VALUES (?, ?, ?, ?, 0, 1);"; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basepath, out); + +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1, +                                &insert_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing insert statment %s : %s", insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind pargfid*/ +        ret = sqlite3_bind_text (insert_stmt, 2, pargfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent gfid %s : %s", pargfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind basename*/ +        ret = sqlite3_bind_text (insert_stmt, 3, basename, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basename %s : %s", basename, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind basepath*/ +        ret = sqlite3_bind_text (insert_stmt, 4, basepath, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basepath %s : %s", basepath, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step (insert_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (insert_stmt); +        return ret; +} + + +static inline int +gf_sql_update_link (gf_sql_connection_t  *sql_conn, +                   char                 *gfid, +                   char                 *pargfid, +                   char                 *basename, +                   char                 *basepath, +                   char                 *old_pargfid, +                   char                 *old_basename) +{ +        int ret = -1; +        sqlite3_stmt *insert_stmt = NULL; +        char *insert_str =  "INSERT INTO " +                            GF_FILE_LINK_TABLE +                            " (GF_ID, GF_PID, FNAME, FPATH," +                            " W_DEL_FLAG, LINK_UPDATE) " +                            " VALUES (? , ?, ?, ?, 0, 1);"; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basepath, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_pargfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_basename, out); + +        /* +         * +         * Delete the old link +         * +         * */ +         ret = gf_sql_delete_link (sql_conn, gfid, old_pargfid, +                                old_basename); +        if (ret) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed deleting old link"); +                goto out; +        } + +        /* +         * +         * insert new link +         * +         * */ +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1, +                                &insert_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing insert statment %s : %s", insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind new pargfid*/ +        ret = sqlite3_bind_text (insert_stmt, 2, pargfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent gfid %s : %s", pargfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind new basename*/ +        ret = sqlite3_bind_text (insert_stmt, 3, basename, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basename %s : %s", basename, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind new basepath*/ +        ret = sqlite3_bind_text (insert_stmt, 4, basepath, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding basename %s : %s", basepath, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step (insert_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + + + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (insert_stmt); +        return ret; +} + +static inline int +gf_sql_insert_write_wind_time (gf_sql_connection_t  *sql_conn, +                                char                 *gfid, +                                gfdb_time_t          *wind_time) +{ +        int ret = -1; +        sqlite3_stmt *insert_stmt = NULL; +        char *insert_str = "INSERT INTO " +                           GF_FILE_TABLE +                           "(GF_ID, W_SEC, W_MSEC, UW_SEC, UW_MSEC)" +                           " VALUES (?, ?, ?, 0, 0);"; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, wind_time, out); + + +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1, +                        &insert_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing insert statment %s : %s", insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind wind secs*/ +        ret = sqlite3_bind_int (insert_stmt, 2, wind_time->tv_sec); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent wind secs %ld : %s", +                        wind_time->tv_sec, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind wind msecs*/ +        ret = sqlite3_bind_int (insert_stmt, 3, wind_time->tv_usec); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent wind msecs %ld : %s", +                        wind_time->tv_usec, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step (insert_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        insert_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (insert_stmt); +        return ret; +} + + + +/*Update write/read times for both wind and unwind*/ +static inline int +gf_update_time (gf_sql_connection_t    *sql_conn, +                char                    *gfid, +                gfdb_time_t             *update_time, +                gf_boolean_t            record_counter, +                gf_boolean_t            is_wind, +                gf_boolean_t            is_read) +{ +        int ret = -1; +        sqlite3_stmt *update_stmt = NULL; +        char update_str[1024] = ""; +        char *freq_cntr_str = NULL; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, update_time, out); + +        /* +         * Constructing the prepare statment string. +         * +         * */ +        /*For write time*/ +        if (!is_read) { +                if (is_wind) { +                        /*if record counter is on*/ +                        freq_cntr_str = (record_counter) ? +                        ", WRITE_FREQ_CNTR = WRITE_FREQ_CNTR + 1" : ""; + +                        /*Prefectly safe as we will not go array of bound*/ +                        sprintf (update_str, "UPDATE " +                                GF_FILE_TABLE +                                " SET W_SEC = ?, W_MSEC = ? " +                                " %s"/*place for read freq counters*/ +                                " WHERE GF_ID = ? ;", freq_cntr_str); +                } else { +                        /*Prefectly safe as we will not go array of bound*/ +                        sprintf (update_str, "UPDATE " +                                GF_FILE_TABLE +                                " SET UW_SEC = ?, UW_MSEC = ? ;"); +                } +        } +        /*For Read Time update*/ +        else { +                if (is_wind) { +                        /*if record counter is on*/ +                        freq_cntr_str = (record_counter) ? +                        ", READ_FREQ_CNTR = READ_FREQ_CNTR + 1" : ""; + +                        /*Prefectly safe as we will not go array of bound*/ +                        sprintf (update_str, "UPDATE " +                                GF_FILE_TABLE +                                " SET W_READ_SEC = ?, W_READ_MSEC = ? " +                                " %s"/*place for read freq counters*/ +                                " WHERE GF_ID = ? ;", freq_cntr_str); +                } else { +                        /*Prefectly safe as we will not go array of bound*/ +                        sprintf (update_str, "UPDATE " +                                GF_FILE_TABLE +                                " SET UW_READ_SEC = ?, UW_READ_MSEC = ? ;"); +                } +        } + +        /*Prepare statement*/ +        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1, +                                &update_stmt, 0); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed preparing insert statment %s : %s", update_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind time secs*/ +        ret = sqlite3_bind_int (update_stmt, 1, update_time->tv_sec); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent wind secs %ld : %s", +                        update_time->tv_sec, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind time msecs*/ +        ret = sqlite3_bind_int (update_stmt, 2, update_time->tv_usec); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding parent wind msecs %ld : %s", +                        update_time->tv_usec, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Bind gfid*/ +        ret = sqlite3_bind_text (update_stmt, 3, gfid, -1, NULL); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed binding gfid %s : %s", gfid, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        /*Execute the prepare statement*/ +        if (sqlite3_step (update_stmt) != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing the prepared stmt %s : %s", +                        update_str, +                        sqlite3_errmsg (sql_conn->sqlite3_db_conn)); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        /*Free prepared statement*/ +        sqlite3_finalize (update_stmt); +        return ret; +} + +/****************************************************************************** + * + *                      Helper functions for gf_sqlite3_insert() + * + * + * ****************************************************************************/ + +int +gf_sql_insert_wind (gf_sql_connection_t  *sql_conn, +                   gfdb_db_record_t     *gfdb_db_record) +{ +        int ret                 = -1; +        gfdb_time_t *modtime    = NULL; +        char *pargfid_str       = NULL; +        char *gfid_str          = NULL; +        char *old_pargfid_str   = NULL; +        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/ + + + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out); + + +        gfid_str = gf_strdup (uuid_utoa (gfdb_db_record->gfid)); +        if (!gfid_str) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Creating gfid string failed."); +                goto out; +        } + +        modtime = &gfdb_db_record->gfdb_wind_change_time; + +        /* handle all dentry based operations */ +        if (isdentryfop (gfdb_db_record->gfdb_fop_type)) { +                /*Parent GFID is always set*/ +                pargfid_str = gf_strdup (uuid_utoa (gfdb_db_record->pargfid)); +                if (!pargfid_str) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Creating gfid string failed."); +                        goto out; +                } + +                /* handle create, mknod */ +                if (isdentrycreatefop (gfdb_db_record->gfdb_fop_type)) { +                        /*insert link*/ +                        ret = gf_sql_insert_link(sql_conn, +                                        gfid_str, pargfid_str, +                                        gfdb_db_record->file_name, +                                        gfdb_db_record->file_path); +                        if (ret) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed inserting link in DB"); +                                goto out; +                        } +                        gfdb_db_record->islinkupdate = _gf_true; + +                        /* +                         * Only for create/mknod insert wind time +                         * for the first time +                         * */ +                        ret = gf_sql_insert_write_wind_time (sql_conn, gfid_str, +                                                                modtime); +                        if (ret) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed inserting wind time in DB"); +                                goto out; +                        } +                        goto out; +                } +                /*handle rename, link */ +                else { +                        /*rename*/ +                        if (strlen (gfdb_db_record->old_file_name) != 0) { +                                old_pargfid_str = gf_strdup (uuid_utoa ( +                                                gfdb_db_record->old_pargfid)); +                                if (!old_pargfid_str) { +                                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                                "Creating gfid string failed."); +                                        goto out; +                                } +                                gf_sql_update_link (sql_conn, gfid_str, +                                                pargfid_str, +                                                gfdb_db_record->file_name, +                                                gfdb_db_record->file_path, +                                                old_pargfid_str, +                                                gfdb_db_record->old_file_name); +                                if (ret) { +                                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                                "Failed updating link"); +                                        goto out; +                                } +                                gfdb_db_record->islinkupdate = _gf_true; +                        } +                        /*link*/ +                        else { +                                ret = gf_sql_insert_link (sql_conn, +                                        gfid_str, pargfid_str, +                                        gfdb_db_record->file_name, +                                        gfdb_db_record->file_path); +                                if (ret) { +                                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                        "Failed inserting link in DB"); +                                        goto out; +                                } +                                gfdb_db_record->islinkupdate = _gf_true; +                        } +                } +        } + +        /*All fops update times read or write*/ +        ret = gf_update_time (sql_conn, gfid_str, modtime, +                gfdb_db_record->do_record_counters, +                its_wind, +                isreadfop (gfdb_db_record->gfdb_fop_type)); +        if (ret) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed update wind time in DB"); +                goto out; +        } + +        ret = 0; +out: +        GF_FREE (gfid_str); +        GF_FREE (pargfid_str); +        GF_FREE (old_pargfid_str); +        return ret; +} + + + + +int +gf_sql_insert_unwind (gf_sql_connection_t  *sql_conn, +                     gfdb_db_record_t     *gfdb_db_record) +{ + +        int ret = -1; +        gfdb_time_t *modtime    = NULL; +        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/ +        char *gfid_str = NULL; +        char *pargfid_str = NULL; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out); + +        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid)); +        if (!gfid_str) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Creating gfid string failed."); +                goto out; +        } + +        /*Only update if recording unwind is set*/ +        if (gfdb_db_record->do_record_uwind_time) { +                modtime = &gfdb_db_record->gfdb_unwind_change_time; +                ret = gf_update_time (sql_conn, gfid_str, modtime, +                        gfdb_db_record->do_record_counters, +                        (!its_wind), +                        isreadfop (gfdb_db_record->gfdb_fop_type)); +                if (ret) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed update unwind time in DB"); +                        goto out; +                } +        } + +        /*For link creation and changes we use link updated*/ +        if (gfdb_db_record->islinkupdate && +                isdentryfop(gfdb_db_record->gfdb_fop_type)) { + +                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid)); +                if (!pargfid_str) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Creating pargfid_str string failed."); +                        goto out; +                } + +                ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str, +                                        gfdb_db_record->file_name, 0, _gf_true); +                if (ret) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed updating link flags in unwind"); +                        goto out; +                } +        } + +        ret = 0; +out: +        GF_FREE (gfid_str); +        GF_FREE (pargfid_str); +        return ret; +} + + +int +gf_sql_update_delete_wind (gf_sql_connection_t  *sql_conn, +                          gfdb_db_record_t     *gfdb_db_record) +{ +        int ret = -1; +        gfdb_time_t *modtime    = NULL; +        char *gfid_str          = NULL; +        char *pargfid_str       = NULL; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out); + +        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid)); +        if (!gfid_str) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Creating gfid string failed."); +                goto out; +        } + +        pargfid_str = gf_strdup (uuid_utoa(gfdb_db_record->pargfid)); +        if (!pargfid_str) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Creating pargfid_str string failed."); +                        goto out; +        } + +        /*Update the wind write times*/ +        modtime = &gfdb_db_record->gfdb_unwind_change_time; +        ret = gf_update_time (sql_conn, gfid_str, modtime, +                        gfdb_db_record->do_record_counters, +                        _gf_true, +                        isreadfop (gfdb_db_record->gfdb_fop_type)); +        if (ret) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed update wind time in DB"); +                goto out; +        } + +        ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str, +                                        gfdb_db_record->file_name, 1, +                                        _gf_false); +        if (ret) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed updating link flags in wind"); +                goto out; +        } + +        ret = 0; +out: +        GF_FREE (gfid_str); +        GF_FREE (pargfid_str); +        return ret; +} + +int +gf_sql_delete_unwind (gf_sql_connection_t  *sql_conn, +                          gfdb_db_record_t     *gfdb_db_record) +{ +        int ret = -1; +        char *gfid_str = NULL; +        char *pargfid_str = NULL; +        gfdb_time_t *modtime    = NULL; + +        CHECK_SQL_CONN (sql_conn, out); +        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out); + +        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid)); +        if (!gfid_str) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Creating gfid string failed."); +                goto out; +        } + +        /*Nuke all the entries for this GFID from DB*/ +        if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL_ALL) { +                gf_sql_delete_all(sql_conn, gfid_str); +        } +        /*Remove link entries only*/ +        else if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL) { + +                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid)); +                if (!pargfid_str) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Creating pargfid_str string failed."); +                        goto out; +                } + +                modtime = &gfdb_db_record->gfdb_unwind_change_time; + +                ret = gf_sql_delete_link(sql_conn, gfid_str, pargfid_str, +                                        gfdb_db_record->file_name); +                if (ret) { +                        gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed deleting link"); +                        goto out; +                } + +                if (gfdb_db_record->do_record_uwind_time) { +                        ret = gf_update_time (sql_conn, gfid_str, modtime, +                                gfdb_db_record->do_record_counters, +                                _gf_false, +                                isreadfop(gfdb_db_record->gfdb_fop_type)); +                        if (ret) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                "Failed update unwind time in DB"); +                                goto out; +                        } +                } +        } +        ret = 0; +out: +        GF_FREE (gfid_str); +        GF_FREE (pargfid_str); +        return ret; +} + +/****************************************************************************** + * + *                      Find/Query helper functions + * + * ****************************************************************************/ +int +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; + +        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_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                        "Failed to create gfdb_query_record"); +                                goto out; +        } + +        /*Loop to access queried rows*/ +        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*/ +                        text_column = (char *)sqlite3_column_text +                                                        (prep_stmt, 0); +                        if (!text_column) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                        "Failed retriving GF_ID"); +                                goto out; +                        } +                        ret = uuid_parse (text_column, gfdb_query_record->gfid); +                        if (ret) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                        "Failed parsing GF_ID"); +                                goto out; +                        } + +                        /*Retrive Link Buffer - column index 1*/ +                        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); +                        if (ret) { +                                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                                        "Query Call back failed!"); +                                goto out; +                        } + +                } + +        } + +        if (ret != SQLITE_DONE) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed retriving records from db : %s", +                        sqlite3_errmsg (db_conn)); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        gfdb_query_record_fini (&gfdb_query_record); +        return ret; +} + + + +int +gf_sql_clear_counters (gf_sql_connection_t *sql_conn) +{ +        int ret                 = -1; +        char *sql_strerror      = NULL; +        char *query_str         = NULL; + +        CHECK_SQL_CONN (sql_conn, out); + +        query_str = "BEGIN;UPDATE " +                    GF_FILE_TABLE +                    " SET " GF_COL_READ_FREQ_CNTR " = 0 , " +                    GF_COL_WRITE_FREQ_CNTR " = 0 ;COMMIT;"; + +        ret = sqlite3_exec (sql_conn->sqlite3_db_conn, query_str, NULL, NULL, +                                &sql_strerror); +        if (ret != SQLITE_OK) { +                gf_log (GFDB_STR_SQLITE3, GF_LOG_ERROR, +                        "Failed executing: %s : %s", +                        query_str, sql_strerror); +                sqlite3_free (sql_strerror); +                        ret = -1; +                        goto out; +        } + +        ret = 0; +out: +        return ret; +}  | 
