/src/lobos/backends/h2.clj

http://github.com/budu/lobos · Clojure · 113 lines · 89 code · 13 blank · 11 comment · 9 complexity · 32063a6686ffd25a76be7525de9673e6 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.backends.h2
  9. "Compiler implementation for H2."
  10. (:refer-clojure :exclude [compile defonce])
  11. (:require (lobos [schema :as schema]))
  12. (:use (clojure [string :only [split]])
  13. (lobos analyzer compiler connectivity internal metadata utils))
  14. (:import (lobos.ast AlterRenameAction
  15. AutoIncClause
  16. CreateSchemaStatement
  17. DataTypeClause
  18. DropStatement)
  19. (lobos.schema ForeignKeyConstraint
  20. UniqueConstraint)))
  21. ;; -----------------------------------------------------------------------------
  22. ;; ## Analyzer
  23. (defmethod analyze [:h2 UniqueConstraint]
  24. [_ sname tname cname meta]
  25. (let [columns (split (:column_list meta) #",")
  26. ctype (-> meta :constraint_type as-keyword)]
  27. (UniqueConstraint.
  28. (make-index-name tname ctype columns)
  29. ctype
  30. (map as-keyword columns))))
  31. (defmethod analyze [:h2 :constraints]
  32. [_ sname tname]
  33. (let [db-spec (db-meta-spec)]
  34. (concat
  35. (map (fn [meta] (analyze UniqueConstraint sname tname
  36. (-> meta :constraint_name keyword)
  37. meta))
  38. (query db-spec
  39. :INFORMATION_SCHEMA
  40. :CONSTRAINTS
  41. (and (or (= :CONSTRAINT_TYPE "UNIQUE")
  42. (= :CONSTRAINT_TYPE "PRIMARY KEY"))
  43. (= :TABLE_SCHEMA (as-str sname))
  44. (= :TABLE_NAME (as-str tname)))))
  45. (map (fn [[cname meta]] (analyze ForeignKeyConstraint cname meta))
  46. (references-meta sname tname)))))
  47. ;; -----------------------------------------------------------------------------
  48. ;; ## Compiler
  49. (defmethod compile [:h2 DataTypeClause]
  50. [expression]
  51. (let [{:keys [dtype args options]} expression]
  52. (unsupported (= dtype :binary)
  53. "Use varbinary instead.")
  54. (unsupported (:time-zone options)
  55. "Time zones not supported.")
  56. (str (as-sql-keyword dtype) (as-list args))))
  57. (defmethod compile [:h2 AutoIncClause]
  58. [_]
  59. "AUTO_INCREMENT")
  60. (defmethod compile [::standard CreateSchemaStatement]
  61. [statement]
  62. (let [{:keys [db-spec sname elements]} statement
  63. [elements foreign-keys] (extract-foreign-keys elements)
  64. alters (map compile (build-alter-add-statements
  65. (assoc db-spec :schema sname)
  66. foreign-keys))]
  67. (conj alters
  68. (str "CREATE SCHEMA "
  69. (apply join "\n" (conj (map compile elements)
  70. (as-identifier db-spec sname)))))))
  71. (defmethod compile [:h2 CreateSchemaStatement]
  72. [statement]
  73. (let [{:keys [db-spec sname elements]} statement
  74. [elements foreign-keys] (extract-foreign-keys elements)
  75. alters (map compile (build-alter-add-statements
  76. (assoc db-spec :schema sname)
  77. foreign-keys))]
  78. (conj (concat (map (comp compile
  79. #(assoc-in % [:db-spec :schema] sname))
  80. elements)
  81. alters)
  82. (str "CREATE SCHEMA "
  83. (as-identifier db-spec sname)))))
  84. (defmethod compile [:h2 DropStatement]
  85. [statement]
  86. (let [{:keys [db-spec otype oname behavior]} statement]
  87. (join \space
  88. "DROP"
  89. (as-sql-keyword otype)
  90. (as-identifier db-spec oname (:schema db-spec))
  91. (when (and behavior (#{:table} otype))
  92. (as-sql-keyword behavior)))))
  93. (defmethod compile [:h2 AlterRenameAction]
  94. [action]
  95. (let [{:keys [db-spec element]} action
  96. old-name (:cname element)
  97. new-name (:others element)]
  98. (format "ALTER COLUMN %s RENAME TO %s"
  99. (as-identifier db-spec old-name)
  100. (as-identifier db-spec new-name))))