PageRenderTime 59ms CodeModel.GetById 52ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lobos/backends/postgresql.clj

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