<commit_before>(ns gitomic.query
  (:require [datomic.api :as d :refer [q]]
            [clojure.pprint :refer [pprint]]
            [gitomic.stats :as stats]))

(defn repo-by-name [db n]
  (:db/id (d/entity db [:repo/name n])))

(defn count-commits [db r]
  (q '[:find (count ?c) .
       :in $ ?r
       :where [?r :repo/commits ?c]]
     db r))

(defn commit-by-sha [db sha]
  (q '[:find ?c .
       :in $ ?sha
       :where [?c :commit/sha ?sha]]
     db sha))

(defn commits-by-path [db r path]
  (q '[:find [?c ...]
       :in $ ?r ?p
       :where
       [?f :file/path ?p]
       [?r :repo/files ?f]
       [?ch :change/file ?f]]
     db r path))

(defn files-in-repo [db repo]
  (q '[:find [?f ...]
       :in $ ?r
       :where
       [?r :repo/files ?f]]
     db repo))

(defn weight [max n]
  (float (/ n max)))

(defn weighted-tuple [xs pos max]
  (mapv (fn [x]
          (concat x (weight max (nth x pos))))
        xs))

(defn churn [db r]
  (q '[:find ?p (count ?ch)
       :in $ ?r
       :where
       [?r :repo/files ?f]
       [?f :file/path ?p]
       [?ch :change/file ?f]]
     db r))

(defn files-per-commit-stats [db repo-name]
  (stats/basic-stats
    (filter #(< % 10)
            (map second
                 (q '[:find ?c (count ?ch)
                      :in $ ?r-name
                      :where
                      [?r :repo/name ?r-name]
                      [?r :repo/commits ?c]
                      [?c :commit/changes ?ch]]
                    db repo-name)))))

(defn commits-by-author [db repo-name]
  (reverse (sort-by second (q '[:find ?n (count ?c)
                                :in $ ?r-name
                                :where
                                [?r :repo/name ?r-name]
                                [?r :repo/commits ?c]
                                [?c :commit/author ?a]
                                [?a :person/name ?n]]
                              db repo-name))))

;; for query example ONLY.  Could run FOREVER on big commits
(defn file-commit-pair [db r file-path]
  (q '[:find ?p2 (count ?c)
       :in $ ?r ?p
       :where
       [?f1 :file/path ?p]
       [?ch1 :change/file ?f1]<commit_msg>added change-tuples and chang-maps<commit_after>(ns gitomic.query
  (:require [datomic.api :as d :refer [q]]
            [clojure.pprint :refer [pprint]]
            [gitomic.stats :as stats]))

(defn repo-by-name [db n]
  (:db/id (d/entity db [:repo/name n])))

(defn count-commits [db r]
  (q '[:find (count ?c) .
       :in $ ?r
       :where [?r :repo/commits ?c]]
     db r))

(defn commit-by-sha [db sha]
  (q '[:find ?c .
       :in $ ?sha
       :where [?c :commit/sha ?sha]]
     db sha))

(defn commits-by-path [db r path]
  (q '[:find [?c ...]
       :in $ ?r ?p
       :where
       [?f :file/path ?p]
       [?r :repo/files ?f]
       [?ch :change/file ?f]]
     db r path))

(defn files-in-repo [db repo]
  (q '[:find [?f ...]
       :in $ ?r
       :where
       [?r :repo/files ?f]]
     db repo))

(defn weight [max n]
  (float (/ n max)))

(defn weighted-tuple [xs pos max]
  (mapv (fn [x]
          (concat x (weight max (nth x pos))))
        xs))

(defn churn [db r]
  (q '[:find ?p (count ?ch)
       :in $ ?r
       :where
       [?r :repo/files ?f]
       [?f :file/path ?p]
       [?ch :change/file ?f]]
     db r))

(defn files-per-commit-stats [db repo-name]
  (stats/basic-stats
    (filter #(< % 10)
            (map second
                 (q '[:find ?c (count ?ch)
                      :in $ ?r-name
                      :where
                      [?r :repo/name ?r-name]
                      [?r :repo/commits ?c]
                      [?c :commit/changes ?ch]]
                    db repo-name)))))

(defn commits-by-author [db repo-name]
  (reverse (sort-by second (q '[:find ?n (count ?c)
                                :in $ ?r-name
                                :where
                                [?r :repo/name ?r-name]
                                [?r :repo/commits ?c]
                                [?c :commit/author ?a]
                                [?a :person/name ?n]]
                              db repo-name))))

(defn change-tuples [db repo-name]
  (q '[:find ?sha ?time ?an ?ae ?subject ?p ?added ?deleted ?lines
       :in $ ?r-name
       :where
       [?r :repo/name ?r-name]
       [?r :repo/commits ?c]
       [?c :commit/sha ?sha]
       [?c :commit/time ?time]
       [?c :commit/subject ?subject]
       [?c :commit/author ?a]
       [?a :person/name ?an]
       [?a :person/email ?ae]
       [?c :commit/changes ?ch]
       [(get-else $ ?ch :change/added 0) ?added]
       [(get-else $ ?ch :change/deleted 0) ?deleted]
       [(- ?added ?deleted) ?lines]
       [?ch :change/file ?f]
       [?f :file/path ?p]]
     db repo-name))

(defn change-maps [db repo-name]
  ;?sha ?time ?an ?ae ?subject ?p ?added ?deleted ?lines
  (q '[:find [(pull ?ch [{:commit/_changes [{:commit/author [:person/name :person/email]}
                                            :commit/sha
                                            :commit/time
                                            :commit/subject]}
                         (default :change/added 0)
                         (default :change/deleted 0)
                         {:change/file [:file/path]}])
              ...]
       :in $ ?r-name
       :where
       [?r :repo/name ?r-name]
       [?r :repo/commits ?c]
       [?c :commit/changes ?ch]]
     db repo-name))





;; for query example ONLY.  Could run FOREVER on big commits
(defn file-commit-pair [db r file-path]
  (q '[:find ?p2 (count ?c)
       :in $ ?r ?p
       :where
       [?f1 :file/path ?p]
       [?ch1 :change/file ?f1]
{'fraction_non_alphanumeric': 0.16698858647936787, 'fraction_numerical': 0.0028094820017559264, 'mean_word_length': 1.3372999589659418, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5906598', 'n_tokens_mistral': 2058, 'n_tokens_neox': 1999, 'n_words': 566}