datasrc.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. #define PY_SSIZE_T_CLEAN
  15. #include <Python.h>
  16. #include <structmember.h>
  17. #include <config.h>
  18. #include <datasrc/client.h>
  19. #include <datasrc/database.h>
  20. #include <datasrc/sqlite3_accessor.h>
  21. #include "datasrc.h"
  22. #include "client_python.h"
  23. #include "finder_python.h"
  24. #include "iterator_python.h"
  25. #include "updater_python.h"
  26. #include <util/python/pycppwrapper_util.h>
  27. #include <dns/python/pydnspp_common.h>
  28. using namespace isc::datasrc;
  29. using namespace isc::datasrc::python;
  30. using namespace isc::util::python;
  31. using namespace isc::dns::python;
  32. namespace isc {
  33. namespace datasrc {
  34. namespace python {
  35. PyObject*
  36. getDataSourceException(const char* ex_name) {
  37. PyObject* ex_obj = NULL;
  38. PyObject* datasrc_module = PyImport_AddModule("isc.datasrc");
  39. if (datasrc_module != NULL) {
  40. PyObject* datasrc_dict = PyModule_GetDict(datasrc_module);
  41. if (datasrc_dict != NULL) {
  42. ex_obj = PyDict_GetItemString(datasrc_dict, ex_name);
  43. }
  44. }
  45. if (ex_obj == NULL) {
  46. ex_obj = PyExc_RuntimeError;
  47. }
  48. return (ex_obj);
  49. }
  50. } // end namespace python
  51. } // end namespace datasrc
  52. } // end namespace isc
  53. namespace {
  54. bool
  55. initModulePart_DataSourceClient(PyObject* mod) {
  56. // We initialize the static description object with PyType_Ready(),
  57. // then add it to the module. This is not just a check! (leaving
  58. // this out results in segmentation faults)
  59. if (PyType_Ready(&datasourceclient_type) < 0) {
  60. return (false);
  61. }
  62. void* dscp = &datasourceclient_type;
  63. if (PyModule_AddObject(mod, "DataSourceClient", static_cast<PyObject*>(dscp)) < 0) {
  64. return (false);
  65. }
  66. Py_INCREF(&datasourceclient_type);
  67. addClassVariable(datasourceclient_type, "SUCCESS",
  68. Py_BuildValue("I", result::SUCCESS));
  69. addClassVariable(datasourceclient_type, "EXIST",
  70. Py_BuildValue("I", result::EXIST));
  71. addClassVariable(datasourceclient_type, "NOTFOUND",
  72. Py_BuildValue("I", result::NOTFOUND));
  73. addClassVariable(datasourceclient_type, "PARTIALMATCH",
  74. Py_BuildValue("I", result::PARTIALMATCH));
  75. return (true);
  76. }
  77. bool
  78. initModulePart_ZoneFinder(PyObject* mod) {
  79. // We initialize the static description object with PyType_Ready(),
  80. // then add it to the module. This is not just a check! (leaving
  81. // this out results in segmentation faults)
  82. if (PyType_Ready(&zonefinder_type) < 0) {
  83. return (false);
  84. }
  85. void* zip = &zonefinder_type;
  86. if (PyModule_AddObject(mod, "ZoneFinder", static_cast<PyObject*>(zip)) < 0) {
  87. return (false);
  88. }
  89. Py_INCREF(&zonefinder_type);
  90. addClassVariable(zonefinder_type, "SUCCESS",
  91. Py_BuildValue("I", ZoneFinder::SUCCESS));
  92. addClassVariable(zonefinder_type, "DELEGATION",
  93. Py_BuildValue("I", ZoneFinder::DELEGATION));
  94. addClassVariable(zonefinder_type, "NXDOMAIN",
  95. Py_BuildValue("I", ZoneFinder::NXDOMAIN));
  96. addClassVariable(zonefinder_type, "NXRRSET",
  97. Py_BuildValue("I", ZoneFinder::NXRRSET));
  98. addClassVariable(zonefinder_type, "CNAME",
  99. Py_BuildValue("I", ZoneFinder::CNAME));
  100. addClassVariable(zonefinder_type, "DNAME",
  101. Py_BuildValue("I", ZoneFinder::DNAME));
  102. addClassVariable(zonefinder_type, "WILDCARD",
  103. Py_BuildValue("I", ZoneFinder::WILDCARD));
  104. addClassVariable(zonefinder_type, "WILDCARD_NXRRSET",
  105. Py_BuildValue("I", ZoneFinder::WILDCARD_NXRRSET));
  106. addClassVariable(zonefinder_type, "FIND_DEFAULT",
  107. Py_BuildValue("I", ZoneFinder::FIND_DEFAULT));
  108. addClassVariable(zonefinder_type, "FIND_GLUE_OK",
  109. Py_BuildValue("I", ZoneFinder::FIND_GLUE_OK));
  110. addClassVariable(zonefinder_type, "FIND_DNSSEC",
  111. Py_BuildValue("I", ZoneFinder::FIND_DNSSEC));
  112. return (true);
  113. }
  114. bool
  115. initModulePart_ZoneIterator(PyObject* mod) {
  116. // We initialize the static description object with PyType_Ready(),
  117. // then add it to the module. This is not just a check! (leaving
  118. // this out results in segmentation faults)
  119. if (PyType_Ready(&zoneiterator_type) < 0) {
  120. return (false);
  121. }
  122. void* zip = &zoneiterator_type;
  123. if (PyModule_AddObject(mod, "ZoneIterator", static_cast<PyObject*>(zip)) < 0) {
  124. return (false);
  125. }
  126. Py_INCREF(&zoneiterator_type);
  127. return (true);
  128. }
  129. bool
  130. initModulePart_ZoneUpdater(PyObject* mod) {
  131. // We initialize the static description object with PyType_Ready(),
  132. // then add it to the module. This is not just a check! (leaving
  133. // this out results in segmentation faults)
  134. if (PyType_Ready(&zoneupdater_type) < 0) {
  135. return (false);
  136. }
  137. void* zip = &zoneupdater_type;
  138. if (PyModule_AddObject(mod, "ZoneUpdater", static_cast<PyObject*>(zip)) < 0) {
  139. return (false);
  140. }
  141. Py_INCREF(&zoneupdater_type);
  142. return (true);
  143. }
  144. PyObject* po_DataSourceError;
  145. PyObject* po_NotImplemented;
  146. PyModuleDef iscDataSrc = {
  147. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  148. "datasrc",
  149. "Python bindings for the classes in the isc::datasrc namespace.\n\n"
  150. "These bindings are close match to the C++ API, but they are not complete "
  151. "(some parts are not needed) and some are done in more python-like ways.",
  152. -1,
  153. NULL,
  154. NULL,
  155. NULL,
  156. NULL,
  157. NULL
  158. };
  159. } // end anonymous namespace
  160. PyMODINIT_FUNC
  161. PyInit_datasrc(void) {
  162. PyObject* mod = PyModule_Create(&iscDataSrc);
  163. if (mod == NULL) {
  164. return (NULL);
  165. }
  166. if (!initModulePart_DataSourceClient(mod)) {
  167. Py_DECREF(mod);
  168. return (NULL);
  169. }
  170. if (!initModulePart_ZoneFinder(mod)) {
  171. Py_DECREF(mod);
  172. return (NULL);
  173. }
  174. if (!initModulePart_ZoneIterator(mod)) {
  175. Py_DECREF(mod);
  176. return (NULL);
  177. }
  178. if (!initModulePart_ZoneUpdater(mod)) {
  179. Py_DECREF(mod);
  180. return (NULL);
  181. }
  182. try {
  183. po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
  184. NULL);
  185. PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
  186. po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
  187. NULL, NULL);
  188. PyObjectContainer(po_NotImplemented).installToModule(mod,
  189. "NotImplemented");
  190. } catch (...) {
  191. Py_DECREF(mod);
  192. return (NULL);
  193. }
  194. return (mod);
  195. }