Skip to content
Browse files

Added increment operation

  • Loading branch information...
1 parent cd56d70 commit 37dd6562f6202a6e32bcaf699bd2e378d2e4b952 @alienscience committed Feb 23, 2011
Showing with 60 additions and 27 deletions.
  1. +21 −2 README.md
  2. +39 −25 src/clj_ldap/client.clj
View
23 README.md
@@ -102,9 +102,15 @@ a map in the form:
:attribute-e [value1 value2]}
:replace
{:attibute-d value
- :attribute-e [value1 value2]}}
+ :attribute-e [value1 value2]}
+ :increment
+ {:attribute-f value}
+ :pre-read
+ #{:attribute-a :attribute-b}
+ :post-read
+ #{:attribute-c :attribute-d}}
-Where :add adds an attribute value, :delete deletes an attribute value and :replace replaces the set of values for the attribute with the ones specified.
+Where :add adds an attribute value, :delete deletes an attribute value and :replace replaces the set of values for the attribute with the ones specified. The entries :pre-read and :post-read specify attributes that have be read and returned either before or after the modifications have taken place.
All the keys in the map are optional e.g:
@@ -116,6 +122,19 @@ The values in the map can also be set to :all when doing a delete e.g:
(ldap/modify conn "cn=dude,ou=people,dc=example,dc=com"
{:delete {:telephoneNumber :all}})
+The values of the attributes given in :pre-read and :post-read are available in the returned map and are part of an atomic ldap operation e.g
+
+ (ldap/modify conn "uid=maxuid,ou=people,dc=example,dc=com"
+ {:increment {:uidNumber 1}
+ :post-read #{:uidNumber}})
+
+ returns>
+ {:code 0
+ :name "success"
+ :post-read {:uidNumber "2002"}}
+
+The above technique can be used to maintain counters for unique ids as described by [rfc4525](http://tools.ietf.org/html/rfc4525).
+
Throws a [LDAPException](http://www.unboundid.com/products/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/LDAPException.html) on error.
## search [connection base] [connection base options]
View
64 src/clj_ldap/client.clj
@@ -34,22 +34,37 @@
;;======== Helper functions ====================================================
+(defn- extract-attribute
+ "Extracts [:name value] from the given attribute object. Converts
+ the objectClass attribute to a set."
+ [attr]
+ (let [k (keyword (.getName attr))]
+ (cond
+ (= :objectClass k) [k (set (vec (.getValues attr)))]
+ (> (.size attr) 1) [k (vec (.getValues attr))]
+ :else [k (.getValue attr)])))
+
(defn- entry-as-map
- "Converts an Entry object into a map"
- [entry]
- (let [col-a (.getAttributes entry)
- attrs (seq (.getAttributes entry))]
- (apply hash-map :dn (.getDN entry)
- (mapcat extract-attribute attrs))))
+ "Converts an Entry object into a map optionally adding the DN"
+ ([entry]
+ (entry-as-map entry true))
+ ([entry dn?]
+ (let [col-a (.getAttributes entry)
+ attrs (seq (.getAttributes entry))]
+ (if dn?
+ (apply hash-map :dn (.getDN entry)
+ (mapcat extract-attribute attrs))
+ (apply hash-map
+ (mapcat extract-attribute attrs))))))
(defn- add-response-control
"Adds the values contained in given response control to the given map"
[m control]
(condp instance? control
PreReadResponseControl
- (update-in m [:pre-read] merge (entry-as-map (.getEntry control)))
+ (update-in m [:pre-read] merge (entry-as-map (.getEntry control) false))
PostReadResponseControl
- (update-in m [:post-read] merge (entry-as-map (.getEntry control)))
+ (update-in m [:post-read] merge (entry-as-map (.getEntry control) false))
m))
(defn- add-response-controls
@@ -150,17 +165,6 @@
bind-request (bind-request options)]
(LDAPConnectionPool. server-set bind-request (or num-connections 1))))
-(defn- extract-attribute
- "Extracts [:name value] from the given attribute object. Converts
- the objectClass attribute to a set."
- [attr]
- (let [k (keyword (.getName attr))]
- (cond
- (= :objectClass k) [k (set (vec (.getValues attr)))]
- (> (.size attr) 1) [k (vec (.getValues attr))]
- :else [k (.getValue attr)])))
-
-
(defn- set-entry-kv!
"Sets the given key/value pair in the given entry object"
@@ -212,7 +216,9 @@
deletes (modify-ops ModificationType/DELETE (modifications :delete))
replacements (modify-ops ModificationType/REPLACE
(modifications :replace))
- all (concat adds deletes replacements)]
+ increments (modify-ops ModificationType/INCREMENT
+ (modifications :increment))
+ all (concat adds deletes replacements increments)]
(doto (ModifyRequest. dn (into-array all))
(add-request-controls modifications))))
@@ -353,6 +359,8 @@
:replace
{:attibute-d value
:attribute-e [value1 value2]}
+ :increment
+ {:attribute-f value}
:pre-read
#{:attribute-a :attribute-b}
:post-read
@@ -367,11 +375,17 @@ Where :add adds an attribute value, :delete deletes an attribute value and :repl
(defn delete
- "Deletes the given entry in the connected ldap server"
- [connection dn]
- (let [delete-obj (DeleteRequest. dn)]
- (ldap-result
- (.delete connection delete-obj))))
+ "Deletes the given entry in the connected ldap server. Optionally takes
+ a map that can contain the entry :pre-read to indicate the attributes
+ that should be read before deletion."
+ ([connection dn]
+ (delete connection dn nil))
+ ([connection dn options]
+ (let [delete-obj (DeleteRequest. dn)]
+ (when options
+ (add-request-controls delete-obj options))
+ (ldap-result
+ (.delete connection delete-obj)))))
(defn search

0 comments on commit 37dd656

Please sign in to comment.
Something went wrong with that request. Please try again.