datasrc.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. try {
  68. installClassVariable(datasourceclient_type, "SUCCESS",
  69. Py_BuildValue("I", result::SUCCESS));
  70. installClassVariable(datasourceclient_type, "EXIST",
  71. Py_BuildValue("I", result::EXIST));
  72. installClassVariable(datasourceclient_type, "NOTFOUND",
  73. Py_BuildValue("I", result::NOTFOUND));
  74. installClassVariable(datasourceclient_type, "PARTIALMATCH",
  75. Py_BuildValue("I", result::PARTIALMATCH));
  76. } catch (const std::exception& ex) {
  77. const std::string ex_what =
  78. "Unexpected failure in DataSourceClient initialization: " +
  79. std::string(ex.what());
  80. PyErr_SetString(po_IscException, ex_what.c_str());
  81. return (false);
  82. } catch (...) {
  83. PyErr_SetString(PyExc_SystemError,
  84. "Unexpected failure in DataSourceClient initialization");
  85. return (false);
  86. }
  87. return (true);
  88. }
  89. bool
  90. initModulePart_ZoneFinder(PyObject* mod) {
  91. // We initialize the static description object with PyType_Ready(),
  92. // then add it to the module. This is not just a check! (leaving
  93. // this out results in segmentation faults)
  94. if (PyType_Ready(&zonefinder_type) < 0) {
  95. return (false);
  96. }
  97. void* zip = &zonefinder_type;
  98. if (PyModule_AddObject(mod, "ZoneFinder", static_cast<PyObject*>(zip)) < 0) {
  99. return (false);
  100. }
  101. Py_INCREF(&zonefinder_type);
  102. try {
  103. installClassVariable(zonefinder_type, "SUCCESS",
  104. Py_BuildValue("I", ZoneFinder::SUCCESS));
  105. installClassVariable(zonefinder_type, "DELEGATION",
  106. Py_BuildValue("I", ZoneFinder::DELEGATION));
  107. installClassVariable(zonefinder_type, "NXDOMAIN",
  108. Py_BuildValue("I", ZoneFinder::NXDOMAIN));
  109. installClassVariable(zonefinder_type, "NXRRSET",
  110. Py_BuildValue("I", ZoneFinder::NXRRSET));
  111. installClassVariable(zonefinder_type, "CNAME",
  112. Py_BuildValue("I", ZoneFinder::CNAME));
  113. installClassVariable(zonefinder_type, "DNAME",
  114. Py_BuildValue("I", ZoneFinder::DNAME));
  115. installClassVariable(zonefinder_type, "WILDCARD",
  116. Py_BuildValue("I", ZoneFinder::WILDCARD));
  117. installClassVariable(zonefinder_type, "WILDCARD_NXRRSET",
  118. Py_BuildValue("I", ZoneFinder::WILDCARD_NXRRSET));
  119. installClassVariable(zonefinder_type, "WILDCARD_CNAME",
  120. Py_BuildValue("I", ZoneFinder::WILDCARD_CNAME));
  121. installClassVariable(zonefinder_type, "FIND_DEFAULT",
  122. Py_BuildValue("I", ZoneFinder::FIND_DEFAULT));
  123. installClassVariable(zonefinder_type, "FIND_GLUE_OK",
  124. Py_BuildValue("I", ZoneFinder::FIND_GLUE_OK));
  125. installClassVariable(zonefinder_type, "FIND_DNSSEC",
  126. Py_BuildValue("I", ZoneFinder::FIND_DNSSEC));
  127. installClassVariable(zonefinder_type, "NO_WILDCARD",
  128. Py_BuildValue("I", ZoneFinder::NO_WILDCARD));
  129. } catch (const std::exception& ex) {
  130. const std::string ex_what =
  131. "Unexpected failure in ZoneFinder initialization: " +
  132. std::string(ex.what());
  133. PyErr_SetString(po_IscException, ex_what.c_str());
  134. return (false);
  135. } catch (...) {
  136. PyErr_SetString(PyExc_SystemError,
  137. "Unexpected failure in ZoneFinder initialization");
  138. return (false);
  139. }
  140. return (true);
  141. }
  142. bool
  143. initModulePart_ZoneIterator(PyObject* mod) {
  144. // We initialize the static description object with PyType_Ready(),
  145. // then add it to the module. This is not just a check! (leaving
  146. // this out results in segmentation faults)
  147. if (PyType_Ready(&zoneiterator_type) < 0) {
  148. return (false);
  149. }
  150. void* zip = &zoneiterator_type;
  151. if (PyModule_AddObject(mod, "ZoneIterator", static_cast<PyObject*>(zip)) < 0) {
  152. return (false);
  153. }
  154. Py_INCREF(&zoneiterator_type);
  155. return (true);
  156. }
  157. bool
  158. initModulePart_ZoneUpdater(PyObject* mod) {
  159. // We initialize the static description object with PyType_Ready(),
  160. // then add it to the module. This is not just a check! (leaving
  161. // this out results in segmentation faults)
  162. if (PyType_Ready(&zoneupdater_type) < 0) {
  163. return (false);
  164. }
  165. void* zip = &zoneupdater_type;
  166. if (PyModule_AddObject(mod, "ZoneUpdater", static_cast<PyObject*>(zip)) < 0) {
  167. return (false);
  168. }
  169. Py_INCREF(&zoneupdater_type);
  170. return (true);
  171. }
  172. PyObject* po_DataSourceError;
  173. PyObject* po_NotImplemented;
  174. PyModuleDef iscDataSrc = {
  175. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  176. "datasrc",
  177. "Python bindings for the classes in the isc::datasrc namespace.\n\n"
  178. "These bindings are close match to the C++ API, but they are not complete "
  179. "(some parts are not needed) and some are done in more python-like ways.",
  180. -1,
  181. NULL,
  182. NULL,
  183. NULL,
  184. NULL,
  185. NULL
  186. };
  187. } // end anonymous namespace
  188. PyMODINIT_FUNC
  189. PyInit_datasrc(void) {
  190. PyObject* mod = PyModule_Create(&iscDataSrc);
  191. if (mod == NULL) {
  192. return (NULL);
  193. }
  194. if (!initModulePart_DataSourceClient(mod)) {
  195. Py_DECREF(mod);
  196. return (NULL);
  197. }
  198. if (!initModulePart_ZoneFinder(mod)) {
  199. Py_DECREF(mod);
  200. return (NULL);
  201. }
  202. if (!initModulePart_ZoneIterator(mod)) {
  203. Py_DECREF(mod);
  204. return (NULL);
  205. }
  206. if (!initModulePart_ZoneUpdater(mod)) {
  207. Py_DECREF(mod);
  208. return (NULL);
  209. }
  210. try {
  211. po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
  212. NULL);
  213. PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
  214. po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
  215. NULL, NULL);
  216. PyObjectContainer(po_NotImplemented).installToModule(mod,
  217. "NotImplemented");
  218. } catch (...) {
  219. Py_DECREF(mod);
  220. return (NULL);
  221. }
  222. return (mod);
  223. }