pyresultstore: implement sequence protocol

This commit is contained in:
Jean-Francois Dockes 2020-12-19 10:41:08 +01:00
parent 66ecb9ec6b
commit b4eb0cacef
3 changed files with 59 additions and 38 deletions

View File

@ -369,6 +369,8 @@ Doc_setbinurl(recoll_DocObject *self, PyObject *value)
self->doc->url = string(PyByteArray_AsString(value), self->doc->url = string(PyByteArray_AsString(value),
PyByteArray_Size(value)); PyByteArray_Size(value));
printableUrl(self->rclconfig->getDefCharset(), self->doc->url,
self->doc->meta[Rcl::Doc::keyurl]);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -539,7 +541,7 @@ static PyMethodDef Doc_methods[] = {
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
static int pys2cpps(PyObject *pyval, std::string& out) int pys2cpps(PyObject *pyval, std::string& out)
{ {
if (PyUnicode_Check(pyval)) { if (PyUnicode_Check(pyval)) {
PyObject* utf8o = PyUnicode_AsUTF8String(pyval); PyObject* utf8o = PyUnicode_AsUTF8String(pyval);

View File

@ -59,4 +59,6 @@ extern PyTypeObject rclx_ExtractorType;
extern PyTypeObject recoll_QResultStoreType; extern PyTypeObject recoll_QResultStoreType;
extern PyTypeObject recoll_QRSDocType; extern PyTypeObject recoll_QRSDocType;
extern int pys2cpps(PyObject *pyval, std::string& out);
#endif // _PYRECOLL_H_INCLUDED_ #endif // _PYRECOLL_H_INCLUDED_

View File

@ -27,6 +27,7 @@
#include "pyrecoll.h" #include "pyrecoll.h"
#include "log.h" #include "log.h"
#include "rclutil.h"
using namespace std; using namespace std;
@ -36,6 +37,8 @@ using namespace std;
#define PyLong_FromLong PyInt_FromLong #define PyLong_FromLong PyInt_FromLong
#endif #endif
struct recoll_QRSDocObject;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
/* Type-specific fields go here. */ /* Type-specific fields go here. */
@ -45,7 +48,7 @@ typedef struct {
static void static void
QResultStore_dealloc(recoll_QResultStoreObject *self) QResultStore_dealloc(recoll_QResultStoreObject *self)
{ {
LOGDEB("QResultStore_dealloc.\n"); LOGDEB1("QResultStore_dealloc.\n");
delete self->store; delete self->store;
Py_TYPE(self)->tp_free((PyObject*)self); Py_TYPE(self)->tp_free((PyObject*)self);
} }
@ -53,10 +56,9 @@ QResultStore_dealloc(recoll_QResultStoreObject *self)
static PyObject * static PyObject *
QResultStore_new(PyTypeObject *type, PyObject *args, PyObject *kwds) QResultStore_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
LOGDEB("QResultStore_new\n"); LOGDEB1("QResultStore_new\n");
recoll_QResultStoreObject *self; recoll_QResultStoreObject *self =
(recoll_QResultStoreObject *)type->tp_alloc(type, 0);
self = (recoll_QResultStoreObject *)type->tp_alloc(type, 0);
if (self == 0) if (self == 0)
return 0; return 0;
self->store = new Rcl::QResultStore(); self->store = new Rcl::QResultStore();
@ -89,6 +91,7 @@ static PyObject *
QResultStore_storeQuery(recoll_QResultStoreObject* self, PyObject *args, QResultStore_storeQuery(recoll_QResultStoreObject* self, PyObject *args,
PyObject *kwargs) PyObject *kwargs)
{ {
LOGDEB0("QResultStore_storeQuery\n");
static const char* kwlist[] = {"query", "fieldspec", "isinc", NULL}; static const char* kwlist[] = {"query", "fieldspec", "isinc", NULL};
PyObject *q{nullptr}; PyObject *q{nullptr};
PyObject *fieldspec{nullptr}; PyObject *fieldspec{nullptr};
@ -142,20 +145,6 @@ QResultStore_storeQuery(recoll_QResultStoreObject* self, PyObject *args,
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyDoc_STRVAR(
qrs_doc_getCount,
"getCount()\n"
"\n"
"Return the stored results count.\n"
);
static PyObject *
QResultStore_getCount(recoll_QResultStoreObject* self, PyObject *args)
{
return PyLong_FromLong(self->store->getCount());
}
PyDoc_STRVAR( PyDoc_STRVAR(
qrs_doc_getField, qrs_doc_getField,
"getField(index, fieldname)\n" "getField(index, fieldname)\n"
@ -181,8 +170,6 @@ QResultStore_getField(recoll_QResultStoreObject* self, PyObject *args)
static PyMethodDef QResultStore_methods[] = { static PyMethodDef QResultStore_methods[] = {
{"storeQuery", (PyCFunction)QResultStore_storeQuery, {"storeQuery", (PyCFunction)QResultStore_storeQuery,
METH_VARARGS|METH_KEYWORDS, qrs_doc_getCount},
{"getCount", (PyCFunction)QResultStore_getCount,
METH_VARARGS|METH_KEYWORDS, qrs_doc_storeQuery}, METH_VARARGS|METH_KEYWORDS, qrs_doc_storeQuery},
{"getField", (PyCFunction)QResultStore_getField, {"getField", (PyCFunction)QResultStore_getField,
METH_VARARGS, qrs_doc_getField}, METH_VARARGS, qrs_doc_getField},
@ -190,6 +177,35 @@ static PyMethodDef QResultStore_methods[] = {
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
static Py_ssize_t QResultStore_Size(PyObject *o)
{
return ((recoll_QResultStoreObject*)o)->store->getCount();
}
static PyObject* QResultStore_GetItem(PyObject *o, Py_ssize_t i)
{
if (i < 0 || i >= ((recoll_QResultStoreObject*)o)->store->getCount()) {
return nullptr;
}
PyObject *args = Py_BuildValue("Oi", o, i);
auto res = PyObject_CallObject((PyObject *)&recoll_QRSDocType, args);
Py_DECREF(args);
return res;
}
static PySequenceMethods resultstore_as_sequence = {
(lenfunc)QResultStore_Size, // sq_length
(binaryfunc)0, // sq_concat
(ssizeargfunc)0, // sq_repeat
(ssizeargfunc)QResultStore_GetItem, // sq_item
0, // was sq_slice
(ssizeobjargproc)0, // sq_ass_item
0, // was sq_ass_slice
(objobjproc)0, // sq_contains
(binaryfunc)0, // sq_inplace_concat
(ssizeargfunc)0, // sq_inplace_repeat
};
PyTypeObject recoll_QResultStoreType = { PyTypeObject recoll_QResultStoreType = {
PyVarObject_HEAD_INIT(NULL, 0) PyVarObject_HEAD_INIT(NULL, 0)
"_recoll.QResultStore", /*tp_name*/ "_recoll.QResultStore", /*tp_name*/
@ -202,7 +218,7 @@ PyTypeObject recoll_QResultStoreType = {
0, /*tp_compare*/ 0, /*tp_compare*/
0, /*tp_repr*/ 0, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ &resultstore_as_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
0, /*tp_hash */ 0, /*tp_hash */
0, /*tp_call*/ 0, /*tp_call*/
@ -233,7 +249,7 @@ PyTypeObject recoll_QResultStoreType = {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// QRSDoc iterator // QRSDoc iterator
typedef struct { typedef struct recoll_QRSDocObject {
PyObject_HEAD PyObject_HEAD
/* Type-specific fields go here. */ /* Type-specific fields go here. */
recoll_QResultStoreObject *pystore; recoll_QResultStoreObject *pystore;
@ -243,6 +259,7 @@ typedef struct {
static void static void
QRSDoc_dealloc(recoll_QRSDocObject *self) QRSDoc_dealloc(recoll_QRSDocObject *self)
{ {
LOGDEB1("QRSDoc_dealloc\n");
Py_DECREF(self->pystore); Py_DECREF(self->pystore);
Py_TYPE(self)->tp_free((PyObject*)self); Py_TYPE(self)->tp_free((PyObject*)self);
} }
@ -287,25 +304,25 @@ QRSDoc_subscript(recoll_QRSDocObject *self, PyObject *key)
return NULL; return NULL;
} }
string name; string name;
if (PyUnicode_Check(key)) { if (pys2cpps(key, name) < 0) {
PyObject* utf8o = PyUnicode_AsUTF8String(key); PyErr_SetString(PyExc_AttributeError, "name??");
if (utf8o == 0) {
PyErr_SetString(PyExc_AttributeError, "name??");
Py_RETURN_NONE;
}
name = PyBytes_AsString(utf8o);
Py_DECREF(utf8o);
} else if (PyBytes_Check(key)) {
name = PyBytes_AsString(key);
} else {
PyErr_SetString(PyExc_AttributeError, "key not unicode nor string??");
Py_RETURN_NONE; Py_RETURN_NONE;
} }
const char *value = self->pystore->store->fieldValue(self->index, name); const char *value = self->pystore->store->fieldValue(self->index, name);
if (nullptr == value) { if (nullptr == value) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
return PyBytes_FromString(value); string urlstring;
if (name == "url") {
printableUrl("UTF-8", value, urlstring);
value = urlstring.c_str();
}
PyObject *bytes = PyBytes_FromString(value);
PyObject *u =
PyUnicode_FromEncodedObject(bytes, "UTF-8", "backslashreplace");
Py_DECREF(bytes);
return u;
} }
static PyMappingMethods qrsdoc_as_mapping = { static PyMappingMethods qrsdoc_as_mapping = {