   [^Cluster cluster]
   (.close cluster))
 
-(def ^:dynamic *async* false)
-
-(defmacro async
-  "Prepare a single statement, return prepared statement"
-  [body]
-  `(binding [*async* true]
-     (do ~body)))
-
-(defmacro with-fetch-size
-  "Temporarily alters fetch size."
-  [^Integer n# & body]
-  `(binding [*fetch-size* ~n#]
-     (do ~@body)))
-
-(defn- set-statement-options-
-  [^Statement statement]
-  (when cp/*retry-policy*
-    (.setRetryPolicy statement cp/*retry-policy*))
-  (when cp/*consistency-level*
-    (.setConsistencyLevel statement (cp/resolve-consistency-level cp/*consistency-level*)))
-  statement)
-
 (defn ^:private build-statement-
   "Builds a Prepare or Simple statement out of given params.
 

     (set-statement-options- (SimpleStatement. string-query))))

(defn bind
  [^PreparedStatement statement values]
  (.bind statement (to-array values)))

(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))))

(defprotocol BuildStatement
  (build-statement [query]))

(extend-protocol BuildStatement
  String
  (build-statement [query]
    (build-statement (SimpleStatement. query)))

  clojure.lang.IPersistentMap
  (build-statement [raw-statement]
    (build-statement (hayt/->raw raw-statement)))

  Statement
  (build-statement [s]
    s))

(defprotocol Listenable
  (add-listener [_ runnable executor]))

(deftype AsyncResult [fut]
  clojure.lang.IDeref
  (deref [_]
    (conv/to-clj @fut))

  clojure.lang.IBlockingDeref
  (deref [_ time-period time-unit]
    (conv/to-clj (deref fut time-period time-unit)))

  Listenable
  (add-listener [_ runnable executor]
    (.addListener fut runnable executor)))

(defn execute
  [^Session session query]
  (if hayt/*prepared-statement*
    (let [^String q (hayt/->raw query)]
      (.prepare session q))
    (let [^Statement built-statement (build-statement query)]
      (if *async*
        (AsyncResult. (.executeAsync session built-statement))
        (-> (.execute session built-statement)
            (conv/to-clj))))))

(defn ^String export-schema
  "Exports the schema as a string"

            SSLOptions ProtocolOptions$Compression]
           [com.datastax.driver.auth DseAuthProvider]
           [com.google.common.util.concurrent ListenableFuture Futures FutureCallback]
           [java.net URI]
           [javax.net.ssl TrustManagerFactory KeyManagerFactory SSLContext]
           [java.security KeyStore SecureRandom]
           [com.datastax.driver.core.exceptions DriverException]))
