Как создать GString из строки без ${str} в Groovy

У меня есть переменная String из Java (например, str), которая хранит какое-то выражение GString, скажем, "SELECT ${path} path FROM dual", это абсолютно динамическая строка из пользовательского ввода, я не могу знать, сколько там будет ${}.

И я не хочу использовать его в sql.rows() с оценкой ${path} по текущей привязке с использованием PreparedStatement.

Проблема в следующем:

  1. Если я каким-то образом не преобразую str в GString, он выдаст SQLException, потому что без PreparedStatement нам нужно использовать кавычки вокруг '${path}'. Но это небезопасно, и Groovy генерирует предупреждения (о том, что мы должны использовать PreparedStatement и убрать кавычки).
  2. Если я преобразую str в GString таким образом: sql.rows("${str}"), то Groovy будет использовать совершенно неправильный подготовленный оператор, содержащий только "?", конечно, это не сработает, мне нужен оператор: "SELECT ? path FROM dual".

Вопрос в том, как мы можем получить GString из String, не обернув его "${}"? Или как мы можем оценить только первый уровень GString (только str, а не path)? Или как решить эту проблему другим способом?

Спасибо.


person marshall    schedule 19.12.2014    source источник
comment
множество примеров здесь: jira.codehaus.org/browse/GROOVY-2505; но не забудьте дезинфицировать запросы, иначе вы получите SQL-инъекцию   -  person cfrick    schedule 19.12.2014
comment
@cfrick, этот (не оценочный) пример не работает в моем случае, он нарушает как минимум один пункт в моей проблеме. Примеры eval не работают, потому что в моей строке есть символы ',' и eval выдает исключение.   -  person marshall    schedule 19.12.2014
comment
Можете ли вы привести пример строки, которая не может быть оценена, и как должна выглядеть окончательная строка GString?   -  person blackdrag    schedule 19.12.2014
comment
@blackdrag, не удается выполнить оценку: "SELECT '123' test\n, ${path} path FROM dual", окончательная GString должна выглядеть так: "SELECT '123' test\n, ${path} path FROM dual" (точно так же, как String, мне нужно преобразовать ее без каких-либо изменений для использования в sql.rows (и без оценки ${path}, конечно, потому что мне нужно использовать auto sql.rows механика подготовленного заявления).   -  person marshall    schedule 21.12.2014
comment
и почему там не работает def gstring = Eval.me(/str/)?, я не вижу причин, по которым запятая должна приводить к проблеме, если только вы не оцениваете напрямую. Но тогда это будет Eval.me(str)   -  person blackdrag    schedule 22.12.2014
comment
@blackdrag, потому что Eval.me(/"str"/) будет оценивать только "str", а Eval.me(str) попытается оценить все слова str (даже SELECT и т. д.), и если он содержит ,, то groovy выдаст groovy: 1: unexpected token: ,. Можете ли вы просто опубликовать проверенный код, который начинается с String str = 'SELECT '123' test\n, ${path} path FROM dual'; и заканчивается на sql.rows(GSTRING_FROM_STR)? ' заключает в кавычки String, это важно.   -  person marshall    schedule 26.12.2014


Ответы (1)


согласно информации, я предлагаю следующее половинчатое решение:

def gsring = Eval.me('"'+str.replaceAll("\"","\\"")+'"')

он заменит все двойные кавычки экранированными кавычками, а затем оценит все это как GString. Это должно работать, если в частях значения не используются двойные кавычки. Затем gstring можно использовать для Sql. Это решение в основном совпадает с первыми двумя примерами оценки в GROOVY-2505. Важный момент, упущенный маршалом, очевидно, заключается в том, что нам нужно заключить содержимое строки в кавычки. /"str"/, конечно же, просто создаст строку "str". Например, если str — это SELECT, то получится «str». Нам нужно '"'+str+'"', что даст "SELECT". Это должны быть двойные кавычки, потому что мы хотим, чтобы вызов Eval оценивал части gstring, что недоступно в строке с одинарными кавычками.

person blackdrag    schedule 27.12.2014