One of the examples in the String Template JEPs, and a stated motivating
factor behind its design, is SQL. Template processors are objects so that
use cases like constructing SQL statements aren't injection prone.

The questions I want to pose are:

* Should java.sql provide an implementation of TemplateProcessor
* Where should that implementation live?
* What, exactly, should be the translation strategy.

The reason I think this isn't an obvious yes and ask that last question is
this.

Say this is some user's code.

try (var conn = ds.getConnection();
     var stmt = conn.prepareStatement("""
         SELECT user.name
         WHERE user.height > ? AND user.width < ?
         """)) {
    stmt.setInt(1, height);
    stmt.setInt(2, width);
    var rs = stmt.executeQuery();
    process(rs);
}

The transliteration to string templates would be something like

try (var conn = ds.getConnection();
     var stmt = conn."""
         SELECT user.name
         WHERE user.height > \{height} AND user.width < \{width}
         """)) {
    var rs = stmt.executeQuery();
    process(rs);
}

Whether Connection implements TemplateProcessor directly or its something
that you wrap a connection with is somewhat immaterial.

How should we handle "partial templating"?

try (var conn = ds.getConnection();
     var stmt = conn."""
         SELECT user.name
         WHERE user.height > ? AND user.width < \{width}
         """)) {
    var rs = stmt.executeQuery();
    rs.setInt(1, height);
    process(rs);
}

Or

try (var conn = ds.getConnection();
     var stmt = conn."""
         SELECT user.name
         WHERE user.height > \{height} AND user.width < ?
         """)) {
    var rs = stmt.executeQuery();
    rs.setInt(2, width);
    process(rs);
}

Is replacing every substitution with ? and calling set* is enough? How
could it be known, without parsing the specific sql dialect, what index to
use for the parameter?

try (var conn = ds.getConnection();
     var stmt = conn."""
         SELECT user.name
         WHERE user.name <> '???'
             AND user.height > ?
             AND user.width < \{width}
         """)) {
    var rs = stmt.executeQuery();
    rs.setInt(1, height);
    process(rs);
}

(this seems more library design than language design, hence I sent it here.
I can forward to amber-dev if that is better)

Reply via email to