1 #include "rpmsystem-py.h"
4 #include <rpm/header.h>
11 * \brief A python rpm.mi match iterator object represents the result of a
14 * Instances of the rpm.mi object provide access to headers that match
15 * certain criteria. Typically, a primary index is accessed to find
16 * a set of headers that contain a key, and each header is returned
19 * The rpm.mi class conains the following methods:
20 * - next() -> hdr Return the next header that matches.
22 * - pattern(tag,mire,pattern) Specify secondary match criteria.
24 * To obtain a rpm.mi object to query the database used by a transaction,
25 * the ts.match(tag,key,len) method is used.
27 * Here's an example that prints the name of all installed packages:
30 * ts = rpm.TransactionSet()
31 * for h in ts.dbMatch():
35 * Here's a more typical example that uses the Name index to retrieve
36 * all installed kernel(s):
39 * ts = rpm.TransactionSet()
40 * mi = ts.dbMatch('name', 'kernel')
42 * print '%s-%s-%s' % (h['name'], h['version'], h['release'])
45 * Finally, here's an example that retrieves all packages whose name
46 * matches the glob expression 'XFree*':
49 * ts = rpm.TransactionSet()
51 * mi.pattern('name', rpm.RPMMIRE_GLOB, 'XFree*')
53 * print '%s-%s-%s' % (h['name'], h['version'], h['release'])
62 struct rpmmiObject_s {
64 PyObject *md_dict; /*!< to look like PyModuleObject */
65 PyObject *ref; /* for db/ts refcounting */
66 rpmdbMatchIterator mi;
70 rpmmi_iternext(rpmmiObject * s)
74 if (s->mi == NULL || (h = rpmdbNextIterator(s->mi)) == NULL) {
75 s->mi = rpmdbFreeIterator(s->mi);
79 return hdr_Wrap(&hdr_Type, h);
83 rpmmi_Instance(rpmmiObject * s, PyObject * unused)
88 rc = rpmdbGetIteratorOffset(s->mi);
90 return Py_BuildValue("i", rc);
94 rpmmi_Count(rpmmiObject * s, PyObject * unused)
96 DEPRECATED_METHOD("use len(mi) instead");
97 return Py_BuildValue("i", PyMapping_Size((PyObject *)s));
101 rpmmi_Pattern(rpmmiObject * s, PyObject * args, PyObject * kwds)
104 const char * pattern;
106 char * kwlist[] = {"tag", "type", "patern", NULL};
108 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&is:Pattern", kwlist,
109 tagNumFromPyObject, &tag, &type, &pattern))
112 rpmdbSetIteratorRE(s->mi, tag, type, pattern);
117 static struct PyMethodDef rpmmi_methods[] = {
118 {"instance", (PyCFunction) rpmmi_Instance, METH_NOARGS,
119 "mi.instance() -- Return the number (db key) of the current header."},
120 {"count", (PyCFunction) rpmmi_Count, METH_NOARGS,
121 "Deprecated, use len(mi) instead.\n" },
122 {"pattern", (PyCFunction) rpmmi_Pattern, METH_VARARGS|METH_KEYWORDS,
123 "mi.pattern(TagN, mire_type, pattern)\n\
124 - Set a secondary match pattern on tags from retrieved header.\n" },
125 {NULL, NULL} /* sentinel */
128 static void rpmmi_dealloc(rpmmiObject * s)
130 s->mi = rpmdbFreeIterator(s->mi);
132 Py_TYPE(s)->tp_free((PyObject *)s);
135 static Py_ssize_t rpmmi_length(rpmmiObject * s)
137 return s->mi ? rpmdbGetIteratorCount(s->mi) : 0;
140 static int rpmmi_bool(rpmmiObject *s)
142 return (s->mi != NULL);
145 PyMappingMethods rpmmi_as_mapping = {
146 (lenfunc) rpmmi_length, /* mp_length */
150 static PyNumberMethods rpmmi_as_number = {
154 #if PY_MAJOR_VERSION < 3
157 0, /* nb_remainder */
163 (inquiry)rpmmi_bool, /* nb_bool/nonzero */
166 static char rpmmi_doc[] =
167 "rpm.mi match iterator object represents the result of a\n"
170 "Instances of the rpm.mi object provide access to headers that match\n"
171 "certain criteria. Typically, a primary index is accessed to find\n"
172 "a set of headers that contain a key, and each header is returned\n"
175 "To obtain a rpm.mi object to query the database used by a transaction,\n"
176 "the ts.match(tag,key,len) method is used.\n"
178 "Here's an example that prints the name of all installed packages:\n"
180 " ts = rpm.TransactionSet()\n"
181 " for h in ts.dbMatch():\n"
184 "Here's a more typical example that uses the Name index to retrieve\n"
185 "all installed kernel(s):\n"
187 " ts = rpm.TransactionSet()\n"
188 " mi = ts.dbMatch('name', 'kernel')\n"
190 " print '%s-%s-%s' % (h['name'], h['version'], h['release'])\n"
192 "Finally, here's an example that retrieves all packages whose name\n"
193 "matches the glob expression 'XFree*':\n"
195 " ts = rpm.TransactionSet()\n"
196 " mi = ts.dbMatch()\n"
197 " mi.pattern('name', rpm.RPMMIRE_GLOB, 'XFree*')\n"
199 " print '%s-%s-%s' % (h['name'], h['version'], h['release'])\n"
202 PyTypeObject rpmmi_Type = {
203 PyVarObject_HEAD_INIT(&PyType_Type, 0)
204 "rpm.mi", /* tp_name */
205 sizeof(rpmmiObject), /* tp_size */
207 (destructor) rpmmi_dealloc, /* tp_dealloc */
209 (getattrfunc)0, /* tp_getattr */
213 &rpmmi_as_number, /* tp_as_number */
214 0, /* tp_as_sequence */
215 &rpmmi_as_mapping, /* tp_as_mapping */
219 PyObject_GenericGetAttr, /* tp_getattro */
220 PyObject_GenericSetAttr, /* tp_setattro */
221 0, /* tp_as_buffer */
222 Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
223 rpmmi_doc, /* tp_doc */
226 0, /* tp_richcompare */
227 0, /* tp_weaklistoffset */
228 PyObject_SelfIter, /* tp_iter */
229 (iternextfunc) rpmmi_iternext, /* tp_iternext */
230 rpmmi_methods, /* tp_methods */
235 0, /* tp_descr_get */
236 0, /* tp_descr_set */
237 0, /* tp_dictoffset */
245 PyObject * rpmmi_Wrap(PyTypeObject *subtype, rpmdbMatchIterator mi, PyObject *s)
247 rpmmiObject * mio = (rpmmiObject *)subtype->tp_alloc(subtype, 0);
248 if (mio == NULL) return NULL;
253 return (PyObject *) mio;