/src/lobos/backends/postgresql.clj

http://github.com/budu/lobos · Clojure · 99 lines · 76 code · 12 blank · 11 comment · 7 complexity · 582db22f817e1c6e2b76bd554c0ded41 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.postgresql
  9. "Compiler implementation for PostgreSQL."
  10. (:refer-clojure :exclude [compile defonce])
  11. (:require (lobos [schema :as schema]))
  12. (:use lobos.analyzer
  13. lobos.compiler
  14. lobos.utils)
  15. (:import (lobos.ast AlterRenameAction
  16. ColumnDefinition
  17. DataTypeClause)
  18. (lobos.schema DataType
  19. Schema)))
  20. ;; -----------------------------------------------------------------------------
  21. ;; ## Analyzer
  22. (def ^{:private true} analyzer-data-type-aliases
  23. {:bool :boolean
  24. :bpchar :char
  25. :bytea :blob
  26. :float4 :real
  27. :float8 :double
  28. :int2 :smallint
  29. :int4 :integer
  30. :int8 :bigint
  31. :text :nclob
  32. :timestamptz :timestamp
  33. :timetz :time})
  34. (defmethod analyze [:postgresql DataType]
  35. [_ column-meta]
  36. (let [dtype (-> column-meta :type_name as-keyword)
  37. options {:time-zone (#{:timetz :timestamptz} dtype)}
  38. dtype (first (replace analyzer-data-type-aliases
  39. [dtype]))]
  40. (schema/data-type
  41. dtype
  42. (analyze-data-type-args dtype column-meta)
  43. options)))
  44. (defmethod analyze [:postgresql Schema]
  45. [_ sname]
  46. (analyze [:lobos.analyzer/standard Schema] (or sname :public)))
  47. ;; -----------------------------------------------------------------------------
  48. ;; ## Compiler
  49. (def ^{:private true} compiler-data-type-aliases
  50. {:blob :bytea
  51. :clob :text
  52. :double :double-precision
  53. :nclob :text
  54. :nvarchar :varchar})
  55. (defmethod compile [:postgresql DataTypeClause]
  56. [expression]
  57. (let [{:keys [dtype args options]} expression
  58. {:keys [time-zone]} options
  59. dtype (first (replace compiler-data-type-aliases [dtype]))
  60. args (if (#{:bytea :text} dtype) [] args)]
  61. (unsupported (#{:binary :varbinary} dtype)
  62. "Use blob instead.")
  63. (join \space
  64. (str (as-sql-keyword dtype) (as-list args))
  65. (when time-zone "WITH TIME ZONE"))))
  66. (defmethod compile [:postgresql ColumnDefinition]
  67. [definition]
  68. (let [{:keys [db-spec cname data-type default
  69. auto-inc not-null others]} definition]
  70. (apply join \space
  71. (as-identifier db-spec cname)
  72. (if auto-inc
  73. (if (= :bigint (:dtype data-type))
  74. "BIGSERIAL"
  75. "SERIAL")
  76. (compile data-type))
  77. (when default (str "DEFAULT " (compile default)))
  78. (not-null-option not-null)
  79. others)))
  80. (defmethod compile [:postgresql AlterRenameAction]
  81. [action]
  82. (let [{:keys [db-spec element]} action
  83. old-name (:cname element)
  84. new-name (:others element)]
  85. (format "RENAME COLUMN %s TO %s"
  86. (as-identifier db-spec old-name)
  87. (as-identifier db-spec new-name))))