Permalink
Browse files

changed virtually everything

  • Loading branch information...
1 parent bb5aa21 commit 3e1535e96346dd3870964bbf33af4364167bf9bf @wagjo committed Mar 4, 2011
Showing with 537 additions and 323 deletions.
  1. +1 −0 .gitignore
  2. +0 −33 README
  3. +40 −0 README.md
  4. +0 −22 build.xml
  5. +0 −1 license.txt
  6. +7 −6 project.clj
  7. +0 −261 src/neo4j.clj
  8. +489 −0 src/neo4j/core.clj
View
@@ -1,3 +1,4 @@
pom.xml
*.jar
lib
+classes
View
33 README
@@ -1,33 +0,0 @@
-The clojure-neo4j project provides a more lispy interface to Neo4j, a graph-structured on-disk transactional database.
-
-This library is under active development and there's plenty more work to do.
-
-Usage:
-
-(use ['neo4j :exclude ['start 'shutdown]])
-
-(neo4j/start "/path/to/db")
-
-;;; Create a root for customers and add a customer.
-(with-tx
- (let [customer-root (new-node)
- bob (new-node)]
- (relate (top-node) :customers customer-root)
- (relate customer-root :customer bob)
- (properties bob {"name" "Bob"
- "age" 30
- "id" "C12345"})))
-
-;;; Fetch all customer IDs
-(with-tx
- (let [customer-root (-> (top-node)
- (.getSingleRelationship (relationship :customers) outgoing)
- (.getEndNode))]
- (doall (map #(property % "id")
- (traverse customer-root
- breadth-first
- (depth-of 1)
- all-but-start
- {:customer outgoing})))))
-
-(neo4j/shutdown)
View
@@ -0,0 +1,40 @@
+The clojure-neo4j project provides a more lispy interface to Neo4j, a graph-structured on-disk transactional database.
+
+This library is under active development and there's plenty more work to do.
+
+Wrapper for Neo4j. Because I was not happy with the current state
+(01/2011) of existing Neo4j wrappers for clojure, I've decided to
+create my own.
+
+Purpose of this ns is to provide intiutive access to commonly used
+Neo4j operations. It uses official Neo4j Java bindings. It does not
+use Blueprints interface.
+
+Disclaimer: I have forked hgavin/clojure-neo4j and modified it
+heavily.
+
+Disclaimer: Some comments and docs are taken from official Neo4j javadocs.
+
+## Usage:
+
+* use with-db! to establish a connection to the database
+
+* all db operations must be inside with-db! body
+
+## Code notes:
+
+* *neo-db* holds the current db instance, so that users do not have
+ to supply db instance at each call to db operations. This
+ approach has of course its drawbacks (e.g. only one connection at
+ time), but I've found it suitable for my purposes.
+
+Examples:
+
+(ns foo.example
+ (:require [neo4j.core :as neo]))
+
+(neo/with-neo "/path/to/db"
+
+
+
+)
View
@@ -1,22 +0,0 @@
-<project name="clojure-neo4j" default="jar">
-
- <description>
- Pack all clojure-neo4j sources into a JAR.
- </description>
-
- <!-- The JAR file to create. -->
- <property name="jarfile" location="clojure-neo4j.jar"/>
-
- <target name="clean"
- description="Remove generated files and directories.">
- <delete file="${jarfile}"/>
- </target>
-
- <target name="jar"
- description="Create jar file.">
- <jar jarfile="${jarfile}">
- <fileset dir="./src" includes="**/*.clj"/>
- </jar>
- </target>
-
-</project>
View
@@ -1 +0,0 @@
-This work is hereby released into the Public Domain. To view a copy of the public domain dedication, visit http://creativecommons.org/licenses/publicdomain/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
View
@@ -1,7 +1,8 @@
-(defproject org.clojars.hgavin/clojure-neo4j "0.3.0-SNAPSHOT"
+(defproject com.wagjo/neo "0.3.0-SNAPSHOT"
:description "The clojure-neo4j project provides a more lispy interface to Neo4j, a graph-structured on-disk transactional database."
- :dependencies [[org.clojure/clojure "1.2.0"]
- [org.clojure/clojure-contrib "1.2.0"]
- [org.neo4j/neo4j-kernel "1.2-SNAPSHOT"]
- [org.neo4j/neo4j-index "1.2-SNAPSHOT"]]
- :dev-dependencies [[swank-clojure "1.2.1"]])
+
+ :dependencies [[org.clojure/clojure "1.2.0"]
+ [org.clojure/clojure-contrib "1.2.0"]
+ [org.neo4j/neo4j "1.2"]]
+ :dev-dependencies [[swank-clojure "1.3.0-SNAPSHOT"]]
+ :jvm-opts ["-Dswank.encoding=utf-8"])
View
@@ -1,261 +0,0 @@
-(ns neo4j
- (:import (org.neo4j.graphdb Direction
- Node
- NotFoundException
- NotInTransactionException
- PropertyContainer
- Relationship
- RelationshipType
- ReturnableEvaluator
- StopEvaluator
- Transaction
- TraversalPosition
- Traverser
- Traverser$Order)
- (org.neo4j.kernel EmbeddedGraphDatabase)))
-
-(declare properties)
-
-(def *neo* nil)
-(def *tx* nil)
-
-(defn start
- [db-path]
- (alter-var-root #'*neo* (fn [_] (EmbeddedGraphDatabase. db-path))))
-
-(defn shutdown
- []
- (.shutdown *neo*))
-
-(def both Direction/BOTH)
-(def incoming Direction/INCOMING)
-(def outgoing Direction/OUTGOING)
-
-(def breadth-first Traverser$Order/BREADTH_FIRST)
-(def depth-first Traverser$Order/DEPTH_FIRST)
-
-(defn depth-of
- "Return a StopEvaluator for the given traversal depth."
- [d]
- (if (== d 1)
- StopEvaluator/DEPTH_ONE
- (proxy [StopEvaluator] []
- (isStopNode [#^TraversalPosition pos]
- (== (.depth pos) d)))))
-
-(def end-of-graph StopEvaluator/END_OF_GRAPH)
-
-(def all ReturnableEvaluator/ALL)
-(def all-but-start ReturnableEvaluator/ALL_BUT_START_NODE)
-
-(defmacro with-neo [#^String fname & body ]
- `(binding [*neo* (new ~EmbeddedGraphDatabase ~fname)]
- (try ~@body
- (finally (.shutdown *neo*)))))
-
-(defmacro tx [& body]
- `(binding [*tx* (.beginTx *neo*)]
- (try ~@body
- (finally (.finish *tx*)))))
-
-(defn success [] (.success *tx*))
-
-(defn failure [] (.failure *tx*))
-
-(defmacro with-tx [& body]
- `(tx
- (let [val# (do ~@body)]
- (success)
- val#)))
-
-(defn name-or-str
- [x]
- (if (keyword? x)
- (name x)
- (str x)))
-
-(defn new-node
- ([] (.createNode *neo*))
- ([props] (let [node (new-node)]
- (properties node props)
- node)))
-
-(defn top-node [] (.getReferenceNode *neo*))
-
-(defn relationship [#^Keyword n]
- (proxy [RelationshipType] []
- (name [] (name n))))
-
-(defn relate [#^Node from #^Keyword type #^Node to]
- (.createRelationshipTo from to (relationship type)))
-
-(defn return-if [f]
- "Creates a ReturnableEvaluator for use with a traverser. Takes a
- function of one argument. The function will be passed the current
- position to act on."
- (proxy [ReturnableEvaluator] []
- (isReturnableNode [#^TraversalPosition p] (f p))))
-
-(defn stop-if [f]
- (proxy [StopEvaluator] []
- (isStopNode [#^TraversalPosition p] (f p))))
-
-(defn property
- "DEPRECATED. Prefer properties."
- {:deprecated "0.3.0"}
- ([#^PropertyContainer c key]
- (.getProperty c (name key)))
- ([#^PropertyContainer c key val]
- (.setProperty c (name-or-str key) val)))
-
-(defn properties
- "Return or set a map of properties."
- ([#^PropertyContainer c]
- (let [ks (.getPropertyKeys c)]
- (into {} (map (fn [k] [(keyword k) (.getProperty c k)]) ks))))
- ([#^PropertyContainer c props]
- (doseq [[k v] props]
- (.setProperty c (name-or-str k) (or v "")))
- nil))
-
-(defn map-node
- "Takes a node and exposes its properties as a map. The node itself
- will be an entry in the map keyed with :node. If a value is already
- at :node, it will be replaced by the refernece to the node itself."
- [#^Node n]
- (assoc (properties n) :node n))
-
-(defn map-node-seq
- "Takes a sequence of nodes and creates a lazy sequence that converts
- each node to a map using map-node."
- [seq]
- (map #(with-tx (map-node %)) seq))
-
-(defn update-mapped-node
- "Upates a node in the Neo4j database that has been mapped with
- map-node. Compares the values of the map to the values stored in the
- mapped node. Any values that have changed will be updated in the
- database."
- [mapped-node]
- (let [node (:node mapped-node)]
- (doseq [k (keys (properties node))]
- (when-not (= (get mapped-node k) (get node k))
- (.setProperty node (name-or-str k) (or (get mapped-node k) ""))))
- mapped-node))
-
-;; Should cond-mapped have an :else?
-(defmacro cond-mapped
- "Tests to see if n is a mapped node. If so, executes mappedexp. If n
- is a regular node, nodeexp is executed."
- [n mappedexp nodeexp]
- `(cond
- (map? ~n)
- ~mappedexp
-
- (isa? (class ~n) Node)
- ~nodeexp))
-
-(defn new-child-node
- "Creates a node that is a child of the specified parent node along
- the specified relationship. props is a map that defines the
- properties of the node."
- [parentnode relkey props]
- (cond-mapped parentnode
- (new-child-node (:node parentnode) relkey props)
- (let [node (new-node)]
- (relate parentnode relkey node)
- (properties node props)
- node)))
-
-(defn node-delete
- "Delete the given node."
- [n]
- (cond-mapped n
- (node-delete (:node n))
- (do
- (if-let [rs (.getRelationships n)]
- (doseq [r rs]
- (.delete r)))
- (.delete n))))
-
-(defn relationships
- "Returns all the relationships attached to this node."
- ([#^Node n #^Direction d] (.getRelationships n d))
- ([#^Node n #^Keyword type #^Direction d]
- (.getRelationships n (relationship type) d))
- ([n]
- (cond-mapped n
- (relationships (:node n))
- (.getRelationships n))))
-
-(defn single-relationship
- "Returns the only relationship for the node of the given type and
- direction."
- [n type dir]
- (cond-mapped n
- (single-relationship (:node n) type dir)
- (.getSingleRelationship n (relationship type) dir)))
-
-(defn traverse
- "Traverse the graph. Starting at the given node, traverse the graph
- in either bread-first or depth-first order, stopping when the
- stop-fn returns true. The filter-fn should return true for any node
- reached during the traversal that is to be returned in the sequence.
- The map of relationships and directions is used to decide which
- edges to traverse."
- [#^Node start-node order stop-evaluator return-evaluator
- relationship-direction]
- (.getAllNodes (.traverse start-node
- order
- stop-evaluator
- return-evaluator
- (into-array
- Object
- (mapcat identity (map (fn [[k v]]
- [(relationship k) v])
- relationship-direction))))))
-
-(defn lookup
- "Inside a transation, looks up nodes by index key for the given index."
- [idx & ids]
- (doall (map (fn [k] (.getSingleNodeFor idx k))
- ids)))
-
-
-(defn new-props-evaluator
- "Creates a ReturnableEvaluator for use with a traverser that returns
- nodes that match the specified property values. propmap is a map that
- defines key value pairs that should ReturnableEvaluator should match
- on."
- [propmap]
-
- (return-if
- (fn [currentPos]
- (let [node (.currentNode currentPos)
- nodeprops (properties node)
- ks (keys propmap)
- nks (count ks)]
- (cond
- (== nks 0) false
- (== nks 1) (and (contains? nodeprops (first ks))
- (= (get nodeprops (first ks))
- (get propmap (first ks))))
- :else
- (let [propcomp (fn [key] (= (get nodeprops key) (get propmap key)))]
- (and (reduce #(and (contains? nodeprops %1)
- (contains? nodeprops %2))
- ks)
- (reduce #(and (propcomp %1) (propcomp %2)) ks))))))))
-
-
-(defn find-by-props
- "Finds a node by traversing outward from start-node along
- relationship relkey. The function looks for nodes with property
- values matching the key value pairs in propmap."
- [start-node relkey propmap]
- (traverse start-node
- breadth-first
- end-of-graph
- (new-props-evaluator propmap)
- {relkey outgoing}))
-
Oops, something went wrong.

0 comments on commit 3e1535e

Please sign in to comment.