Lose unnecessary next() methods
[platform/upstream/rpm.git] / python / rpmmi-py.c
1 /** \ingroup py_c
2  * \file python/rpmmi-py.c
3  */
4
5 #include "system.h"
6
7 #include <rpm/rpmdb.h>
8
9 #include "rpmmi-py.h"
10 #include "header-py.h"
11
12 #include "debug.h"
13
14 /** \ingroup python
15  * \class Rpmmi
16  * \brief A python rpm.mi match iterator object represents the result of a
17  *      database query.
18  *
19  * Instances of the rpm.mi object provide access to headers that match
20  * certain criteria. Typically, a primary index is accessed to find
21  * a set of headers that contain a key, and each header is returned
22  * serially.
23  *
24  * The rpm.mi class conains the following methods:
25  * - next() -> hdr              Return the next header that matches.
26  *
27  * - pattern(tag,mire,pattern)  Specify secondary match criteria.
28  *
29  * To obtain a rpm.mi object to query the database used by a transaction,
30  * the ts.match(tag,key,len) method is used.
31  *
32  * Here's an example that prints the name of all installed packages:
33  * \code
34  *      import rpm
35  *      ts = rpm.TransactionSet()
36  *      for h in ts.dbMatch():
37  *          print h['name']
38  * \endcode
39  *
40  * Here's a more typical example that uses the Name index to retrieve
41  * all installed kernel(s):
42  * \code
43  *      import rpm
44  *      ts = rpm.TransactionSet()
45  *      mi = ts.dbMatch('name', "kernel")
46  *      for h in mi:
47  *          print "%s-%s-%s" % (h['name'], h['version'], h['release'])
48  * \endcode
49  *
50  * Finally, here's an example that retrieves all packages whose name
51  * matches the glob expression "XFree*":
52  * \code
53  *      import rpm
54  *      ts = rpm.TransactionSet()
55  *      mi = ts.dbMatch()
56  *      mi.pattern('name', rpm.RPMMIRE_GLOB, "XFree*")
57  *      for h in mi:
58  *          print "%s-%s-%s" % (h['name'], h['version'], h['release'])
59  * \endcode
60  *
61  */
62
63 /** \ingroup python
64  * \name Class: Rpmmi
65  */
66
67 /** \ingroup py_c
68  */
69 struct rpmmiObject_s {
70     PyObject_HEAD
71     PyObject *md_dict;          /*!< to look like PyModuleObject */
72     PyObject *ref;              /* for db/ts refcounting */
73     rpmdbMatchIterator mi;
74 } ;
75
76 /**
77  */
78 static PyObject *
79 rpmmi_iternext(rpmmiObject * s)
80 {
81     Header h;
82
83     if (s->mi == NULL || (h = rpmdbNextIterator(s->mi)) == NULL) {
84         s->mi = rpmdbFreeIterator(s->mi);
85         return NULL;
86     }
87     return (PyObject *) hdr_Wrap(h);
88 }
89
90 /**
91  */
92 static PyObject *
93 rpmmi_Instance(rpmmiObject * s)
94 {
95     int rc = 0;
96
97     if (s->mi != NULL)
98         rc = rpmdbGetIteratorOffset(s->mi);
99
100     return Py_BuildValue("i", rc);
101 }
102
103 /**
104  */
105 static PyObject *
106 rpmmi_Count(rpmmiObject * s)
107 {
108     int rc = 0;
109
110     if (s->mi != NULL)
111         rc = rpmdbGetIteratorCount(s->mi);
112
113     return Py_BuildValue("i", rc);
114 }
115
116 /**
117  */
118 static PyObject *
119 rpmmi_Pattern(rpmmiObject * s, PyObject * args, PyObject * kwds)
120 {
121     PyObject *TagN = NULL;
122     int type;
123     char * pattern;
124     rpmTag tag;
125     char * kwlist[] = {"tag", "type", "patern", NULL};
126
127     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Ois:Pattern", kwlist,
128             &TagN, &type, &pattern))
129         return NULL;
130
131     tag = tagNumFromPyObject (TagN);
132     if (tag == RPMTAG_NOT_FOUND) return NULL;
133
134     rpmdbSetIteratorRE(s->mi, tag, type, pattern);
135
136     Py_RETURN_NONE;
137 }
138
139 /** \ingroup py_c
140  */
141 static struct PyMethodDef rpmmi_methods[] = {
142     {"instance",    (PyCFunction) rpmmi_Instance,       METH_NOARGS,
143         NULL },
144     {"count",       (PyCFunction) rpmmi_Count,          METH_NOARGS,
145         NULL },
146     {"pattern",     (PyCFunction) rpmmi_Pattern,        METH_VARARGS|METH_KEYWORDS,
147 "mi.pattern(TagN, mire_type, pattern)\n\
148 - Set a secondary match pattern on tags from retrieved header.\n" },
149     {NULL,              NULL}           /* sentinel */
150 };
151
152 /** \ingroup py_c
153  */
154 static void rpmmi_dealloc(rpmmiObject * s)
155 {
156     if (s) {
157         s->mi = rpmdbFreeIterator(s->mi);
158         Py_DECREF(s->ref);
159         PyObject_Del(s);
160     }
161 }
162
163 /**
164  */
165 static char rpmmi_doc[] =
166 "";
167
168 /** \ingroup py_c
169  */
170 PyTypeObject rpmmi_Type = {
171         PyObject_HEAD_INIT(&PyType_Type)
172         0,                              /* ob_size */
173         "rpm.mi",                       /* tp_name */
174         sizeof(rpmmiObject),            /* tp_size */
175         0,                              /* tp_itemsize */
176         (destructor) rpmmi_dealloc,     /* tp_dealloc */
177         0,                              /* tp_print */
178         (getattrfunc)0,                 /* tp_getattr */
179         0,                              /* tp_setattr */
180         0,                              /* tp_compare */
181         0,                              /* tp_repr */
182         0,                              /* tp_as_number */
183         0,                              /* tp_as_sequence */
184         0,                              /* tp_as_mapping */
185         0,                              /* tp_hash */
186         0,                              /* tp_call */
187         0,                              /* tp_str */
188         PyObject_GenericGetAttr,        /* tp_getattro */
189         PyObject_GenericSetAttr,        /* tp_setattro */
190         0,                              /* tp_as_buffer */
191         Py_TPFLAGS_DEFAULT,             /* tp_flags */
192         rpmmi_doc,                      /* tp_doc */
193         0,                              /* tp_traverse */
194         0,                              /* tp_clear */
195         0,                              /* tp_richcompare */
196         0,                              /* tp_weaklistoffset */
197         PyObject_SelfIter,              /* tp_iter */
198         (iternextfunc) rpmmi_iternext,  /* tp_iternext */
199         rpmmi_methods,                  /* tp_methods */
200         0,                              /* tp_members */
201         0,                              /* tp_getset */
202         0,                              /* tp_base */
203         0,                              /* tp_dict */
204         0,                              /* tp_descr_get */
205         0,                              /* tp_descr_set */
206         0,                              /* tp_dictoffset */
207         0,                              /* tp_init */
208         0,                              /* tp_alloc */
209         0,                              /* tp_new */
210         0,                              /* tp_free */
211         0,                              /* tp_is_gc */
212 };
213
214 rpmmiObject * rpmmi_Wrap(rpmdbMatchIterator mi, PyObject *s)
215 {
216     rpmmiObject * mio = (rpmmiObject *) PyObject_New(rpmmiObject, &rpmmi_Type);
217
218     if (mio == NULL) {
219         PyErr_SetString(pyrpmError, "out of memory creating rpmmiObject");
220         return NULL;
221     }
222     mio->mi = mi;
223     mio->ref = s;
224     Py_INCREF(mio->ref);
225     return mio;
226 }
227