1
1
# SqlStrings
2
2
3
- This package provides the ` @sql_cmd ` macro to allow SQL query strings to be
4
- constructed by normal-looking string interpolation but without danger of SQL
5
- injection attacks.
3
+ SqlStrings.jl provides the ` @sql_cmd ` macro to allow SQL query strings to be
4
+ constructed by normal-looking string interpolation but without risking SQL
5
+ formatting errors or SQL injection attacks on your application. For example,
6
+ the code
7
+
8
+ ``` julia
9
+ query = " INSERT INTO Students VALUES ('$name ', $age , '$class ')"
10
+ runquery (connection, query);
11
+ ```
12
+
13
+ is vulerable to the canonical SQL injection attack:
6
14
7
15
[ ![ Little Bobby Tables] ( https://imgs.xkcd.com/comics/exploits_of_a_mom.png )] ( https://xkcd.com/327 )
8
16
9
- ` @sql_cmd ` is quite simple — it understands only the basic rules of SQL
10
- quoting and Julia string interpolation, but does no other parsing of the source
11
- text. In this sense it is quite similar to ` Base.Cmd ` - it keeps any literal
12
- SQL text you write as-is and captures the Julia-level string interpolations
13
- in a safe way.
17
+ Here's how to make this safe using SqlStrings.jl:
18
+
19
+ ``` julia
20
+ query = sql ` INSERT INTO Students VALUES ($name , $age , $class )`
21
+ runquery (connection, query);
22
+ ```
23
+
24
+ In addition to making the above code safe, it allows the Julia types of
25
+ interpolated parameters to be preserved and passed to the database driver
26
+ library which can then marshal them correctly into types it understands. This
27
+ provides more control than using string interpolation which is for human
28
+ readability rather than data transfer.
14
29
15
- ## Simple usage
30
+ # Simple usage
16
31
17
32
To use with a given database backend, you'll need a small amount of integration
18
33
code. In the examples below we'll use with LibPQ.jl and a ` runquery() ` function
19
34
(hopefully integration will be automatic in future).
20
35
21
36
``` julia
37
+ using SqlStrings
22
38
import LibPQ
23
39
24
40
runquery (conn, sql:: SqlStrings.Sql )
@@ -52,7 +68,9 @@ julia> runquery(conn, sql`SELECT * FROM foo`) |> DataFrame
52
68
2 │ foo@example . com 2
53
69
```
54
70
55
- ## Howto: Inserting values from a Julia array into a row
71
+ # Howtos
72
+
73
+ ## Inserting values from a Julia collection into a row
56
74
57
75
In some circumstances it can be useful to use splatting syntax to interpolate a
58
76
Julia collection into a comma-separated list of values. Generally simple scalar
@@ -64,7 +82,7 @@ email_and_id = ("bar@example.com", 3)
64
82
runquery (conn, sql ` INSERT INTO foo VALUES ($(email_and_id... ) )` )
65
83
```
66
84
67
- ## Howto: Using the ` in ` operator with a Julia collection
85
+ ## Using the ` in ` operator with a Julia collection
68
86
69
87
There's two ways to do this. First, using ` in ` and splatting syntax
70
88
@@ -92,7 +110,7 @@ julia> ids = [1,2]
92
110
2 │ foo@example . com 2
93
111
```
94
112
95
- ## Howto: Building up a query from fragments
113
+ ## Building up a query from fragments
96
114
97
115
On occasion you might want to dynamically build up a complicated query from
98
116
fragments of SQL source text. To do this, the result of ` @sql_cmd ` can be
@@ -118,3 +136,18 @@ A word of warning that constructing SQL logic with Julia-level logic can make
118
136
the code quite hard to understand. It can be worth considering writing one
119
137
larger SQL query which does more of the logic on the SQL side.
120
138
139
+ # Design
140
+
141
+ ` SqlStrings ` is a minimal approach to integrating SQL with Julia code in a safe
142
+ way — it understands only the basic rules of SQL quoting and Julia string
143
+ interpolation, but does no other parsing of the source text. This allows tight
144
+ integration with your database of choice by being unopinionated about its
145
+ source language and any SQL language extensions it may have.
146
+
147
+ I've chosen backticks for ` @sql_cmd ` rather than a normal string macro because
148
+ * It's important to have syntax highlighting, and it seems editors disable
149
+ syntax highlighting of interpolations within normal string macros.
150
+ * ` @sql_cmd ` is very conceptually similar to the builtin backticks and
151
+ ` Base.Cmd ` : it's a lightweight layer which deals only with preserving the
152
+ structure of tokens in the source text.
153
+
0 commit comments