From 41c3bda527d7562214ebde52e84a2614e66ad394 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 21 Dec 2010 14:05:18 +0100 Subject: ldb: Add ldb.Message.add and ldb.Message.elements. Autobuild-User: Jelmer Vernooij Autobuild-Date: Tue Dec 21 15:03:17 CET 2010 on sn-devel-104 --- source4/lib/ldb/pyldb.c | 104 +++++++++++++++++++++++++----------- source4/lib/ldb/tests/python/api.py | 18 +++++-- 2 files changed, 86 insertions(+), 36 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 0167c570c5..57e932fc82 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -57,7 +57,7 @@ extern PyTypeObject PyLdbMessage; extern PyTypeObject PyLdbModule; extern PyTypeObject PyLdbDn; extern PyTypeObject PyLdb; -extern PyTypeObject PyLdbMessageElement; +staticforward PyTypeObject PyLdbMessageElement; extern PyTypeObject PyLdbTree; static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); @@ -649,23 +649,23 @@ static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args) return NULL; } - /* do request and autostart a transaction */ + /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ ret = ldb_transaction_start(ldb_ctx); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } + } - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { + ret = ldb_transaction_commit(ldb_ctx); + } else { ldb_transaction_cancel(ldb_ctx); if (ldb_ctx->err_string == NULL) { /* no error string was setup by the backend */ @@ -782,15 +782,15 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) } ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { + if (ret != LDB_SUCCESS) { PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); talloc_free(mem_ctx); return NULL; - } + } - ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, + ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { + if (ret != LDB_SUCCESS) { PyErr_SetString(PyExc_TypeError, "failed to build request"); talloc_free(mem_ctx); return NULL; @@ -799,21 +799,21 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) /* do request and autostart a transaction */ /* Then let's LDB handle the message error in case of pb as they are meaningful */ - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - } + } - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); if (ldb_ctx->err_string == NULL) { /* no error string was setup by the backend */ ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); @@ -1978,7 +1978,7 @@ static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) if (el->num_values == 1) return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length); - else + else Py_RETURN_NONE; } @@ -1988,7 +1988,7 @@ static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) self->ob_type->tp_free(self); } -PyTypeObject PyLdbMessageElement = { +static PyTypeObject PyLdbMessageElement = { .tp_name = "ldb.MessageElement", .tp_basicsize = sizeof(PyLdbMessageElementObject), .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, @@ -2127,16 +2127,56 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self) return l; } -static PyMethodDef py_ldb_msg_methods[] = { +static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + Py_ssize_t i = 0; + PyObject *l = PyList_New(msg->num_elements); + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); + } + return l; +} + +static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) +{ + struct ldb_message *msg = PyLdbMessage_AsMessage(self); + PyObject *py_element; + int flags, ret; + struct ldb_message_element *el; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) + return NULL; + + el = talloc_reference(msg, PyLdbMessageElement_AsMessageElement(py_element)); + if (el == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = ldb_msg_add(msg, el, el->flags); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_msg_methods[] = { { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, - "Message.from_dict(ldb, dict, mod_flag) -> ldb.Message\n" + "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" "Class method to create ldb.Message object from Dictionary.\n" - "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE.\n" - "mod_flag defaults to FLAG_MOD_REPLACE"}, - { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL }, - { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL }, + "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, + { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, + "S.keys() -> list\n\n" + "Return sequence of all attribute names." }, + { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, + "S.remove(name)\n\n" + "Remove all entries for attributes with the specified name."}, { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL }, { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, + { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, + { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, + "S.append(element)\n\n" + "Add an element to this message." }, { NULL }, }; @@ -2158,7 +2198,7 @@ static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject PyErr_SetNone(PyExc_TypeError); return -1; } - + attr_name = PyString_AsString(name); if (value == NULL) { /* delitem */ diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index d9c9023b93..74de70769b 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -278,15 +278,14 @@ class SimpleLdb(unittest.TestCase): rm = l.search(m.dn)[0] self.assertEquals(2, len(rm)) self.assertEquals(["1234", "456"], list(rm["bla"])) - - #Now create another modify, but switch the flags before we do it + + # Now create another modify, but switch the flags before we do it m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") m["bla"].set_flags(ldb.FLAG_MOD_DELETE) l.modify(m) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEquals(1, len(rm)) self.assertEquals(["1234"], list(rm["bla"])) - finally: l.delete(ldb.Dn(l, "dc=add")) @@ -421,7 +420,7 @@ class DnTests(unittest.TestCase): self.assertTrue(isinstance(msg[1], ldb.Message)) ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) self.assertEquals("dn: foo=bar\n\n", ldif) - + def test_parse_ldif_more(self): msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") msg = msgs.next() @@ -466,6 +465,17 @@ class LdbMsgTests(unittest.TestCase): def test_del(self): del self.msg["foo"] + def test_add(self): + self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) + + def test_elements_empty(self): + self.assertEquals([], self.msg.elements()) + + def test_elements(self): + el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.msg.add(el) + self.assertEquals([el], self.msg.elements()) + def test_add_value(self): self.assertEquals(0, len(self.msg)) self.msg["foo"] = ["foo"] -- cgit