On 12/8/21 4:31 PM, kdevel wrote:
> Further down we must read this:
void main(string[] args) {
import std.stdio;
writeln(i"The program $(args[0]) received $(args.length - 1) arguments.");
// Lowering: --->
// writeln(InterpolationHeader!("The program ", "args[0]", " received ", "args.length - 1", " arguments.")(),
// "The program ", args[0], " received ", args.length - 1, " arguments.");
auto s = sqlExec(i"INSERT INTO runs VALUES ($(args[0]), $(args.length - 1))");
// Lowering: --->
// auto s = sqlExec(InterpolationHeader!("INSERT INTO runs VALUES(", "args[0]", ", ", "args.length - 1", ")")(),
// args[0], $(args.length - 1));
}
How is the proper separation of code (query) and data achieved in this case?
Because the sqlExec
function figures it out based on the interpolation header. It can tell which parts were literal strings, and which parts were interpolation parameters. The interpolation parameters are replaced with "?", and then the parameters are passed as data (to avoid SQL injection as expected).
> To me
auto argsmaxidx = args.length - 1;
auto s = sqlExec("INSERT INTO runs VALUES (?, ?)", args [0], argsmaxidx);
appears way more readable.
Both are readable, though I'd argue that for this particular example, the usage of $(expr)
for syntax makes things complex to read (syntax highlighting should help). In our DIP we used ${expr}, which for SQL would be more readable, but might look worse for things like code mixins.
But there are plenty of examples where the string-blueprint form is less readable (the INSERT form where you specify fields first, and then parameters later is kind of a terrible syntax to begin with).
e.g. (from a real line of code in my codebase):
conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = ?", loc_latitude, loc_longitude, id);
// compare to:
conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = $loc_longitude WHERE id = $id");
-Steve