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