Merge rpmdbIndexIteratorKey and rpmdbIndexIteratorKeySize into rpmdbIndexIteratorNext
[platform/upstream/rpm.git] / python / rpmii-py.c
1 #include "rpmsystem-py.h"
2
3 #include <rpm/rpmdb.h>
4
5 #include "rpmii-py.h"
6 #include "header-py.h"
7
8 #include "debug.h"
9
10 /** \ingroup python
11  * \class Rpmii
12  * \brief A python rpm.ii key iterator object represents the keys of a
13  *      database index.
14  *
15  * The rpm.ii class conains the following methods:
16  * - next() -> key              Return the next key.
17  *
18  * To obtain a rpm.ii object to query the database used by a transaction,
19  * the ts.dbKeys(tag) method is used.
20  *
21  * Here's an example that prints the name of all installed packages:
22  * \code
23  *      import rpm
24  *      ts = rpm.TransactionSet()
25  *      for name in ts.dbKeys("conflictname"):
26  *          print name
27  * \endcode
28  *
29  * ts.dbMatch() can be used to get the packages containing the keys of interest
30  */
31
32 /** \ingroup python
33  * \name Class: Rpmii
34  */
35
36 struct rpmiiObject_s {
37     PyObject_HEAD
38     PyObject *md_dict;          /*!< to look like PyModuleObject */
39     PyObject *ref;              /* for db/ts refcounting */
40     rpmdbIndexIterator ii;
41 };
42
43 static PyObject *
44 rpmii_iternext(rpmiiObject * s)
45 {
46     char * key;
47     size_t keylen;
48     if (s->ii == NULL || (rpmdbIndexIteratorNext(s->ii, (const void**)&key, &keylen)) != 0) {
49         s->ii = rpmdbIndexIteratorFree(s->ii);
50         return NULL;
51     }
52     return PyString_FromStringAndSize(key, keylen);
53 };
54
55 static PyObject *
56 rpmii_offsets(rpmiiObject * s)
57 {
58     int entries = rpmdbIndexIteratorNumPkgs(s->ii);
59     PyObject * list = PyList_New(0);
60     PyObject * tuple;
61     for (int i = 0; i < entries; i++) {
62         tuple = PyTuple_New(2);
63         PyTuple_SET_ITEM(tuple, 0,
64                          PyInt_FromLong(rpmdbIndexIteratorPkgOffset(s->ii, i)));
65         PyTuple_SET_ITEM(tuple, 1,
66                          PyInt_FromLong(rpmdbIndexIteratorTagNum(s->ii, i)));
67         PyList_Append(list, tuple);
68     }
69     return list;
70 }
71
72 static struct PyMethodDef rpmii_methods[] = {
73     {"offsets",    (PyCFunction) rpmii_offsets,       METH_NOARGS,
74      NULL },
75     {NULL,              NULL}           /* sentinel */
76 };
77
78 static void rpmii_dealloc(rpmiiObject * s)
79 {
80     s->ii = rpmdbIndexIteratorFree(s->ii);
81     Py_DECREF(s->ref);
82     Py_TYPE(s)->tp_free((PyObject *)s);
83 }
84
85 static int rpmii_bool(rpmiiObject *s)
86 {
87     return (s->ii != NULL);
88 }
89
90 static PyNumberMethods rpmii_as_number = {
91         0, /* nb_add */
92         0, /* nb_subtract */
93         0, /* nb_multiply */
94         0, /* nb_divide */
95         0, /* nb_remainder */
96         0, /* nb_divmod */
97         0, /* nb_power */
98         0, /* nb_negative */
99         0, /* nb_positive */
100         0, /* nb_absolute */
101         (inquiry)rpmii_bool, /* nb_bool/nonzero */
102 };
103
104 static char rpmii_doc[] =
105 "";
106
107 PyTypeObject rpmii_Type = {
108         PyVarObject_HEAD_INIT(&PyType_Type, 0)
109         "rpm.ii",                       /* tp_name */
110         sizeof(rpmiiObject),            /* tp_size */
111         0,                              /* tp_itemsize */
112         (destructor) rpmii_dealloc,     /* tp_dealloc */
113         0,                              /* tp_print */
114         (getattrfunc)0,                 /* tp_getattr */
115         0,                              /* tp_setattr */
116         0,                              /* tp_compare */
117         0,                              /* tp_repr */
118         &rpmii_as_number,               /* tp_as_number */
119         0,                              /* tp_as_sequence */
120         0,                              /* tp_as_mapping */
121         0,                              /* tp_hash */
122         0,                              /* tp_call */
123         0,                              /* tp_str */
124         PyObject_GenericGetAttr,        /* tp_getattro */
125         PyObject_GenericSetAttr,        /* tp_setattro */
126         0,                              /* tp_as_buffer */
127         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
128         rpmii_doc,                      /* tp_doc */
129         0,                              /* tp_traverse */
130         0,                              /* tp_clear */
131         0,                              /* tp_richcompare */
132         0,                              /* tp_weaklistoffset */
133         PyObject_SelfIter,              /* tp_iter */
134         (iternextfunc) rpmii_iternext,  /* tp_iternext */
135         rpmii_methods,                  /* tp_methods */
136         0,                              /* tp_members */
137         0,                              /* tp_getset */
138         0,                              /* tp_base */
139         0,                              /* tp_dict */
140         0,                              /* tp_descr_get */
141         0,                              /* tp_descr_set */
142         0,                              /* tp_dictoffset */
143         0,                              /* tp_init */
144         0,                              /* tp_alloc */
145         0,                              /* tp_new */
146         0,                              /* tp_free */
147         0,                              /* tp_is_gc */
148 };
149
150 PyObject * rpmii_Wrap(PyTypeObject *subtype, rpmdbIndexIterator ii, PyObject *s)
151 {
152     rpmiiObject * iio = (rpmiiObject *)subtype->tp_alloc(subtype, 0);
153     if (iio == NULL) return NULL;
154
155     iio->ii = ii;
156     iio->ref = s;
157     Py_INCREF(iio->ref);
158     return (PyObject *) iio;
159 }