Merge branch 'master' of github.com:jkk/honeysql
This commit is contained in:
commit
ed20b39056
1 changed files with 45 additions and 13 deletions
58
README.md
58
README.md
|
|
@ -39,6 +39,8 @@ Everything is built on top of maps representing SQL queries:
|
|||
|
||||
Column names can be provided as keywords or symbols (but not strings -- HoneySQL treats strings as values that should be lifted out of the SQL as parameters).
|
||||
|
||||
### `format`
|
||||
|
||||
`format` turns maps into `clojure.java.jdbc`-compatible, parameterized SQL:
|
||||
|
||||
```clojure
|
||||
|
|
@ -66,6 +68,8 @@ to jdbc:
|
|||
(jdbc/query conn (sql/format sqlmap))
|
||||
```
|
||||
|
||||
### `build`
|
||||
|
||||
You can build up SQL maps yourself or use helper functions. `build` is the Swiss Army Knife helper. It lets you leave out brackets here and there:
|
||||
|
||||
```clojure
|
||||
|
|
@ -86,6 +90,8 @@ You can provide a "base" map as the first argument to build:
|
|||
:from [:foo]}
|
||||
```
|
||||
|
||||
### Vanilla SQL clause helpers
|
||||
|
||||
There are also functions for each clause type in the `honeysql.helpers` namespace:
|
||||
|
||||
```clojure
|
||||
|
|
@ -119,7 +125,7 @@ To add to clauses instead of replacing them, use `merge-select`, `merge-where`,
|
|||
=> ["SELECT a, b, c, d, e FROM foo WHERE (f.a = ? AND b > ?)" "baz" 10]
|
||||
```
|
||||
|
||||
`where` will combine multiple clauses together using and:
|
||||
`where` will combine multiple clauses together using SQL's `AND`:
|
||||
|
||||
```clojure
|
||||
(-> (select :*)
|
||||
|
|
@ -143,6 +149,8 @@ name and the desired alias:
|
|||
In particular, note that `(select [:a :b])` means `SELECT a AS b` rather than
|
||||
`SELECT a, b` -- `select` is variadic and does not take a collection of column names.
|
||||
|
||||
### Inserts
|
||||
|
||||
Inserts are supported in two patterns.
|
||||
In the first pattern, you must explicitly specify the columns to insert,
|
||||
then provide a collection of rows, each a collection of column values:
|
||||
|
|
@ -179,6 +187,8 @@ and the remaining maps *must* have the same set of keys and values:
|
|||
"Jane" "Daniels" 56]
|
||||
```
|
||||
|
||||
### Nested subqueries
|
||||
|
||||
The column values do not have to be literals, they can be nested queries:
|
||||
|
||||
```clojure
|
||||
|
|
@ -198,6 +208,16 @@ The column values do not have to be literals, they can be nested queries:
|
|||
"user"]
|
||||
```
|
||||
|
||||
```clojure
|
||||
(-> (select :*)
|
||||
(from :foo)
|
||||
(where [:in :foo.a (-> (select :a) (from :bar))])
|
||||
sql/format)
|
||||
=> ["SELECT * FROM foo WHERE (foo.a in (SELECT a FROM bar))"]
|
||||
```
|
||||
|
||||
### Composite types
|
||||
|
||||
Composite types are supported:
|
||||
|
||||
```clojure
|
||||
|
|
@ -213,6 +233,8 @@ Composite types are supported:
|
|||
"small" 1 "inch" "large" 10 "feet"]
|
||||
```
|
||||
|
||||
### Updates
|
||||
|
||||
Updates are possible too (note the double S in `sset` to avoid clashing
|
||||
with `clojure.core/set`):
|
||||
|
||||
|
|
@ -238,6 +260,8 @@ There are two variants of `sset` (and the underlying `:set` in the SQL map):
|
|||
* `set0` (and `:set0`) -- this puts the `SET` before `FROM`,
|
||||
* `set1` (and `:set1`) -- a synonym for `sset` (and `:set`) that puts the `SET` after `JOIN`.
|
||||
|
||||
### Deletes
|
||||
|
||||
Deletes look as you would expect:
|
||||
|
||||
```clojure
|
||||
|
|
@ -271,15 +295,7 @@ If you want to delete everything from a table, you can use `truncate`:
|
|||
=> ["TRUNCATE films"]
|
||||
```
|
||||
|
||||
Queries can be nested:
|
||||
|
||||
```clojure
|
||||
(-> (select :*)
|
||||
(from :foo)
|
||||
(where [:in :foo.a (-> (select :a) (from :bar))])
|
||||
sql/format)
|
||||
=> ["SELECT * FROM foo WHERE (foo.a in (SELECT a FROM bar))"]
|
||||
```
|
||||
### Unions
|
||||
|
||||
Queries may be united within a :union or :union-all keyword:
|
||||
|
||||
|
|
@ -289,6 +305,8 @@ Queries may be united within a :union or :union-all keyword:
|
|||
=> ["SELECT * FROM foo UNION SELECT * FROM bar"]
|
||||
```
|
||||
|
||||
### Functions
|
||||
|
||||
Keywords that begin with `%` are interpreted as SQL function calls:
|
||||
|
||||
```clojure
|
||||
|
|
@ -298,6 +316,8 @@ Keywords that begin with `%` are interpreted as SQL function calls:
|
|||
=> ["SELECT max(id) FROM foo"]
|
||||
```
|
||||
|
||||
### Bindable parameters
|
||||
|
||||
Keywords that begin with `?` are interpreted as bindable parameters:
|
||||
|
||||
```clojure
|
||||
|
|
@ -308,6 +328,8 @@ Keywords that begin with `?` are interpreted as bindable parameters:
|
|||
=> ["SELECT id FROM foo WHERE a = ?" "BAZ"]
|
||||
```
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
There are helper functions and data literals for SQL function calls, field
|
||||
qualifiers, raw SQL fragments, inline values, and named input parameters:
|
||||
|
||||
|
|
@ -326,6 +348,8 @@ call-qualify-map
|
|||
=> ["SELECT foo(bar), foo.a, @var := foo.bar FROM foo WHERE (a = ? AND b = 42)" "BAZ"]
|
||||
```
|
||||
|
||||
#### PostGIS
|
||||
|
||||
A common example in the wild is the PostGIS extension to PostgreSQL where you
|
||||
have a lot of function calls needed in code:
|
||||
|
||||
|
|
@ -341,6 +365,8 @@ have a lot of function calls needed in code:
|
|||
0.291 32.621 4326]
|
||||
```
|
||||
|
||||
#### Raw SQL fragments
|
||||
|
||||
Raw SQL fragments that are strings are treated exactly as-is when rendered into
|
||||
the formatted SQL string (with no parsing or parameterization). Inline values
|
||||
will not be lifted out as parameters, so they end up in the SQL string as-is.
|
||||
|
|
@ -366,6 +392,8 @@ or the `param` helper.
|
|||
=> ["SELECT * FROM foo WHERE expired_at < now() - '? seconds'" 5]
|
||||
```
|
||||
|
||||
#### Identifiers
|
||||
|
||||
To quote identifiers, pass the `:quoting` keyword option to `format`. Valid options are `:ansi` (PostgreSQL), `:mysql`, or `:sqlserver`:
|
||||
|
||||
```clojure
|
||||
|
|
@ -376,9 +404,11 @@ To quote identifiers, pass the `:quoting` keyword option to `format`. Valid opti
|
|||
=> ["SELECT `foo`.`a` FROM `foo` WHERE `foo`.`a` = ?" "baz"]
|
||||
```
|
||||
|
||||
#### Locking
|
||||
|
||||
To issue a locking select, add a `:lock` to the query or use the lock helper. The lock value must be a map with a `:mode` value. The built-in
|
||||
modes are the standard :update (FOR UPDATE) or the vendor-specific `:mysql-share` (LOCK IN SHARE MODE) or `:postresql-share` (FOR SHARE). The
|
||||
lock map may also provide a :wait value, which if false will append the NOWAIT parameter, supported by PostgreSQL.
|
||||
modes are the standard `:update` (FOR UPDATE) or the vendor-specific `:mysql-share` (LOCK IN SHARE MODE) or `:postresql-share` (FOR SHARE). The
|
||||
lock map may also provide a `:wait` value, which if false will append the NOWAIT parameter, supported by PostgreSQL.
|
||||
|
||||
```clojure
|
||||
(-> (select :foo.a)
|
||||
|
|
@ -402,6 +432,8 @@ To be able to use dashes in quoted names, you can pass ```:allow-dashed-names tr
|
|||
=> ["SELECT \"f\".\"foo-id\", \"f\".\"foo-name\" FROM \"foo-bar\" \"f\" WHERE \"f\".\"foo-id\" = ?" 12345]
|
||||
```
|
||||
|
||||
### Big, complicated example
|
||||
|
||||
Here's a big, complicated query. Note that Honey SQL makes no attempt to verify that your queries make any sense. It merely renders surface syntax.
|
||||
|
||||
```clojure
|
||||
|
|
@ -538,7 +570,7 @@ To teach `honeysql` how to handle your datatype you need to implement [`honeysql
|
|||
```
|
||||
## TODO
|
||||
|
||||
* Create table, etc.
|
||||
- [ ] Create table, etc.
|
||||
|
||||
## Extensions
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue