Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : // Enable this if you use s# variants with PyArg_ParseTuple(), see
16 : : // http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
17 : : //#define PY_SSIZE_T_CLEAN
18 : :
19 : : // Python.h needs to be placed at the head of the program file, see:
20 : : // http://docs.python.org/py3k/extending/extending.html#a-simple-example
21 : : #include <Python.h>
22 : :
23 : : #include <util/python/pycppwrapper_util.h>
24 : :
25 : : #include <datasrc/client.h>
26 : : #include <datasrc/database.h>
27 : : #include <datasrc/data_source.h>
28 : : #include <datasrc/sqlite3_accessor.h>
29 : : #include <datasrc/zone.h>
30 : :
31 : : #include <dns/python/name_python.h>
32 : : #include <dns/python/rrset_python.h>
33 : : #include <dns/python/rrclass_python.h>
34 : : #include <dns/python/rrtype_python.h>
35 : :
36 : : #include "datasrc.h"
37 : : #include "updater_python.h"
38 : :
39 : : #include "updater_inc.cc"
40 : : #include "finder_inc.cc"
41 : :
42 : : using namespace std;
43 : : using namespace isc::util::python;
44 : : using namespace isc::dns::python;
45 : : using namespace isc::datasrc;
46 : : using namespace isc::datasrc::python;
47 : :
48 : : namespace isc_datasrc_internal {
49 : : // See finder_python.cc
50 : : PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args);
51 : : PyObject* ZoneFinder_helper_all(ZoneFinder* finder, PyObject* args);
52 : : }
53 : :
54 : : namespace {
55 : : // The s_* Class simply covers one instantiation of the object
56 : : class s_ZoneUpdater : public PyObject {
57 : : public:
58 : : s_ZoneUpdater() : cppobj(ZoneUpdaterPtr()), base_obj(NULL) {};
59 : : ZoneUpdaterPtr cppobj;
60 : : // This is a reference to a base object; if the object of this class
61 : : // depends on another object to be in scope during its lifetime,
62 : : // we use INCREF the base object upon creation, and DECREF it at
63 : : // the end of the destructor
64 : : // This is an optional argument to createXXX(). If NULL, it is ignored.
65 : : PyObject* base_obj;
66 : : };
67 : :
68 : : // Shortcut type which would be convenient for adding class variables safely.
69 : : typedef CPPPyObjectContainer<s_ZoneUpdater, ZoneUpdater> ZoneUpdaterContainer;
70 : :
71 : : //
72 : : // We declare the functions here, the definitions are below
73 : : // the type definition of the object, since both can use the other
74 : : //
75 : :
76 : : // General creation and destruction
77 : : int
78 : 1 : ZoneUpdater_init(PyObject*, PyObject*, PyObject*) {
79 : : // can't be called directly
80 : : PyErr_SetString(PyExc_TypeError,
81 : 1 : "ZoneUpdater cannot be constructed directly");
82 : :
83 : 1 : return (-1);
84 : : }
85 : :
86 : : void
87 : 29 : ZoneUpdater_destroy(PyObject* po_self) {
88 : 29 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
89 : :
90 : : // cppobj is a shared ptr, but to make sure things are not destroyed in
91 : : // the wrong order, we reset it here.
92 : 29 : self->cppobj.reset();
93 [ + + ]: 29 : if (self->base_obj != NULL) {
94 [ + + ]: 28 : Py_DECREF(self->base_obj);
95 : : }
96 : 29 : Py_TYPE(self)->tp_free(self);
97 : 29 : }
98 : :
99 : : PyObject*
100 : 216 : ZoneUpdater_addRRset(PyObject* po_self, PyObject* args) {
101 : 216 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
102 : : PyObject* rrset_obj;
103 [ + - ]: 216 : if (PyArg_ParseTuple(args, "O!", &rrset_type, &rrset_obj)) {
104 : : try {
105 [ + - ][ + + ]: 216 : self->cppobj->addRRset(PyRRset_ToRRset(rrset_obj));
106 : 216 : Py_RETURN_NONE;
107 : 0 : } catch (const DataSourceError& dse) {
108 [ # # ][ # # ]: 0 : PyErr_SetString(getDataSourceException("Error"), dse.what());
109 : : return (NULL);
110 [ - - + ]: 6 : } catch (const std::exception& exc) {
111 [ - + ][ - + ]: 3 : PyErr_SetString(getDataSourceException("Error"), exc.what());
112 : : return (NULL);
113 : : }
114 : : } else {
115 : : return (NULL);
116 : : }
117 : : }
118 : :
119 : : PyObject*
120 : 215 : ZoneUpdater_deleteRRset(PyObject* po_self, PyObject* args) {
121 : 215 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
122 : : PyObject* rrset_obj;
123 [ + - ]: 215 : if (PyArg_ParseTuple(args, "O!", &rrset_type, &rrset_obj)) {
124 : : try {
125 [ + - ][ + + ]: 215 : self->cppobj->deleteRRset(PyRRset_ToRRset(rrset_obj));
126 : 215 : Py_RETURN_NONE;
127 : 4 : } catch (const DataSourceError& dse) {
128 [ - + ][ - + ]: 2 : PyErr_SetString(getDataSourceException("Error"), dse.what());
129 : : return (NULL);
130 [ - + + ]: 6 : } catch (const std::exception& exc) {
131 [ - + ][ - + ]: 2 : PyErr_SetString(getDataSourceException("Error"), exc.what());
132 : : return (NULL);
133 : : }
134 : : } else {
135 : : return (NULL);
136 : : }
137 : : }
138 : :
139 : : PyObject*
140 : 16 : ZoneUpdater_commit(PyObject* po_self, PyObject*) {
141 : 16 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
142 : : try {
143 [ + + ]: 16 : self->cppobj->commit();
144 : 16 : Py_RETURN_NONE;
145 : 4 : } catch (const DataSourceError& dse) {
146 [ - + ][ - + ]: 2 : PyErr_SetString(getDataSourceException("Error"), dse.what());
147 : : return (NULL);
148 [ - + + ]: 4 : } catch (const std::exception& exc) {
149 [ - + ][ - + ]: 1 : PyErr_SetString(getDataSourceException("Error"), exc.what());
150 : : return (NULL);
151 : : }
152 : : }
153 : :
154 : : PyObject*
155 : 14 : ZoneUpdater_getClass(PyObject* po_self, PyObject*) {
156 : 14 : s_ZoneUpdater* self = static_cast<s_ZoneUpdater*>(po_self);
157 : : try {
158 [ + - ][ + - ]: 14 : return (createRRClassObject(self->cppobj->getFinder().getClass()));
[ + - ]
159 : 0 : } catch (const std::exception& exc) {
160 [ # # ][ # # ]: 0 : PyErr_SetString(getDataSourceException("Error"), exc.what());
161 : : return (NULL);
162 [ # # ]: 0 : } catch (...) {
163 : : PyErr_SetString(getDataSourceException("Error"),
164 [ # # ][ # # ]: 0 : "Unexpected exception");
165 : : return (NULL);
166 : : }
167 : : }
168 : :
169 : : PyObject*
170 : 0 : ZoneUpdater_getOrigin(PyObject* po_self, PyObject*) {
171 : 0 : s_ZoneUpdater* self = static_cast<s_ZoneUpdater*>(po_self);
172 : : try {
173 [ # # ][ # # ]: 0 : return (createNameObject(self->cppobj->getFinder().getOrigin()));
[ # # ]
174 : 0 : } catch (const std::exception& exc) {
175 [ # # ][ # # ]: 0 : PyErr_SetString(getDataSourceException("Error"), exc.what());
176 : : return (NULL);
177 [ # # ]: 0 : } catch (...) {
178 : : PyErr_SetString(getDataSourceException("Error"),
179 [ # # ][ # # ]: 0 : "Unexpected exception");
180 : : return (NULL);
181 : : }
182 : : }
183 : :
184 : : PyObject*
185 : 4 : ZoneUpdater_find(PyObject* po_self, PyObject* args) {
186 : 4 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
187 : 4 : return (isc_datasrc_internal::ZoneFinder_helper(&self->cppobj->getFinder(),
188 : 4 : args));
189 : : }
190 : :
191 : : PyObject*
192 : 3 : ZoneUpdater_find_all(PyObject* po_self, PyObject* args) {
193 : 3 : s_ZoneUpdater* const self = static_cast<s_ZoneUpdater*>(po_self);
194 : : return (isc_datasrc_internal::ZoneFinder_helper_all(
195 : 3 : &self->cppobj->getFinder(), args));
196 : : }
197 : :
198 : : // This list contains the actual set of functions we have in
199 : : // python. Each entry has
200 : : // 1. Python method name
201 : : // 2. Our static function here
202 : : // 3. Argument type
203 : : // 4. Documentation
204 : : PyMethodDef ZoneUpdater_methods[] = {
205 : : { "add_rrset", ZoneUpdater_addRRset,
206 : : METH_VARARGS, ZoneUpdater_addRRset_doc },
207 : : { "delete_rrset", ZoneUpdater_deleteRRset,
208 : : METH_VARARGS, ZoneUpdater_deleteRRset_doc },
209 : : { "commit", ZoneUpdater_commit, METH_NOARGS, ZoneUpdater_commit_doc },
210 : : // Instead of a getFinder, we implement the finder functionality directly
211 : : // This is because ZoneFinder is non-copyable, and we should not create
212 : : // a ZoneFinder object from a reference only (which is what is returned
213 : : // by getFinder(). Apart from that
214 : : { "get_origin", ZoneUpdater_getOrigin,
215 : : METH_NOARGS, ZoneFinder_getOrigin_doc },
216 : : { "get_class", ZoneUpdater_getClass,
217 : : METH_NOARGS, ZoneFinder_getClass_doc },
218 : : { "find", ZoneUpdater_find, METH_VARARGS, ZoneFinder_find_doc },
219 : : { "find_all", ZoneUpdater_find_all, METH_VARARGS,
220 : : ZoneFinder_findAll_doc },
221 : : { NULL, NULL, 0, NULL }
222 : : };
223 : :
224 : : } // end of unnamed namespace
225 : :
226 : : namespace isc {
227 : : namespace datasrc {
228 : : namespace python {
229 : : PyTypeObject zoneupdater_type = {
230 : : PyVarObject_HEAD_INIT(NULL, 0)
231 : : "datasrc.ZoneUpdater",
232 : : sizeof(s_ZoneUpdater), // tp_basicsize
233 : : 0, // tp_itemsize
234 : : ZoneUpdater_destroy, // tp_dealloc
235 : : NULL, // tp_print
236 : : NULL, // tp_getattr
237 : : NULL, // tp_setattr
238 : : NULL, // tp_reserved
239 : : NULL, // tp_repr
240 : : NULL, // tp_as_number
241 : : NULL, // tp_as_sequence
242 : : NULL, // tp_as_mapping
243 : : NULL, // tp_hash
244 : : NULL, // tp_call
245 : : NULL, // tp_str
246 : : NULL, // tp_getattro
247 : : NULL, // tp_setattro
248 : : NULL, // tp_as_buffer
249 : : Py_TPFLAGS_DEFAULT, // tp_flags
250 : : ZoneUpdater_doc,
251 : : NULL, // tp_traverse
252 : : NULL, // tp_clear
253 : : NULL, // tp_richcompare
254 : : 0, // tp_weaklistoffset
255 : : NULL, // tp_iter
256 : : NULL, // tp_iternext
257 : : ZoneUpdater_methods, // tp_methods
258 : : NULL, // tp_members
259 : : NULL, // tp_getset
260 : : NULL, // tp_base
261 : : NULL, // tp_dict
262 : : NULL, // tp_descr_get
263 : : NULL, // tp_descr_set
264 : : 0, // tp_dictoffset
265 : : ZoneUpdater_init, // tp_init
266 : : NULL, // tp_alloc
267 : : PyType_GenericNew, // tp_new
268 : : NULL, // tp_free
269 : : NULL, // tp_is_gc
270 : : NULL, // tp_bases
271 : : NULL, // tp_mro
272 : : NULL, // tp_cache
273 : : NULL, // tp_subclasses
274 : : NULL, // tp_weaklist
275 : : NULL, // tp_del
276 : : 0 // tp_version_tag
277 : : };
278 : :
279 : : PyObject*
280 : 28 : createZoneUpdaterObject(isc::datasrc::ZoneUpdaterPtr source,
281 : : PyObject* base_obj)
282 : : {
283 : : s_ZoneUpdater* py_zu = static_cast<s_ZoneUpdater*>(
284 : 28 : zoneupdater_type.tp_alloc(&zoneupdater_type, 0));
285 [ + - ]: 28 : if (py_zu != NULL) {
286 : 28 : py_zu->cppobj = source;
287 : 28 : py_zu->base_obj = base_obj;
288 [ + - ]: 28 : if (base_obj != NULL) {
289 : 28 : Py_INCREF(base_obj);
290 : : }
291 : : }
292 : 28 : return (py_zu);
293 : : }
294 : :
295 : : } // namespace python
296 : : } // namespace datasrc
297 : 104 : } // namespace isc
298 : :
|