Skip to content
/ rel Public

experiment about handling relational data in a functional programming language (here: clojure)

Notifications You must be signed in to change notification settings

hoeck/rel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

experiment about handling relational data in a functional programming language (here: clojure)

Resources

Stars

Watchers

Forks

Packages

No packages published