1 /// Escape special characters in MySQL strings.
2 module mysql.escape;
3 
4 
5 /++
6 Simple escape function for dangerous SQL characters
7 
8 Params:
9 	input = string to escape
10 	buffer = buffer to use for the output
11 +/
12 void mysql_escape ( Buffer, Input ) ( Input input, Buffer buffer )
13 {
14 	import std.string : translate;
15 
16 	immutable string[dchar] transTable = [
17 		'\\' : "\\\\",
18 		'\'' : "\\'",
19 		'\0' : "\\0",
20 		'\n' : "\\n",
21 		'\r' : "\\r",
22 		'"'  : "\\\"",
23 		'\032' : "\\Z"
24 	];
25 
26 	translate(input, transTable, null, buffer);
27 }
28 
29 
30 /++
31 Struct to wrap around a string so it can be passed to formattedWrite and be
32 properly escaped all using the buffer that formattedWrite provides.
33 
34 Template Params:
35 	Input = Type of the input
36 +/
37 struct MysqlEscape ( Input )
38 {
39 	Input input;
40 
41 	const void toString ( scope void delegate(const(char)[]) sink )
42 	{
43 		struct SinkOutputRange
44 		{
45 			void put ( const(char)[] t ) { sink(t); }
46 		}
47 
48 		SinkOutputRange r;
49 		mysql_escape(input, r);
50 	}
51 }
52 
53 /++
54 Helper function to easily construct a escape wrapper struct
55 
56 Template Params:
57 	T = type of the input
58 
59 Params:
60 	input = input to escape
61 +/
62 MysqlEscape!(T) mysqlEscape ( T ) ( T input )
63 {
64 	return MysqlEscape!(T)(input);
65 }
66 
67 unittest
68 {
69 	import std.array : appender;
70 
71 	auto buf = appender!string();
72 
73 	import std.format : formattedWrite;
74 
75 	formattedWrite(buf, "%s, %s, %s, mkay?", 1, 2,
76 			mysqlEscape("\0, \r, \n, \", \\"));
77 
78 	assert(buf.data() == `1, 2, \0, \r, \n, \", \\, mkay?`);
79 }