ldb/python: Add bindings for schema functions.
[ira/wip.git] / source / lib / ldb / ldb.i
index cf4a33595490515d754208b6b617d2e087277852..336100c4f0a8bbfad118e67f2016f89b98301c0b 100644 (file)
@@ -5,7 +5,7 @@
 
    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
    Copyright (C) 2006 Simo Sorce <idra@samba.org>
-   Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
+   Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -102,8 +102,44 @@ typedef int ldb_error;
        $1->data = PyString_AsString($input);
 }
 
+%inline %{
+PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx, 
+                               struct ldb_message_element *el, 
+                               struct ldb_val *val)
+{
+        const struct ldb_schema_attribute *a;
+        struct ldb_val new_val;
+        TALLOC_CTX *mem_ctx = talloc_new(NULL);
+        PyObject *ret;
+        
+        new_val = *val;
+        
+        if (ldb_ctx != NULL) {        
+               a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
+        
+               if (a != NULL) {
+                       if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
+                               talloc_free(mem_ctx);
+                               return NULL;
+                       }
+               }
+        } 
+        
+       ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
+       
+       talloc_free(mem_ctx);
+       
+       return ret;
+}
+
+%}
+
+%typemap(out,noblock=1) struct ldb_val * {
+       $result = PyString_FromStringAndSize((const char *)$1->data, $1->length)
+}
+
 %typemap(out,noblock=1) struct ldb_val {
-       $result = PyString_FromStringAndSize((const char *)$1.data, $1.length);
+       $result = PyString_FromStringAndSize((const char *)$1.data, $1.length)
 }
 
 /*
@@ -201,6 +237,14 @@ fail:
 
         /* FIXME: implement __getslice__ */
 #endif
+    %pythoncode {
+        def __eq__(self, other):
+            if isinstance(other, self.__class__):
+                return self.__cmp__(other) == 0
+            if isinstance(other, str):
+                return str(self) == other
+            return False
+    }
     }
 } ldb_dn;
 
@@ -251,7 +295,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
     return me;
 }
 
-PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
+PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
+                                 ldb_msg_element *me)
 {
     int i;
     PyObject *result;
@@ -261,8 +306,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
 
     for (i = 0; i < me->num_values; i++) {
         PyList_SetItem(result, i,
-            PyString_FromStringAndSize((const char *)me->values[i].data, 
-                                       me->values[i].length));
+            ldb_val_to_py_object(ldb_ctx, me, &me->values[i]));
     }
 
     return result;
@@ -279,12 +323,12 @@ typedef struct ldb_message_element {
 #ifdef SWIGPYTHON
         PyObject *__iter__(void)
         {
-            return PyObject_GetIter(ldb_msg_element_to_set($self));
+            return PyObject_GetIter(ldb_msg_element_to_set(NULL, $self));
         }
 
         PyObject *__set__(void)
         {
-            return ldb_msg_element_to_set($self);
+            return ldb_msg_element_to_set(NULL, $self);
         }
 
         ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
@@ -303,9 +347,7 @@ typedef struct ldb_message_element {
             if (i < 0 || i >= $self->num_values)
                 return Py_None;
 
-            return PyString_FromStringAndSize(
-                        (const char *)$self->values[i].data, 
-                        $self->values[i].length);
+            return ldb_val_to_py_object(NULL, $self, &$self->values[i]);
         }
 
         ~ldb_msg_element() { talloc_free($self); }
@@ -514,11 +556,49 @@ typedef struct ldb_context {
             const char *options[] = NULL);
 
         ~ldb() { talloc_free($self); }
-        ldb_error search(ldb_dn *base = NULL, 
+        ldb_error search_ex(TALLOC_CTX *mem_ctx,
+                   ldb_dn *base = NULL, 
                    enum ldb_scope scope = LDB_SCOPE_DEFAULT, 
                    const char *expression = NULL, 
-                   const char * const *attrs = NULL, 
-                   struct ldb_result **OUT);
+                   const char *const *attrs = NULL, 
+                   struct ldb_control **controls = NULL,
+                   struct ldb_result **OUT) {
+            int ret;
+            struct ldb_result *res;
+            struct ldb_request *req;
+            res = talloc_zero(mem_ctx, struct ldb_result);
+            if (!res) {
+                return LDB_ERR_OPERATIONS_ERROR;
+            }
+
+            ret = ldb_build_search_req(&req, $self, mem_ctx,
+                           base?base:ldb_get_default_basedn($self),
+                           scope,
+                           expression,
+                           attrs,
+                           controls,
+                           res,
+                           ldb_search_default_callback);
+
+            if (ret != LDB_SUCCESS) {
+                talloc_free(res);
+                return ret;
+            }
+
+            ldb_set_timeout($self, req, 0); /* use default timeout */
+                
+            ret = ldb_request($self, req);
+                
+            if (ret == LDB_SUCCESS) {
+                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+            }
+
+            talloc_free(req);
+
+            *OUT = res;
+            return ret;
+        }
+
         ldb_error delete(ldb_dn *dn);
         ldb_error rename(ldb_dn *olddn, ldb_dn *newdn);
         struct ldb_control **parse_control_strings(TALLOC_CTX *mem_ctx, 
@@ -576,6 +656,35 @@ typedef struct ldb_context {
         ldb_dn *get_root_basedn();
         ldb_dn *get_schema_basedn();
         ldb_dn *get_default_basedn();
+        PyObject *schema_format_value(const char *element_name, PyObject *val)
+        {
+               const struct ldb_schema_attribute *a;
+               struct ldb_val old_val;
+               struct ldb_val new_val;
+               TALLOC_CTX *mem_ctx = talloc_new(NULL);
+               PyObject *ret;
+               
+               old_val.data = PyString_AsString(val);
+               old_val.length = PyString_Size(val);
+                
+               a = ldb_schema_attribute_by_name($self, element_name);
+        
+               if (a == NULL) {
+                       return Py_None;
+               }
+               
+               if (a->syntax->ldif_write_fn($self, mem_ctx, &old_val, &new_val) != 0) {
+                       talloc_free(mem_ctx);
+                       return Py_None;
+                }
+        
+               ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
+               
+               talloc_free(mem_ctx);
+               
+               return ret;
+        }
+
         const char *errstring();
         void set_create_perms(unsigned int perms);
         void set_modules_dir(const char *path);
@@ -587,7 +696,10 @@ typedef struct ldb_context {
         ldb_error transaction_start();
         ldb_error transaction_commit();
         ldb_error transaction_cancel();
-
+        void schema_attribute_remove(const char *name);
+        ldb_error schema_attribute_add(const char *attribute, unsigned flags, const char *syntax);
+       ldb_error setup_wellknown_attributes(void);
+       
 #ifdef SWIGPYTHON
         %typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
         %typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }
@@ -615,6 +727,14 @@ typedef struct ldb_context {
             _ldb.Ldb_swiginit(self,_ldb.new_Ldb())
             if url is not None:
                 self.connect(url, flags, options)
+
+        def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, 
+                   attrs=None, controls=None):
+            parsed_controls = None
+            if controls is not None:
+                parsed_controls = self.parse_control_strings(controls)
+            return self.search_ex(base, scope, expression, attrs, 
+                                  parsed_controls)
     }
 
 } ldb;