Expand documentation
This commit is contained in:
parent
e585ded37e
commit
2d9ceb73a6
1 changed files with 131 additions and 0 deletions
|
|
@ -96,6 +96,69 @@ the table name, i.e., `:foo/bar` instead of `:foo.bar`:
|
||||||
;;=> ["SELECT t.id, name AS item FROM table AS t WHERE id = ?" 1]
|
;;=> ["SELECT t.id, name AS item FROM table AS t WHERE id = ?" 1]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## SQL Expressions
|
||||||
|
|
||||||
|
In addition to using hash maps to describe SQL clauses,
|
||||||
|
HoneySQL uses vectors to describe SQL expressions. Any
|
||||||
|
sequence that begins with a keyword (or symbol) is considered
|
||||||
|
to be a kind of function invocation. Certain "functions" are
|
||||||
|
considered to be "special syntax" and have custom rendering.
|
||||||
|
Some "functions" are considered to be operators. In general,
|
||||||
|
`[:foo :a 42 "c"]` will render as `FOO(a, ?, ?)` with the parameters
|
||||||
|
`42` and `"c"` lifted out into the overall vector result
|
||||||
|
(with a SQL string followed by all its parameters).
|
||||||
|
|
||||||
|
Operators can be strictly binary or variadic (most are strictly binary).
|
||||||
|
Special syntax can have zero or more arguments and each form is
|
||||||
|
described in the [docs/special-syntax.md](Special Syntax) section.
|
||||||
|
|
||||||
|
Some examples:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[:= :a 42] ;=> "a = ?" with a parameter of 42
|
||||||
|
[:+ 42 :a :b] ;=> "? + a + b" with a parameter of 42
|
||||||
|
[:= :x [:inline "foo"]] ;=> "x = 'foo'" -- the string is inlined
|
||||||
|
[:now] ;=> "NOW()"
|
||||||
|
[:count :*] ;=> "COUNT(*)"
|
||||||
|
[:or [:<> :name nil] [:= :status-id 0]] ;=> "(name IS NOT NULL) OR (status_id = ?)"
|
||||||
|
;; with a parameter of 0 -- the nil value is inlined as NULL
|
||||||
|
```
|
||||||
|
|
||||||
|
`:inline` is an example of "special syntax" and it renders its
|
||||||
|
(single) argument as part of the SQL string generated by `format`.
|
||||||
|
|
||||||
|
## SQL Parameters
|
||||||
|
|
||||||
|
As indicated in the preceding sections, values found in the DSL data structure
|
||||||
|
that are not keywords or symbols are lifted out as positional parameters.
|
||||||
|
They are replaced by `?` in the generated SQL string and added to the
|
||||||
|
parameter list in order:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[:between :size 10 20] ;=> "size BETWEEN ? AND ?" with parameters 10 and 20
|
||||||
|
```
|
||||||
|
|
||||||
|
HoneySQL also supports named parameters. There are two ways
|
||||||
|
of identifying a named parameter:
|
||||||
|
* a keyword or symbol that begins with `?`
|
||||||
|
* the `:param` special (functional) syntax
|
||||||
|
|
||||||
|
The values of those parameters are supplied in the `format`
|
||||||
|
call as the `:params` key of the options hash map.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(sql/format {:select [:*] :from [:table]
|
||||||
|
:where [:= :a :?x]}
|
||||||
|
{:params {:x 42}})
|
||||||
|
["SELECT * FROM table WHERE a = ?" 42]
|
||||||
|
(sql/format {:select [:*] :from [:table]
|
||||||
|
:where [:= :a [:param :x]]}
|
||||||
|
{:params {:x 42}})
|
||||||
|
["SELECT * FROM table WHERE a = ?" 42]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functional Helpers
|
||||||
|
|
||||||
In addition to the hash map (and vectors) approach of building
|
In addition to the hash map (and vectors) approach of building
|
||||||
SQL queries with raw Clojure data structures, a namespace full
|
SQL queries with raw Clojure data structures, a namespace full
|
||||||
of helper functions is also available. These functions are
|
of helper functions is also available. These functions are
|
||||||
|
|
@ -156,10 +219,78 @@ you need to consider this when referring symbols in from the
|
||||||
`honey.sql.helpers` namespace: `for`, `group-by`, `partition-by`,
|
`honey.sql.helpers` namespace: `for`, `group-by`, `partition-by`,
|
||||||
`set`, and `update`.
|
`set`, and `update`.
|
||||||
|
|
||||||
|
## Dialects
|
||||||
|
|
||||||
|
By default, HoneySQL operates in ANSI SQL mode but it supports
|
||||||
|
a lot of PostgreSQL extensions in that mode. PostgreSQL is mostly
|
||||||
|
a superset of ANSI SQL so it makes sense to support as much as
|
||||||
|
possible of the union of ANSI SQL and PostgreSQL out of the box.
|
||||||
|
|
||||||
|
The dialects supported by HoneySQL v2 are:
|
||||||
|
* `:ansi` -- the default, including most PostgreSQL extensions
|
||||||
|
* `:sqlserver` -- Microsoft SQL Server
|
||||||
|
* `:mysql` -- MySQL (and Percona and MariaDB)
|
||||||
|
* `:oracle` -- Oracle
|
||||||
|
|
||||||
|
The most visible difference between dialects is how SQL entities
|
||||||
|
should be quoted (if the `:quoted true` option is provided to `format`).
|
||||||
|
Most databases use `"` for quoting (the `:ansi` and `:oracle` dialects).
|
||||||
|
The `:sqlserver` dialect uses `[`..`]` and the `:mysql` dialect uses
|
||||||
|
```..```.
|
||||||
|
|
||||||
|
Currently, the only dialect that has substantive differences from
|
||||||
|
the others is `:mysql` which has a `:lock` clause (that is very
|
||||||
|
similar to the ANSI `:for` clause) and for which the `:set` clause
|
||||||
|
has a different precedence than ANSI SQL.
|
||||||
|
|
||||||
|
You can change the dialect globally using the `set-dialect!` function,
|
||||||
|
passing in one of the keywords above. You need to call this function
|
||||||
|
before you call `format` for the first time.
|
||||||
|
|
||||||
|
You can change the dialect for a single `format` call by
|
||||||
|
specifying the `:dialect` option in that call.
|
||||||
|
|
||||||
|
SQL entities are not quoted by default but if you specify the
|
||||||
|
dialect in a `format` call, they will be quoted. If you don't
|
||||||
|
specify a dialect in the `format` call, you can specify
|
||||||
|
`:quoted true` to have SQL entities quoted.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(sql/format '{select (id) from (table)} {:quoted true})
|
||||||
|
;;=> ["SELECT \"id\" FROM \"table\""]
|
||||||
|
(sql/format '{select (id) from (table)} {:dialect :mysql})
|
||||||
|
;;=> ["SELECT `id` FROM `table`"]
|
||||||
|
(sql/set-dialect! :sqlserver)
|
||||||
|
;;=> nil
|
||||||
|
(sql/format '{select (id) from (table)} {:quoted true})
|
||||||
|
;;=> ["SELECT [id] FROM [table]"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Format Options
|
||||||
|
|
||||||
|
In addition to the `:quoted` and `:dialect` options described above,
|
||||||
|
`format` also accepts `:inline` and `:params`.
|
||||||
|
|
||||||
|
The `:params` option was mentioned above and is used to specify
|
||||||
|
the values of named parameters in the DSL.
|
||||||
|
|
||||||
|
The `:inline` option suppresses the generation of parameters in
|
||||||
|
the SQL string and instead tries to inline all the values directly
|
||||||
|
into the SQL string. The behavior is as if each value in the DSL
|
||||||
|
was wrapped in `[:inline `..`]`:
|
||||||
|
|
||||||
|
* `nil` becomes the SQL value `NULL`,
|
||||||
|
* Clojure strings become inline SQL strings with single quotes (so `"foo"` becomes `'foo'`),
|
||||||
|
* keywords and symbols become SQL keywords (uppercase, with `-` replaced by a space),
|
||||||
|
* everything else is just turned into a string (by calling `str`) and added to the SQL string.
|
||||||
|
|
||||||
## Reference Documentation
|
## Reference Documentation
|
||||||
|
|
||||||
The full list of supported SQL clauses is documented in the
|
The full list of supported SQL clauses is documented in the
|
||||||
[docs/clause-reference.md](Clause Reference). The full list
|
[docs/clause-reference.md](Clause Reference). The full list
|
||||||
|
of operators supported (as prefix-form "functions") is
|
||||||
|
documented in the [docs/operator-reference.md](Operator Reference)
|
||||||
|
section. The full list
|
||||||
of "special syntax" functions is documented in the
|
of "special syntax" functions is documented in the
|
||||||
[docs/special-syntax.md](Special Syntax) section. The best
|
[docs/special-syntax.md](Special Syntax) section. The best
|
||||||
documentation for the helper functions is the
|
documentation for the helper functions is the
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue