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; +} |