2
* $Id: CreateTableParser.java 86 2007-10-29 11:29:53Z fordfrog $
4
package cz.startnet.utils.pgdiff.parsers;
6
import cz.startnet.utils.pgdiff.schema.PgColumn;
7
import cz.startnet.utils.pgdiff.schema.PgConstraint;
8
import cz.startnet.utils.pgdiff.schema.PgDatabase;
9
import cz.startnet.utils.pgdiff.schema.PgSchema;
10
import cz.startnet.utils.pgdiff.schema.PgTable;
12
import java.util.regex.Matcher;
13
import java.util.regex.Pattern;
17
* Parses CREATE TABLE commands.
20
* @version $Id: CreateTableParser.java 86 2007-10-29 11:29:53Z fordfrog $
22
public class CreateTableParser {
24
* Pattern for getting table name from CREATE TABLE.
26
private static final Pattern PATTERN_TABLE_NAME =
28
"CREATE[\\s]+TABLE[\\s]+\"?([^\\s\"]+)\"?[\\s]*\\(",
29
Pattern.CASE_INSENSITIVE);
32
* Pattern for getting CONSTRAINT parameters.
34
private static final Pattern PATTERN_CONSTRAINT =
36
"CONSTRAINT[\\s]+\"?([^\\s\"]+)\"?[\\s]+(.*)",
37
Pattern.CASE_INSENSITIVE);
40
* Pattern for parsing column definition.
42
private static final Pattern PATTERN_COLUMN =
44
"\"?([^\\s\"]+)\"?[\\s]+(.*)",
45
Pattern.CASE_INSENSITIVE);
48
* Pattern for parsing INHERITS.
50
private static final Pattern PATTERN_INHERITS =
51
Pattern.compile("INHERITS[\\s]+([^;]+)[;]?", Pattern.CASE_INSENSITIVE);
54
* Pattern for checking whether string contains WITH OIDS string.
56
private static final Pattern PATTERN_WITH_OIDS =
57
Pattern.compile(".*WITH[\\s]+OIDS.*", Pattern.CASE_INSENSITIVE);
60
* Pattern for checking whether string contains WITHOUT OIDS
63
private static final Pattern PATTERN_WITHOUT_OIDS =
64
Pattern.compile(".*WITHOUT[\\s]+OIDS.*", Pattern.CASE_INSENSITIVE);
67
* Creates a new instance of CreateTableParser.
69
private CreateTableParser() {
74
* Parses CREATE TABLE command.
76
* @param database database
77
* @param command CREATE TABLE command
79
* @throws ParserException Thrown if problem occured while parsing DDL.
80
* @throws RuntimeException DOCUMENT ME!
82
public static void parse(final PgDatabase database, final String command) {
83
String line = command;
84
final Matcher matcher = PATTERN_TABLE_NAME.matcher(line);
85
final String tableName;
88
tableName = matcher.group(1).trim();
90
ParserUtils.removeSubString(
95
throw new ParserException(
96
ParserException.CANNOT_PARSE_COMMAND + line);
99
final PgTable table = new PgTable(ParserUtils.getObjectName(tableName));
100
final String schemaName =
101
ParserUtils.getSchemaName(tableName, database);
102
final PgSchema schema = database.getSchema(schemaName);
104
if (schema == null) {
105
throw new RuntimeException(
106
"Cannot get schema '" + schemaName
107
+ "'. Need to issue 'CREATE SCHEMA " + schemaName
108
+ ";' before 'CREATE TABLE " + tableName + "...;'?");
111
schema.addTable(table);
112
parseRows(table, ParserUtils.removeLastSemicolon(line));
116
* Parses COLUMN and other DDL within '(' and ')' in CREATE TABLE
119
* @param table table being parsed
120
* @param line line being processed
122
* @throws ParserException Thrown if problem occured while parsing DDL.
124
private static void parseColumnDefs(final PgTable table, final String line) {
125
if (line.length() > 0) {
126
boolean matched = false;
127
Matcher matcher = PATTERN_CONSTRAINT.matcher(line.trim());
129
if (matcher.matches()) {
130
final PgConstraint constraint =
131
new PgConstraint(matcher.group(1).trim());
132
table.addConstraint(constraint);
133
constraint.setDefinition(matcher.group(2).trim());
134
constraint.setTableName(table.getName());
139
matcher = PATTERN_COLUMN.matcher(line);
141
if (matcher.matches()) {
142
final PgColumn column =
143
new PgColumn(matcher.group(1).trim());
144
table.addColumn(column);
145
column.parseDefinition(matcher.group(2).trim());
151
throw new ParserException(
152
ParserException.CANNOT_PARSE_COMMAND + line);
158
* Parses definitions that are present after column definition is
161
* @param table table being parsed
162
* @param commands commands being processed
164
* @return true if the command was the last command for CREATE TABLE,
167
private static String parsePostColumns(
169
final String commands) {
170
String line = commands;
171
final Matcher matcher = PATTERN_INHERITS.matcher(line);
173
if (matcher.find()) {
174
table.setInherits(matcher.group(1).trim());
176
ParserUtils.removeSubString(
182
if (PATTERN_WITH_OIDS.matcher(line).matches()) {
183
table.setWithOIDS(true);
184
line = ParserUtils.removeSubString(line, "WITH OIDS");
185
} else if (PATTERN_WITHOUT_OIDS.matcher(line).matches()) {
186
table.setWithOIDS(false);
187
line = ParserUtils.removeSubString(line, "WITHOUT OIDS");
194
* Parses all rows in CREATE TABLE command.
196
* @param table table being parsed
197
* @param command command without 'CREATE SEQUENCE ... (' string
199
* @throws ParserException Thrown if problem occured with parsing of DDL.
201
private static void parseRows(final PgTable table, final String command) {
202
String line = command;
203
boolean postColumns = false;
206
while (line.length() > 0) {
207
final int commandEnd = ParserUtils.getCommandEnd(line, 0);
208
final String subCommand = line.substring(0, commandEnd).trim();
211
line = parsePostColumns(table, subCommand);
214
} else if (line.charAt(commandEnd) == ')') {
218
parseColumnDefs(table, subCommand);
220
(commandEnd >= line.length()) ? ""
224
} catch (RuntimeException ex) {
225
throw new ParserException(
226
ParserException.CANNOT_PARSE_COMMAND + "CREATE TABLE "
227
+ table.getName() + " ( " + command,
233
if (line.length() > 0) {
234
throw new ParserException(
235
"Cannot parse CREATE TABLE '" + table.getName()
236
+ "' - do not know how to parse '" + line + "'");