Skip to content

Commit

Permalink
Merge pull request #51 from michaelklishin/connection
Browse files Browse the repository at this point in the history
Removed dynamic var for the connection
  • Loading branch information
michaelklishin committed Apr 23, 2014
2 parents a3924b7 + 3440db8 commit c2368c8
Show file tree
Hide file tree
Showing 29 changed files with 1,178 additions and 1,059 deletions.
16 changes: 16 additions & 0 deletions ChangeLog.md
@@ -1,3 +1,19 @@
## Changes between Neocons 2.1.0 and 3.0.0

Neocons no longer uses a dynamic var to hold the state of the connection.
This leads to significant changes to the API as the connection has to be
passed to functions. The position of the connection argument is always the
first argument for the sake of consistency.

Additionally `connect!` function in `clojurewerkz.neocons.rest` no longer
exists. This has been replaced by function `connect` in `clojurewerkz.neocons.rest`.
The `connect` function has the same arguments as the `connect!` function
only it returns a `Connection` record.

The `Connection` record has a key called `:options` which can be used to pass
additional parameters to be used by [clj-http](https://github.com/dakrone/clj-http)
like `debug`.

## Changes between Neocons 2.0.0 and 2.1.0-beta1

### Clojure 1.6
Expand Down
2 changes: 1 addition & 1 deletion project.clj
@@ -1,4 +1,4 @@
(defproject clojurewerkz/neocons "2.1.0-beta1-SNAPSHOT"
(defproject clojurewerkz/neocons "3.0.0-SNAPSHOT"
:description "Neocons is a feature rich idiomatic Clojure client for the Neo4J REST API"
:url "http://clojureneo4j.info"
:license {:name "Eclipse Public License"}
Expand Down
119 changes: 60 additions & 59 deletions src/clojure/clojurewerkz/neocons/rest.clj
Expand Up @@ -18,56 +18,58 @@
;;
;; Implementation
;;
(defrecord Neo4JEndpoint
[version
node-uri
relationships-uri
node-index-uri
relationship-index-uri
relationship-types-uri
batch-uri
extensions-info-uri
extensions
reference-node-uri
uri
cypher-uri
transaction-uri])

(defrecord Connection [^Neo4JEndpoint endpoint http-auth options])


(defn- env-var
[^String s]
(get (System/getenv) s))

(def ^{:private true}
global-options {:throw-entire-message? true})
global-options {:throw-entire-message? true
:accept :json})

(defn- get-options
[^Connection connection options]
(merge global-options (:http-auth connection) (:options connection) options))

(def ^{:private true}
http-authentication-options {})

(defn GET
[^String uri & {:as options}]
[^Connection connection ^String uri & {:as options}]
(io!
(http/get uri (merge global-options http-authentication-options options {:accept :json}))))
(http/get uri (get-options connection options))))

(defn POST
[^String uri &{:keys [body] :as options}]
[^Connection connection ^String uri &{:keys [body] :as options}]
(io!
(http/post uri (merge global-options http-authentication-options options {:accept :json :content-type :json :body body}))))
(http/post uri (merge (get-options connection options)
{:content-type :json :body body}))))

(defn PUT
[^String uri &{:keys [body] :as options}]
[^Connection connection ^String uri &{:keys [body] :as options}]
(io!
(http/put uri (merge global-options http-authentication-options options {:accept :json :content-type :json :body body}))))
(http/put uri (merge (get-options connection options)
{:content-type :json :body body}))))

(defn DELETE
[^String uri &{:keys [body] :as options}]
[^Connection connection ^String uri &{:keys [body] :as options}]
(io!
(http/delete uri (merge global-options http-authentication-options options {:accept :json}))))




(defrecord Neo4JEndpoint
[version
node-uri
relationships-uri
node-index-uri
relationship-index-uri
relationship-types-uri
batch-uri
extensions-info-uri
extensions
reference-node-uri
uri
cypher-uri
transaction-uri])

(def ^{:dynamic true} *endpoint*)
(http/delete uri (get-options connection options))))

;;
;; API
Expand All @@ -82,32 +84,31 @@
password (env-var "NEO4J_PASSWORD")]
(connect uri login password)))
([^String uri login password]
(let [{ :keys [status body] } (if (and login password)
(GET uri :basic-auth [login password])
(GET uri))]
(let [basic-auth (if (and login password)
{:basic-auth [login password]}
{})
{:keys [status body]} (GET (map->Connection
{:http-auth basic-auth :options {}})
uri)]
(if (success? status)
(let [payload (json/decode body true)]
(alter-var-root (var http-authentication-options) (constantly { :basic-auth [login password] }))
(Neo4JEndpoint. (:neo4j_version payload)
(:node payload)
(str uri (if (.endsWith uri "/")
"relationship"
"/relationship"))
(:node_index payload)
(:relationship_index payload)
(:relationship_types payload)
(:batch payload)
(:extensions_info payload)
(:extensions payload)
(:reference_node payload)
(maybe-append uri "/")
(:cypher payload)
(:transaction payload)
))))))

(defn connect!
"Like connect but also mutates *endpoint* state to store the connection"
([uri]
(alter-var-root (var *endpoint*) (fn [_] (connect uri))))
([uri login password]
(alter-var-root (var *endpoint*) (fn [_] (connect uri login password)))))
(let [payload (json/decode body true)
http-auth (:basic-auth basic-auth)
endpoint (Neo4JEndpoint. (:neo4j_version payload)
(:node payload)
(str uri (if (.endsWith uri "/")
"relationship"
"/relationship"))
(:node_index payload)
(:relationship_index payload)
(:relationship_types payload)
(:batch payload)
(:extensions_info payload)
(:extensions payload)
(:reference_node payload)
(maybe-append uri "/")
(:cypher payload)
(:transaction payload))]
(map->Connection
{:endpoint endpoint
:options {}
:http-auth http-auth}))))))
8 changes: 5 additions & 3 deletions src/clojure/clojurewerkz/neocons/rest/batch.clj
Expand Up @@ -12,7 +12,8 @@
"Batch operation execution"
(:require [clojurewerkz.neocons.rest :as rest]
[clojurewerkz.neocons.rest.records :as rec]
[cheshire.core :as json]))
[cheshire.core :as json])
(:import clojurewerkz.neocons.rest.Connection))



Expand All @@ -35,7 +36,8 @@
If you need to insert a batch of nodes at once, consider using neocons.rest.nodes/create-batch.
See http://docs.neo4j.org/chunked/milestone/rest-api-batch-ops.html for more information."
[ops]
(let [{:keys [status headers body]} (rest/POST (:batch-uri rest/*endpoint*) :body (json/encode ops))
[^Connection connection ops]
(let [{:keys [status headers body]} (rest/POST connection (get-in connection [:endpoint :batch-uri])
:body (json/encode ops))
payload (map :body (json/decode body true))]
(map rec/instantiate-record-from payload)))
41 changes: 21 additions & 20 deletions src/clojure/clojurewerkz/neocons/rest/constraints.clj
Expand Up @@ -14,30 +14,33 @@
[cheshire.core :as json]
[clojurewerkz.neocons.rest.conversion :as conv]
[clojurewerkz.support.http.statuses :refer [missing?]])
(:import clojurewerkz.neocons.rest.Connection)
(:refer-clojure :exclude [rest]))

(defn- get-url
[^String label]
(str (:uri rest/*endpoint*) "schema/constraint/" (conv/encode-kw-to-string label)))
[^Connection connection ^String label]
(str (get-in connection [:endpoint :uri]) "schema/constraint/" (conv/encode-kw-to-string label)))

(defn- get-uniqueness-url
[label]
(str (get-url label) "/uniqueness"))
[^Connection connection label]
(str (get-url connection label) "/uniqueness"))

(defn create-unique
"Creates a unique constraint on a given label and property.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-create-uniqueness-constraint"
[label property]
[^Connection connection label property]
(let [req-body (json/encode {"property_keys" [(conv/kw-to-string property)]})
{:keys [status headers body]} (rest/POST (get-uniqueness-url label) :body req-body)]
{:keys [status headers body]} (rest/POST connection (get-uniqueness-url connection label)
:body req-body)]
(when-not (missing? status)
(conv/map-values-to-kw
(json/decode body true)
[:label :property-keys]))))

(defn- get-uniquess-constraints
[label ^String uri]
(let [{:keys [status headers body]} (rest/GET (str (get-url label) uri))]
[^Connection connection label ^String uri]
(let [{:keys [status headers body]} (rest/GET connection (str (get-url connection label)
uri))]
(when-not (missing? status)
(map
#(conv/map-values-to-kw % [:label :property-keys])
Expand All @@ -49,26 +52,24 @@
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-get-all-uniqueness-constraints-for-a-label
and http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-get-all-constraints-for-a-label"
([label]
(get-uniquess-constraints label "/uniqueness"))
([label property]
(get-uniquess-constraints label (str "/uniqueness/" (conv/encode-kw-to-string property)))))
([^Connection connection label]
(get-uniquess-constraints connection label "/uniqueness"))
([^Connection connection label property]
(get-uniquess-constraints connection label (str "/uniqueness/" (conv/encode-kw-to-string property)))))

(defn get-all
"Gets information about all the different constraints associated with a label.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-get-all-constraints-for-a-label
If no label is passed, gets information about all the constraints.
http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-get-all-constraints"
([]
(get-uniquess-constraints "" ""))
([label]
(get-uniquess-constraints label "")))
([^Connection connection ]
(get-uniquess-constraints connection "" ""))
([^Connection connection label]
(get-uniquess-constraints connection label "")))

(defn drop-unique
"Drops an existing uniquenss constraint on an label and property.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-constraints.html#rest-api-drop-constraint"

[label property]
(rest/DELETE (str (get-uniqueness-url label) "/" (conv/encode-kw-to-string property))))

[^Connection connection label property]
(rest/DELETE connection (str (get-uniqueness-url connection label) "/" (conv/encode-kw-to-string property))))
18 changes: 9 additions & 9 deletions src/clojure/clojurewerkz/neocons/rest/cypher.clj
Expand Up @@ -16,16 +16,16 @@
[clojurewerkz.neocons.rest.helpers :refer :all]
[clojurewerkz.neocons.rest.records :refer :all])
(:import [java.net URI URL]
clojurewerkz.neocons.rest.Neo4JEndpoint
clojurewerkz.neocons.rest.Connection
clojurewerkz.neocons.rest.records.CypherQueryResponse))

;;
;; Implementation
;;

(defn cypher-query-location-for
[^Neo4JEndpoint endpoint]
(:cypher-uri endpoint))
[^Connection connection]
(get-in connection [:endpoint :cypher-uri]))



Expand All @@ -44,12 +44,12 @@

(defn query
"Performs a Cypher query, returning columns and rows separately (the way Neo4J REST API does)"
([^String q]
(query q {}))
([^String q params]
(let [{:keys [status headers body]} (rest/POST (cypher-query-location-for rest/*endpoint*) :body (json/encode {:query q :params params}))]
(if (missing? status)
nil
([^Connection connection ^String q]
(query connection q {}))
([^Connection connection ^String q params]
(let [{:keys [status headers body]} (rest/POST connection (cypher-query-location-for connection)
:body (json/encode {:query q :params params}))]
(when-not (missing? status)
(instantiate-cypher-query-response-from (json/decode body true))))))

(def ^{:doc "Performs a Cypher query, returning result formatted as a table (using tableize)"}
Expand Down
18 changes: 10 additions & 8 deletions src/clojure/clojurewerkz/neocons/rest/index.clj
Expand Up @@ -14,18 +14,20 @@
[cheshire.core :as json]
[clojurewerkz.neocons.rest.conversion :as conv]
[clojurewerkz.support.http.statuses :refer [missing?]])
(:import [clojurewerkz.neocons.rest Connection])
(:refer-clojure :exclude [drop]))

(defn- get-url
[label]
(str (:uri rest/*endpoint*) "schema/index/" (conv/kw-to-string label)))
[^Connection connection label]
(str (get-in connection [:endpoint :uri]) "schema/index/" (conv/kw-to-string label)))

(defn create
"Creates an index on a given label and property.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-indexes.html#rest-api-create-index"
[label property]
[^Connection connection label property]
(let [req-body (json/encode {"property_keys" [(conv/kw-to-string property)]})
{:keys [status headers body]} (rest/POST (get-url label) :body req-body)]
{:keys [status headers body]} (rest/POST connection (get-url connection label)
:body req-body)]
(when-not (missing? status)
(conv/map-values-to-kw
(json/decode body true)
Expand All @@ -35,13 +37,13 @@
"Gets all indices for a given label.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-indexes.html#rest-api-list-indexes-for-a-label"

[label]
(let [{:keys [status headers body]} (rest/GET (get-url label))]
[^Connection connection label]
(let [{:keys [status headers body]} (rest/GET connection (get-url connection label))]
(when-not (missing? status)
(json/decode body true))))

(defn drop
"Drops an index on an existing label and property.
See http://docs.neo4j.org/chunked/milestone/rest-api-schema-indexes.html#rest-api-list-indexes-for-a-label"
[label property]
(rest/DELETE (str (get-url label) "/" (conv/kw-to-string property))))
[^Connection connection label property]
(rest/DELETE connection (str (get-url connection label) "/" (conv/kw-to-string property))))

0 comments on commit c2368c8

Please sign in to comment.