Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
experiment about handling relational data in a functional programming language (here: clojure)
Clojure
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
hoeck
.gitignore
README.textile
build.xml

README.textile

Relational Algebra for Clojure

Description

Implementation of the relational operators: project, select (restrict),
rename, crossproduct, various joins, union, difference and intersection.

See example code at the bottom of hoeck/rel/reflection.clj

To use it in clojure, include this directiory to your
classpath and then simply type (use ’hoeck.rel.reflection).

Needs also some
clojure.contrib modules
and lazymap from kotarak.

Build

Clone or download the contents of this repository and then build it using ant:


ant -Dclojure.jar=<..path to clojure.jar..> -Dlazymap.jar=<..path to lazymap.jar..>

Include the generated rel.jar in your classpath

Some examples using the reflection relations

  • Load the hoeck.rel library
    
    user> (use 'hoeck.rel.reflection)
    
  • Print all accessible relations in a map rel-name → fields
    
    user> (with-relations (pprint (into {} (field-map (relations) :relation :field))))
    {:publics (:ns :name :varname),
     :namespace (:name),
     :interfaces (:class :interface),
     :methods (:returntype :returns-array :modifiers :arity :class :name),
     :imports (:ns :class :name),
     :jars (:jar :time :compressed-size :path :comment :name :directory :size),
     :interns (:ns :name :varname),
     :classpaths (:path),
     :files (:time :path :name :directory :size),
     :method-args (:arity :position :class :method :type),
     :classes (:super :class :type :modifiers),
     :refers (:ns :name :varname),
     :aliases (:ns :name :alias)}
    
  • Private definitions in the hoeck.rel.reflection namespace
    
    user> (with-relations (project (select (difference :interns :publics)
                                           (= ~ns 'hoeck.rel.reflection))
                                   :name))
    #{{:name classnames-from-ns   }
      {:name method-args          }
      {:name class-interfaces     }
      {:name path->package        }
      {:name read-files-from-jar  }
      {:name class-methods        }
      {:name without-dotclass     }
      {:name classnames-from-files}
      {:name class-tuple          }
      {:name find-classnames      }
      {:name classnames-from-jars }}
    
  • Relation of all files on the classpath, ordered by size
    
    user> (with-relations
           (order-by
            (project :files [(/ ~size 1000.0) :size-in-kb] :name :path)
            :size-in-kb
            '>))
    #{{:size-in-kb  43800.36, :name "rt.jar",       :path "C:\\Programme\\Java\\jre6\\lib"}
      {:size-in-kb  6592.915, :name "charsets.jar", :path "C:\\Programme\\Java\\jre6\\lib"}
      ...}
    
  • Relations are first-class citizens
    
    user> (with-relations (def java-lang-classes (select :classes (rlike "^java\\.lang\\.[A-Z].*" ~class))))
    #'hoeck.rel.reflection/java-lang-classes

user> (defn without-inner-classes [classes-rel]
(select classes-rel (rlike “[^\\$]*” ~class)))
#’hoeck.rel.reflection/without-inner-classes

  • The number of classes in the java.lang package
    
    user> (count (without-inner-classes java-lang-classes))
    108
    
  • All inner classes in the java.lang package
    (takes some time to compute, calculates all indexes over the :classes relation due to my poor difference implementation)
    
    user> (count (difference java-lang-classes (without-inner-classes java-lang-classes)))
    48
    
  • Number of implemented interfaces
    
    user> (with-relations (count (project :interfaces :interface)))
    2035
    
  • Total number of interfaces
    
    user> (with-relations (count (select :classes (= ~type :interface))))
    2580
    
  • Classes (directly) implementing clojure.lang.IFn
    
    user> (with-relations (-> (select :interfaces 
                                      (= 'clojure.lang.IFn ~interface))
                              (field-seq :class)
                              (pprint)))
    (hoeck.mapped_map.MappedMap
     hoeck.magicmap.MagicMap
     clojure.lang.AFn
     clojure.lang.Keyword
     clojure.lang.Ref
     clojure.lang.Var)
    

TODO:

  • function-join
  • datalog (iris and/or clojure.contrib.datalog)
  • sql backend
  • index-aware select
  • more index types: sorted-index, none
  • other backends, query-by-example, constraints, query-compiler
Something went wrong with that request. Please try again.