/src/lobos/internal.clj

http://github.com/budu/lobos · Clojure · 132 lines · 101 code · 18 blank · 13 comment · 17 complexity · 6c011d9a991b27b503e0a6fe7c7a97ae MD5 · raw file

  1. ; Copyright (c) Nicolas Buduroi. All rights reserved.
  2. ; The use and distribution terms for this software are covered by the
  3. ; Eclipse Public License 1.0 which can be found in the file
  4. ; epl-v10.html at the root of this distribution. By using this software
  5. ; in any fashion, you are agreeing to be bound by the terms of this
  6. ; license.
  7. ; You must not remove this notice, or any other, from this software.
  8. (ns lobos.internal
  9. (:refer-clojure :exclude [defonce])
  10. (:require (lobos [compiler :as compiler]
  11. [connectivity :as conn]
  12. [metadata :as metadata]
  13. [schema :as schema]))
  14. (:use (clojure.tools [macro :only [name-with-attributes]])
  15. lobos.utils))
  16. (defonce debug-level
  17. (atom nil)
  18. "This atom keeps the currently set debug level, see
  19. `set-debug-level`. *For internal use*.")
  20. ;; -----------------------------------------------------------------------------
  21. ;; ## Statement Execution Helpers
  22. (defn autorequire-backend
  23. "Automatically require the backend for the given connection-info."
  24. [connection-info]
  25. (if (:subprotocol connection-info)
  26. (->> connection-info
  27. :subprotocol
  28. (str "lobos.backends.")
  29. symbol
  30. require)
  31. (throw (Exception. "The :subprotocol key is missing from db-spec."))))
  32. (defn- execute*
  33. "Execute the given SQL string or sequence of strings. Prints them if
  34. the `debug-level` is set to `:sql`."
  35. [sql]
  36. (doseq [sql-string (if (seq? sql) sql [sql])]
  37. (when (= :sql @debug-level) (println sql-string))
  38. (with-open [stmt (.createStatement (conn/connection))]
  39. (.execute stmt sql-string))))
  40. (defn execute
  41. "Executes the given statement(s) using the specified connection
  42. information, the bound one or the default connection. It will executes
  43. an extra *mode* statement if defined by the backend compiler. *For
  44. internal purpose*."
  45. [statements & [connection-info]]
  46. (let [statements (if (seq? statements)
  47. statements
  48. [statements])
  49. db-spec (conn/get-db-spec connection-info)
  50. mode (compiler/compile (compiler/mode db-spec))]
  51. (conn/with-connection connection-info
  52. (autorequire-backend connection-info)
  53. (when mode (execute* mode))
  54. (doseq [statement statements]
  55. (let [sql (if (string? statement)
  56. statement
  57. (compiler/compile statement))]
  58. (when sql (execute* sql)))))) nil)
  59. ;; -----------------------------------------------------------------------------
  60. ;; ## Optional Arguments Helpers
  61. (defn optional-cnx-or-schema [args]
  62. (let [[cnx-or-schema args]
  63. (optional #(or (schema/schema? %)
  64. (and (-> % schema/definition? not)
  65. (conn/connection? %))) args)
  66. args* args
  67. schema (when (schema/schema? cnx-or-schema) cnx-or-schema)
  68. cnx (or (conn/find-connection)
  69. (-> schema :options :db-spec)
  70. (when-not schema cnx-or-schema)
  71. :default-connection)
  72. db-spec (merge (conn/get-db-spec cnx)
  73. (when schema
  74. {:schema (-> schema :sname name)}))]
  75. [db-spec schema args]))
  76. (defn optional-cnx-and-sname [args]
  77. (let [[db-spec schema args] (optional-cnx-or-schema args)
  78. [sname args] (conn/with-connection db-spec
  79. (optional #(or (nil? %)
  80. ((set (metadata/schemas)) %)) args))
  81. sname (or sname (:name schema))]
  82. [db-spec sname args]))
  83. ;; -----------------------------------------------------------------------------
  84. ;; ## DML Helpers
  85. (defn raw-query [sql-string]
  86. (with-open [stmt (.createStatement (conn/connection))]
  87. (let [resultset (.executeQuery stmt sql-string)]
  88. (when resultset
  89. (doall (resultset-seq resultset))))))
  90. (defn raw-update [sql-string]
  91. (with-open [stmt (.createStatement (conn/connection))]
  92. (.executeUpdate stmt sql-string)))
  93. (defn sql-from-where [db-spec stmt sname tname where-expr]
  94. (do
  95. (require (symbol (str "lobos.backends."
  96. (:subprotocol db-spec))))
  97. (str stmt
  98. " from "
  99. (compiler/as-identifier db-spec tname sname)
  100. (when where-expr
  101. (str
  102. " where "
  103. (compiler/compile
  104. (schema/build-definition where-expr db-spec)))))))
  105. (defmacro query [db-spec sname tname & [conditions]]
  106. `(raw-query
  107. (sql-from-where ~db-spec "select *" ~sname ~tname
  108. (when-not ~(nil? conditions)
  109. (schema/expression ~conditions)))))
  110. (defmacro delete [db-spec sname tname & [conditions]]
  111. `(raw-update
  112. (sql-from-where ~db-spec "delete" ~sname ~tname
  113. (when-not ~(nil? conditions)
  114. (schema/expression ~conditions)))))