int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char sql[256]; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); snprintf (sql, sizeof(sql), "SELECT commit_id FROM Branch WHERE name='%s' AND repo_id='%s'", branch->name, branch->repo_id); if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id) < 0) { seaf_db_rollback (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { g_warning ("[branch mgr] Branch update conflict for repo %s, rollback.\n", branch->repo_id); seaf_db_rollback (trans); return -1; } snprintf (sql, sizeof(sql), "UPDATE Branch SET commit_id = '%s' " "WHERE name = '%s' AND repo_id = '%s'", branch->commit_id, branch->name, branch->repo_id); if (seaf_db_trans_query (trans, sql) < 0) { seaf_db_rollback (trans); return -1; } seaf_db_commit (trans); return 0; }
int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char *sql; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); if (!trans) return -1; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: case SEAF_DB_TYPE_PGSQL: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=? FOR UPDATE"; break; case SEAF_DB_TYPE_SQLITE: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=?"; break; default: g_return_val_if_reached (-1); } if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id, 2, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } sql = "UPDATE Branch SET commit_id = ? " "WHERE name = ? AND repo_id = ?"; if (seaf_db_trans_query (trans, sql, 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (seaf_db_commit (trans) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } seaf_db_trans_close (trans); on_branch_updated (mgr, branch); return 0; }
int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char sql[256]; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); if (!trans) return -1; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: snprintf (sql, sizeof(sql), "SELECT commit_id FROM Branch WHERE name='%s' " "AND repo_id='%s' FOR UPDATE", branch->name, branch->repo_id); break; case SEAF_DB_TYPE_SQLITE: snprintf (sql, sizeof(sql), "SELECT commit_id FROM Branch WHERE name='%s' " "AND repo_id='%s'", branch->name, branch->repo_id); break; } if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { g_message ("[branch mgr] Branch update conflict for repo %s, rollback.\n", branch->repo_id); seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } snprintf (sql, sizeof(sql), "UPDATE Branch SET commit_id = '%s' " "WHERE name = '%s' AND repo_id = '%s'", branch->commit_id, branch->name, branch->repo_id); if (seaf_db_trans_query (trans, sql) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (seaf_db_commit (trans) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } seaf_db_trans_close (trans); on_branch_updated (mgr, branch); return 0; }
static int set_repo_size (SeafDB *db, const char *repo_id, const char *old_head_id, const char *new_head_id, gint64 size) { SeafDBTrans *trans; char *sql; char cached_head_id[41] = {0}; int ret = 0; trans = seaf_db_begin_transaction (db); if (!trans) return -1; switch (seaf_db_type (db)) { case SEAF_DB_TYPE_MYSQL: case SEAF_DB_TYPE_PGSQL: sql = "SELECT head_id FROM RepoSize WHERE repo_id=? FOR UPDATE"; break; case SEAF_DB_TYPE_SQLITE: sql = "SELECT head_id FROM RepoSize WHERE repo_id=?"; break; default: g_return_val_if_reached (-1); } int n = seaf_db_trans_foreach_selected_row (trans, sql, get_head_id, cached_head_id, 1, "string", repo_id); if (n < 0) { ret = SET_SIZE_ERROR; goto rollback; } if (n == 0) { /* Size not set before. */ sql = "INSERT INTO RepoSize VALUES (?, ?, ?)"; if (seaf_db_trans_query (trans, sql, 3, "string", repo_id, "int64", size, "string", new_head_id) < 0) { ret = SET_SIZE_ERROR; goto rollback; } } else { if (strcmp (old_head_id, cached_head_id) != 0) { g_message ("[size sched] Size update conflict for repo %s, rollback.\n", repo_id); ret = SET_SIZE_CONFLICT; goto rollback; } sql = "UPDATE RepoSize SET size = ?, head_id = ? WHERE repo_id = ?"; if (seaf_db_trans_query (trans, sql, 3, "int64", size, "string", new_head_id, "string", repo_id) < 0) { ret = SET_SIZE_ERROR; goto rollback; } } if (seaf_db_commit (trans) < 0) { ret = SET_SIZE_ERROR; goto rollback; } seaf_db_trans_close (trans); return ret; rollback: seaf_db_rollback (trans); seaf_db_trans_close (trans); return ret; }