01: /*
02: * PostgresDDLFilter.java
03: *
04: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
05: *
06: * Copyright 2002-2008, Thomas Kellerer
07: * No part of this code maybe reused without the permission of the author
08: *
09: * To contact the author please send an email to: support@sql-workbench.net
10: *
11: */
12: package workbench.db.postgres;
13:
14: import workbench.db.DDLFilter;
15: import workbench.sql.formatter.SQLLexer;
16: import workbench.sql.formatter.SQLToken;
17:
18: /**
19: * @author support@sql-workbench.net
20: */
21: public class PostgresDDLFilter implements DDLFilter {
22:
23: public PostgresDDLFilter() {
24: }
25:
26: /**
27: * PG's documentation shows CREATE FUNCTION samples that use
28: * a "dollar quoting" to avoid the nested single quotes
29: * e.g. http://www.postgresql.org/docs/8.0/static/plpgsql-structure.html
30: *
31: * But the JDBC driver does not (yet) understand this - this
32: * seems to be only implemented in the psql command line tool.
33: *
34: * So we'll replace the "dollar quotes" with regular single quotes
35: * Every single quote inside the function body will be replaced with
36: * two single quotes to properly "escape" them.
37: *
38: * This does not mimic psql's quoting completely as basically
39: * you can also use some descriptive words between the dollar signs, such
40: * as $body$ which will not be detected by this method.
41: */
42: public String adjustDDL(String sql) {
43: int bodyStart = -1;
44: int bodyEnd = -1;
45:
46: SQLLexer lexer = new SQLLexer(sql);
47:
48: try {
49: SQLToken t = lexer.getNextToken(false, false);
50: if (t != null) {
51: String v = t.getContents();
52: if (!"CREATE".equals(v)
53: && !"CREATE OR REPLACE".equals(v))
54: return sql;
55: }
56:
57: while (t != null) {
58: String value = t.getContents();
59: if ("$$".equals(value)) {
60: if (bodyStart == -1)
61: bodyStart = t.getCharEnd();
62: else
63: bodyEnd = t.getCharBegin();
64: }
65: t = lexer.getNextToken(false, false);
66: }
67: } catch (Exception e) {
68:
69: }
70:
71: if (bodyStart == -1 || bodyEnd == -1)
72: return sql;
73:
74: String body = sql.substring(bodyStart, bodyEnd);
75: body = body.replaceAll("'", "''");
76:
77: StringBuilder newSql = new StringBuilder(sql.length() + 10);
78: newSql.append(sql.substring(0, bodyStart - 2));
79: newSql.append(" '");
80: newSql.append(body);
81: newSql.append("' ");
82: newSql.append(sql.substring(bodyEnd + 2));
83: return newSql.toString();
84: }
85:
86: }
|