journal_reader_python.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. // Python.h needs to be placed at the head of the program file, see:
  15. // http://docs.python.org/py3k/extending/extending.html#a-simple-example
  16. #include <Python.h>
  17. #include <util/python/pycppwrapper_util.h>
  18. #include <datasrc/client.h>
  19. #include <datasrc/database.h>
  20. #include <dns/python/rrset_python.h>
  21. #include "datasrc.h"
  22. #include "journal_reader_python.h"
  23. #include "journal_reader_inc.cc"
  24. using namespace isc::util::python;
  25. using namespace isc::dns::python;
  26. using namespace isc::datasrc;
  27. using namespace isc::datasrc::python;
  28. namespace {
  29. // The s_* Class simply covers one instantiation of the object
  30. class s_ZoneJournalReader : public PyObject {
  31. public:
  32. s_ZoneJournalReader() : cppobj(ZoneJournalReaderPtr()), base_obj(NULL) {};
  33. ZoneJournalReaderPtr cppobj;
  34. // This is a reference to a base object; if the object of this class
  35. // depends on another object to be in scope during its lifetime,
  36. // we use INCREF the base object upon creation, and DECREF it at
  37. // the end of the destructor
  38. // This is an optional argument to createXXX(). If NULL, it is ignored.
  39. PyObject* base_obj;
  40. };
  41. // General creation and destruction
  42. int
  43. ZoneJournalReader_init(PyObject*, PyObject*, PyObject*) {
  44. // can't be called directly
  45. PyErr_SetString(PyExc_TypeError,
  46. "ZoneJournalReader cannot be constructed directly");
  47. return (-1);
  48. }
  49. void
  50. ZoneJournalReader_destroy(PyObject* po_self) {
  51. s_ZoneJournalReader* const self =
  52. static_cast<s_ZoneJournalReader*>(po_self) ;
  53. // cppobj is a shared ptr, but to make sure things are not destroyed in
  54. // the wrong order, we reset it here.
  55. self->cppobj.reset();
  56. if (self->base_obj != NULL) {
  57. Py_DECREF(self->base_obj);
  58. }
  59. Py_TYPE(self)->tp_free(self);
  60. }
  61. //
  62. // We declare the functions here, the definitions are below
  63. // the type definition of the object, since both can use the other
  64. //
  65. PyObject*
  66. ZoneJournalReader_getNextDiff(PyObject* po_self, PyObject*) {
  67. s_ZoneJournalReader* self = static_cast<s_ZoneJournalReader*>(po_self);
  68. try {
  69. isc::dns::ConstRRsetPtr rrset = self->cppobj->getNextDiff();
  70. if (!rrset) {
  71. Py_RETURN_NONE;
  72. }
  73. return (createRRsetObject(*rrset));
  74. } catch (const isc::InvalidOperation& ex) {
  75. PyErr_SetString(PyExc_ValueError, ex.what());
  76. return (NULL);
  77. } catch (const isc::Exception& isce) {
  78. PyErr_SetString(getDataSourceException("Error"), isce.what());
  79. return (NULL);
  80. } catch (const std::exception& exc) {
  81. PyErr_SetString(getDataSourceException("Error"), exc.what());
  82. return (NULL);
  83. } catch (...) {
  84. PyErr_SetString(getDataSourceException("Error"),
  85. "Unexpected exception");
  86. return (NULL);
  87. }
  88. }
  89. PyObject*
  90. ZoneJournalReader_iter(PyObject *self) {
  91. Py_INCREF(self);
  92. return (self);
  93. }
  94. PyObject*
  95. ZoneJournalReader_next(PyObject* self) {
  96. PyObject* result = ZoneJournalReader_getNextDiff(self, NULL);
  97. // iter_next must return NULL without error instead of Py_None
  98. if (result == Py_None) {
  99. Py_DECREF(result);
  100. return (NULL);
  101. } else {
  102. return (result);
  103. }
  104. }
  105. PyMethodDef ZoneJournalReader_methods[] = {
  106. { "get_next_diff", ZoneJournalReader_getNextDiff, METH_NOARGS,
  107. ZoneJournalReader_getNextDiff_doc },
  108. { NULL, NULL, 0, NULL }
  109. };
  110. } // end of unnamed namespace
  111. namespace isc {
  112. namespace datasrc {
  113. namespace python {
  114. PyTypeObject journal_reader_type = {
  115. PyVarObject_HEAD_INIT(NULL, 0)
  116. "datasrc.ZoneJournalReader",
  117. sizeof(s_ZoneJournalReader), // tp_basicsize
  118. 0, // tp_itemsize
  119. ZoneJournalReader_destroy, // tp_dealloc
  120. NULL, // tp_print
  121. NULL, // tp_getattr
  122. NULL, // tp_setattr
  123. NULL, // tp_reserved
  124. NULL, // tp_repr
  125. NULL, // tp_as_number
  126. NULL, // tp_as_sequence
  127. NULL, // tp_as_mapping
  128. NULL, // tp_hash
  129. NULL, // tp_call
  130. NULL, // tp_str
  131. NULL, // tp_getattro
  132. NULL, // tp_setattro
  133. NULL, // tp_as_buffer
  134. Py_TPFLAGS_DEFAULT, // tp_flags
  135. ZoneJournalReader_doc,
  136. NULL, // tp_traverse
  137. NULL, // tp_clear
  138. NULL, // tp_richcompare
  139. 0, // tp_weaklistoffset
  140. ZoneJournalReader_iter, // tp_iter
  141. ZoneJournalReader_next, // tp_iternext
  142. ZoneJournalReader_methods, // tp_methods
  143. NULL, // tp_members
  144. NULL, // tp_getset
  145. NULL, // tp_base
  146. NULL, // tp_dict
  147. NULL, // tp_descr_get
  148. NULL, // tp_descr_set
  149. 0, // tp_dictoffset
  150. ZoneJournalReader_init, // tp_init
  151. NULL, // tp_alloc
  152. PyType_GenericNew, // tp_new
  153. NULL, // tp_free
  154. NULL, // tp_is_gc
  155. NULL, // tp_bases
  156. NULL, // tp_mro
  157. NULL, // tp_cache
  158. NULL, // tp_subclasses
  159. NULL, // tp_weaklist
  160. NULL, // tp_del
  161. 0 // tp_version_tag
  162. };
  163. PyObject*
  164. createZoneJournalReaderObject(ZoneJournalReaderPtr source,
  165. PyObject* base_obj)
  166. {
  167. s_ZoneJournalReader* po = static_cast<s_ZoneJournalReader*>(
  168. journal_reader_type.tp_alloc(&journal_reader_type, 0));
  169. if (po != NULL) {
  170. po->cppobj = source;
  171. po->base_obj = base_obj;
  172. if (base_obj != NULL) {
  173. Py_INCREF(base_obj);
  174. }
  175. }
  176. return (po);
  177. }
  178. } // namespace python
  179. } // namespace datasrc
  180. } // namespace isc