Beispiel #1
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;
}
Beispiel #2
0
int batch_insert_stripe_info(lmgr_t *p_mgr, pktype *pklist, int *validators,
                             attr_set_t **p_attrs, unsigned int count,
                             bool update_if_exists)
{
    bool first;
    int i, rc = 0;
    int total_si;
    GString *req = g_string_new("");
    attr_mask_t tmp_mask = { ATTR_MASK_stripe_info, 0, 0LL };

    if (!attr_mask_is_null(sum_masks(p_attrs, count, tmp_mask))) {
        /* build batch request for STRIPE_INFO table */
        g_string_assign(req, "INSERT INTO " STRIPE_INFO_TABLE " ("
                        STRIPE_INFO_FIELDS ") VALUES ");

        first = true;
        for (i = 0; i < count; i++) {
            /* no request if the entry has no stripe info */
            if (!ATTR_MASK_TEST(p_attrs[i], stripe_info))
                continue;

            g_string_append_printf(req, "%s(" DPK ",%d,%u,%u,'%s')",
                                   first ? "" : ",", pklist[i], validators[i],
                                   ATTR(p_attrs[i], stripe_info).stripe_count,
                                   (unsigned int)ATTR(p_attrs[i],
                                                      stripe_info).stripe_size,
                                   ATTR(p_attrs[i], stripe_info).pool_name);
            first = false;
        }

        if (update_if_exists)
            /* append "on duplicate key ..." */
            g_string_append(req,
                            " ON DUPLICATE KEY UPDATE " STRIPE_INFO_SET_VALUES);

        if (!first) {   /* do nothing if no entry had stripe info */
            rc = db_exec_sql(&p_mgr->conn, req->str, NULL);
            if (rc)
                goto out;
        }
        /* reset the string */
        g_string_assign(req, "");
    }

    /* Stripe items more tricky because we want to delete previous items
     * on update. */
    /* If update_if_exists is false, insert them all as a batch.
     * For the update case, remove previous items before bluk insert.
     */
    if (update_if_exists) {
        for (i = 0; i < count; i++) {
            /* no request if the entry has no stripe items */
            if (!ATTR_MASK_TEST(p_attrs[i], stripe_items))
                continue;

            g_string_printf(req,
                            "DELETE FROM " STRIPE_ITEMS_TABLE " WHERE id=" DPK,
                            pklist[i]);

            rc = db_exec_sql(&p_mgr->conn, req->str, NULL);
            if (rc)
                goto out;
        }
    }

    /* bulk insert stripe items (if any is set) */
    tmp_mask.std = ATTR_MASK_stripe_items;
    if (attr_mask_is_null(sum_masks(p_attrs, count, tmp_mask)))
        goto out;

    total_si = 0;
    first = true;
    g_string_assign(req, "INSERT INTO " STRIPE_ITEMS_TABLE
                    " (" STRIPE_ITEMS_FIELDS ") VALUES ");

    /* loop on all entries and all stripe items */
    for (i = 0; i < count; i++) {
        int s;
        const stripe_items_t *p_items;

        /* skip the entry if it has no stripe items */
        if (!ATTR_MASK_TEST(p_attrs[i], stripe_items))
            continue;

        p_items = &ATTR(p_attrs[i], stripe_items);
        for (s = 0; s < p_items->count; s++) {
            char buff[2 * STRIPE_DETAIL_SZ + 1];

            total_si++;
            if (buf2hex
                (buff, sizeof(buff),
                 (unsigned char *)(&p_items->stripe[s].ost_gen),
                 STRIPE_DETAIL_SZ) < 0) {
                DisplayLog(LVL_CRIT, LISTMGR_TAG,
                           "Buffer too small to store details stripe info");
                memset(buff, 0, sizeof(buff));
            }
            g_string_append_printf(req, "%s(" DPK ",%u,%u,x'%s')",
                                   first && (s == 0) ? "" : ",", pklist[i],
                                   s, p_items->stripe[s].ost_idx, buff);
            first = false;
        }
    }

    /* only execute it if there was some stripe items */
    if (total_si > 0)
        rc = db_exec_sql(&p_mgr->conn, req->str, NULL);

 out:
    g_string_free(req, TRUE);
    return rc;
}