 
 ;
 ;
-;
+; Methods for providing a sql abstraction over the column store.
+;
+;
+
 
 (def ^:private field-ids-query
   (cached-statement

        (update-in new-cache [:codes] update-codes-cache field-id missing new-cache))
       cache)))

; return fn of rows->vals
(defn fetch-rows [fields cache rows field]
  (swap! cache update-in [field] update-cache (fields field) rows)
  (let [f (@cache field)
        getter (match [(:codes f)]
                      ; XXX cast to int here is pretty horrible.
                      ; Really calls for an int array bin in h2.

      (map :row)))

(defn fetch-genes [field-id values]
  (into (sorted-set) (field-genes field-id values)))

; fetch-indexed doesn't cache, and it's unclear
; if we should cache the indexed fields during 'restrict'.
; h2 also has caches, so it might be better to rely on them,
; simply doing the query again if we need it. 

; Otherwise, we might want to inform the cache of what columns are
; required later during 'restrict', or in 'project', so
; we know if they should be cached.

(defn fetch-indexed [fields field values]
  (let [field-id (fields field)]
    (cond
      (has-position? field-id) #{}) ; XXX fix this!
      (has-genes? field-id) (fetch-genes field-id values)))

; XXX Look at memory use of pulling :gene field. If it's not
; interned, it could be expensive.

; XXX Add some param guards, esp. unknown field.
(defn eval-sql [{[from] :from where :where select :select :as exp}]
  (let [{dataset-id :id N :rows} (dataset-by-name from :id :rows)
        fields (into {} (fetch-field-ids dataset-id
                                         (into (collect-fields where) select)))
        cache (atom {})
        fetch (fn [rows field] (fetch-rows cache rows (fields field)))]
    ; XXX project, perhaps in sqleval
  (evaluate (apply sorted-set (range N)) {:fetch fetch
                       :fetch-indexed (partial fetch-indexed fields)
                       :indexed? (partial has-index? fields)} exp)))


;
;
;
;
;
;

; Each req is a map of
;  :table "tablename"
