 
   (select-accounts-by-entity-id
     [_ entity-id]
-    (let [sql (sql/format (-> (h/select :*)
-                              (h/from :accounts)
-                              (h/where [:= :entity_id entity-id])))]
-      (map ->clojure-keys (jdbc/query db-spec sql))))
+    (query db-spec (-> (h/select :*)
+                       (h/from :accounts)
+                       (h/where [:= :entity_id entity-id]))))
 
   (update-account
     [_ account]


  (select-transaction-items-by-transaction-id
    [_ transaction-id]
    (let [sql (sql/format (-> (h/select :*)
                              (h/from :transaction_items)
                              (h/where [:= :transaction_id transaction-id])))]
            (->> (jdbc/query db-spec sql)
                (map ->clojure-keys))))

  (select-transaction-items-by-account-id
    [_ account-id]
    (let [sql (sql/format (-> (h/select :*)
                              (h/from :transaction_items)
                              (h/where [:= :account_id account-id])
                              (h/order-by [:index :desc])))]
            (->> (jdbc/query db-spec sql)
                (map ->clojure-keys))))

  (select-transaction-items-by-account-id-and-starting-index
    [_ account-id index]
    (let [sql (sql/format (-> (h/select :*)
                              (h/from :transaction_items)
                              (h/where [:and
                                        [:= :account_id account-id]
                                        [:>= :index index]])
                              (h/order-by [:index :desc])))]
      (->> (jdbc/query db-spec sql)
          (map ->clojure-keys))))

  (select-transaction-items-by-account-id-on-or-after-date
    [_ account-id transaction-date]
    (let [sql (sql/format (-> (h/select :i.*)
                                (h/from [:transaction_items :i])
                                (h/join [:transactions :t] [:= :t.id :i.transaction-id])
                                (h/where [:and
                                          [:= :i.account_id account-id]
                                          [:>= :t.transaction_date transaction-date]])
                                (h/order-by :index)))]
        (->> (jdbc/query db-spec sql)
            (map ->clojure-keys))))

  (find-transaction-item-by-id
    [_ id]
    (let [sql (sql/format (-> (h/select :*)
                              (h/from :transaction_items)
                              (h/where [:= :id id])
                              (h/limit 1)))]
      (->> (jdbc/query db-spec sql)
           first
           ->clojure-keys)))

  (find-transaction-items-preceding-date
    [_ account-id transaction-date]
    (let [sql (sql/format (-> (h/select :i.*)
                              (h/from [:transaction_items :i])
                              (h/join [:transactions :t] [:= :t.id :i.transaction-id])
                              (h/where [:and
                                        [:= :i.account-id account-id]
                                        [:< :t.transaction-date transaction-date]])
                              (h/order-by [:t.transaction-date :desc] [:i.index :desc])
                              (h/limit 2)))]
      (->> (jdbc/query db-spec sql)
          (map ->clojure-keys))))

  (update-transaction-item
    [_ transaction-item]

      (assoc :updated-at (t/now))
      ->sql-keys))

(defn- query
  "Executes a SQL query and maps field names into
  clojure keys"
  [db-spec sql-map]
  (->> (sql/format sql-map)
       (jdbc/query db-spec)
       (map ->clojure-keys)))

(deftype SqlStorage [db-spec]
  Storage

