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.
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
- 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)
- 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