~subsetpark/doozer

doozer/doozer/backends/sql.janet -rw-r--r-- 3.1 KiB
4a8e0e3e — Zach Smith update docs 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(import /doozer/common)

(def backend
  ```
  The generic doozer backend for all SQL dialects. To be used as a
  prototype to be overridden by implementation-specific backends (SQLite,
  PostgresQL, etc.)
  ```
  @{:assemble-base
    (fn assemble-base
      [self source join where select limit]
      (string "SELECT "
              select
              " FROM "
              source
              join
              where
              limit))

    :assemble-where-clauses
    (fn assemble-where-clauses
      [self clause-strs]
      (if (empty? clause-strs)
        ""
        (string "\nWHERE " (string/join clause-strs " AND "))))

    :assemble-join-clauses
    (fn assemble-join-clauses
      [self clause-strs]
      (string/join clause-strs " "))

    :assemble-select-clauses
    (fn assemble-select-clauses
      [self clause-strs]
      (if (empty? clause-strs)
        "*"
        (string/join clause-strs ", ")))

    :render-operation
    (fn render-operation
      [self op args]
      (let [template (case op
                       nil "%s"
                       (if-let [t (common/operators (symbol op))]
                         t
                         (errorf "Tried to render unknown operator: %q" op)))]
        (string/format template ;args)))

    :render-as
    (fn render-as
      [self expr alias]
      (string/format "%s AS %s" expr alias))

    :render-apply
    (fn apply-template
      [self function args]
      (string/format "%s(%s)" function args))

    :render-function-arguments
    (fn function-arguments
      [self args]
      (string/join args ", "))

    :render-join
    (fn render-join
      [self join-type tab as rendered-clause]
      (let [rendered-type (case join-type
                            :inner "INNER"
                            :natural-inner "NATURAL INNER"
                            :cross-inner "CROSS INNER"
                            :left "LEFT OUTER")]
        (string/format "\n%s JOIN %s AS %s ON %s"
                       rendered-type
                       tab
                       as
                       rendered-clause)))

    :render-element
    (defn- render-expression-element
      `Given an element that can be found in an relational expression, render
      it correctly.

      References to a given column in a given row should be rendered "foo.bar",
      but if we've received a generated symbol, this element is a user-supplied
      parameter and should be rendered as a reference to that parameter in a
      parameters table.
      `
      [self element]
      (match element
        {:symbol sym} (string ":" sym)
        {:table tab :column col} (string (:quote-element self tab)
                                         "."
                                         (:quote-element self col))))

    :render-apply
    (fn render-apply
      [self fun clause]
      (string/format "%s(%s)" fun clause))

    :render-limit
    (fn render-limit
      [self limit]
      (if (not (empty? limit)) (string/format " LIMIT %s" limit) ""))

    :render-subquery
    (fn render-subquery
      [self subquery]
      (string "(" subquery ")"))})