Esempio n. 1
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;
}
Esempio n. 2
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;
}