Exemplo n.º 1
0
/*
_bdb_delete_cursor -- called from bdb_delete when the query involves operators
  other than equal '='. Adds support for queries like this:
	DELETE from SomeTable WHERE _k[0] < _v[0]
  In this case, the keys _k are not the actually schema keys, so we need to
  iterate via cursor to perform this operation.
*/
int _bdb_delete_cursor(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v, int _n)
{
    tbl_cache_p _tbc = NULL;
    table_p _tp = NULL;
    db_res_t* _r   = NULL;
    char kbuf[MAX_ROW_SIZE];
    char dbuf[MAX_ROW_SIZE];
    int i, ret, klen=MAX_ROW_SIZE;
    DBT key, data;
    DB *db;
    DBC *dbcp;
    int *lkey=NULL;
    str s;

    i = ret = 0;

    if ((!_h) || !CON_TABLE(_h))
        return -1;

    s.s = (char*)CON_TABLE(_h);
    s.len = strlen(CON_TABLE(_h));

    _tbc = bdblib_get_table(BDB_CON_CONNECTION(_h), &s);
    if(!_tbc)
    {   LM_WARN("table does not exist!\n");
        return -3;
    }

    _tp = _tbc->dtp;
    if(!_tp)
    {   LM_WARN("table not loaded!\n");
        return -4;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("DELETE by cursor in %.*s\n", _tp->name.len, _tp->name.s );
#endif

    if(_k)
    {   lkey = bdb_get_colmap(_tp, _k, _n);
        if(!lkey)
        {   ret = -1;
            goto error;
        }
    }

    /* create an empty db_res_t which gets returned even if no result */
    _r = db_new_result();
    if (!_r)
    {   LM_ERR("no memory for result \n");
    }

    RES_ROW_N(_r) = 0;

    /* fill in the col part of db_res_t */
    if ((ret = bdb_get_columns(_tp, _r, 0, 0)) != 0)
    {   LM_ERR("Error while getting column names\n");
        goto error;
    }

    db = _tp->db;
    memset(&key, 0, sizeof(DBT));
    memset(kbuf, 0, klen);
    memset(&data, 0, sizeof(DBT));
    memset(dbuf, 0, MAX_ROW_SIZE);

    data.data = dbuf;
    data.ulen = MAX_ROW_SIZE;
    data.flags = DB_DBT_USERMEM;

    /* Acquire a cursor for the database. */
    if ((ret = db->cursor(db, NULL, &dbcp, DB_WRITECURSOR)) != 0)
    {   LM_ERR("Error creating cursor\n");
    }

    while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
    {
        if(!strncasecmp((char*)key.data,"METADATA",8))
            continue;

        /*fill in the row part of db_res_t */
        if ((ret=bdb_convert_row( _r, dbuf, 0)) < 0)
        {   LM_ERR("Error while converting row\n");
            goto error;
        }

        if(bdb_row_match(_k, _op, _v, _n, _r, lkey ))
        {

#ifdef BDB_EXTRA_DEBUG
            LM_DBG("DELETE ROW by KEY:  [%.*s]\n", (int) key.size,
                   (char *)key.data);
#endif

            if((ret = dbcp->c_del(dbcp, 0)) != 0)
            {
                /* Berkeley DB error handler */
                LM_CRIT("DB->get error: %s.\n", db_strerror(ret));
                bdblib_recover(_tp,ret);
            }

        }

        memset(dbuf, 0, MAX_ROW_SIZE);
        bdb_free_rows( _r);
    }
    ret = 0;

error:
    if(dbcp)
        dbcp->c_close(dbcp);
    if(_r)
        bdb_free_result(_r);
    if(lkey)
        pkg_free(lkey);

    return ret;
}
Exemplo n.º 2
0
/*
 * Delete a row from table
 *
 * To delete ALL rows:
 *   do Not specify any keys, or values, and _n <=0
 *
 */
int bdb_delete(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v, int _n)
{
    tbl_cache_p _tbc = NULL;
    table_p _tp = NULL;
    char kbuf[MAX_ROW_SIZE];
    int i, j, ret, klen;
    int *lkey=NULL;
    DBT key;
    DB *db;
    DBC *dbcp;
    str s;

    i = j = ret = 0;
    klen=MAX_ROW_SIZE;

    if (_op)
        return ( _bdb_delete_cursor(_h, _k, _op, _v, _n) );

    if ((!_h) || !CON_TABLE(_h))
        return -1;

    s.s = (char*)CON_TABLE(_h);
    s.len = strlen(CON_TABLE(_h));

    _tbc = bdblib_get_table(BDB_CON_CONNECTION(_h), &s);
    if(!_tbc)
    {   LM_WARN("table does not exist!\n");
        return -3;
    }

    _tp = _tbc->dtp;
    if(!_tp)
    {   LM_WARN("table not loaded!\n");
        return -4;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("DELETE in %.*s\n", _tp->name.len, _tp->name.s );
#endif

    db = _tp->db;
    memset(&key, 0, sizeof(DBT));
    memset(kbuf, 0, klen);

    if(!_k || !_v || _n<=0)
    {
        /* Acquire a cursor for the database. */
        if ((ret = db->cursor(db, NULL, &dbcp, DB_WRITECURSOR) ) != 0)
        {   LM_ERR("Error creating cursor\n");
            goto error;
        }

        while ((ret = dbcp->c_get(dbcp, &key, NULL, DB_NEXT)) == 0)
        {
            if(!strncasecmp((char*)key.data,"METADATA",8))
                continue;
#ifdef BDB_EXTRA_DEBUG
            LM_DBG("KEY: [%.*s]\n"
                   , (int)   key.size
                   , (char *)key.data);
#endif
            ret = dbcp->c_del(dbcp, 0);
        }

        dbcp->c_close(dbcp);
        return 0;
    }

    lkey = bdb_get_colmap(_tp, _k, _n);
    if(!lkey)  return -5;

    /* make the key */
    if ( (ret = bdblib_valtochar(_tp, lkey, kbuf, &klen, _v, _n, BDB_KEY)) != 0 )
    {   LM_ERR("Error in bdblib_makekey\n");
        ret = -6;
        goto error;
    }

    key.data = kbuf;
    key.ulen = MAX_ROW_SIZE;
    key.flags = DB_DBT_USERMEM;
    key.size = klen;

    if ((ret = db->del(db, NULL, &key, 0)) == 0)
    {
        bdblib_log(JLOG_DELETE, _tp, kbuf, klen);

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("DELETED ROW \n KEY: %s \n", (char *)key.data);
#endif
    }
    else
    {   /*Berkeley DB error handler*/
        switch(ret) {

        case DB_NOTFOUND:
            ret = 0;
            break;

        /*The following are all critical/fatal */
        case DB_LOCK_DEADLOCK:
        /* The operation was selected to resolve a deadlock. */
        case DB_SECONDARY_BAD:
        /* A secondary index references a nonexistent primary key. */
        case DB_RUNRECOVERY:
        default:
            LM_CRIT("DB->del error: %s.\n"
                    , db_strerror(ret));
            bdblib_recover(_tp, ret);
            goto error;
        }
    }

    ret = 0;

error:
    if(lkey)
        pkg_free(lkey);

    return ret;

}
Exemplo n.º 3
0
/*
 * Insert a row into table
 */
int bdb_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n)
{
    tbl_cache_p _tbc = NULL;
    table_p _tp = NULL;
    char kbuf[MAX_ROW_SIZE];
    char dbuf[MAX_ROW_SIZE];
    int i, j, ret, klen, dlen;
    int *lkey=NULL;
    DBT key, data;
    DB *db;
    str s;

    i = j = ret = 0;
    klen=MAX_ROW_SIZE;
    dlen=MAX_ROW_SIZE;

    if ((!_h) || (!_v) || !CON_TABLE(_h))
    {   return -1;
    }

    if (!_k)
    {
#ifdef BDB_EXTRA_DEBUG
        LM_ERR("DB INSERT without KEYs not implemented! \n");
#endif
        return -2;
    }

    s.s = (char*)CON_TABLE(_h);
    s.len = strlen(CON_TABLE(_h));

    _tbc = bdblib_get_table(BDB_CON_CONNECTION(_h), &s);
    if(!_tbc)
    {   LM_WARN("table does not exist!\n");
        return -3;
    }

    _tp = _tbc->dtp;
    if(!_tp)
    {   LM_WARN("table not loaded!\n");
        return -4;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("INSERT in %.*s\n", _tp->name.len, _tp->name.s );
#endif

    db = _tp->db;
    memset(&key, 0, sizeof(DBT));
    memset(kbuf, 0, klen);

    if(_tp->ncols<_n)
    {   LM_WARN("more values than columns!!\n");
        return -5;
    }

    lkey = bdb_get_colmap(_tp, _k, _n);
    if(!lkey)  return -7;

    /* verify col types provided */
    for(i=0; i<_n; i++)
    {   j = (lkey)?lkey[i]:i;
        if(bdb_is_neq_type(_tp->colp[j]->type, _v[i].type))
        {
            LM_WARN("incompatible types v[%d] - c[%d]!\n", i, j);
            ret = -8;
            goto error;
        }
    }

    /* make the key */
    if ( (ret = bdblib_valtochar(_tp, lkey, kbuf, &klen, _v, _n, BDB_KEY)) != 0 )
    {   LM_ERR("Error in bdblib_valtochar  \n");
        ret = -9;
        goto error;
    }

    key.data = kbuf;
    key.ulen = MAX_ROW_SIZE;
    key.flags = DB_DBT_USERMEM;
    key.size = klen;

    //make the value (row)
    memset(&data, 0, sizeof(DBT));
    memset(dbuf, 0, MAX_ROW_SIZE);

    if ( (ret = bdblib_valtochar(_tp, lkey, dbuf, &dlen, _v, _n, BDB_VALUE)) != 0 )
    {   LM_ERR("Error in bdblib_valtochar \n");
        ret = -9;
        goto error;
    }

    data.data = dbuf;
    data.ulen = MAX_ROW_SIZE;
    data.flags = DB_DBT_USERMEM;
    data.size = dlen;

    if ((ret = db->put(db, NULL, &key, &data, 0)) == 0)
    {
        bdblib_log(JLOG_INSERT, _tp, dbuf, dlen);

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("INSERT\nKEY:  [%.*s]\nDATA: [%.*s]\n"
               , (int)   key.size
               , (char *)key.data
               , (int)   data.size
               , (char *)data.data);
#endif
    }
    else
    {   /*Berkeley DB error handler*/
        switch(ret)
        {
        /*The following are all critical/fatal */
        case DB_LOCK_DEADLOCK:
        /* The operation was selected to resolve a deadlock. */

        case DB_RUNRECOVERY:
        default:
            LM_CRIT("DB->put error: %s.\n", db_strerror(ret));
            bdblib_recover(_tp, ret);
            goto error;
        }
    }

error:
    if(lkey)
        pkg_free(lkey);

    return ret;

}
Exemplo n.º 4
0
/*
 * Query table for specified rows
 * _con: structure representing database connection
 * _k: key names
 * _op: operators
 * _v: values of the keys that must match
 * _c: column names to return
 * _n: number of key=values pairs to compare
 * _nc: number of columns to return
 * _o: order by the specified column
 */
int bdb_query(db_con_t* _con, db_key_t* _k, db_op_t* _op, db_val_t* _v,
              db_key_t* _c, int _n, int _nc, db_key_t _o, db_res_t** _r)
{
    tbl_cache_p _tbc = NULL;
    table_p _tp = NULL;
    char kbuf[MAX_ROW_SIZE];
    char dbuf[MAX_ROW_SIZE];
    u_int32_t i, len, ret;
    int klen=MAX_ROW_SIZE;
    int *lkey=NULL, *lres=NULL;
    str s;
    DBT key, data;
    DB *db;
    DBC *dbcp;

    if ((!_con) || (!_r) || !CON_TABLE(_con))
    {
#ifdef BDB_EXTRA_DEBUG
        LM_ERR("Invalid parameter value\n");
#endif
        return -1;
    }
    *_r = NULL;

    /*check if underlying DB file has changed inode */
    if(auto_reload)
        bdb_check_reload(_con);

    s.s = (char*)CON_TABLE(_con);
    s.len = strlen(CON_TABLE(_con));

    _tbc = bdblib_get_table(BDB_CON_CONNECTION(_con), &s);
    if(!_tbc)
    {   LM_WARN("table does not exist!\n");
        return -1;
    }

    _tp = _tbc->dtp;
    if(!_tp)
    {   LM_WARN("table not loaded!\n");
        return -1;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("QUERY in %.*s\n", _tp->name.len, _tp->name.s);

    if (_o)  LM_DBG("DONT-CARE : _o: order by the specified column \n");
    if (_op) LM_DBG("DONT-CARE : _op: operators for refining query \n");
#endif

    db = _tp->db;
    if(!db) return -1;

    memset(&key, 0, sizeof(DBT));
    memset(kbuf, 0, MAX_ROW_SIZE);
    memset(&data, 0, sizeof(DBT));
    memset(dbuf, 0, MAX_ROW_SIZE);

    data.data = dbuf;
    data.ulen = MAX_ROW_SIZE;
    data.flags = DB_DBT_USERMEM;

    /* if _c is NULL and _nc is zero, you will get all table
       columns in the result
    */
    if (_c)
    {   lres = bdb_get_colmap(_tbc->dtp, _c, _nc);
        if(!lres)
        {   ret = -1;
            goto error;
        }
    }

    if(_k)
    {   lkey = bdb_get_colmap(_tbc->dtp, _k, _n);
        if(!lkey)
        {   ret = -1;
            goto error;
        }
    }
    else
    {
        DB_HASH_STAT st;
        memset(&st, 0, sizeof(DB_HASH_STAT));
        i =0 ;

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("SELECT * FROM %.*s\n", _tp->name.len, _tp->name.s);
#endif

        /* Acquire a cursor for the database. */
        if ((ret = db->cursor(db, NULL, &dbcp, 0)) != 0)
        {   LM_ERR("Error creating cursor\n");
            goto error;
        }

        /*count the number of records*/
        while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
        {   if(!strncasecmp((char*)key.data,"METADATA",8))
                continue;
            i++;
        }

        dbcp->c_close(dbcp);
        ret=0;

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("%i = SELECT COUNT(*) FROM %.*s\n", i, _tp->name.len, _tp->name.s);
#endif

        *_r = db_new_result();
        if (!*_r)
        {   LM_ERR("no memory left for result \n");
            ret = -2;
            goto error;
        }

        if(i == 0)
        {
            /*return empty table*/
            RES_ROW_N(*_r) = 0;
            BDB_CON_RESULT(_con) = *_r;
            return 0;
        }

        /*allocate N rows in the result*/
        RES_ROW_N(*_r) = i;
        len  = sizeof(db_row_t) * i;
        RES_ROWS(*_r) = (db_row_t*)pkg_malloc( len );
        memset(RES_ROWS(*_r), 0, len);

        /*fill in the column part of db_res_t (metadata) */
        if ((ret = bdb_get_columns(_tbc->dtp, *_r, lres, _nc)) < 0)
        {   LM_ERR("Error while getting column names\n");
            goto error;
        }

        /* Acquire a cursor for the database. */
        if ((ret = db->cursor(db, NULL, &dbcp, 0)) != 0)
        {   LM_ERR("Error creating cursor\n");
            goto error;
        }

        /*convert each record into a row in the result*/
        i =0 ;
        while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
        {
            if(!strncasecmp((char*)key.data,"METADATA",8))
                continue;

#ifdef BDB_EXTRA_DEBUG
            LM_DBG("KEY: [%.*s]\nDATA: [%.*s]\n"
                   , (int)   key.size
                   , (char *)key.data
                   , (int)   data.size
                   , (char *)data.data);
#endif

            /*fill in the row part of db_res_t */
            if ((ret=bdb_append_row( *_r, dbuf, lres, i)) < 0)
            {   LM_ERR("Error while converting row\n");
                goto error;
            }
            i++;
        }

        dbcp->c_close(dbcp);
        BDB_CON_RESULT(_con) = *_r;
        return 0;
    }

    if ( (ret = bdblib_valtochar(_tp, lkey, kbuf, &klen, _v, _n, BDB_KEY)) != 0 )
    {   LM_ERR("error in query key \n");
        goto error;
    }

    key.data = kbuf;
    key.ulen = MAX_ROW_SIZE;
    key.flags = DB_DBT_USERMEM;
    key.size = klen;

    data.data = dbuf;
    data.ulen = MAX_ROW_SIZE;
    data.flags = DB_DBT_USERMEM;

    /*create an empty db_res_t which gets returned even if no result*/
    *_r = db_new_result();
    if (!*_r)
    {   LM_ERR("no memory left for result \n");
        ret = -2;
        goto error;
    }
    RES_ROW_N(*_r) = 0;
    BDB_CON_RESULT(_con) = *_r;

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("SELECT  KEY: [%.*s]\n"
           , (int)   key.size
           , (char *)key.data );
#endif

    /*query Berkely DB*/
    if ((ret = db->get(db, NULL, &key, &data, 0)) == 0)
    {
#ifdef BDB_EXTRA_DEBUG
        LM_DBG("RESULT\nKEY:  [%.*s]\nDATA: [%.*s]\n"
               , (int)   key.size
               , (char *)key.data
               , (int)   data.size
               , (char *)data.data);
#endif

        /*fill in the col part of db_res_t */
        if ((ret = bdb_get_columns(_tbc->dtp, *_r, lres, _nc)) < 0)
        {   LM_ERR("Error while getting column names\n");
            goto error;
        }
        /*fill in the row part of db_res_t */
        if ((ret=bdb_convert_row( *_r, dbuf, lres)) < 0)
        {   LM_ERR("Error while converting row\n");
            goto error;
        }

    }
    else
    {
        /*Berkeley DB error handler*/
        switch(ret)
        {

        case DB_NOTFOUND:

#ifdef BDB_EXTRA_DEBUG
            LM_DBG("NO RESULT for QUERY \n");
#endif

            ret=0;
            break;
        /*The following are all critical/fatal */
        case DB_LOCK_DEADLOCK:
        // The operation was selected to resolve a deadlock.
        case DB_SECONDARY_BAD:
        // A secondary index references a nonexistent primary key.
        case DB_RUNRECOVERY:
        default:
            LM_CRIT("DB->get error: %s.\n", db_strerror(ret));
            bdblib_recover(_tp,ret);
            goto error;
        }
    }

    if(lkey)
        pkg_free(lkey);
    if(lres)
        pkg_free(lres);

    return ret;

error:
    if(lkey)
        pkg_free(lkey);
    if(lres)
        pkg_free(lres);
    if(*_r)
        bdb_free_result(*_r);
    *_r = NULL;

    return ret;
}
Exemplo n.º 5
0
/*
 * Updates a row in table
 * Limitation: only knows how to update a single row
 *
 * _con: structure representing database connection
 * _k: key names
 * _op: operators
 * _v: values of the keys that must match
 * _uk: update keys; cols that need to be updated
 * _uv: update values; col values that need to be commited
 * _un: number of rows to update
 */
int bdb_update(db_con_t* _con, db_key_t* _k, db_op_t* _op, db_val_t* _v,
               db_key_t* _uk, db_val_t* _uv, int _n, int _un)
{
    str s;
    char *c, *t;
    int ret, i, qcol, len, sum;
    int *lkey=NULL;
    tbl_cache_p _tbc = NULL;
    table_p _tp = NULL;
    char kbuf[MAX_ROW_SIZE];
    char qbuf[MAX_ROW_SIZE];
    char ubuf[MAX_ROW_SIZE];
    DBT key, qdata, udata;
    DB *db;

    sum = ret = i = qcol = len = 0;

    if (!_con || !CON_TABLE(_con) || !_uk || !_uv || _un <= 0)
        return -1;

    s.s = (char*)CON_TABLE(_con);
    s.len = strlen(CON_TABLE(_con));

    _tbc = bdblib_get_table(BDB_CON_CONNECTION(_con), &s);
    if(!_tbc)
    {   LM_ERR("table does not exist\n");
        return -1;
    }

    _tp = _tbc->dtp;
    if(!_tp)
    {   LM_ERR("table not loaded\n");
        return -1;
    }

    db = _tp->db;
    if(!db)
    {   LM_ERR("DB null ptr\n");
        return -1;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("UPDATE in %.*s\n", _tp->name.len, _tp->name.s);
    if (_op) LM_DBG("DONT-CARE : _op: operators for refining query \n");
#endif

    memset(&key, 0, sizeof(DBT));
    memset(kbuf, 0, MAX_ROW_SIZE);
    memset(&qdata, 0, sizeof(DBT));
    memset(qbuf, 0, MAX_ROW_SIZE);

    qdata.data = qbuf;
    qdata.ulen = MAX_ROW_SIZE;
    qdata.flags = DB_DBT_USERMEM;

    if(_k)
    {   lkey = bdb_get_colmap(_tbc->dtp, _k, _n);
        if(!lkey) return -4;
    }
    else
    {
        LM_ERR("Null keys in update _k=0 \n");
        return -1;
    }

    len = MAX_ROW_SIZE;

    if ( (ret = bdblib_valtochar(_tp, lkey, kbuf, &len, _v, _n, BDB_KEY)) != 0 )
    {   LM_ERR("Error in query key \n");
        goto cleanup;
    }

    if(lkey) pkg_free(lkey);

    key.data = kbuf;
    key.ulen = MAX_ROW_SIZE;
    key.flags = DB_DBT_USERMEM;
    key.size = len;

    /*stage 1: QUERY Berkely DB*/
    if ((ret = db->get(db, NULL, &key, &qdata, 0)) == 0)
    {

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("RESULT\nKEY:  [%.*s]\nDATA: [%.*s]\n"
               , (int)   key.size
               , (char *)key.data
               , (int)   qdata.size
               , (char *)qdata.data);
#endif

    }
    else
    {   goto db_error;
    }

    /* stage 2: UPDATE row with new values */

    /* map the provided keys to those in our schema */
    lkey = bdb_get_colmap(_tbc->dtp, _uk, _un);
    if(!lkey) return -4;

    /* build a new row for update data (udata) */
    memset(&udata, 0, sizeof(DBT));
    memset(ubuf, 0, MAX_ROW_SIZE);

    /* loop over each column of the qbuf and copy it to our new ubuf unless
       its a field that needs to update
    */
    c = strtok(qbuf, DELIM);
    t = ubuf;
    while( c!=NULL)
    {   char* delim = DELIM;
        int k;

        len = strlen(c);
        sum+=len;

        if(sum > MAX_ROW_SIZE)
        {   LM_ERR("value too long for string \n");
            ret = -3;
            goto cleanup;
        }

        for(i=0; i<_un; i++)
        {
            k = lkey[i];
            if (qcol == k)
            {   /* update this col */
                int j = MAX_ROW_SIZE - sum;
                if( bdb_val2str( &_uv[i], t, &j) )
                {   LM_ERR("value too long for string \n");
                    ret = -3;
                    goto cleanup;
                }

                goto next;
            }

        }

        /* copy original column to the new column */
        strncpy(t, c, len);

next:
        t+=len;

        /* append DELIM */
        sum += DELIM_LEN;
        if(sum > MAX_ROW_SIZE)
        {   LM_ERR("value too long for string \n");
            ret = -3;
            goto cleanup;
        }

        strncpy(t, delim, DELIM_LEN);
        t += DELIM_LEN;

        c = strtok(NULL, DELIM);
        qcol++;
    }

    ubuf[sum]  = '0';
    udata.data = ubuf;
    udata.ulen  = MAX_ROW_SIZE;
    udata.flags = DB_DBT_USERMEM;
    udata.size  = sum;

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("MODIFIED Data\nKEY:  [%.*s]\nDATA: [%.*s]\n"
           , (int)   key.size
           , (char *)key.data
           , (int)   udata.size
           , (char *)udata.data);
#endif
    /* stage 3: DELETE old row using key*/
    if ((ret = db->del(db, NULL, &key, 0)) == 0)
    {
#ifdef BDB_EXTRA_DEBUG
        LM_DBG("DELETED ROW\nKEY: %s \n", (char *)key.data);
#endif
    }
    else
    {   goto db_error;
    }

    /* stage 4: INSERT new row with key*/
    if ((ret = db->put(db, NULL, &key, &udata, 0)) == 0)
    {
        bdblib_log(JLOG_UPDATE, _tp, ubuf, sum);
#ifdef BDB_EXTRA_DEBUG
        LM_DBG("INSERT \nKEY:  [%.*s]\nDATA: [%.*s]\n"
               , (int)   key.size
               , (char *)key.data
               , (int)   udata.size
               , (char *)udata.data);
#endif
    }
    else
    {   goto db_error;
    }

#ifdef BDB_EXTRA_DEBUG
    LM_DBG("UPDATE COMPLETE \n");
#endif


cleanup:
    if(lkey)
        pkg_free(lkey);

    return ret;


db_error:

    /*Berkeley DB error handler*/
    switch(ret)
    {

    case DB_NOTFOUND:

#ifdef BDB_EXTRA_DEBUG
        LM_DBG("NO RESULT \n");
#endif
        return -1;

    /* The following are all critical/fatal */
    case DB_LOCK_DEADLOCK:
    /* The operation was selected to resolve a deadlock. */
    case DB_SECONDARY_BAD:
    /* A secondary index references a nonexistent primary key.*/
    case DB_RUNRECOVERY:
    default:
        LM_CRIT("DB->get error: %s.\n", db_strerror(ret));
        bdblib_recover(_tp,ret);
    }

    if(lkey)
        pkg_free(lkey);

    return ret;
}
Exemplo n.º 6
0
/** opens the underlying Berkeley DB.
  assumes the lib data-structures are already initialzed;
  used to sync and reload the db file.
*/
int bdblib_reopen(bdb_db_p _db_p, str *dirpath)
{
	int rc, flags;
	bdb_tcache_p _tbc;
	DB* _db = NULL;
	DB_ENV* _env = NULL;
	rc = flags = 0;
	_tbc = NULL;
	
	if (_db_p==NULL || dirpath==NULL)
		return -1;

	
	if (_db_p)
	{
		DBG("bdb: DB not found %.*s \n", dirpath->len, dirpath->s);
		return 1; /*table not found*/
	}
	
	_env = _db_p->dbenv;
	_tbc = _db_p->tables;
		
	if(dirpath->len ==_db_p->name.len && 
		!strncasecmp(dirpath->s, _db_p->name.s, _db_p->name.len))
	{
		//open the whole dbenv
		DBG("-- bdblib_reopen ENV %.*s \n", dirpath->len, dirpath->s);
		if(!_db_p->dbenv)
		{
			rc = bdblib_create_dbenv(&_env, dirpath->s);
			_db_p->dbenv = _env;
		}
			
		if(rc!=0) return rc;

		_env = _db_p->dbenv;
		_tbc = _db_p->tables;

		while(_tbc)
		{
			if(_tbc->dtp)
			{
				if(!_tbc->dtp->db)
				{
					if ((rc = db_create(&_db, _env, 0)) != 0)
					{
						_env->err(_env, rc, "db_create");
						ERR("error in db_create, db error: %s.\n",
								db_strerror(rc));
						bdblib_recover(_tbc->dtp, rc);
					}
				}
					
				if ((rc = _db->open(_db, NULL, dirpath->s, NULL, DB_HASH,
								DB_CREATE, 0664)) != 0)
				{
					_db->dbenv->err(_env, rc, "DB->open: %s", dirpath->s);
					ERR("error in db_open: %s.\n",db_strerror(rc));
					bdblib_recover(_tbc->dtp, rc);
				}
					
				_tbc->dtp->db = _db;
			}
			_tbc = _tbc->next;
		}
		_env->close(_env, 0);
		return rc;
	}
		
	// open a particular db
	while(_tbc)
	{
		if(_tbc->dtp)
		{
			ERR("checking DB %.*s \n", _tbc->dtp->name.len, _tbc->dtp->name.s);
				
			if(_tbc->dtp->name.len == dirpath->len && 
				!strncasecmp(_tbc->dtp->name.s, dirpath->s, dirpath->len ))
			{
				ERR("DB %.*s \n", dirpath->len, dirpath->s);
				if(!_tbc->dtp->db) 
				{
					if ((rc = db_create(&_db, _env, 0)) != 0)
					{
						_env->err(_env, rc, "db_create");
						ERR("error in db_create, db error: %s.\n",
								db_strerror(rc));
						bdblib_recover(_tbc->dtp, rc);
					}
				}
					
				if ((rc = _db->open(_db, NULL, dirpath->s, NULL, DB_HASH,
								DB_CREATE, 0664)) != 0)
				{
					_db->dbenv->err(_env, rc, "DB->open: %s", dirpath->s);
					ERR("bdb open: %s.\n",db_strerror(rc));
					bdblib_recover(_tbc->dtp, rc);
				}
				_tbc->dtp->db = _db;
				return rc;
			}
		}
		_tbc = _tbc->next;
	}

	DBG("DB not found %.*s \n", dirpath->len, dirpath->s);
	return 1; /*table not found*/
}