예제 #1
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);

    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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}