|
97 | 97 | #error "eek! DBVER can't handle minor versions > 9" |
98 | 98 | #endif |
99 | 99 |
|
100 | | -#define PY_BSDDB_VERSION "4.2.7" |
| 100 | +#define PY_BSDDB_VERSION "4.2.8" |
101 | 101 | static char *rcs_id = "$Id$"; |
102 | 102 |
|
103 | 103 |
|
@@ -1463,6 +1463,94 @@ DB_get(DBObject* self, PyObject* args, PyObject* kwargs) |
1463 | 1463 | return retval; |
1464 | 1464 | } |
1465 | 1465 |
|
| 1466 | +static PyObject* |
| 1467 | +DB_pget(DBObject* self, PyObject* args, PyObject* kwargs) |
| 1468 | +{ |
| 1469 | + int err, flags=0; |
| 1470 | + PyObject* txnobj = NULL; |
| 1471 | + PyObject* keyobj; |
| 1472 | + PyObject* dfltobj = NULL; |
| 1473 | + PyObject* retval = NULL; |
| 1474 | + int dlen = -1; |
| 1475 | + int doff = -1; |
| 1476 | + DBT key, pkey, data; |
| 1477 | + DB_TXN *txn = NULL; |
| 1478 | + char* kwnames[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL}; |
| 1479 | + |
| 1480 | + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames, |
| 1481 | + &keyobj, &dfltobj, &txnobj, &flags, &dlen, |
| 1482 | + &doff)) |
| 1483 | + return NULL; |
| 1484 | + |
| 1485 | + CHECK_DB_NOT_CLOSED(self); |
| 1486 | + if (!make_key_dbt(self, keyobj, &key, &flags)) |
| 1487 | + return NULL; |
| 1488 | + if (!checkTxnObj(txnobj, &txn)) { |
| 1489 | + FREE_DBT(key); |
| 1490 | + return NULL; |
| 1491 | + } |
| 1492 | + |
| 1493 | + CLEAR_DBT(data); |
| 1494 | + if (CHECK_DBFLAG(self, DB_THREAD)) { |
| 1495 | + /* Tell BerkeleyDB to malloc the return value (thread safe) */ |
| 1496 | + data.flags = DB_DBT_MALLOC; |
| 1497 | + } |
| 1498 | + if (!add_partial_dbt(&data, dlen, doff)) { |
| 1499 | + FREE_DBT(key); |
| 1500 | + return NULL; |
| 1501 | + } |
| 1502 | + |
| 1503 | + CLEAR_DBT(pkey); |
| 1504 | + pkey.flags = DB_DBT_MALLOC; |
| 1505 | + |
| 1506 | + MYDB_BEGIN_ALLOW_THREADS; |
| 1507 | + err = self->db->pget(self->db, txn, &key, &pkey, &data, flags); |
| 1508 | + MYDB_END_ALLOW_THREADS; |
| 1509 | + |
| 1510 | + if ((err == DB_NOTFOUND) && (dfltobj != NULL)) { |
| 1511 | + err = 0; |
| 1512 | + Py_INCREF(dfltobj); |
| 1513 | + retval = dfltobj; |
| 1514 | + } |
| 1515 | + else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) { |
| 1516 | + err = 0; |
| 1517 | + Py_INCREF(Py_None); |
| 1518 | + retval = Py_None; |
| 1519 | + } |
| 1520 | + else if (!err) { |
| 1521 | + PyObject *pkeyObj; |
| 1522 | + PyObject *dataObj; |
| 1523 | + dataObj = PyString_FromStringAndSize(data.data, data.size); |
| 1524 | + |
| 1525 | + if (self->primaryDBType == DB_RECNO || |
| 1526 | + self->primaryDBType == DB_QUEUE) |
| 1527 | + pkeyObj = PyInt_FromLong(*(long *)pkey.data); |
| 1528 | + else |
| 1529 | + pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size); |
| 1530 | + |
| 1531 | + if (flags & DB_SET_RECNO) /* return key , pkey and data */ |
| 1532 | + { |
| 1533 | + PyObject *keyObj; |
| 1534 | + int type = _DB_get_type(self); |
| 1535 | + if (type == DB_RECNO || type == DB_QUEUE) |
| 1536 | + keyObj = PyInt_FromLong(*(long *)key.data); |
| 1537 | + else |
| 1538 | + keyObj = PyString_FromStringAndSize(key.data, key.size); |
| 1539 | + retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj); |
| 1540 | + } |
| 1541 | + else /* return just the pkey and data */ |
| 1542 | + { |
| 1543 | + retval = Py_BuildValue("OO", pkeyObj, dataObj); |
| 1544 | + } |
| 1545 | + FREE_DBT(pkey); |
| 1546 | + FREE_DBT(data); |
| 1547 | + } |
| 1548 | + FREE_DBT(key); |
| 1549 | + |
| 1550 | + RETURN_IF_ERR(); |
| 1551 | + return retval; |
| 1552 | +} |
| 1553 | + |
1466 | 1554 |
|
1467 | 1555 | /* Return size of entry */ |
1468 | 1556 | static PyObject* |
@@ -2827,6 +2915,106 @@ DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs) |
2827 | 2915 | return retval; |
2828 | 2916 | } |
2829 | 2917 |
|
| 2918 | +static PyObject* |
| 2919 | +DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs) |
| 2920 | +{ |
| 2921 | + int err, flags=0; |
| 2922 | + PyObject* keyobj = NULL; |
| 2923 | + PyObject* dataobj = NULL; |
| 2924 | + PyObject* retval = NULL; |
| 2925 | + int dlen = -1; |
| 2926 | + int doff = -1; |
| 2927 | + DBT key, pkey, data; |
| 2928 | + char* kwnames[] = { "key","data", "flags", "dlen", "doff", NULL }; |
| 2929 | + |
| 2930 | + CLEAR_DBT(key); |
| 2931 | + CLEAR_DBT(data); |
| 2932 | + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2], |
| 2933 | + &flags, &dlen, &doff)) |
| 2934 | + { |
| 2935 | + PyErr_Clear(); |
| 2936 | + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget", |
| 2937 | + &kwnames[1], |
| 2938 | + &keyobj, &flags, &dlen, &doff)) |
| 2939 | + { |
| 2940 | + PyErr_Clear(); |
| 2941 | + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget", |
| 2942 | + kwnames, &keyobj, &dataobj, |
| 2943 | + &flags, &dlen, &doff)) |
| 2944 | + { |
| 2945 | + return NULL; |
| 2946 | + } |
| 2947 | + } |
| 2948 | + } |
| 2949 | + |
| 2950 | + CHECK_CURSOR_NOT_CLOSED(self); |
| 2951 | + |
| 2952 | + if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL)) |
| 2953 | + return NULL; |
| 2954 | + if ( (dataobj && !make_dbt(dataobj, &data)) || |
| 2955 | + (!add_partial_dbt(&data, dlen, doff)) ) { |
| 2956 | + FREE_DBT(key); |
| 2957 | + return NULL; |
| 2958 | + } |
| 2959 | + |
| 2960 | + if (CHECK_DBFLAG(self->mydb, DB_THREAD)) { |
| 2961 | + data.flags = DB_DBT_MALLOC; |
| 2962 | + if (!(key.flags & DB_DBT_REALLOC)) { |
| 2963 | + key.flags |= DB_DBT_MALLOC; |
| 2964 | + } |
| 2965 | + } |
| 2966 | + |
| 2967 | + CLEAR_DBT(pkey); |
| 2968 | + pkey.flags = DB_DBT_MALLOC; |
| 2969 | + |
| 2970 | + MYDB_BEGIN_ALLOW_THREADS; |
| 2971 | + err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags); |
| 2972 | + MYDB_END_ALLOW_THREADS; |
| 2973 | + |
| 2974 | + if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) { |
| 2975 | + Py_INCREF(Py_None); |
| 2976 | + retval = Py_None; |
| 2977 | + } |
| 2978 | + else if (makeDBError(err)) { |
| 2979 | + retval = NULL; |
| 2980 | + } |
| 2981 | + else { |
| 2982 | + PyObject *pkeyObj; |
| 2983 | + PyObject *dataObj; |
| 2984 | + dataObj = PyString_FromStringAndSize(data.data, data.size); |
| 2985 | + |
| 2986 | + if (self->mydb->primaryDBType == DB_RECNO || |
| 2987 | + self->mydb->primaryDBType == DB_QUEUE) |
| 2988 | + pkeyObj = PyInt_FromLong(*(long *)pkey.data); |
| 2989 | + else |
| 2990 | + pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size); |
| 2991 | + |
| 2992 | + if (flags & DB_SET_RECNO) /* return key, pkey and data */ |
| 2993 | + { |
| 2994 | + PyObject *keyObj; |
| 2995 | + int type = _DB_get_type(self->mydb); |
| 2996 | + if (type == DB_RECNO || type == DB_QUEUE) |
| 2997 | + keyObj = PyInt_FromLong(*(long *)key.data); |
| 2998 | + else |
| 2999 | + keyObj = PyString_FromStringAndSize(key.data, key.size); |
| 3000 | + retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj); |
| 3001 | + FREE_DBT(key); |
| 3002 | + } |
| 3003 | + else /* return just the pkey and data */ |
| 3004 | + { |
| 3005 | + retval = Py_BuildValue("OO", pkeyObj, dataObj); |
| 3006 | + } |
| 3007 | + FREE_DBT(pkey); |
| 3008 | + FREE_DBT(data); |
| 3009 | + } |
| 3010 | + /* the only time REALLOC should be set is if we used an integer |
| 3011 | + * key that make_key_dbt malloc'd for us. always free these. */ |
| 3012 | + if (key.flags & DB_DBT_REALLOC) { |
| 3013 | + FREE_DBT(key); |
| 3014 | + } |
| 3015 | + return retval; |
| 3016 | +} |
| 3017 | + |
2830 | 3018 |
|
2831 | 3019 | static PyObject* |
2832 | 3020 | DBC_get_recno(DBCursorObject* self, PyObject* args) |
@@ -2974,8 +3162,13 @@ DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs) |
2974 | 3162 | break; |
2975 | 3163 | } |
2976 | 3164 | FREE_DBT(data); |
| 3165 | + FREE_DBT(key); |
| 3166 | + } |
| 3167 | + /* the only time REALLOC should be set is if we used an integer |
| 3168 | + * key that make_key_dbt malloc'd for us. always free these. */ |
| 3169 | + if (key.flags & DB_DBT_REALLOC) { |
| 3170 | + FREE_DBT(key); |
2977 | 3171 | } |
2978 | | - FREE_DBT(key); |
2979 | 3172 |
|
2980 | 3173 | return retval; |
2981 | 3174 | } |
@@ -3044,7 +3237,7 @@ DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs) |
3044 | 3237 | FREE_DBT(data); |
3045 | 3238 | } |
3046 | 3239 | /* the only time REALLOC should be set is if we used an integer |
3047 | | - * key that make_dbt_key malloc'd for us. always free these. */ |
| 3240 | + * key that make_key_dbt malloc'd for us. always free these. */ |
3048 | 3241 | if (key.flags & DB_DBT_REALLOC) { |
3049 | 3242 | FREE_DBT(key); |
3050 | 3243 | } |
@@ -4183,6 +4376,7 @@ static PyMethodDef DB_methods[] = { |
4183 | 4376 | {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS}, |
4184 | 4377 | {"fd", (PyCFunction)DB_fd, METH_VARARGS}, |
4185 | 4378 | {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS}, |
| 4379 | + {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS}, |
4186 | 4380 | {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS}, |
4187 | 4381 | {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS}, |
4188 | 4382 | {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS}, |
@@ -4242,6 +4436,7 @@ static PyMethodDef DBCursor_methods[] = { |
4242 | 4436 | {"dup", (PyCFunction)DBC_dup, METH_VARARGS}, |
4243 | 4437 | {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS}, |
4244 | 4438 | {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS}, |
| 4439 | + {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS}, |
4245 | 4440 | {"get_recno", (PyCFunction)DBC_get_recno, METH_VARARGS}, |
4246 | 4441 | {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS}, |
4247 | 4442 | {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS}, |
|
0 commit comments