[cl-neo4j-cvs] r1 -

Kevin Raison kraison at common-lisp.net
Tue May 18 19:43:41 UTC 2010


Author: kraison
Date: Tue May 18 15:43:41 2010
New Revision: 1

Log:
initial check in



Added:
   LICENSE
   README
   cl-neo4j-package.lisp
   cl-neo4j.asd
   conditions.lisp
   globals.lisp
   neo4j.lisp
   utilities.lisp

Added: LICENSE
==============================================================================
--- (empty file)
+++ LICENSE	Tue May 18 15:43:41 2010
@@ -0,0 +1,25 @@
+ cl-neo4j
+
+ Copyright (c) 2010 Kevin Raison <raison at chatsubo.net>
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+

Added: README
==============================================================================
--- (empty file)
+++ README	Tue May 18 15:43:41 2010
@@ -0,0 +1 @@
+TODO.

Added: cl-neo4j-package.lisp
==============================================================================
--- (empty file)
+++ cl-neo4j-package.lisp	Tue May 18 15:43:41 2010
@@ -0,0 +1,35 @@
+(in-package #:cl-user)
+
+(defpackage #:cl-neo4j
+  (:use #:cl
+	#:json
+	#:json-rpc
+	#:drakma)
+  (:export #:do-neo4j-query
+	   #:get-node
+	   #:extract-node-id
+	   #:create-node
+	   #:set-node-properties
+	   #:get-node-properties
+	   #:del-node-properties
+	   #:set-node-property
+	   #:get-node-property
+	   #:del-node-property
+	   #:delete-node
+	   #:create-relationship
+	   #:set-relationship-properties
+	   #:get-relationship-properties
+	   #:del-relationship-properties
+	   #:set-relationship-property
+	   #:get-relationship-property
+	   #:del-relationship-property
+	   #:delete-relationship
+	   #:get-node-relationships
+	   #:list-indices
+	   #:add-to-index
+	   #:remove-from-index
+	   #:query-index
+	   #:traverse
+	   ;; Vars
+	   #:*neo4j-host*
+	   #:*neo4j-port*))

Added: cl-neo4j.asd
==============================================================================
--- (empty file)
+++ cl-neo4j.asd	Tue May 18 15:43:41 2010
@@ -0,0 +1,22 @@
+;; ASDF package description for cl-neo4j              -*- Lisp -*-
+
+(defpackage :cl-neo4j-system (:use :cl :asdf))
+(in-package :cl-neo4j-system)
+
+(defsystem cl-neo4j
+  :name "neo4j RESTful Client Interface ()"
+  :maintainer "Kevin Raison"
+  :author "Kevin Raison <last name @ chatsubo dot net>"
+  :version "0.1"
+  :description "neo4j RESTful Client Interface"
+  :long-description "neo4j RESTful Client Interface."
+  :depends-on (:drakma
+	       :cl-json)
+  :components ((:file "cl-neo4j-package")
+	       (:file "globals" :depends-on ("cl-neo4j-package"))
+	       (:file "utilities" :depends-on ("globals"))
+	       (:file "conditions" :depends-on ("utilities"))
+	       (:file "neo4j" :depends-on ("conditions"))))
+
+
+

Added: conditions.lisp
==============================================================================
--- (empty file)
+++ conditions.lisp	Tue May 18 15:43:41 2010
@@ -0,0 +1,44 @@
+(in-package #:cl-neo4j)
+
+(define-condition unknown-return-type-error (error)
+  ((uri :accessor uri :initarg :uri)
+   (property :accessor property :initarg :property)
+   (status :accessor status :initarg :status))
+  (:report (lambda (condition stream)
+	     (format stream "Unknown status ~A returned for ~A (~A)" 
+		     (status condition) (uri condition) (property condition)))))
+  
+(define-condition invalid-data-sent-error (error)
+  ((json :accessor json :initarg :json)
+   (uri :accessor uri :initarg :uri))
+  (:report (lambda (condition stream)
+	     (format stream "Invalid data sent to ~A: ~A" (uri condition) (json condition)))))
+
+(define-condition node-not-found-error (error)
+  ((uri :accessor uri :initarg :uri)
+   (property :accessor property :initarg :property))
+  (:report (lambda (condition stream)
+	     (if (slot-boundp condition 'property)
+		 (format stream "Property ~A not found for node ~A" 
+			 (property condition) (uri condition))
+		 (format stream "Node not found ~A" (uri condition))))))
+  
+(define-condition unable-to-delete-node-error (error)
+  ((uri :accessor uri :initarg :uri))
+  (:report (lambda (condition stream)
+	     (format stream "Unable to delete node ~A. Still has relationships?" (uri condition)))))
+
+(define-condition relationship-not-found-error (error)
+  ((uri :accessor uri :initarg :uri)
+   (property :accessor property :initarg :property))
+  (:report (lambda (condition stream)
+	     (if (slot-boundp condition 'property)
+		 (format stream "Property ~A not found for relationship ~A" 
+			 (property condition) (uri condition))
+		 (format stream "Relationship not found ~A" (uri condition))))))
+  
+(define-condition index-entry-not-found-error (error)
+  ((uri :accessor uri :initarg :uri))
+  (:report (lambda (condition stream)
+	     (format stream "Index entry not found ~A" (uri condition)))))
+  

Added: globals.lisp
==============================================================================
--- (empty file)
+++ globals.lisp	Tue May 18 15:43:41 2010
@@ -0,0 +1,4 @@
+(in-package #:cl-neo4j)
+
+(defvar *neo4j-host* "localhost")
+(defvar *neo4j-port* 9999)

Added: neo4j.lisp
==============================================================================
--- (empty file)
+++ neo4j.lisp	Tue May 18 15:43:41 2010
@@ -0,0 +1,269 @@
+(in-package #:cl-neo4j)
+
+(defun do-neo4j-query (uri method &key json decode?)
+  (multiple-value-bind (body status headers uri stream must-close reason)
+      (http-request uri
+		    :method method
+		    :content json
+		    :content-type (if json "application/json")
+		    :accept "application/json")
+    (declare (ignore headers uri stream must-close reason))
+    (values status (if decode?
+		       (decode-json-from-string (map 'string #'code-char body))
+		       body))))
+
+(defmacro def-neo4j-fun (name lambda-list method &rest args)
+  `(progn
+     (defun ,name ,(append '(&key (host *neo4j-host*) (port *neo4j-port*)) lambda-list)
+       (let ((uri ,(cadr (assoc :uri-spec args)))
+	     (json ,(cond ((cadr (assoc :encode-properties? args))
+			   `(encode-json-to-string properties))
+			  ((cadr (assoc :encode-value? args))
+			   `(encode-json-to-string value))
+			  ((cadr (assoc :encode-node-id? args))
+			   `(format nil "http://~A:~A/node/~A" host port node-id))
+			  ((cadr (assoc :encode-relationship? args))
+			   `(encode-json-to-string
+			     (list (cons "to" 
+					 (format nil "http://~A:~A/node/~A" host port to-node-id))
+				   (cons "type" relationship-type)
+				   (cons "data" properties))))
+			  (t nil))))
+	 (multiple-value-bind (body status headers drakma-uri stream must-close reason)
+	     (http-request uri
+			   :method ,method
+			   :content json
+			   :content-type (if json "application/json" nil)
+			   :accept "application/json")
+	   (declare (ignore headers drakma-uri stream must-close reason))
+	   (case status
+	     ,@(mapcar 
+		#'(lambda (s) s) 
+		(append (cadr (assoc :status-handlers args))
+			`((othwerwise 
+			   (error 'unknown-return-type-error :uri uri :status status
+				  :property (cond ((boundp 'properties) (symbol-value 'properties))
+						  ((boundp 'value) (symbol-value 'value))
+						  ((boundp 'node-id) (symbol-value 'node-id))
+						  (t nil)))))))))))))
+
+(defun extract-node-id (url)
+  "http://localhost:9999/node/1"
+  (subseq url (1+ (search "/" url :from-end t))))
+
+(def-neo4j-fun get-node (node-id)
+  :get
+  (:uri-spec (if node-id
+		 (format nil "http://~A:~A/node/~A" host port node-id)
+		 (format nil "http://~A:~A/" host port)))
+  (:status-handlers 
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (404 (error 'node-not-found-error :uri uri :property node-id)))))
+
+(def-neo4j-fun create-node (properties)
+  :post
+  (:encode-properties? t)
+  (:uri-spec (format nil "http://~A:~A/node" host port))
+  (:status-handlers
+   ((201 (decode-json-from-string (map 'string #'code-char body)))
+    (400 (error 'invalid-data-sent-error :uri uri :json json)))))
+
+(def-neo4j-fun delete-node (node-id)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/node/~A" host port node-id))
+  (:status-handlers
+   ((204 (values t body))
+    (404 (error 'node-not-found-error :uri uri))
+    (409 (error 'unable-to-delete-node-error :uri uri)))))
+
+(def-neo4j-fun set-node-properties (node-id properties)
+  :put
+  (:encode-properties? t)
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties" host port node-id))
+  (:status-handlers
+   ((204 (values t body))
+    (400 (error 'invalid-data-sent-error :uri uri :json json))
+    (404 (error 'node-not-found-error :uri uri)))))
+
+(def-neo4j-fun get-node-properties (node-id)
+  :get
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties" host port node-id))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (204 nil)
+    (404 (error 'node-not-found-error :uri uri)))))
+   
+(def-neo4j-fun del-node-properties (node-id)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties" host port node-id))
+  (:status-handlers
+   ((202 (values t body))
+    (404 (error 'node-not-found-error :uri uri)))))
+
+(def-neo4j-fun set-node-property (node-id property value)
+  :put
+  (:encode-value? t)
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties/~A" host port node-id 
+		     (if (symbolp property)
+			 (string-downcase (symbol-name property))
+			 property)))
+  (:status-handlers
+   ((204 (values t body))
+    (400 (error 'invalid-data-sent-error :uri uri :json json)))))
+
+(def-neo4j-fun get-node-property (node-id property)
+  :get
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties/~A" host port node-id
+		     (if (symbolp property)
+			 (string-downcase (symbol-name property))
+			 property)))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (400 (error 'invalid-data-sent-error :uri uri :json json)))))
+
+(def-neo4j-fun del-node-property (node-id property)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/node/~A/properties/~A" host port node-id
+		     (if (symbolp property)
+			 (string-downcase (symbol-name property))
+			 property)))
+  (:status-handlers
+   ((204 (values t body))
+    (404 (error 'node-not-found-error :uri uri))
+    (409 (error 'unable-to-delete-node-error :uri uri)))))
+
+(def-neo4j-fun create-relationship (node-id to-node-id relationship-type properties)
+  :post
+  (:encode-relationship? t)
+  (:uri-spec (format nil "http://~A:~A/node/~A/relationships" host port node-id))
+  (:status-handlers
+   ((201 (decode-json-from-string (map 'string #'code-char body)))
+    (400 (error 'invalid-data-sent-error :uri uri :json json))
+    (404 (error 'node-not-found-error :uri to-node-id)))))
+
+(def-neo4j-fun set-relationship-properties (relationship-id properties)
+  :put
+  (:encode-properties? t)
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties" host port relationship-id))
+  (:status-handlers
+   ((204 (values t body))
+    (400 (error 'invalid-data-sent-error :uri uri :json json))
+    (404 (error 'relationship-not-found-error :uri uri)))))
+
+(def-neo4j-fun get-relationship-properties (relationship-id)
+  :get
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties" host port relationship-id))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (204 nil)
+    (404 (error 'relationship-not-found-error :uri uri)))))
+   
+(def-neo4j-fun del-relationship-properties (relationship-id)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties" host port relationship-id))
+  (:status-handlers
+   ((202 (values t body))
+    (404 (error 'relationship-not-found-error :uri uri)))))
+
+(def-neo4j-fun set-relationship-property (relationship-id property value)
+  :put
+  (:encode-value? t)
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties/~A" 
+		     host port relationship-id property))
+  (:status-handlers
+   ((204 (values t body))
+    (400 (error 'invalid-data-sent-error :uri uri :json json))
+    (404 (error 'relationship-not-found-error :uri uri)))))
+
+(def-neo4j-fun get-relationship-property (relationship-id property)
+  :get
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties/~A" 
+		     host port relationship-id property))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (400 (error 'invalid-data-sent-error :uri uri :json json)))))
+
+(def-neo4j-fun del-relationship-property (relationship-id property)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/relationship/~A/properties/~A" 
+		     host port relationship-id property))
+  (:status-handlers
+   ((204 (values t body))
+    (404 (error 'relationship-not-found-error :uri uri)))))
+
+(def-neo4j-fun delete-relationship (relationship-id)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/relationship/~A" host port relationship-id))
+  (:status-handlers
+   ((204 (values t body))
+    (404 (error 'relationship-not-found-error :uri uri)))))
+
+(def-neo4j-fun get-node-relationships (node-id direction types)
+  :get
+  (:uri-spec (format nil "http://~A:~A/node/~A/relationships/~A/~{~A~^\\&~}" 
+		     host port node-id 
+		     (cond ((null direction) "all")
+			   ((symbolp direction)
+			    (string-downcase (symbol-name direction)))
+			   (t direction)) 
+		     types))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body)))
+    (404 (error 'node-not-found-error :uri uri :property node-id)))))
+
+(def-neo4j-fun list-indices ()
+  :get
+  (:uri-spec (format nil "http://~A:~A/index" host port))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body))))))
+
+(def-neo4j-fun add-to-index (node-id key value)
+  :post
+  (:uri-spec (format nil "http://~A:~A/index/node/~A/~A" host port key value))
+  (:encode-node-id? t)
+  (:status-handlers
+   ((201 (values t body)))))
+
+(def-neo4j-fun remove-from-index (node-id key value)
+  :delete
+  (:uri-spec (format nil "http://~A:~A/index/node/~A/~A/~A" host port key value node-id))
+  (:status-handlers
+   ((204 (values t body))
+    (404 (error 'index-entry-not-found-error :uri uri)))))
+
+(def-neo4j-fun query-index (key value)
+  :get
+  (:uri-spec (format nil "http://~A:~A/index/node/~A/~A" host port key value))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body))))))
+
+(def-neo4j-fun query-fulltext-index (key value)
+  :get
+  (:uri-spec (format nil "http://~A:~A/index/node-fulltext/~A/~A" host port key value))
+  (:status-handlers
+   ((200 (decode-json-from-string (map 'string #'code-char body))))))
+
+(defun traverse (&key (host *neo4j-host*) (port *neo4j-port*) node-id (return-type :node) 
+		 (max-depth 1) (order :depth-first) uniqueness relationships prune-evaluator 
+		 return-filter)
+  (let ((uri (format nil "http://~A:~A/node/~A/traverse/~A" 
+		     host port node-id (string-downcase (symbol-name return-type))))
+	(json (with-output-to-string (s)
+		(format s "{\"order\":\"~A\"," (case order
+						 (:depth-first "depth first")
+						 (:breadth-first "breadth first")))
+		(if uniqueness (format s "\"uniqueness\":\"~A\"," uniqueness))
+		(if relationships (format s "\"relationships\":~A,"
+					  (encode-json-to-string relationships)))
+		(if prune-evaluator (format s "\"prune evaluator\":~A,"
+					    (encode-json-to-string prune-evaluator)))
+		(if return-filter (format s "\"return filter\":~A,"
+					  (encode-json-to-string return-filter)))
+		(format s "\"max depth\":~A}" max-depth))))
+    (multiple-value-bind (status body) (do-neo4j-query uri :post :json json)
+      (case status
+	(200 (decode-json-from-string (map 'string #'code-char body)))
+	(404 (error 'node-not-found-error :uri uri))
+	(otherwise 
+	 (error 'unknown-return-type-error :status status :uri uri :property nil))))))
+	 

Added: utilities.lisp
==============================================================================
--- (empty file)
+++ utilities.lisp	Tue May 18 15:43:41 2010
@@ -0,0 +1 @@
+(in-package #:cl-neo4j)




More information about the cl-neo4j-cvs mailing list