svn commit: samba r25709 - in branches/4.0-python: . source/lib/ldb/swig source/lib/ldb/tests/python source/scripting/python/samba

jelmer at samba.org jelmer at samba.org
Tue Oct 23 21:29:09 GMT 2007


Author: jelmer
Date: 2007-10-23 21:29:08 +0000 (Tue, 23 Oct 2007)
New Revision: 25709

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=25709

Log:
Implement modify, and make several bits and pieces a bit more "pythonic'.

Modified:
   branches/4.0-python/
   branches/4.0-python/source/lib/ldb/swig/ldb.i
   branches/4.0-python/source/lib/ldb/tests/python/api.py
   branches/4.0-python/source/scripting/python/samba/provision.py


Changeset:

Property changes on: branches/4.0-python
___________________________________________________________________
Name: bzr:revision-info
...skipped...
Name: bzr:file-ids
...skipped...
Name: bzr:revision-id:v3-trunk0
...skipped...

Modified: branches/4.0-python/source/lib/ldb/swig/ldb.i
===================================================================
--- branches/4.0-python/source/lib/ldb/swig/ldb.i	2007-10-23 21:28:57 UTC (rev 25708)
+++ branches/4.0-python/source/lib/ldb/swig/ldb.i	2007-10-23 21:29:08 UTC (rev 25709)
@@ -46,6 +46,7 @@
 typedef struct ldb_context ldb;
 typedef struct ldb_dn ldb_dn;
 typedef struct ldb_ldif ldb_ldif;
+typedef struct ldb_message_element ldb_msg_element;
 typedef int ldb_error;
 
 %}
@@ -59,6 +60,11 @@
 %constant int SCOPE_ONELEVEL = LDB_SCOPE_ONELEVEL;
 %constant int SCOPE_SUBTREE = LDB_SCOPE_SUBTREE;
 
+%constant int CHANGETYPE_NONE = LDB_CHANGETYPE_NONE;
+%constant int CHANGETYPE_ADD = LDB_CHANGETYPE_ADD;
+%constant int CHANGETYPE_DELETE = LDB_CHANGETYPE_DELETE;
+%constant int CHANGETYPE_MODIFY = LDB_CHANGETYPE_MODIFY;
+
 /* 
  * Wrap struct ldb_context
  */
@@ -123,7 +129,7 @@
         $1 = NULL;
     } else if (PySequence_Check($input)) {
         int i;
-        $1 = talloc_array(NULL, const char *, PySequence_Size($input)+1);
+        $1 = talloc_array(NULL, char *, PySequence_Size($input)+1);
         for(i = 0; i < PySequence_Size($input); i++)
             $1[i] = PyString_AsString(PySequence_GetItem($input, i));
         $1[i] = NULL;
@@ -194,11 +200,110 @@
     }
 } ldb_dn;
 
+#ifdef SWIGPYTHON
+%inline {
+ldb_msg_element *ldb_msg_element_from_pyobject(PyObject *set_obj, int flags,
+                                               const char *attr_name)
+{
+    struct ldb_message_element *me = talloc(NULL, struct ldb_message_element);
+    me->name = attr_name;
+    me->flags = flags;
+    if (PyString_Check(set_obj)) {
+        me->num_values = 1;
+        me->values = talloc_array(me, struct ldb_val, me->num_values);
+        me->values[0].length = PyString_Size(set_obj);
+        me->values[0].data = talloc_strdup(me->values, 
+                                           PyString_AsString(set_obj));
+    } else if (PySequence_Check(set_obj)) {
+        int i;
+        me->num_values = PySequence_Size(set_obj);
+        me->values = talloc_array(me, struct ldb_val, me->num_values);
+        for (i = 0; i < me->num_values; i++) {
+            PyObject *obj = PySequence_GetItem(set_obj, i);
+            me->values[i].length = PyString_Size(obj);
+            me->values[i].data = PyString_AsString(obj);
+        }
+    } else {
+        talloc_free(me);
+        me = NULL;
+    }
+
+    return me;
+}
+
+PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
+{
+    int i;
+    PyObject *result;
+
+    /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
+    result = PyList_New(me->num_values);
+
+    for (i = 0; i < me->num_values; i++) {
+        PyList_SetItem(result, i,
+            PyString_FromStringAndSize((const char *)me->values[i].data, 
+                                       me->values[i].length));
+    }
+
+    return result;
+}
+
+}
+#endif
+
+/* ldb_message_element */
+%rename(__cmp__) ldb_message_element::compare;
+%rename(MessageElement) ldb_msg_element;
+typedef struct ldb_message_element {
+    %extend {
+#ifdef SWIGPYTHON
+        PyObject *__iter__(void)
+        {
+            return PyObject_GetIter(ldb_msg_element_to_set($self));
+        }
+
+        PyObject *__set__(void)
+        {
+            return ldb_msg_element_to_set($self);
+        }
+
+        ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
+        {
+            return ldb_msg_element_from_pyobject(set_obj, flags, name);
+        }
+#endif
+        ~ldb_msg_element() { talloc_free($self); }
+        int compare(ldb_msg_element *);
+    }
+} ldb_msg_element;
+
 /* ldb_message */
 
 %rename(Message) ldb_message;
+#ifdef SWIGPYTHON
 %rename(__delitem__) ldb_message::remove_attr;
+%typemap(out) ldb_msg_element * {
+	if ($1 == NULL)
+		PyErr_SetString(PyExc_KeyError, "no such element");
+    else
+        $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0);
+}
+%rename(__getitem__) ldb_message::find_element;
+//%typemap(out) ldb_msg_element *;
 
+%inline {
+    PyObject *ldb_msg_list_elements(ldb_msg *msg)
+    {
+        int i;
+        PyObject *obj = PyList_New(msg->num_elements);
+        for (i = 0; i < msg->num_elements; i++)
+            PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name));
+        return obj;
+    }
+}
+
+#endif
+
 typedef struct ldb_message {
 	ldb_dn *dn;
 
@@ -209,59 +314,39 @@
             return ret;
         }
         ~ldb_msg() { talloc_free($self); }
+
+        ldb_msg_element *find_element(const char *name);
         
 #ifdef SWIGPYTHON
-        PyObject *__getitem__(const char *attr_name)
+        void __setitem__(const char *attr_name, ldb_msg_element *val)
         {
-            PyObject *result;
-            int i;
-            struct ldb_message_element *ret = ldb_msg_find_element($self, 
-                                                                   attr_name);
-            if (ret == NULL) {
-                PyErr_SetString(PyExc_KeyError, "no such element");
-                return NULL;
-            }
+            struct ldb_message_element *el;
+            
+            ldb_msg_remove_attr($self, attr_name);
 
-            /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
-            result = PyObject_CallObject(&PySet_Type, NULL);
+            el = talloc($self, struct ldb_message_element);
+            el->name = talloc_strdup(el, attr_name);
+            el->num_values = val->num_values;
+            el->values = talloc_reference(el, val->values);
 
-            for (i = 0; i < ret->num_values; i++) {
-                PyObject_CallMethod(result, "add", "O", 
-                    PyString_FromStringAndSize((const char *)ret->values[i].data, ret->values[i].length));
-            }
-
-            return result;
+            ldb_msg_add($self, el, val->flags);
         }
 
-        void __setitem__(const char *attr_name, PyObject *set_obj)
+        void __setitem__(const char *attr_name, PyObject *val)
         {
-            struct ldb_message_element *me = talloc($self, 
-                                                    struct ldb_message_element);
+            struct ldb_message_element *el = ldb_msg_element_from_pyobject(
+                                                val, 0, attr_name);
+            talloc_steal($self, el);
             ldb_msg_remove_attr($self, attr_name);
-            me->flags =0 ;
-            me->name = attr_name;
-            if (PyAnySet_Check(set_obj)) {
-                PyObject *iter, *obj;
-                int i;
-                me->num_values = PyObject_Size(set_obj);
-                me->values = talloc_array(me, struct ldb_val, me->num_values);
-                iter = PyObject_GetIter(set_obj);
-                i = 0;
-                while((obj = PyIter_Next(iter))) {
-                    me->values[i].length = PyString_Size(obj);
-                    me->values[i].data = PyString_AsString(obj);
-                    i++;
-                }
-            } else {
-                me->num_values = 1;
-                me->values = talloc_array(me, struct ldb_val, me->num_values);
-                me->values[0].length = PyString_Size(set_obj);
-                me->values[0].data = PyString_AsString(set_obj);
-            }
-            ldb_msg_add($self, me, 0);
+            ldb_msg_add($self, el, el->flags);
         }
 
         unsigned int __len__() { return $self->num_elements; }
+
+        PyObject *__iter__(void)
+        {
+            return PyObject_GetIter(ldb_msg_list_elements($self));
+        }
 #endif
         void remove_attr(const char *name);
     }
@@ -316,10 +401,12 @@
         ldb_error delete(ldb_dn *dn);
         ldb_error rename(ldb_dn *olddn, ldb_dn *newdn);
         ldb_error add(ldb_msg *message);
+        ldb_error modify(ldb_msg *message);
         ldb_dn *get_config_basedn();
         ldb_dn *get_root_basedn();
         ldb_dn *get_schema_basedn();
         ldb_dn *get_default_basedn();
+        const char *errstring();
 
         ldb_error transaction_start();
         ldb_error transaction_commit();

Modified: branches/4.0-python/source/lib/ldb/tests/python/api.py
===================================================================
--- branches/4.0-python/source/lib/ldb/tests/python/api.py	2007-10-23 21:28:57 UTC (rev 25708)
+++ branches/4.0-python/source/lib/ldb/tests/python/api.py	2007-10-23 21:29:08 UTC (rev 25709)
@@ -47,10 +47,12 @@
         l = ldb.Ldb("foo.tdb")
         m = ldb.Message()
         m.dn = ldb.Dn(l, "dc=foo")
-        m["b"] = "a"
+        m["b"] = ["a"]
         l.add(m)
-        self.assertTrue(ldb.Dn(l, "dc=foo") in l)
-        l.delete(m.dn)
+        try:
+            self.assertTrue(ldb.Dn(l, "dc=foo") in l)
+        finally:
+            l.delete(m.dn)
 
     def test_get_config_basedn(self):
         l = ldb.Ldb("foo.tdb")
@@ -72,28 +74,84 @@
         l = ldb.Ldb("foo.tdb")
         m = ldb.Message()
         m.dn = ldb.Dn(l, "dc=foo")
-        m["bla"] = set("bla")
+        m["bla"] = "bla"
         self.assertEquals(len(l.search()), 1)
         l.add(m)
-        self.assertEquals(len(l.search()), 2)
-        l.delete(ldb.Dn(l, "dc=foo"))
+        try:
+            self.assertEquals(len(l.search()), 2)
+        finally:
+            l.delete(ldb.Dn(l, "dc=foo"))
 
     def test_rename(self):
         l = ldb.Ldb("foo.tdb")
         m = ldb.Message()
         m.dn = ldb.Dn(l, "dc=foo")
-        m["bla"] = set("bla")
+        m["bla"] = "bla"
         self.assertEquals(len(l.search()), 1)
         l.add(m)
-        l.rename(ldb.Dn(l, "dc=foo"), ldb.Dn(l, "dc=bar"))
-        self.assertEquals(len(l.search()), 2)
-        l.delete(ldb.Dn(l, "dc=bar"))
+        try:
+            l.rename(ldb.Dn(l, "dc=foo"), ldb.Dn(l, "dc=bar"))
+            self.assertEquals(len(l.search()), 2)
+        finally:
+            l.delete(ldb.Dn(l, "dc=bar"))
 
+    def test_modify_delete(self):
+        l = ldb.Ldb("foo.tdb")
+        m = ldb.Message()
+        m.dn = ldb.Dn(l, "dc=modify")
+        m["bla"] = ["1234"]
+        l.add(m)
+        rm = l.search(m.dn)[0]
+        self.assertEquals(["1234"], list(rm["bla"]))
+        try:
+            m = ldb.Message()
+            m.dn = ldb.Dn(l, "dc=modify")
+            m["bla"] = ldb.MessageElement([], ldb.CHANGETYPE_DELETE, "bla")
+            l.modify(m)
+            rm = l.search(m.dn)[0]
+            self.assertEquals(1, len(rm))
+        finally:
+            l.delete(ldb.Dn(l, "dc=modify"))
+
+    def test_modify_add(self):
+        l = ldb.Ldb("foo.tdb")
+        m = ldb.Message()
+        m.dn = ldb.Dn(l, "dc=modify")
+        m["bla"] = ["1234"]
+        l.add(m)
+        try:
+            m = ldb.Message()
+            m.dn = ldb.Dn(l, "dc=modify")
+            m["bla"] = ldb.MessageElement(["456"], ldb.CHANGETYPE_ADD, "bla")
+            l.modify(m)
+            rm = l.search(m.dn)[0]
+            self.assertEquals(2, len(rm))
+            self.assertEquals(["1234", "456"], list(rm["bla"]))
+        finally:
+            l.delete(ldb.Dn(l, "dc=modify"))
+
+    def test_modify_modify(self):
+        l = ldb.Ldb("foo.tdb")
+        m = ldb.Message()
+        m.dn = ldb.Dn(l, "dc=modify")
+        m["bla"] = ["1234", "456"]
+        l.add(m)
+        try:
+            m = ldb.Message()
+            m.dn = ldb.Dn(l, "dc=modify")
+            m["bla"] = ldb.MessageElement(["456"], ldb.CHANGETYPE_MODIFY, "bla")
+            l.modify(m)
+            rm = l.search(m.dn)[0]
+            self.assertEquals(2, len(rm))
+            self.assertEquals(["1234"], list(rm["bla"]))
+        finally:
+            l.delete(ldb.Dn(l, "dc=modify"))
+
     def test_transaction_commit(self):
         l = ldb.Ldb("foo.tdb")
         l.transaction_start()
         m = ldb.Message(ldb.Dn(l, "dc=foo"))
-        m["foo"] = set(["bar"])
+        m["foo"] = ["bar"]
         l.add(m)
         l.transaction_commit()
         l.delete(m.dn)
@@ -102,9 +160,10 @@
         l = ldb.Ldb("foo.tdb")
         l.transaction_start()
         m = ldb.Message(ldb.Dn(l, "dc=foo"))
-        m["foo"] = set(["bar"])
+        m["foo"] = ["bar"]
         l.add(m)
         l.transaction_cancel()
+        self.assertEquals(0, len(l.search(ldb.Dn(l, "dc=foo"))))
 
 class DnTests(unittest.TestCase):
     def setUp(self):
@@ -207,22 +266,34 @@
 
     def test_add_value(self):
         self.assertEquals(0, len(self.msg))
-        self.msg["foo"] = set(["foo"])
+        self.msg["foo"] = ["foo"]
         self.assertEquals(1, len(self.msg))
 
     def test_add_value_multiple(self):
         self.assertEquals(0, len(self.msg))
-        self.msg["foo"] = set(["foo", "bla"])
+        self.msg["foo"] = ["foo", "bla"]
         self.assertEquals(1, len(self.msg))
-        self.assertEquals(set(["foo", "bla"]), self.msg["foo"])
+        self.assertEquals(["foo", "bla"], list(self.msg["foo"]))
 
     def test_set_value(self):
-        self.msg["foo"] = set(["fool"])
-        self.assertEquals(set(["fool"]), self.msg["foo"])
-        self.msg["foo"] = set(["bar"])
-        self.assertEquals(set(["bar"]), self.msg["foo"])
+        self.msg["foo"] = ["fool"]
+        self.assertEquals(["fool"], list(self.msg["foo"]))
+        self.msg["foo"] = ["bar"]
+        self.assertEquals(["bar"], list(self.msg["foo"]))
 
     def test_dn(self):
         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
         self.assertEquals("@BASEINFO", self.msg.dn.__str__())
 
+
+class MessageElementTests(unittest.TestCase):
+    def test_cmp_element(self):
+        x = ldb.MessageElement(["foo"])
+        y = ldb.MessageElement(["foo"])
+        z = ldb.MessageElement(["bzr"])
+        self.assertEquals(x, y)
+        self.assertNotEquals(x, z)
+
+    def test_create_iterable(self):
+        x = ldb.MessageElement(["foo"])
+        self.assertEquals(["foo"], list(x))


Property changes on: branches/4.0-python/source/lib/ldb/tests/python/api.py
___________________________________________________________________
Name: svn:executable
   + *

Modified: branches/4.0-python/source/scripting/python/samba/provision.py
===================================================================
--- branches/4.0-python/source/scripting/python/samba/provision.py	2007-10-23 21:28:57 UTC (rev 25708)
+++ branches/4.0-python/source/scripting/python/samba/provision.py	2007-10-23 21:29:08 UTC (rev 25709)
@@ -475,7 +475,7 @@
         setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb)
 
         message("Erasing data from partitions")
-        ldb_erase_partitions(subobj, message, samdb, ldapbackend)
+        # FIXME ldb_erase_partitions(subobj, message, samdb, ldapbackend)
         
         message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn)
         try:



More information about the samba-cvs mailing list