 (ns clojurewerkz.cassaforte.client
   "Provides fundamental functions for
 
-   * connecting to Cassandra nodes and clusters
-   * configuring connections
-   * tuning load balancing, retries, reconnection strategies and consistency settings
-   * preparing and executing queries constructed via DSL
-   * working with executing results"
+  * connecting to Cassandra nodes and clusters
+  * configuring connections
+  * tuning load balancing, retries, reconnection strategies and consistency settings
+  * preparing and executing queries constructed via DSL
+  * working with executing results"
   (:require [clojure.java.io                    :as io]
             [clojurewerkz.cassaforte.policies   :as cp]
             [clojurewerkz.cassaforte.conversion :as conv]

(defmacro prepare
  "Prepare a single statement, return prepared statement"
  ([body]
     `(binding [hayt/*prepared-statement* true
                hayt/*param-stack*        (atom [])]
        ~body))
  ([session body]
     `(binding [hayt/*prepared-statement* true
                hayt/*param-stack*        (atom [])]
        (.prepare ~session ~body))))

;;
;; Protocols

(defn ^Session connect
  "Connects to the Cassandra cluster. Use `build-cluster` to build a cluster."
  ([hosts]
   (connect-or-close (build-cluster {:hosts hosts})))
  ([hosts keyspace-or-opts]
   (if (string? keyspace-or-opts)
     (connect hosts keyspace-or-opts {})
     (let [keyspace (:keyspace keyspace-or-opts)
           opts     (dissoc keyspace-or-opts :keyspace)]
       (if keyspace
         (connect hosts keyspace opts)
         (connect-or-close (-> opts (merge {:hosts hosts}) build-cluster))))))
  ([hosts keyspace opts]
   (let [c (build-cluster (merge opts {:hosts hosts}))]
     (connect-or-close c (name keyspace)))))

(defn ^Session connect-with-uri
  ([^String uri]
   (connect-with-uri uri {}))
  ([^String uri opts]
   (let [^URI u (URI. uri)]
     (connect [(.getHost u)] (merge {:port (.getPort u) :keyspace (-> u .getPath (.substring 1))} opts)))))

(defn disconnect
  "1-arity version receives Session, and shuts it down. It doesn't shut down all other sessions
