lib/ldb: add schema based ldb_val comparison and ldb_msg_element search routines
[metze/samba/wip.git] / lib / ldb / common / ldb_msg.c
index 1177cf487ed2c1962860bccfe0bfe7211719605d..0318a21194f9e1ad80887adef40abd98884ea9a0 100644 (file)
@@ -73,6 +73,30 @@ int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2)
        return 0;
 }
 
+/*
+  see if two ldb_val structures contain exactly the same data in respect to
+  schema equivalence.
+  set *matched on match, returns LDB error codes
+*/
+int ldb_val_equal_schema(struct ldb_context *ldb,
+                        const struct ldb_schema_attribute *a,
+                        const struct ldb_val *v1, const struct ldb_val *v2,
+                        bool *matched)
+{
+       if (a->syntax->operator_fn) {
+               return a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
+                                             v1, v2, matched);
+       } else {
+               int ret = a->syntax->comparison_fn(ldb, ldb, v1, v2);
+               if (ret == 0) {
+                       *matched = true;
+               } else {
+                       *matched = false;
+               }
+       }
+       return LDB_SUCCESS;
+}
+
 /*
   find a value in an element
   assumes case sensitive comparison
@@ -89,6 +113,47 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
        return NULL;
 }
 
+/*
+  find a value in an element
+  assumes schema exact comparison.
+  This returns LDB_SUCCESS and sets *matched_val to NULL or
+  to the found element.
+  Other return values is are errors.
+*/
+int ldb_msg_find_val_schema(struct ldb_context *ldb,
+                           const struct ldb_schema_attribute *a,
+                           const struct ldb_message_element *el,
+                           const struct ldb_val *val,
+                           struct ldb_val **matched_val)
+{
+       unsigned int i;
+
+       if (matched_val != NULL) {
+               *matched_val = NULL;
+       }
+
+       for (i = 0; i < el->num_values; i++) {
+               int ret;
+               bool match;
+
+               ret = ldb_val_equal_schema(ldb, a, val, &el->values[i], &match);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+
+               if (!match) {
+                       continue;
+               }
+
+               if (matched_val) {
+                       *matched_val = &el->values[i];
+               }
+               return LDB_SUCCESS;
+       }
+
+       return LDB_SUCCESS;
+}
+
 /*
   duplicate a ldb_val structure
 */