 (s/defn select-statement
   "returns a Hayt select statement"
 
-  ([table :- s/Keyword]
-   (select-statement table {}))
-
   ([table :- s/Keyword
     {:keys [limit columns] :as opts} :- sch/FullTableSelectOptsSchema]
 
    (h/select table
              (when columns (apply h/columns columns))
              (when limit (h/limit limit))))
-
-  ([table :- s/Keyword
-    key :- sch/KeySchema
-    record-or-key-value :- sch/RecordOrKeyValueSchema]
-   (select-statement table key record-or-key-value {}))
 
   ([table :- s/Keyword
     key :- sch/KeySchema


(s/defn insert-statement
  "returns a Hayt insert statement"

  ([table :- s/Keyword
    record :- sch/RecordSchema] (insert-statement table record {}))

  ([table :- s/Keyword
    record :- sch/RecordSchema
    {:keys [if-not-exists using] :as opts} :- sch/InsertOptsSchema]
   (h/insert table
             (h/values record)
             (when if-not-exists (h/if-not-exists true))
             (when (not-empty using) (apply h/using (flatten (seq using)))))))


(s/defn prepare-insert-statement
  "returns a Hayt prepared insert statement"
  ([table :- s/Keyword
    record :- sch/RecordSchema] (prepare-insert-statement table record {}))

  ([table :- s/Keyword
    record :- sch/RecordSchema
    {:keys [if-not-exists using] :as opts} :- sch/InsertOptsSchema]
   (let [insert-placeholders (prepare-record-placeholders :insert record)]

     (h/insert table
               (h/values insert-placeholders)
               (when if-not-exists (h/if-not-exists true))
               (when (not-empty using) (apply h/using (flatten (seq using))))))))

(s/defn update-statement
  "returns a Hayt update statement"

  ([table :- s/Keyword
    key :- sch/KeySchema
    record :- sch/RecordSchema] (update-statement table key record {}))

  ([table :- s/Keyword
    key :- sch/KeySchema
    record :- sch/RecordSchema
    {:keys [only-if
            if-exists
            if-not-exists
            using
            set-columns] :as opts} :- sch/UpdateOptsSchema]
   (let [key-clause (extract-key-equality-clause key record opts)
         set-cols (if (not-empty set-columns)
                    (select-keys record set-columns)
                    (apply dissoc record (flatten-key key)))

         stmt (h/update table
                        (h/set-columns set-cols)
                        (h/where key-clause)
                        (when only-if (h/only-if only-if))
                        (when if-exists (h/if-exists true))
                        (when if-not-exists (h/if-exists false))
                        (when (not-empty using) (apply h/using (flatten (seq using)))))]
     stmt)))

(s/defn delete-statement
  "returns a Hayt delete statement"

  ([table :- s/Keyword
    key :- sch/KeySchema
    record-or-key-value :- sch/RecordOrKeyValueSchema]
   (delete-statement table key record-or-key-value {}))

  ([table :- s/Keyword
    key :- sch/KeySchema
    record-or-key-value :- sch/RecordOrKeyValueSchema
    {:keys [only-if if-exists using where] :as opts} :- sch/DeleteOptsSchema]
   (let [key-clause (extract-key-equality-clause key record-or-key-value opts)]
     (h/delete table
               (h/where (combine-where key-clause where))
               (when only-if (h/only-if only-if))
               (when if-exists (h/if-exists true))
               (when (not-empty using) (apply h/using (flatten (seq using))))))))

              [k (placeholder-kw prefix k)]))
       (into {})))

(s/defn prepare-record-values
  "replace the keys in a record with the prepared-statement placeholders"
  [prefix record]
  (->> record
