예제 #1
0
/**
 * print parent condition depending on parent list count:
 *      parent_id == xxx or parent_id IN ( xxx, yyy, zzz )
 * \return db error code
 */
static int append_parent_cond(lmgr_t *p_mgr, GString *str, const wagon_t *parent_list,
                              unsigned int parent_count, const char *prefix)
{
    DEF_PK(pk);

    if (unlikely(parent_count == 0))
    {
        DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Warning: parent list is empty in %s()", __func__ );
        return DB_INVALID_ARG;
    }

    if (likely(parent_count == 1)) /* the only expected for now */
    {
        entry_id2pk(&parent_list[0].id, PTR_PK(pk));
        g_string_append_printf(str, "%sparent_id="DPK, prefix ? prefix : "", pk);
    }
    else
    {
        int i;

        g_string_append_printf(str, "%sparent_id IN (", prefix ? prefix : "");
        for (i = 0; i < parent_count; i++)
        {
            entry_id2pk(&parent_list[i].id, PTR_PK(pk));
            g_string_append_printf(str, "%s"DPK, (i == 0)? "":",", pk);
        }
        g_string_append(str,")");
    }
    return DB_SUCCESS;
}
예제 #2
0
int ListMgr_Get( lmgr_t * p_mgr, const entry_id_t * p_id, attr_set_t * p_info )
{
    int rc;
    DEF_PK(pk);

    entry_id2pk(p_id, PTR_PK(pk));
retry:
    rc = listmgr_get_by_pk(p_mgr, pk, p_info);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    return rc;
}
예제 #3
0
int ListMgr_SetStripe( lmgr_t * p_mgr, const entry_id_t * p_id,
                       stripe_info_t * p_stripe_info, stripe_items_t * p_stripe_items )
{
    DEF_PK(pk);

    int rc = entry_id2pk( p_mgr, p_id, FALSE, PTR_PK(pk) );

    if (rc)
        return rc;

    return insert_stripe_info( p_mgr, pk, VALID(p_id), p_stripe_info, p_stripe_items,
                               TRUE );
}
예제 #4
0
/**
 * print parent condition depending on parent list count:
 *      parent_id == xxx or parent_id IN ( xxx, yyy, zzz )
 */
static char * parent_cond(lmgr_t * p_mgr, char * buff, size_t buffsz,
                          const wagon_t * parent_list, unsigned int parent_count,
                          const char * prefix)
{
    DEF_PK(pk);

    if (parent_count == 0)
    {
        DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Warning: parent list is empty in %s()", __func__ );
        return NULL;
    }
    if (parent_count == 1)
    {
        entry_id2pk(&parent_list[0].id, PTR_PK(pk));
        sprintf(buff, "%sparent_id="DPK, prefix ? prefix : "", pk);
    }
    else
    {
        int i;
        char * curr = buff;
        curr += sprintf(curr, "%sparent_id IN (", prefix ? prefix : "");
        for (i = 0; i < parent_count; i++)
        {
            entry_id2pk(&parent_list[i].id, PTR_PK(pk));
            if ((ssize_t)(curr - buff) + strlen(pk) + 2 >= buffsz)
            {
                DisplayLog(LVL_CRIT, LISTMGR_TAG, "ERROR: request overflow in %s(): parent_list length=%u, current buff_usage=%zu",
                           __func__, parent_count, (size_t)(curr - buff));
                return NULL;
            }
            if (i == 0)
                curr += sprintf(curr, DPK, pk);
            else
                curr += sprintf(curr, ","DPK, pk);
        }
        strcpy(curr, ")");
    }
    return buff;
}
예제 #5
0
int ListMgr_Exists(lmgr_t *p_mgr, const entry_id_t *p_id)
{
    GString        *req;
    int             rc;
    result_handle_t result;
    char           *str_count = NULL;
    DEF_PK(pk);
    int             retry_status;

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */
    req = g_string_new("SELECT id FROM " MAIN_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

retry:
    /* execute the request (must return negative value on error) */
    rc = -db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, -rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = -DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, &str_count, 1);
    if (rc == 0)
        rc = 1; /* return 1 if entry exists */
    else if (rc != DB_END_OF_LIST)
    {
        retry_status = lmgr_delayed_retry(p_mgr, -rc);
        if (retry_status == 1)
            goto retry;
        else if (retry_status == 2) {
            rc = -DB_RBH_SIG_SHUTDOWN;
            goto free_result;
        }
    }
    else
        rc = 0;

free_result:
    db_result_free(&p_mgr->conn, &result);

free_str:
    g_string_free(req, TRUE);
    return rc;
}
예제 #6
0
int ListMgr_RecovSetState( lmgr_t * p_mgr, const entry_id_t * p_id,
                           recov_status_t status )
{
    char query[4096];
    DEF_PK(pk);

    entry_id2pk(p_id, PTR_PK(pk));

    sprintf( query, "UPDATE "RECOV_TABLE" SET recov_status=%u WHERE id="DPK,
             status, pk );

    /* execute request */
    return db_exec_sql( &p_mgr->conn, query, NULL );
}
예제 #7
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    GString        *req = NULL;
    char            escaped[RBH_NAME_MAX*2+1];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];
    int             retry_status;

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, sizeof(escaped), name);

    req = g_string_new("SELECT id FROM "DNAMES_TABLE" WHERE pkn=");
    g_string_append_printf(req, HNAME_FMT, pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, str_info, 1);

    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_res;
    } else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

free_res:
    db_result_free(&p_mgr->conn, &result);
free_str:
    g_string_free(req, TRUE);
    return rc;
}
예제 #8
0
int ListMgr_Get( lmgr_t * p_mgr, const entry_id_t * p_id, attr_set_t * p_info )
{
    int rc;
    DEF_PK(pk);
    int retry_status;

    entry_id2pk(p_id, PTR_PK(pk));
retry:
    rc = listmgr_get_by_pk(p_mgr, pk, p_info);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2)
        rc = DB_RBH_SIG_SHUTDOWN;
    return rc;
}
예제 #9
0
static void no_name_warning(PK_PARG_T pk, attr_set_t *p_attrs, unsigned int count)
{
    DEF_PK(ppk);
    char msg[256];

    entry_id2pk(&ATTR(p_attrs, parent_id), PTR_PK(ppk));

    if (count > 1)
        snprintf(msg, sizeof(msg), "%u entries", count);
    else
        rh_strncpy(msg, "entry", sizeof(msg));

    DisplayLog(LVL_MAJOR, LISTMGR_TAG, "WARNING: %s created without"
               " name or parent information: pk="DPK", name='%s', parent='%s'",
               msg, pk, ATTR_MASK_TEST(p_attrs, name) ? ATTR(p_attrs, name) : "",
               ATTR_MASK_TEST(p_attrs, parent_id) ? ppk : "");
}
예제 #10
0
int ListMgr_RecovGetNext( struct lmgr_iterator_t *p_iter,
                          entry_id_t * p_id,
                          attr_set_t * p_info,
                          recov_status_t * last_status )
{
    int            rc = 0;
    char          *result_tab[2+RECOV_FIELD_COUNT]; /* +2 for id and recov_status */
    DEF_PK(pk);
    int entry_disappeared = FALSE;

    do
    {
        entry_disappeared = FALSE;

        rc = db_next_record( &p_iter->p_mgr->conn, &p_iter->select_result,
                             result_tab, RECOV_FIELD_COUNT+2 );

        if ( rc )
            return rc;
        if ( result_tab[0] == NULL ) /* no id? */
            return DB_REQUEST_FAILED;

        if ( sscanf( result_tab[0], SPK, PTR_PK(pk) ) != 1 )
            return DB_REQUEST_FAILED;

        if ( result_tab[1] == NULL ) { /* no status */
            if (last_status)
                *last_status = -1;
        }
        else if (last_status)
            *last_status = str2int(result_tab[1]);

        /* retrieve entry id (except validator) */
        rc = pk2entry_id( p_iter->p_mgr, pk, p_id );

        /* /!\ If the entry disappeared from DB, we must go to next record */
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;
        else if ( rc )
            return rc;

    }
    while ( entry_disappeared );        /* goto next record if entry desappered */

    return result2attrset( T_RECOV, result_tab + 2, RECOV_FIELD_COUNT, p_info );
}
예제 #11
0
/* check that validator is matching for a given entry */
int ListMgr_CheckStripe( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           query[1024];
    char          *res;
    result_handle_t result;
    int            rc = DB_SUCCESS;
    DEF_PK(pk);

    rc = entry_id2pk( p_mgr, p_id, FALSE, PTR_PK(pk) );
    if (rc)
        return rc;

    sprintf( query, "SELECT validator FROM " STRIPE_INFO_TABLE " WHERE id="DPK, pk );

    rc = db_exec_sql( &p_mgr->conn, query, &result );
    if ( rc )
        goto out;

    rc = db_next_record( &p_mgr->conn, &result, &res, 1 );

    if ( rc == DB_END_OF_LIST )
        rc = DB_NOT_EXISTS;

    if ( rc )
        goto res_free;

    if ( res == NULL )
    {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    if ( atoi( res ) != VALID(p_id) )
    {
        delete_stipe_info( p_mgr, pk );
        rc = DB_OUT_OF_DATE;
    }
    else
        rc = DB_SUCCESS;

  res_free:
    db_result_free( &p_mgr->conn, &result );
  out:
    return rc;
}
예제 #12
0
int ListMgr_GetNext( struct lmgr_iterator_t *p_iter, entry_id_t * p_id, attr_set_t * p_info )
{
    int            rc = 0;
    char          *idstr;
    DEF_PK(pk);

    int            entry_disappeared = FALSE;

    do
    {
        entry_disappeared = FALSE;

        rc = db_next_record( &p_iter->p_mgr->conn, &p_iter->select_result, &idstr, 1 );

        if ( rc )
            return rc;
        if ( idstr == NULL )
            return DB_REQUEST_FAILED;

        if ( sscanf( idstr, SPK, PTR_PK(pk) ) != 1 )
            return DB_REQUEST_FAILED;

        /* retrieve entry id (except validator) */
        rc = pk2entry_id( p_iter->p_mgr, pk, p_id );

        /* /!\ If the entry disappeared from DB, we must go to next record */
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;
        else if ( rc )
            return rc;

        /* Idem */
        rc = listmgr_get_by_pk( p_iter->p_mgr, pk, p_info );
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;

    }
    while ( entry_disappeared );        /* goto next record if entry desappered */

    return rc;

}
예제 #13
0
int ListMgr_SetStripe(lmgr_t *p_mgr, const entry_id_t *p_id,
                      stripe_info_t *p_stripe_info,
                      stripe_items_t *p_stripe_items)
{
    DEF_PK(pk);
    int rc;
#ifdef HAVE_LLAPI_FSWAP_LAYOUTS
    int validator = (p_stripe_info ? p_stripe_info->validator : VALID_NOSTRIPE);
#else
    int validator = VALID(p_id);
#endif

    entry_id2pk(p_id, PTR_PK(pk));
 retry:
    rc = insert_stripe_info(p_mgr, pk, validator, p_stripe_info, p_stripe_items,
                            true);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;

    return rc;
}
예제 #14
0
int ListMgr_Exists( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           request[4096];
    int            rc;
    result_handle_t result;
    char          *str_count = NULL;
    DEF_PK( pk );

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */

    sprintf( request, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk );

retry:
    /* execute the request */
    rc = db_exec_sql(&p_mgr->conn, request, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return -rc;

    rc = db_next_record( &p_mgr->conn, &result, &str_count, 1 );
    if (rc == 0)
        rc = 1;
    else if (rc != DB_END_OF_LIST)
    {
        if (lmgr_delayed_retry(p_mgr, rc))
            goto retry;
        rc = -rc;
    }
    else
        rc = 0;

    db_result_free( &p_mgr->conn, &result );
    return rc;
}
예제 #15
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    char           query[4096];
    char           escaped[RBH_NAME_MAX*2];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, RBH_NAME_MAX*2, name);

    sprintf(query, "SELECT id FROM "DNAMES_TABLE" WHERE pkn="HNAME_FMT,
            pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, query, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = db_next_record( &p_mgr->conn, &result, str_info, 1 );

    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

  free_res:
    db_result_free( &p_mgr->conn, &result );
    return rc;
}
예제 #16
0
/** check that validator is matching for a given entry */
int ListMgr_CheckStripe(lmgr_t *p_mgr, const entry_id_t *p_id, int validator)
{
    char *res;
    result_handle_t result;
    int rc = DB_SUCCESS;
    GString *req = NULL;
    DEF_PK(pk);

#ifndef HAVE_LLAPI_FSWAP_LAYOUTS
    if (validator != VALID_EXISTS)
        validator = VALID(p_id);
#endif

    entry_id2pk(p_id, PTR_PK(pk));

    req = g_string_new("SELECT validator FROM " STRIPE_INFO_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

 retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        goto out;

    rc = db_next_record(&p_mgr->conn, &result, &res, 1);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;

    if (rc)
        goto res_free;

    if (res == NULL) {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    if (validator == VALID_EXISTS) {
        DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": validator exists (%s): OK",
                   PFID(p_id), res);
        /* just check it exists */
        rc = DB_SUCCESS;
    } else if (atoi(res) != validator) {
        DisplayLog(LVL_FULL, LISTMGR_TAG,
                   DFID ": stripe change detected: gen %s->%d", PFID(p_id), res,
                   validator);
        rc = DB_OUT_OF_DATE;
    } else {    /* validator matches */

        DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": stripe gen is unchanged (%d)",
                   PFID(p_id), validator);
        rc = DB_SUCCESS;
    }

 res_free:
    db_result_free(&p_mgr->conn, &result);
 out:
    g_string_free(req, TRUE);
    DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": %s returns with status=%d",
               PFID(p_id), __func__, rc);
    return rc;
}
예제 #17
0
int listmgr_batch_insert_no_tx(lmgr_t * p_mgr, entry_id_t **p_ids,
                               attr_set_t **p_attrs,
                               unsigned int count,
                               int update_if_exists)
{
    int            rc = 0;
    int            i, full_mask;
    char           fields[1024]; /* field list */
    pktype        *pklist = NULL;
    var_str        query = VAR_STR_NULL;
    char           values[4096] = "";
    char          *values_curr = NULL;
    bool           first;
    /* fake attribute struct, to write generic name fields */
    attr_set_t fake_attrs = *(p_attrs[0]);

    full_mask = sum_masks(p_attrs, count, ~0);
    fake_attrs.attr_mask = full_mask;

    pklist = (pktype *)MemCalloc(count, sizeof(pktype));
    if (pklist == NULL)
        return DB_NO_MEMORY;

    for (i = 0; i < count; i++)
    {
        /* check attr mask */
        if (!lmgr_batch_compat(full_mask, p_attrs[i]->attr_mask))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Incompatible attr mask in batched operation: %#x vs. %#x",
                       p_attrs[i]->attr_mask, full_mask);
            rc = DB_INVALID_ARG;
            goto out_free;
        }
        /* fill pk array */
        entry_id2pk(p_ids[i], PTR_PK(pklist[i])); /* The same for all tables? */
    }

    /* build batch request for main table */
    attrmask2fieldlist(fields, full_mask, T_MAIN, TRUE, FALSE, "", "");

    var_str_append(&query, "INSERT INTO " MAIN_TABLE "(id");
    var_str_append(&query, fields);
    var_str_append(&query, ") VALUES ");

    first = true;
    for (i = 0; i < count; i++)
    {
        /* don't set this entry if no attribute is in main table */
        if ((p_attrs[i]->attr_mask & main_attr_set) == 0)
            continue;

        values_curr = values + sprintf(values, DPK, pklist[i]);
        attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_MAIN, TRUE);

        /* add "[,](values)" to query */
        var_str_append(&query, first ? "(" : ",(");
        var_str_append(&query, values);
        var_str_append(&query, ")");
        first = false;
    }

    if (update_if_exists)
    {
        /* append "on duplicate key ..." */
        attrset2updatelist(p_mgr, values, &fake_attrs, T_MAIN, FALSE, TRUE);
        var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
        var_str_append(&query, values);
    }

    rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
    if (rc)
        goto out_free;

    var_str_reset(&query);

    /* allow inserting entries in MAIN_TABLE, without name information */

    /* both parent and name are defined */
    if ((full_mask & ATTR_MASK_name) && (full_mask & ATTR_MASK_parent_id))
    {
        /* build batch request for names table */
        attrmask2fieldlist(fields, full_mask, T_DNAMES, TRUE, FALSE, "", "");

        var_str_append(&query, "INSERT INTO " DNAMES_TABLE "(id");
        var_str_append(&query, fields);
        var_str_append(&query, ",pkn) VALUES ");

        first = true;
        for (i = 0; i < count; i++)
        {
            /* don't set this entry if parent or name is missing */
            if (!ATTR_MASK_TEST(p_attrs[i], name) || !ATTR_MASK_TEST(p_attrs[i], parent_id))
            {
                /* warn for create operations without name information */
                if (!update_if_exists)
                    no_name_warning(pklist[i], p_attrs[i], 1);

                continue;
            }

            values_curr = values + sprintf(values, DPK, pklist[i]);
            attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_DNAMES, TRUE);

            /* add "[,](values,<pk>)" to query */
            var_str_append(&query, first ? "(" : ",(");
            var_str_append(&query, values);
            var_str_append(&query, ","HNAME_DEF")");
            first = false;
        }

        values_curr = values + sprintf(values, "id=VALUES(id)"); /* not part of the PK */
        attrset2updatelist(p_mgr, values_curr, &fake_attrs, T_DNAMES, TRUE, TRUE);
        var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
        var_str_append(&query, values);

        rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
        if (rc)
            goto out_free;

    } else if (!update_if_exists) { /* only warn for create operations */

        /* if we get here, the name information is missing in all fields.
         * use entry[0] as example for the warning message. */
        no_name_warning(pklist[0], p_attrs[0], count);
    }

    var_str_reset(&query);

    /* insert all info in annex table, if any */
    if (annex_table && (full_mask & annex_attr_set))
    {
        /* Create field and values lists.
         * Do nothing if no fields are to be set.
         */
        if (attrmask2fieldlist(fields, full_mask, T_ANNEX, TRUE, FALSE, "", "") > 0)
        {

            var_str_append(&query, "INSERT INTO "ANNEX_TABLE "(id");
            var_str_append(&query, fields);
            var_str_append(&query, ") VALUES ");

            first = true;
            for (i = 0; i < count; i++)
            {
                char           values[4096] = "";
                char          *values_curr = NULL;

                /* don't set this entry if no attribute is in annex table */
                if ((p_attrs[i]->attr_mask & annex_attr_set) == 0)
                    continue;

                sprintf(values, DPK, pklist[i]);
                values_curr = values + strlen(values);
                attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_ANNEX, TRUE);

                /* add "[,](values)" to query */
                var_str_append(&query, first ? "(" : ",(");
                var_str_append(&query, values);
                var_str_append(&query, ")");
                first = false;
            }

            /* always update as having the entry in the main table
             * is the reference to know if we knew the entry */
            /* append "on duplicate key ..." */
            attrset2updatelist(p_mgr, values, &fake_attrs, T_ANNEX, FALSE, TRUE);
            var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
            var_str_append(&query, values);

            rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
            if (rc)
                goto out_free;
        }
    }

#ifdef _LUSTRE
    /* batch insert of striping info */
    if (ATTR_MASK_TEST(&fake_attrs, stripe_info) || ATTR_MASK_TEST(&fake_attrs, stripe_items))
    {
        /* create validator list */
        int *validators = (int*)MemCalloc(count, sizeof(int));
        if (!validators)
        {
            rc =  DB_NO_MEMORY;
            goto out_free;
        }
        for (i = 0; i < count; i++)
#ifdef HAVE_LLAPI_FSWAP_LAYOUTS
            validators[i] = ATTR_MASK_TEST(p_attrs[i], stripe_info)?
                                ATTR(p_attrs[i],stripe_info).validator:VALID_NOSTRIPE;
#else
            validators[i] = VALID(p_ids[i]);
#endif

        rc = batch_insert_stripe_info(p_mgr, pklist, validators, p_attrs,
                                      count, TRUE);
        MemFree(validators);
        if (rc)
            goto out_free;
    }
#endif

out_free:
    var_str_free(&query);
    MemFree(pklist);
    return rc;
}
예제 #18
0
int ListMgr_Update( lmgr_t * p_mgr, const entry_id_t * p_id, const attr_set_t * p_update_set )
{
    int            rc, main_count, annex_count;
    char           query[4096];
    char           fields[4096];
    char           annex_fields[4096];
    DEF_PK(pk);
    int            nb_tables = 0;

    /* read only fields in info mask? */
    if ( readonly_attr_set & p_update_set->attr_mask )
    {
        DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Error: trying to update read only values: attr_mask=%#x",
                    readonly_attr_set & p_update_set->attr_mask );
        return DB_INVALID_ARG;
    }

    rc = entry_id2pk( p_mgr, p_id, FALSE, PTR_PK(pk) );
    if (rc)
        return rc;

    /* check how many tables are to be updated */
    if ( main_fields( p_update_set->attr_mask ) )
    {
        main_count = attrset2updatelist( p_mgr, fields, p_update_set, T_MAIN, FALSE );
        if ( main_count < 0 )
            return -main_count;
        if ( main_count > 0 )
            nb_tables++;
    }
    else
        main_count = 0;

    if ( annex_table && annex_fields( p_update_set->attr_mask ) )
    {
        annex_count = attrset2updatelist( p_mgr, annex_fields, p_update_set, T_ANNEX, FALSE );
        if ( annex_count < 0 )
            return -annex_count;
        if ( annex_count > 0 )
            nb_tables++;
    }
    else
        annex_count = 0;


    if ( stripe_fields( p_update_set->attr_mask ) )
        nb_tables += 2;

    /* if only 1 table is impacted, switch to autocommit mode */
    if ( nb_tables > 1 )
    {
        /* @todo in the case of sqlite, we may want to do periodic commit
         * instead of systematic one. */
        rc = lmgr_begin( p_mgr );
        if ( rc )
            return rc;
    }

    /* update main table */

    if ( main_count > 0 )
    {
        sprintf( query, "UPDATE " MAIN_TABLE " SET %s WHERE id="DPK, fields, pk );
        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }

    /* update annex table (if any) */
    if ( annex_count > 0 )
    {
        sprintf( query, "UPDATE " ANNEX_TABLE " SET %s WHERE id="DPK, annex_fields, pk );
        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }

    /* insert new stripe info if provided (and eventually remove previous values) */
    if ( ATTR_MASK_TEST( p_update_set, stripe_info ) )
    {
        rc = insert_stripe_info( p_mgr, pk, VALID(p_id), &ATTR( p_update_set, stripe_info ),
                                 ATTR_MASK_TEST( p_update_set, stripe_items ) ?
                                    &ATTR( p_update_set, stripe_items ) : NULL, TRUE );
        if ( rc )
            goto rollback;
    }


    if ( nb_tables > 1 )
        return lmgr_commit( p_mgr );
    else
        return DB_SUCCESS;

  rollback:
    lmgr_rollback( p_mgr );
    return rc;
}