<commit_before>;   Copyright (c) <NAME>. All rights reserved.
;   The use and distribution terms for this software are covered by the
;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;   which can be found in the file LICENSE at the root of this distribution.
;   By using this software in any fashion, you are agreeing to be bound by
;   the terms of this license.
;   You must not remove this notice, or any other, from this software.


(ns asphalt.param
  (:require
    [asphalt.internal :as i]
    [asphalt.param.internal :as pi])
  (:import
    [java.util Calendar TimeZone]
    [java.sql Date PreparedStatement Time Timestamp]))


;; ----- utility fns to turn (local) date/time/timestamp into another timezone -----


(defn date->cal
  "Given a (local) date and a timezone/calendar instance, return a calendar suitable to set SQL date param."
  [^Date date tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTime date)))


(defn time->cal
  "Given a (local) time and a timezone/calendar instance, return a calendar suitable to set SQL time param."
  [^Time time tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTimeInMillis (.getTime time))))


(defn timestamp->cal
  "Given a (local) timestamp and a timezone/calendar instance, return a calendar suitable to set SQL timestamp param."
  [^Timestamp timestamp tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTimeInMillis (.getTime timestamp))))


;; ----- lay SQL params for known SQL types -----


(defmacro lay-params*
  "Implementation detail of `lay-params`.
  See: `lay-params`"
  [prepared-stmt param-keys param-types params]
  (i/expected vector? "vector of SQL param keys" param-keys)
  (i/expected vector? "vector of SQL param types" param-types)
  (doseq [each-type param-types]
    (i/expected (partial contains? pi/sql-all-types-map)
      (str "a valid SQL param type - either of " pi/sql-all-types-keys) each-type))
  (when (not= (count param-types) (count param-keys))
    (i/expected (format "param-types (%d) and param-keys (%d) to be of the same length"
                  (count param-types) (count param-keys)) {:param-types param-types
                                                           :param-keys  param-keys}))
  (let [prepared-stmt-sym (with-meta (gensym "prepared-stmt-") {:tag "java.sql.PreparedStatement"})
        params-sym  (gensym "sql-params-")
        param-count (count param-types)
        indices-sym (gensym "param-indices-")
        indices-exp (pi/params-indices param-keys param-types params-sym)]
    `(let [~params-sym ~params
           ~@(when-not (vector? indices-exp)  ; indices-exp is a vector for single params, S-expr otherwise
               [indices-sym indices-exp])]
       (if (<= ~param-count (count ~params-sym))
         (let [~prepared-stmt-sym ~prepared-stmt]
           (doseq [each-key# ~param-keys]
             (when-not (contains? ~params-sym each-key#)
               (i/expected (str "key " each-key# " to be present in SQL params") ~params-sym)))
           ~@(->> (map vector param-types param-keys)
               (map-indexed (fn [^long idx [t k]]
                              (pi/lay-param-expr prepared-stmt-sym t
                                (if (vector? indices-exp)  ; indices-exp is vector for single params, S-expr otherwise
                                  (get indices-exp idx)<commit_msg>add short-circuit bounds check for vector params<commit_after>;   Copyright (c) <NAME>. All rights reserved.
;   The use and distribution terms for this software are covered by the
;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;   which can be found in the file LICENSE at the root of this distribution.
;   By using this software in any fashion, you are agreeing to be bound by
;   the terms of this license.
;   You must not remove this notice, or any other, from this software.


(ns asphalt.param
  (:require
    [asphalt.internal :as i]
    [asphalt.param.internal :as pi])
  (:import
    [java.util Calendar TimeZone]
    [java.sql Date PreparedStatement Time Timestamp]))


;; ----- utility fns to turn (local) date/time/timestamp into another timezone -----


(defn date->cal
  "Given a (local) date and a timezone/calendar instance, return a calendar suitable to set SQL date param."
  [^Date date tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTime date)))


(defn time->cal
  "Given a (local) time and a timezone/calendar instance, return a calendar suitable to set SQL time param."
  [^Time time tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTimeInMillis (.getTime time))))


(defn timestamp->cal
  "Given a (local) timestamp and a timezone/calendar instance, return a calendar suitable to set SQL timestamp param."
  [^Timestamp timestamp tz-or-cal]
  (doto ^Calendar (pi/resolve-cal tz-or-cal)
    (.setTimeInMillis (.getTime timestamp))))


;; ----- lay SQL params for known SQL types -----


(defmacro lay-params*
  "Implementation detail of asphalt.param/lay-params.
  See:
    asphalt.param/lay-params"
  [prepared-stmt param-keys param-types params]
  (i/expected vector? "vector of SQL param keys" param-keys)
  (i/expected vector? "vector of SQL param types" param-types)
  (doseq [each-type param-types]
    (i/expected (partial contains? pi/sql-all-types-map)
      (str "a valid SQL param type - either of " pi/sql-all-types-keys) each-type))
  (when (not= (count param-types) (count param-keys))
    (i/expected (format "param-types (%d) and param-keys (%d) to be of the same length"
                  (count param-types) (count param-keys)) {:param-types param-types
                                                           :param-keys  param-keys}))
  (let [prepared-stmt-sym (with-meta (gensym "prepared-stmt-") {:tag "java.sql.PreparedStatement"})
        params-sym  (gensym "sql-params-")
        param-count (count param-types)
        indices-sym (gensym "param-indices-")
        indices-exp (pi/params-indices param-keys param-types params-sym)]
    `(let [~params-sym ~params
           ~@(when-not (vector? indices-exp)  ; indices-exp is a vector for single params, S-expr otherwise
               [indices-sym indices-exp])]
       (if (<= ~param-count (count ~params-sym))
         (let [~prepared-stmt-sym ~prepared-stmt]
           ~(if (= param-keys (vec (range (count param-keys))))  ; is it vector params?
              `(when (< (count ~params-sym) ~(count param-keys)) ; short circuit for vector params
                 (i/expected (str ~(count param-keys) " or more params") ~params-sym))
              `(doseq [each-key# ~param-keys]
                 (when-not (contains? ~params-sym each-key#)
                   (i/expected (str "key " each-key# " to be present in SQL params") ~params-sym))))
           ~@(->> (map vector param-types param-keys)
               (map-indexed (fn [^long idx [t k]]
                              (pi/lay-param-expr prepared-stmt-sym t
                                (if (vector? indices-exp)  ; indices-exp is vector for single params, S-expr otherwise
                                  (get indices-exp idx)
{'fraction_non_alphanumeric': 0.12649763165227082, 'fraction_numerical': 0.0011145165784341043, 'mean_word_length': 2.532972440944882, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6848756', 'n_tokens_mistral': 2202, 'n_tokens_neox': 2103, 'n_words': 735}