 
 (defrecord Context [rels sources])
 ;; attrs:
-;;    [?e ?v ?e2 ?age]
+;;    {?e 0, ?v 1} or {?e2 "a", ?age "v"}
 ;; tuples:
-;;   [ #js [1 "Ivan" 5 14]
-;;     #js [2 "Oleg" 1 55]
-;;     ... ]
+;;    [ #js [1 "Ivan" 5 14] ... ]
+;; or [ (Datom. 2 "Oleg" 1 55) ... ]
 (defrecord Relation [attrs tuples])
 
-(defn intersect-keys [a1 a2]
-  (set/intersection (set a1)) (set a2))
+(defn intersect-keys [attrs1 attrs2]
+  (set/intersection (set (keys attrs1)) 
+                    (set (keys attrs2))))
 
 (defn concatv [& xs]
   (vec (apply concat xs)))
 
-(defn index [coll]
-  (map vector coll (range)))
-
-(defn index-map [coll]
-  (into {} (index coll)))
-
 (defn tuple-key-fn [idxs]
-  (if (== (alength idxs) 1)
+  (if (== (count idxs) 1)
     (let [idx (first idxs)]
       (fn [tuple]
         (aget tuple idx)))
-    (fn [tuple]
-      (list* (.map idxs #(aget tuple %))))))
+    (let [idxs (to-array idxs)]
+      (fn [tuple]
+        (list* (.map idxs #(aget tuple %))))))) ;; FIXME aget
 
 (defn hash-attrs [idxs tuples]
   (let [key-fn (tuple-key-fn idxs)]

       (not (in? vars symbol))))


;; (defn -q-clause [where vars data]
;;   (let [bound   (filter #(bound? % vars) where)
;;         unbound (filter #(unbound? % vars) where)
;;         bound-vals (into {} (for [var bound]
;;                               [var (build-var var data)]))]
;;     ...

;; (defn -q [ins->sources where vars data])
  

;; (defn q [query & sources]
;;   (-q (zipmap (:in query '[$]) sources)
;;       (:where query)
;;       [] []))

;; (defn aconj [arr x]
;;   (datascript.btset/insert arr (alength arr) #js [x]))



;; (defn get-avet [db a v]
;;   (->> (slice (.-avet db) (Datom. nil a v nil nil))
;;        (mapv #(vector (.-e %)))))

;; (defn get-aevt [db a es]
;;   (let [lookup-hash (hash-attr #(nth % 0) es)
;;         lookup-map  (:hash-table lookup-hash)
;; ;;                     {:min (aget (first es) 0)
;; ;;                      :max (aget (nth es (dec (count es))) 0)}
;;         datoms      (slice (.-aevt db)
;;                       (Datom. (:min lookup-hash) a nil nil nil)
;;                       (Datom. (:max lookup-hash) a nil nil nil))]
;;     (->>
;; ;;       (loop [_res (transient [])
;; ;;              _ds  datoms
;; ;;              _es  es]
;; ;;         (let [_fd (first _ds)
;; ;;               _fe (first _es)]
;; ;;           (if (and _fd _fe)
;; ;;             (condp == (cmp-val (.-e _fd) (aget _fe 0))
;; ;;               0  (recur (conj! _res #js [(aget _fe 0) (.-v _fd)]) (next _ds) (next _es))
;; ;;               -1 (recur _res (next _ds) _es)
;; ;;               1  (recur _res _ds (next _es))
;; ;;               )
;; ;;             _res)))

;;       (reduce (fn [acc d]
;;                 (if-let [datas (get lookup-map (.-e d))]
;;                   (reduce (fn [acc data]
;;                             (conj! acc (conj data (.-v d))))
;;                     acc datas)
;;                   acc))
;;         (transient []) datoms)
;;       (persistent!))))

;; (defn search [db]
;;   (->> (get-avet db :name "Ivan")
;;        (get-aevt db :age)))


(defn build-relation-db [db pattern]
  (let [search-pattern (mapv #(if (symbol? %) nil %) pattern)
        datoms         (d/-search db search-pattern)
        attr->prop     (->> (map vector pattern ["e" "a" "v" "t"])
                            (filter (fn [[s _]] (and (symbol? s)
                                                     (not= '_ s))))
                            (into {}))]
    (Relation. attr->prop (vec datoms))))

#_(build-relation-db (-> (d/empty-db)
                       (d/with [[:db/add 1 :name "Ivan"]
