├── src ├── test │ ├── resources │ │ ├── test.txt │ │ ├── example.field │ │ ├── import1.sql │ │ ├── standard.sql │ │ ├── oracle2.sql │ │ ├── mysql1.sql │ │ ├── oracle1.sql │ │ ├── postgres.sql │ │ ├── mysql_mysqldump.sql │ │ ├── postgres_pg_dump.sql │ │ ├── mysql_mysqlworkbench.sql │ │ ├── postgres.backup │ │ └── oracle_sqldeveloper.sql │ └── java │ │ └── com │ │ └── restlet │ │ └── sqlimport │ │ ├── util │ │ └── UtilTest.java │ │ ├── parser │ │ └── GetSqlQueryTest.java │ │ ├── validation │ │ └── DatabaseValidatorTest.java │ │ ├── MainProcessTest.java │ │ ├── type │ │ └── TypeConverterTest.java │ │ └── export │ │ ├── ExportToPivotFormatTest.java │ │ └── DatabaseToResdefTest.java └── main │ ├── java │ └── com │ │ └── restlet │ │ └── sqlimport │ │ ├── report │ │ ├── ReportStatus.java │ │ ├── ReportLineStatus.java │ │ ├── ReportLine.java │ │ ├── Report.java │ │ └── ReportManager.java │ │ ├── model │ │ ├── sql │ │ │ ├── PrimaryKey.java │ │ │ ├── Database.java │ │ │ ├── ForeignKey.java │ │ │ ├── Column.java │ │ │ └── Table.java │ │ └── resdef │ │ │ ├── Resdef.java │ │ │ ├── Entity.java │ │ │ └── Field.java │ │ ├── export │ │ ├── ResdefToJson.java │ │ └── DatabaseToResdef.java │ │ ├── validation │ │ └── DatabaseValidator.java │ │ ├── Main.java │ │ ├── MainProcess.java │ │ ├── parser │ │ ├── SqlImport.java │ │ ├── AlterTableParseListener.java │ │ ├── GetSqlQuery.java │ │ └── CreateTableParseListener.java │ │ ├── util │ │ └── Util.java │ │ └── type │ │ └── TypeConverter.java │ └── antlr4 │ └── com │ └── restlet │ └── sqlimport │ └── parser │ └── Sql.g4.old ├── .gitignore ├── README.md ├── pom.xml └── samples ├── mysql.sql └── postgres.backup /src/test/resources/test.txt: -------------------------------------------------------------------------------- 1 | Ligne 1 2 | Ligne 2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swo 2 | *.swp 3 | /target 4 | /.settings 5 | /.classpath 6 | /.project 7 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/report/ReportStatus.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.report; 2 | 3 | /** 4 | * Global status. 5 | */ 6 | public enum ReportStatus { 7 | 8 | /** The content of the pivot file generated successfully */ 9 | SUCCESS, 10 | 11 | /** Empty database */ 12 | EMPTY_DATABASE, 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/example.field: -------------------------------------------------------------------------------- 1 | "Demo Field" 2 | "Golden Crown" scores 50 points 3 | "Iron Sword" scores 20 points 4 | "Broken Crockery" scores 1 points 5 | "Golden Sword" is buried at 4,1 6 | "Iron Sword" is buried at 2,3 7 | "Broken Crockery" is buried at 3,2 8 | "Broken Crockery" is buried at 1,4 9 | "Broken Crockery" is buried at 0,4 10 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/sql/PrimaryKey.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.sql; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Primary key. 8 | */ 9 | public class PrimaryKey { 10 | 11 | /** 12 | * Column names. 13 | */ 14 | List columnNames = new ArrayList(); 15 | 16 | public List getColumnNames() { 17 | return columnNames; 18 | } 19 | 20 | public void setColumnNames(final List columnNames) { 21 | this.columnNames = columnNames; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/import1.sql: -------------------------------------------------------------------------------- 1 | SELECT log AS x FROM t1 2 | GROUP BY x 3 | HAVING count(*) >= 4 4 | ORDER BY max(n) + 0 5 | 6 | CREATE TABLE films ( 7 | code char(5) CONSTRAINT firstkey PRIMARY KEY, 8 | title varchar(40) NOT NULL, 9 | did integer NOT NULL, 10 | date_prod date, 11 | kind varchar(10), 12 | len interval hour to minute 13 | ); 14 | 15 | CREATE TABLE distributors ( 16 | did integer PRIMARY KEY DEFAULT nextval('serial'), 17 | name varchar(40) NOT NULL CHECK (name <> '') 18 | ); -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/sql/Database.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.sql; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Database 8 | */ 9 | public class Database { 10 | 11 | /** 12 | * Tables 13 | */ 14 | private List tables = new ArrayList
(); 15 | 16 | public Table getTableForName(final String tableName) { 17 | for(final Table table : tables) { 18 | if(table.getName().equalsIgnoreCase(tableName)) { 19 | return table; 20 | } 21 | } 22 | return null; 23 | } 24 | 25 | public List
getTables() { 26 | return tables; 27 | } 28 | 29 | public void setTables(final List
tables) { 30 | this.tables = tables; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ANTLR-SQLPARSER 2 | =============== 3 | 4 | Main 5 | ==== 6 | 7 | Run : ```java com.restlet.sqlimport.Main "[input file]" "[output file]"``` 8 | , with : 9 | - [input file] : file path to the SQL input file 10 | - [output file] : file path to the output file 11 | 12 | Tests 13 | ===== 14 | 15 | Run tests : "SqlImportTest.java" 16 | 17 | SQL scripts for databases tests : 18 | - mysql.sql 19 | - oracle1.sql 20 | - oracle2.sql 21 | - postgres.sql 22 | - standard.sql 23 | 24 | Source code 25 | =========== 26 | 27 | - grammar : src/main/antlr4/com/restlet/sqlimport/parser/Sql.g4 28 | - Main class : com.restlet.sqlimport.Main 29 | - Tests : 30 | - Java test : src/test/java/SqlImportTest.java 31 | - SQL file : src/test/resources/import1.sql 32 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/report/ReportLineStatus.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.report; 2 | 3 | /** 4 | * Status of the import. 5 | */ 6 | public enum ReportLineStatus { 7 | 8 | /** Successful import */ 9 | PARSED, 10 | 11 | /** SQL query filtered : not a CREATE TABLE or a ALTER TABLE */ 12 | IGNORED, 13 | 14 | /** SQL query not filtered - it is a temporary status : the query will be parsed by the parser */ 15 | TO_PARSE, 16 | 17 | /** Error during parsing */ 18 | PARSING_ERROR, 19 | 20 | /** Unknown SQL type */ 21 | UNKNOWN_SQL_TYPE, 22 | 23 | /** More than one column in the primary key */ 24 | PRIMARY_KEY_MORE_THAN_ONE_COLUMN, 25 | 26 | /** More than one column in the foreign key */ 27 | FOREIGN_KEY_MORE_THAN_ONE_COLUMN, 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/resources/standard.sql: -------------------------------------------------------------------------------- 1 | 2 | CREATE TABLE table3 3 | ( 4 | id INTEGER PRIMARY KEY NOT NULL, 5 | nom VARCHAR(100) 6 | ); 7 | 8 | CREATE TABLE table2 9 | ( 10 | id INTEGER PRIMARY KEY NOT NULL, 11 | nom VARCHAR(100), 12 | id_table3 INTEGER, 13 | nom_table3 VARCHAR(100) 14 | ); 15 | 16 | CREATE TABLE table1 17 | ( 18 | id INTEGER PRIMARY KEY NOT NULL, 19 | nom VARCHAR(100), 20 | dt DATE NOT NULL, 21 | num INTEGER DEFAULT 1, 22 | id_table2 INTEGER REFERENCES table2(id), 23 | id_table3 INTEGER, 24 | FOREIGN KEY(id_table3) 25 | REFERENCES table3(id) ON DELETE CASCADE 26 | ); 27 | 28 | ALTER TABLE table3 29 | ADD CONSTRAINT u_table3 30 | UNIQUE (id, nom); 31 | 32 | ALTER TABLE table2 33 | ADD CONSTRAINT fk_table2_table3 34 | FOREIGN KEY (id_table3, nom_table3) 35 | REFERENCES table3(id, nom) 36 | ON UPDATE CASCADE 37 | ON DELETE RESTRICT; -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/resdef/Resdef.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.resdef; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.annotation.JsonInclude; 7 | 8 | /** 9 | * Root of the Resdef model to describe the entity stores. 10 | */ 11 | @JsonInclude(JsonInclude.Include.NON_NULL) 12 | public class Resdef { 13 | 14 | private List entities = new ArrayList(); 15 | 16 | public Entity getEntityForName(final String name) { 17 | for(final Entity entity : entities) { 18 | if(entity.getName().equalsIgnoreCase(name)) { 19 | return entity; 20 | } 21 | } 22 | return null; 23 | } 24 | 25 | public List getEntities() { 26 | return entities; 27 | } 28 | 29 | public void setEntities(final List entities) { 30 | this.entities = entities; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/resdef/Entity.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.resdef; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Entity 8 | */ 9 | public class Entity { 10 | 11 | private String name; 12 | private String pkPolicy; 13 | private List fields = new ArrayList(); 14 | 15 | public Field getFieldForName(final String name) { 16 | for(final Field field : fields) { 17 | if(field.getName().equalsIgnoreCase(name)) { 18 | return field; 19 | } 20 | } 21 | return null; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | public void setName(final String name) { 28 | this.name = name; 29 | } 30 | public List getFields() { 31 | return fields; 32 | } 33 | public void setFields(final List fields) { 34 | this.fields = fields; 35 | } 36 | public String getPkPolicy() { 37 | return pkPolicy; 38 | } 39 | public void setPkPolicy(final String pkPolicy) { 40 | this.pkPolicy = pkPolicy; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/util/UtilTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.util; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | 8 | public class UtilTest { 9 | 10 | private Util util = new Util(); 11 | 12 | @Test 13 | public void testUnformatSql() { 14 | assertEquals(null, util.unformatSqlName(null)); 15 | assertEquals("", util.unformatSqlName("")); 16 | // escape character : " 17 | assertEquals("\"", util.unformatSqlName("\"")); 18 | assertEquals("", util.unformatSqlName("\"\"")); 19 | assertEquals("table", util.unformatSqlName("table")); 20 | assertEquals("table", util.unformatSqlName("\"table\"")); 21 | assertEquals("\"table", util.unformatSqlName("\"table")); 22 | // escape character : ` 23 | assertEquals("`", util.unformatSqlName("`")); 24 | assertEquals("", util.unformatSqlName("``")); 25 | assertEquals("table", util.unformatSqlName("table")); 26 | assertEquals("table", util.unformatSqlName("`table`")); 27 | assertEquals("`table", util.unformatSqlName("`table")); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/export/ResdefToJson.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.export; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import com.fasterxml.jackson.annotation.JsonInclude.Include; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import com.restlet.sqlimport.model.resdef.Resdef; 10 | 11 | /** 12 | * Serialize Resdef to JSON. 13 | */ 14 | public class ResdefToJson { 15 | 16 | /** 17 | * Convert Resdef to JSON. 18 | * @param resdef Resdef 19 | * @return Json content 20 | */ 21 | public String resdefToJson(final Resdef resdef) { 22 | final ObjectMapper objectMapper = new ObjectMapper(); 23 | 24 | // Indent JSON 25 | //objectMapper.enable(SerializationFeature.INDENT_OUTPUT); 26 | 27 | // Escape null entries 28 | objectMapper.setSerializationInclusion(Include.NON_NULL); 29 | 30 | final OutputStream out = new ByteArrayOutputStream(); 31 | try { 32 | objectMapper.writeValue(out, resdef.getEntities()); 33 | } catch (final IOException e) { 34 | throw new RuntimeException(e); 35 | } 36 | return out.toString(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/resdef/Field.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.resdef; 2 | 3 | /** 4 | * Entity field 5 | */ 6 | public class Field { 7 | 8 | private String name; 9 | private String type; 10 | private Boolean isPrimaryKey; 11 | private Boolean nullable; 12 | private String defaultValue; 13 | private Integer minOccurs; 14 | private String maxOccurs; 15 | public String getName() { 16 | return name; 17 | } 18 | public void setName(final String name) { 19 | this.name = name; 20 | } 21 | public String getType() { 22 | return type; 23 | } 24 | public void setType(final String type) { 25 | this.type = type; 26 | } 27 | public Boolean getIsPrimaryKey() { 28 | return isPrimaryKey; 29 | } 30 | public void setIsPrimaryKey(final Boolean isPrimaryKey) { 31 | this.isPrimaryKey = isPrimaryKey; 32 | } 33 | public Boolean getNullable() { 34 | return nullable; 35 | } 36 | public void setNullable(final Boolean nullable) { 37 | this.nullable = nullable; 38 | } 39 | public String getDefaultValue() { 40 | return defaultValue; 41 | } 42 | public void setDefaultValue(final String defaultValue) { 43 | this.defaultValue = defaultValue; 44 | } 45 | public Integer getMinOccurs() { 46 | return minOccurs; 47 | } 48 | public void setMinOccurs(final Integer minOccurs) { 49 | this.minOccurs = minOccurs; 50 | } 51 | public String getMaxOccurs() { 52 | return maxOccurs; 53 | } 54 | public void setMaxOccurs(final String maxOccurs) { 55 | this.maxOccurs = maxOccurs; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/sql/ForeignKey.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.sql; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Foreing key 8 | */ 9 | public class ForeignKey { 10 | 11 | /** 12 | * Name of columns in the origin table 13 | */ 14 | private List columnNameOrigins = new ArrayList(); 15 | /** 16 | * Name of columns in the foreign table 17 | */ 18 | private List columnNameTargets = new ArrayList(); 19 | /** 20 | * Name of the origin table 21 | */ 22 | private String tableNameOrigin; 23 | /** 24 | * Name of the foreign table 25 | */ 26 | private String tableNameTarget; 27 | 28 | public List getColumnNameOrigins() { 29 | return columnNameOrigins; 30 | } 31 | public void setColumnNameOrigins(final List columnNameOrigins) { 32 | this.columnNameOrigins = columnNameOrigins; 33 | } 34 | public List getColumnNameTargets() { 35 | return columnNameTargets; 36 | } 37 | public void setColumnNameTargets(final List columnNameTargets) { 38 | this.columnNameTargets = columnNameTargets; 39 | } 40 | public String getTableNameOrigin() { 41 | return tableNameOrigin; 42 | } 43 | public void setTableNameOrigin(final String tableNameOrigin) { 44 | this.tableNameOrigin = tableNameOrigin; 45 | } 46 | public String getTableNameTarget() { 47 | return tableNameTarget; 48 | } 49 | public void setTableNameTarget(final String tableNameTarget) { 50 | this.tableNameTarget = tableNameTarget; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/sql/Column.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.sql; 2 | 3 | /** 4 | * Table column 5 | */ 6 | public class Column { 7 | 8 | /** 9 | * name 10 | */ 11 | private String name; 12 | /** 13 | * type 14 | */ 15 | private String type; 16 | /** 17 | * Length 18 | */ 19 | private String length; 20 | /** 21 | * Indicates if the column must be not null 22 | */ 23 | private Boolean isNotNull = false; 24 | /** 25 | * Converted type. 26 | */ 27 | private String convertedType; 28 | /** 29 | * Default value. 30 | */ 31 | private String defaultValue; 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public void setName(final String name) { 38 | this.name = name; 39 | } 40 | 41 | public String getType() { 42 | return type; 43 | } 44 | 45 | public void setType(final String type) { 46 | this.type = type; 47 | } 48 | 49 | public String getLength() { 50 | return length; 51 | } 52 | 53 | public void setLength(final String length) { 54 | this.length = length; 55 | } 56 | 57 | public Boolean getIsNotNull() { 58 | return isNotNull; 59 | } 60 | 61 | public void setIsNotNull(final Boolean isNotNull) { 62 | this.isNotNull = isNotNull; 63 | } 64 | 65 | public String getConvertedType() { 66 | return convertedType; 67 | } 68 | 69 | public void setConvertedType(final String convertedType) { 70 | this.convertedType = convertedType; 71 | } 72 | 73 | public String getDefaultValue() { 74 | return defaultValue; 75 | } 76 | 77 | public void setDefaultValue(final String defaultValue) { 78 | this.defaultValue = defaultValue; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/test/resources/oracle2.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE employees_demo 2 | ( employee_id NUMBER(6) 3 | , first_name VARCHAR2(20) 4 | , last_name VARCHAR2(25) 5 | CONSTRAINT emp_last_name_nn_demo NOT NULL 6 | , email VARCHAR2(25) 7 | CONSTRAINT emp_email_nn_demo NOT NULL 8 | , phone_number VARCHAR2(20) 9 | , hire_date DATE DEFAULT SYSDATE 10 | CONSTRAINT emp_hire_date_nn_demo NOT NULL 11 | , job_id VARCHAR2(10) 12 | CONSTRAINT emp_job_nn_demo NOT NULL 13 | , salary NUMBER(8,2) 14 | CONSTRAINT emp_salary_nn_demo NOT NULL 15 | , commission_pct NUMBER(2,2) 16 | , manager_id NUMBER(6) 17 | , department_id NUMBER(4) 18 | , dn VARCHAR2(300) 19 | , CONSTRAINT emp_salary_min_demo 20 | CHECK (salary > 0) 21 | , CONSTRAINT emp_email_uk_demo 22 | UNIQUE (email) 23 | ) 24 | TABLESPACE example 25 | STORAGE (INITIAL 6144 26 | NEXT 6144 27 | MINEXTENTS 1 28 | MAXEXTENTS 5 ); 29 | 30 | 31 | SELECT log AS x FROM t1 32 | GROUP BY x 33 | HAVING count(*) >= 4 34 | ORDER BY max(n) + 0; 35 | 36 | CREATE TABLE films ( 37 | code char(5) CONSTRAINT firstkey PRIMARY KEY, 38 | title varchar(40) NOT NULL, 39 | did integer NOT NULL, 40 | date_prod date, 41 | kind varchar(10), 42 | len interval hour to minute 43 | ); 44 | 45 | CREATE TABLE distributors ( 46 | did integer PRIMARY KEY DEFAULT nextval('serial'), 47 | name varchar(40) NOT NULL CHECK (name <> '') 48 | ); -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/report/ReportLine.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.report; 2 | 3 | /** 4 | * Report line. 5 | */ 6 | public class ReportLine { 7 | 8 | /** 9 | * Message to display. 10 | */ 11 | private String message; 12 | /** 13 | * Query. 14 | */ 15 | private String query; 16 | /** 17 | * Status. 18 | */ 19 | private ReportLineStatus reportLineStatus; 20 | /** 21 | * Table. 22 | */ 23 | private String table; 24 | /** 25 | * Column. 26 | */ 27 | private String column; 28 | 29 | @Override 30 | public String toString() { 31 | final StringBuffer out = new StringBuffer(); 32 | if(reportLineStatus != null) { 33 | out.append("\n - status : ").append(reportLineStatus); 34 | } 35 | if(message != null) { 36 | out.append("\n - message : ").append(message); 37 | } 38 | if(query != null) { 39 | out.append("\n - query : ").append(query); 40 | } 41 | if(table != null) { 42 | out.append("\n - table : ").append(table); 43 | } 44 | if(column != null) { 45 | out.append("\n - column : ").append(column); 46 | } 47 | return out.toString(); 48 | } 49 | 50 | public String getMessage() { 51 | return message; 52 | } 53 | public void setMessage(final String message) { 54 | this.message = message; 55 | } 56 | public String getQuery() { 57 | return query; 58 | } 59 | public void setQuery(final String query) { 60 | this.query = query; 61 | } 62 | public ReportLineStatus getReportLineStatus() { 63 | return reportLineStatus; 64 | } 65 | public void setReportLineStatus(final ReportLineStatus reportStatus) { 66 | this.reportLineStatus = reportStatus; 67 | } 68 | public String getTable() { 69 | return table; 70 | } 71 | public void setTable(final String table) { 72 | this.table = table; 73 | } 74 | public String getColumn() { 75 | return column; 76 | } 77 | public void setColumn(final String column) { 78 | this.column = column; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/validation/DatabaseValidator.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.validation; 2 | 3 | import com.restlet.sqlimport.model.sql.Database; 4 | import com.restlet.sqlimport.model.sql.ForeignKey; 5 | import com.restlet.sqlimport.model.sql.Table; 6 | import com.restlet.sqlimport.report.Report; 7 | import com.restlet.sqlimport.report.ReportLine; 8 | import com.restlet.sqlimport.report.ReportLineStatus; 9 | 10 | /** 11 | * Validate database 12 | */ 13 | public class DatabaseValidator { 14 | 15 | /** 16 | * Report 17 | */ 18 | private final Report report; 19 | 20 | /** 21 | * Constructor 22 | * @param report Report (must not be null) 23 | */ 24 | public DatabaseValidator(final Report report) { 25 | this.report = report; 26 | } 27 | 28 | /** 29 | * Validate database 30 | * @param database Database 31 | */ 32 | public void validateDatabase(final Database database) { 33 | for(final Table table : database.getTables()) { 34 | validateTable(table); 35 | } 36 | } 37 | 38 | /** 39 | * Validate table and return true if the table is valid. 40 | * @param table Table 41 | * @return true if the table is valid 42 | */ 43 | public void validateTable(final Table table) { 44 | // primary key with only one column 45 | if(table.getPrimaryKey().getColumnNames().size() > 1) { 46 | final ReportLine reportLine = new ReportLine(); 47 | report.add(reportLine); 48 | reportLine.setReportLineStatus(ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN); 49 | reportLine.setTable(table.getName()); 50 | } 51 | 52 | // foreign key with only one column 53 | for(final ForeignKey foreignKey : table.getForeignKeys()) { 54 | if((foreignKey.getColumnNameOrigins().size() > 1) || (foreignKey.getColumnNameTargets().size() > 1)) { 55 | final ReportLine reportLine = new ReportLine(); 56 | report.add(reportLine); 57 | reportLine.setReportLineStatus(ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN); 58 | reportLine.setTable(table.getName()); 59 | } 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/resources/mysql1.sql: -------------------------------------------------------------------------------- 1 | 2 | ddd; 3 | 4 | create database test; 5 | use test; 6 | 7 | DROP table IF EXISTS Contact; 8 | DROP table IF EXISTS Company; 9 | 10 | CREATE TABLE Company ( 11 | id INT NOT NULL AUTO_INCREMENT, 12 | duns VARCHAR(9) UNIQUE, 13 | name VARCHAR(255), 14 | address VARCHAR(255), 15 | zip_code VARCHAR(5), 16 | company_creation Date, 17 | website VARCHAR(255), 18 | phone_number VARCHAR(255), 19 | city VARCHAR(255), 20 | PRIMARY KEY(id) 21 | ); 22 | 23 | CREATE TABLE Contact ( 24 | id VARCHAR(255), 25 | email VARCHAR (255) NOT NULL UNIQUE, 26 | age INT, 27 | name VARCHAR (255), 28 | firstname VARCHAR (255), 29 | company_id INT, 30 | PRIMARY KEY(id), 31 | FOREIGN KEY (company_id) REFERENCES Company(id) 32 | ); 33 | 34 | CREATE USER 'test'@'localhost' IDENTIFIED BY 'test'; 35 | GRANT ALL PRIVILEGES ON *.* TO 'test'@'localhost' WITH GRANT OPTION; 36 | FLUSH PRIVILEGES; 37 | 38 | 39 | CREATE TABLE table3 40 | ( 41 | id INTEGER PRIMARY KEY NOT NULL, 42 | nom VARCHAR(100) 43 | ); 44 | 45 | CREATE TABLE table2 46 | ( 47 | id INTEGER PRIMARY KEY NOT NULL, 48 | nom VARCHAR(100), 49 | id_table3 INTEGER, 50 | nom_table3 VARCHAR(100) 51 | ); 52 | 53 | CREATE TABLE `table1` ( 54 | `id` int(11) NOT NULL, 55 | `nom` varchar(100) DEFAULT NULL, 56 | `dt` date DEFAULT NULL, 57 | `num` int(11) DEFAULT NULL, 58 | `id_table2` int(11) DEFAULT NULL, 59 | `id_table3` int(11) DEFAULT NULL, 60 | PRIMARY KEY (`id`), 61 | KEY `id_table2` (`id_table2`), 62 | KEY `id_table3` (`id_table3`), 63 | CONSTRAINT `table1_ibfk_1` FOREIGN KEY (`id_table2`) REFERENCES `table2` (`id`), 64 | CONSTRAINT `table1_ibfk_2` FOREIGN KEY (`id_table3`) REFERENCES `table3` (`id`) ON DELETE CASCADE 65 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 66 | 67 | ALTER TABLE table3 68 | ADD CONSTRAINT u_table3 69 | UNIQUE (id, nom); 70 | 71 | ALTER TABLE table2 72 | ADD CONSTRAINT fk_table2_table3 73 | FOREIGN KEY (id_table3, nom_table3) 74 | REFERENCES table3(id, nom) 75 | ON UPDATE CASCADE 76 | ON DELETE RESTRICT; -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/model/sql/Table.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.model.sql; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Table 10 | */ 11 | public class Table { 12 | 13 | /** 14 | * name 15 | */ 16 | private String name; 17 | /** 18 | * Columns by names 19 | */ 20 | private Map columnByNames = new HashMap(); 21 | /** 22 | * Column which is the primary key 23 | */ 24 | private PrimaryKey primaryKey = new PrimaryKey(); 25 | /** 26 | * Foreign keys 27 | */ 28 | private List foreignKeys = new ArrayList(); 29 | 30 | /** 31 | * Get the foreign key which corresponding to the column. 32 | * @param column Column 33 | * @return Foreign key (null if not found) 34 | */ 35 | public ForeignKey getForeignKeyForColumnNameOrigin(final Column column) { 36 | for(final ForeignKey foreignKey : getForeignKeys()) { 37 | // We ignore foreign keys with more than one column 38 | if(foreignKey.getColumnNameOrigins().size() == 1) { 39 | for(final String columnNameOrigin : foreignKey.getColumnNameOrigins()) { 40 | if(column.getName().equals(columnNameOrigin)) { 41 | return foreignKey; 42 | } 43 | } 44 | } 45 | } 46 | return null; 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | public void setName(final String name) { 54 | this.name = name; 55 | } 56 | 57 | public Map getColumnByNames() { 58 | return columnByNames; 59 | } 60 | 61 | public void setColumnByNames(final Map columnByNames) { 62 | this.columnByNames = columnByNames; 63 | } 64 | 65 | public PrimaryKey getPrimaryKey() { 66 | return primaryKey; 67 | } 68 | 69 | public void setPrimaryKey(final PrimaryKey primaryKey) { 70 | this.primaryKey = primaryKey; 71 | } 72 | 73 | public List getForeignKeys() { 74 | return foreignKeys; 75 | } 76 | 77 | public void setForeignKeys(final List foreignKeys) { 78 | this.foreignKeys = foreignKeys; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/Main.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.OutputStream; 7 | 8 | import com.restlet.sqlimport.report.Report; 9 | import com.restlet.sqlimport.report.ReportManager; 10 | import com.restlet.sqlimport.util.Util; 11 | 12 | /** 13 | * Main class to parse SQL file and export to a file in the pivot format. 14 | */ 15 | public class Main { 16 | 17 | public static void main(final String[] args) throws FileNotFoundException { 18 | 19 | if(args.length != 2) { 20 | System.out.println("Please define these two arguments :"); 21 | System.out.println(" 1: input file name"); 22 | System.out.println(" 2: output file name"); 23 | System.exit(1); 24 | } 25 | 26 | final String input = args[0]; 27 | final String output = args[1]; 28 | 29 | final Util util = new Util(); 30 | 31 | InputStream in = null; 32 | OutputStream os = null; 33 | 34 | try { 35 | in = util.getInputStream(input); 36 | os = util.getOutputStream(output); 37 | 38 | final MainProcess mainProcess = new MainProcess(); 39 | 40 | final String inputContent = util.read(in); 41 | final String outputContent = mainProcess.process(inputContent); 42 | util.write(outputContent, os); 43 | 44 | final Report report = mainProcess.getReport(); 45 | 46 | final ReportManager reportManager = new ReportManager(); 47 | System.out.println(reportManager.toString(report)); 48 | System.out.println("\n\n==========================\n\n"); 49 | System.out.println(reportManager.toStringSchema(report)); 50 | 51 | System.exit(0); 52 | } 53 | catch (final Exception e) { 54 | System.err.println(e.getMessage()); 55 | System.err.println(e); 56 | System.exit(1); 57 | } 58 | finally { 59 | if(in != null) { 60 | try { 61 | in.close(); 62 | } catch (final IOException e) { 63 | System.err.println(e.getMessage()); 64 | System.err.println(e); 65 | } 66 | } 67 | if(os != null) { 68 | try { 69 | os.close(); 70 | } catch (final IOException e) { 71 | System.err.println(e.getMessage()); 72 | System.err.println(e); 73 | } 74 | } 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/MainProcess.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport; 2 | 3 | import com.restlet.sqlimport.export.DatabaseToResdef; 4 | import com.restlet.sqlimport.export.ResdefToJson; 5 | import com.restlet.sqlimport.model.resdef.Resdef; 6 | import com.restlet.sqlimport.model.sql.Database; 7 | import com.restlet.sqlimport.parser.SqlImport; 8 | import com.restlet.sqlimport.report.Report; 9 | import com.restlet.sqlimport.report.ReportStatus; 10 | import com.restlet.sqlimport.type.TypeConverter; 11 | import com.restlet.sqlimport.validation.DatabaseValidator; 12 | 13 | /** 14 | * Main manager for SQL import and export in the pivot format file 15 | */ 16 | public class MainProcess { 17 | 18 | /** 19 | * Report. 20 | */ 21 | private Report report = new Report(); 22 | 23 | /** 24 | * Main method 25 | */ 26 | public String process(final String sqlContent) { 27 | 28 | // Load SQL file, filter and parse SQL queries 29 | final SqlImport sqlImport = new SqlImport(report); 30 | final Database database = sqlImport.getDatabase(sqlContent); 31 | 32 | if((database == null) || database.getTables().isEmpty()) { 33 | // Empty database 34 | report.setReportStatus(ReportStatus.EMPTY_DATABASE); 35 | return null; 36 | } 37 | 38 | // Convert SQL types to Entity store types 39 | final TypeConverter typeConverter = new TypeConverter(report); 40 | typeConverter.convertTypeFromSQLToEntityStore(database); 41 | 42 | // Database schema validator 43 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 44 | databaseValidator.validateDatabase(database); 45 | 46 | // Convert to Resdef bean 47 | final DatabaseToResdef databaseToResdef = new DatabaseToResdef(); 48 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 49 | report.setResdef(resdef); 50 | 51 | // Export to JSON 52 | final ResdefToJson resdefToJson = new ResdefToJson(); 53 | final String json = resdefToJson.resdefToJson(resdef); 54 | report.setReportStatus(ReportStatus.SUCCESS); 55 | 56 | // Summary 57 | report.setNbCreatedEntity(database.getTables().size()); 58 | 59 | return json; 60 | } 61 | 62 | /** 63 | * Get report. 64 | * @return report 65 | */ 66 | public Report getReport() { 67 | return report; 68 | } 69 | 70 | public void setReport(final Report report) { 71 | this.report = report; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/test/resources/oracle1.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "SCHEMA"."PROPOSAL" ("ID_PROPOSAL" NUMBER(9,0), "ID_PRODUCT" VARCHAR2(50 BYTE), "CREATE_DATE" DATE, "COD_PROPOSAL_TYPE" VARCHAR2(50 BYTE), "LIBPROD" VARCHAR2(50 BYTE), "FLAG_EXP" NUMBER(1,0), "NB_HYP" NUMBER(9,0), "FLAG_AM" NUMBER(1,0), "FLAG_DURATION" NUMBER(1,0), "ID_PROPOSITION" VARCHAR2(50 BYTE), "MT_FINANCED" NUMBER(9,2), "NB_MONTH_" VARCHAR2(100 BYTE)) ; 2 | 3 | CREATE TABLE "SCHEMA"."CONTRACT" ("ID_CONTRACT" NUMBER(9,0), "NB_DURATION_IN_MONTHS" NUMBER(9,0), "TX" NUMBER(9,4), "MT_ORIG" NUMBER(9,2), "MT_MONTH" NUMBER(9,2), "NB_DURATION_MONTH" NUMBER(9,0), "TX_TA" NUMBER(9,4), "COD_PERIOD" VARCHAR2(50 BYTE), "ID_CATEGORY" NUMBER(9,0), "ID_TYPE_CONTRACT" NUMBER(9,0), "ID_PROPOSAL" NUMBER(9,0), "COD_RANK" NUMBER(1,0), "ID_PRODUCT" VARCHAR2(50 BYTE)) ; 4 | 5 | CREATE TABLE "SCHEMA"."CATEGORY" ("ID_CATEGORY" NUMBER(9,0), "COD_ACCOUNTING" VARCHAR2(50 BYTE), "LIB_CATEGORY" VARCHAR2(50 BYTE)) ; 6 | 7 | CREATE TABLE "SCHEMA"."TYPE_CONTRACT" ("ID_TYPE_CONTRACT" NUMBER(9,0), "COD_ACCOUNT" VARCHAR2(50 BYTE), "LIB_CONTRACT_OBJECT" VARCHAR2(520 BYTE)) ; 8 | 9 | ALTER TABLE "SCHEMA"."CONTRACT" ADD CONSTRAINT "PK_CONTRACT" PRIMARY KEY ("ID_CONTRACT") ENABLE; 10 | 11 | ALTER TABLE "SCHEMA"."CATEGORY" ADD CONSTRAINT "PK_CATEGORY" PRIMARY KEY ("ID_CATEGORY") ENABLE; 12 | 13 | ALTER TABLE "SCHEMA"."TYPE_CONTRACT" ADD CONSTRAINT "PK_TYPECONTRACT" PRIMARY KEY ("ID_TYPE_CONTRACT") ENABLE; 14 | 15 | ALTER TABLE "SCHEMA"."CONTRACT" MODIFY ("ID_CONTRACT" NOT NULL ENABLE); 16 | 17 | ALTER TABLE "SCHEMA"."CATEGORY" MODIFY ("ID_CATEGORY" NOT NULL ENABLE); 18 | 19 | ALTER TABLE "SCHEMA"."CATEGORY" MODIFY ("LIB_CATEGORY" NOT NULL ENABLE); 20 | 21 | ALTER TABLE "SCHEMA"."TYPE_CONTRACT" MODIFY ("ID_TYPE_CONTRACT" NOT NULL ENABLE); 22 | 23 | ALTER TABLE "SCHEMA"."TYPE_CONTRACT" MODIFY ("LIB_CONTRACT_OBJECT" NOT NULL ENABLE); 24 | 25 | ALTER TABLE "SCHEMA"."CONTRACT" ADD CONSTRAINT "FK_CONTRACT_PROPOSAL" FOREIGN KEY ("ID_PROPOSAL") REFERENCES "SCHEMA"."PROPOSAL" ("ID_PROPOSAL") ENABLE; 26 | 27 | ALTER TABLE "SCHEMA"."CONTRACT" ADD CONSTRAINT "FK_CONTRACT_CATEGORY" FOREIGN KEY ("ID_CATEGORY") REFERENCES "SCHEMA"."CATEGORY" ("ID_CATEGORY") ENABLE; 28 | 29 | ALTER TABLE "SCHEMA"."CONTRACT" ADD CONSTRAINT "FK_CONTRACT_TYPECONTRACT" FOREIGN KEY ("ID_TYPE_CONTRACT") REFERENCES "SCHEMA"."TYPE_CONTRACT" ("ID_TYPE_CONTRACT") ENABLE; 30 | 31 | CREATE SEQUENCE "SCHEMA"."CONTRACT_ID_CONTRACT_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 11006 NOCACHE NOORDER NOCYCLE ; 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.restlet.sqlparser 8 | antlr-sqlparser 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | 15 | org.antlr 16 | antlr4-maven-plugin 17 | 4.3 18 | 19 | 20 | antlr 21 | 22 | antlr4 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-resources-plugin 30 | 2.6 31 | 32 | UTF-8 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 3.1 39 | 40 | UTF-8 41 | 1.6 42 | 1.6 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.antlr 51 | antlr4-runtime 52 | 4.3 53 | 54 | 55 | org.json 56 | json 57 | 20140107 58 | 59 | 60 | com.fasterxml.jackson.core 61 | jackson-core 62 | 2.4.2 63 | 64 | 65 | com.fasterxml.jackson.core 66 | jackson-annotations 67 | 2.4.2 68 | 69 | 70 | com.fasterxml.jackson.core 71 | jackson-databind 72 | 2.4.2 73 | 74 | 75 | junit 76 | junit 77 | 4.10 78 | test 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/export/DatabaseToResdef.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.export; 2 | 3 | import com.restlet.sqlimport.model.resdef.Entity; 4 | import com.restlet.sqlimport.model.resdef.Field; 5 | import com.restlet.sqlimport.model.resdef.Resdef; 6 | import com.restlet.sqlimport.model.sql.Column; 7 | import com.restlet.sqlimport.model.sql.Database; 8 | import com.restlet.sqlimport.model.sql.ForeignKey; 9 | import com.restlet.sqlimport.model.sql.Table; 10 | 11 | /** 12 | * Transform Database schema to Resdef bean. 13 | */ 14 | public class DatabaseToResdef { 15 | 16 | /** 17 | * Get Resdef from database schema 18 | * @param database Database schema 19 | * @return Resdef 20 | */ 21 | public Resdef databaseToResdef(final Database database) { 22 | final Resdef resdef = new Resdef(); 23 | for(final Table table : database.getTables()) { 24 | final Entity entity = new Entity(); 25 | entity.setName(table.getName()); 26 | entity.setPkPolicy("user_generated_value"); 27 | // if there is no primary key or there is a primary key with more than one column in the table, 28 | // we define a new column named "id" which will be the unique primary key of the entity 29 | if(table.getPrimaryKey().getColumnNames().size() != 1) { 30 | final Field field = new Field(); 31 | field.setName("id"); 32 | field.setType("string"); 33 | field.setIsPrimaryKey(true); 34 | entity.getFields().add(field); 35 | } 36 | // columns 37 | for(final String columnName : table.getColumnByNames().keySet()) { 38 | final Column column = table.getColumnByNames().get(columnName); 39 | final Field field = new Field(); 40 | field.setName(column.getName()); 41 | // Foreign key 42 | final ForeignKey foreignKey = table.getForeignKeyForColumnNameOrigin(column); 43 | if(foreignKey == null) { 44 | // converted type 45 | if(column.getConvertedType() != null) { 46 | field.setType(column.getConvertedType()); 47 | } 48 | } else { 49 | // foreign key : type is in the name of the foreign table 50 | field.setType(foreignKey.getTableNameTarget()); 51 | // number of occurences for the relation 52 | field.setMinOccurs(0); 53 | field.setMaxOccurs("*"); 54 | } 55 | // primary key 56 | boolean isPrimaryKey = false; 57 | // define only primary key with only one column 58 | if(table.getPrimaryKey().getColumnNames().size() == 1) { 59 | for(final String columnNameInPrimaryKey : table.getPrimaryKey().getColumnNames()) { 60 | if(columnName.equals(columnNameInPrimaryKey)) { 61 | isPrimaryKey = true; 62 | } 63 | } 64 | } 65 | if(isPrimaryKey) { 66 | field.setIsPrimaryKey(true); 67 | } 68 | // nullable 69 | if((column.getIsNotNull() != null) && column.getIsNotNull()) { 70 | field.setNullable(false); 71 | } else { 72 | field.setNullable(true); 73 | } 74 | field.setDefaultValue(column.getDefaultValue()); 75 | entity.getFields().add(field); 76 | } 77 | resdef.getEntities().add(entity); 78 | } 79 | return resdef; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/parser/GetSqlQueryTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.parser; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileNotFoundException; 8 | import java.io.InputStream; 9 | import java.util.List; 10 | 11 | import org.junit.Test; 12 | 13 | import com.restlet.sqlimport.report.Report; 14 | import com.restlet.sqlimport.report.ReportLineStatus; 15 | import com.restlet.sqlimport.util.Util; 16 | 17 | 18 | public class GetSqlQueryTest { 19 | 20 | private Report report = new Report(); 21 | private GetSqlQuery getSqlQuery = new GetSqlQuery(report); 22 | private Util util = new Util(); 23 | 24 | @Test 25 | public void testRead_standard() throws FileNotFoundException { 26 | // Given 27 | final File file = util.getFileByClassPath("/standard.sql"); 28 | final InputStream in = new FileInputStream(file); 29 | final String sqlContent = util.read(in); 30 | 31 | // When 32 | final List lines = getSqlQuery.getSqlQuerys(sqlContent); 33 | 34 | // Then 35 | assertEquals(4, lines.size()); 36 | 37 | assertEquals(ReportLineStatus.TO_PARSE, report.getReportLineForQuery(lines.get(0)).getReportLineStatus()); 38 | assertEquals(ReportLineStatus.TO_PARSE, report.getReportLineForQuery(lines.get(1)).getReportLineStatus()); 39 | assertEquals(ReportLineStatus.TO_PARSE, report.getReportLineForQuery(lines.get(2)).getReportLineStatus()); 40 | 41 | } 42 | 43 | @Test 44 | public void testRead_mysql() throws FileNotFoundException { 45 | // Given 46 | final File file = util.getFileByClassPath("/mysql1.sql"); 47 | final InputStream in = new FileInputStream(file); 48 | final String sqlContent = util.read(in); 49 | 50 | // When 51 | final List lines = getSqlQuery.getSqlQuerys(sqlContent); 52 | 53 | // Then 54 | assertEquals(6, lines.size()); 55 | } 56 | 57 | @Test 58 | public void testRead_postgres() throws FileNotFoundException { 59 | // Given 60 | final File file = util.getFileByClassPath("/postgres.sql"); 61 | final InputStream in = new FileInputStream(file); 62 | final String sqlContent = util.read(in); 63 | 64 | // When 65 | final List lines = getSqlQuery.getSqlQuerys(sqlContent); 66 | 67 | // Then 68 | assertEquals(9, lines.size()); 69 | } 70 | 71 | @Test 72 | public void testRead_oracle1() throws FileNotFoundException { 73 | // Given 74 | final File file = util.getFileByClassPath("/oracle1.sql"); 75 | final InputStream in = new FileInputStream(file); 76 | final String sqlContent = util.read(in); 77 | 78 | // When 79 | final List lines = getSqlQuery.getSqlQuerys(sqlContent); 80 | 81 | // Then 82 | assertEquals(10, lines.size()); 83 | } 84 | 85 | @Test 86 | public void testRead_oracle2() throws FileNotFoundException { 87 | // Given 88 | final File file = util.getFileByClassPath("/oracle2.sql"); 89 | final InputStream in = new FileInputStream(file); 90 | final String sqlContent = util.read(in); 91 | 92 | // When 93 | final List lines = getSqlQuery.getSqlQuerys(sqlContent); 94 | 95 | // Then 96 | assertEquals(3, lines.size()); 97 | } 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/validation/DatabaseValidatorTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.validation; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | import com.restlet.sqlimport.model.sql.Database; 9 | import com.restlet.sqlimport.model.sql.ForeignKey; 10 | import com.restlet.sqlimport.model.sql.Table; 11 | import com.restlet.sqlimport.report.Report; 12 | import com.restlet.sqlimport.report.ReportLine; 13 | import com.restlet.sqlimport.report.ReportLineStatus; 14 | 15 | 16 | public class DatabaseValidatorTest { 17 | 18 | @Test 19 | public void testValidateTable_ok() { 20 | // Given 21 | final Report report = new Report(); 22 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 23 | 24 | final Database database = new Database(); 25 | final Table table = new Table(); 26 | database.getTables().add(table); 27 | 28 | // When 29 | databaseValidator.validateDatabase(database); 30 | 31 | // Then 32 | assertTrue(report.getReportLines().isEmpty()); 33 | } 34 | 35 | @Test 36 | public void testValidateTable_pk_with_one_column() { 37 | // Given 38 | final Report report = new Report(); 39 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 40 | 41 | final Database database = new Database(); 42 | final Table table = new Table(); 43 | database.getTables().add(table); 44 | table.getPrimaryKey().getColumnNames().add("c1"); 45 | 46 | // When 47 | databaseValidator.validateDatabase(database); 48 | 49 | // Then 50 | assertTrue(report.getReportLines().isEmpty()); 51 | } 52 | 53 | @Test 54 | public void testValidateTable_pk_with_two_columns() { 55 | // Given 56 | final Report report = new Report(); 57 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 58 | 59 | final Database database = new Database(); 60 | final Table table = new Table(); 61 | database.getTables().add(table); 62 | table.getPrimaryKey().getColumnNames().add("c1"); 63 | table.getPrimaryKey().getColumnNames().add("c2"); 64 | 65 | // When 66 | databaseValidator.validateDatabase(database); 67 | 68 | // Then 69 | assertEquals(1,report.getReportLines().size()); 70 | final ReportLine reportLine = report.getReportLines().get(0); 71 | assertEquals(ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN,reportLine.getReportLineStatus()); 72 | } 73 | 74 | @Test 75 | public void testValidateTable_fk_with_one_column() { 76 | // Given 77 | final Report report = new Report(); 78 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 79 | 80 | final Database database = new Database(); 81 | final Table table = new Table(); 82 | database.getTables().add(table); 83 | final ForeignKey foreignKey = new ForeignKey(); 84 | table.getForeignKeys().add(foreignKey); 85 | foreignKey.getColumnNameOrigins().add("c1"); 86 | foreignKey.getColumnNameTargets().add("c1"); 87 | 88 | // When 89 | databaseValidator.validateDatabase(database); 90 | 91 | // Then 92 | assertTrue(report.getReportLines().isEmpty()); 93 | } 94 | 95 | @Test 96 | public void testValidateTable_fk_with_two_columns() { 97 | // Given 98 | final Report report = new Report(); 99 | final DatabaseValidator databaseValidator = new DatabaseValidator(report); 100 | 101 | final Database database = new Database(); 102 | final Table table = new Table(); 103 | database.getTables().add(table); 104 | final ForeignKey foreignKey = new ForeignKey(); 105 | table.getForeignKeys().add(foreignKey); 106 | foreignKey.getColumnNameOrigins().add("c1"); 107 | foreignKey.getColumnNameOrigins().add("c2"); 108 | foreignKey.getColumnNameTargets().add("c1"); 109 | foreignKey.getColumnNameTargets().add("c2"); 110 | 111 | // When 112 | databaseValidator.validateDatabase(database); 113 | 114 | // Then 115 | assertEquals(1,report.getReportLines().size()); 116 | final ReportLine reportLine = report.getReportLines().get(0); 117 | assertEquals(ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN,reportLine.getReportLineStatus()); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/test/resources/postgres.sql: -------------------------------------------------------------------------------- 1 | CREATE SEQUENCE rank_id_seq; 2 | CREATE SEQUENCE rank_id_seq2; 3 | CREATE SEQUENCE id_article_keyword; 4 | CREATE SEQUENCE id_keyword; 5 | 6 | CREATE TABLE users ( 7 | email VARCHAR (100) PRIMARY KEY , 8 | name VARCHAR (255), 9 | password VARCHAR (255), 10 | isadmin BOOLEAN 11 | ); 12 | 13 | CREATE TABLE article ( 14 | id INTEGER PRIMARY KEY default nextval('rank_id_seq'), 15 | name varchar(100), 16 | url varchar(200) 17 | ) ; 18 | 19 | create table Comment ( 20 | id bigint not null, 21 | comment varchar(255), 22 | author varchar(100), 23 | constraint pk_Comment primary key (id)); 24 | 25 | CREATE TABLE Link ( 26 | id INTEGER PRIMARY KEY default nextval('rank_id_seq2'), 27 | Article1 INTEGER, 28 | Article2 INTEGER, 29 | Weight FLOAT 30 | ); 31 | 32 | CREATE TABLE keyword ( 33 | id INTEGER PRIMARY KEY default nextval('id_keyword'), 34 | name varchar(100) 35 | ); 36 | 37 | CREATE TABLE article_keyword( 38 | id INTEGER PRIMARY KEY default nextval('id_article_keyword'), 39 | article_id INTEGER references article(id), 40 | keyword_id INTEGER references keyword(id) 41 | ); 42 | 43 | INSERT into article (name,url) values 44 | ('tablette','tablette.jpg'), 45 | ('ordinateur','ordi.jpg'), 46 | ('table','table.jpg'), 47 | ('guitare','guitare.jpg') , 48 | ('retroprojecteur','retropro.jpg'), 49 | ('bouteille','bouteille.jpg'), 50 | ('goblet','goblet.jpg'), 51 | ('souris','souris.jpg'), 52 | ('barquettes','barquettes.jpg'), 53 | ('ecolier','ecolier.jpg'), 54 | ('ecran','ecran.jpg'); 55 | 56 | INSERT INTO users (email, name, password, isAdmin) values ('blondeau.gui@gmail.com', 'Guillaume Blondeau', 'test', true); 57 | 58 | INSERT INTO Link (Article1, Article2, Weight) values 59 | ((SELECT id FROM Article where name ='tablette' limit 1), (SELECT id FROM Article where name ='ordinateur' limit 1), 0.5), 60 | ((SELECT id FROM Article where name ='tablette' limit 1), (SELECT id FROM Article where name ='table' limit 1), 0.8), 61 | ((SELECT id FROM Article where name ='table' limit 1), (SELECT id FROM Article where name ='guitare' limit 1), 0.1); 62 | 63 | insert into keyword(name) values('delicieux'); 64 | insert into keyword(name) values('sexy'); 65 | 66 | insert into article_keyword(article_id, keyword_id) values( 67 | (SELECT id FROM Article where name ='tablette' limit 1), 68 | (SELECT id FROM Keyword where name = 'delicieux' limit 1) 69 | ); 70 | 71 | insert into article_keyword(article_id, keyword_id) values( 72 | (SELECT id FROM Article where name ='table' limit 1), 73 | (SELECT id FROM Keyword where name = 'sexy' limit 1) 74 | ); 75 | 76 | -- Table: table3 77 | 78 | -- DROP TABLE table3; 79 | 80 | CREATE TABLE table3 81 | ( 82 | id integer NOT NULL, 83 | nom character varying(100), 84 | CONSTRAINT table3_pkey PRIMARY KEY (id), 85 | CONSTRAINT u_table3 UNIQUE (id, nom) 86 | ) 87 | WITH ( 88 | OIDS=FALSE 89 | ); 90 | ALTER TABLE table3 91 | OWNER TO postgres; 92 | 93 | -- Table: table2 94 | 95 | -- DROP TABLE table2; 96 | 97 | CREATE TABLE table2 98 | ( 99 | id integer NOT NULL, 100 | nom character varying(100), 101 | id_table3 integer, 102 | nom_table3 character varying(100), 103 | CONSTRAINT table2_pkey PRIMARY KEY (id), 104 | CONSTRAINT fk_table2_table3 FOREIGN KEY (id_table3, nom_table3) 105 | REFERENCES table3 (id, nom) MATCH SIMPLE 106 | ON UPDATE CASCADE ON DELETE RESTRICT 107 | ) 108 | WITH ( 109 | OIDS=FALSE 110 | ); 111 | ALTER TABLE table2 112 | OWNER TO postgres; 113 | 114 | -- Table: table1 115 | 116 | -- DROP TABLE table1; 117 | 118 | CREATE TABLE table1 119 | ( 120 | id integer NOT NULL, 121 | nom character varying(100), 122 | dt date, 123 | num integer, 124 | id_table2 integer, 125 | id_table3 integer, 126 | CONSTRAINT table1_pkey PRIMARY KEY (id), 127 | CONSTRAINT table1_id_table2_fkey FOREIGN KEY (id_table2) 128 | REFERENCES table2 (id) MATCH SIMPLE 129 | ON UPDATE NO ACTION ON DELETE NO ACTION, 130 | CONSTRAINT table1_id_table3_fkey FOREIGN KEY (id_table3) 131 | REFERENCES table3 (id) MATCH SIMPLE 132 | ON UPDATE NO ACTION ON DELETE CASCADE 133 | ) 134 | WITH ( 135 | OIDS=FALSE 136 | ); 137 | ALTER TABLE table1 138 | OWNER TO postgres; 139 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/MainProcessTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport; 2 | 3 | 4 | import static org.junit.Assert.assertEquals; 5 | import static org.junit.Assert.assertNotNull; 6 | import static org.junit.Assert.assertNull; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.InputStream; 12 | 13 | import org.junit.Test; 14 | 15 | import com.restlet.sqlimport.report.Report; 16 | import com.restlet.sqlimport.report.ReportLineStatus; 17 | import com.restlet.sqlimport.report.ReportStatus; 18 | import com.restlet.sqlimport.util.Util; 19 | 20 | /** 21 | * Test : SQL import. 22 | */ 23 | public class MainProcessTest { 24 | 25 | private MainProcess mainProcess = new MainProcess(); 26 | private Util util = new Util(); 27 | 28 | @Test 29 | public void testGetDatabase_nofile() { 30 | 31 | // When 32 | final String out = mainProcess.process(null); 33 | 34 | // Then 35 | final Report report = mainProcess.getReport(); 36 | assertEquals(ReportStatus.EMPTY_DATABASE, report.getReportStatus()); 37 | assertNull(out); 38 | } 39 | 40 | @Test 41 | public void testGetDatabase_standard() throws FileNotFoundException { 42 | // Given 43 | final File file = util.getFileByClassPath("/standard.sql"); 44 | final InputStream in = new FileInputStream(file); 45 | final String sqlContent = util.read(in); 46 | 47 | // When 48 | final String out = mainProcess.process(sqlContent); 49 | 50 | // Then 51 | final Report report = mainProcess.getReport(); 52 | assertEquals(ReportStatus.SUCCESS, report.getReportStatus()); 53 | assertNotNull(out); 54 | } 55 | 56 | @Test 57 | public void testGetDatabase_mysql() throws FileNotFoundException { 58 | // Given 59 | final File file = util.getFileByClassPath("/mysql1.sql"); 60 | final InputStream in = new FileInputStream(file); 61 | final String sqlContent = util.read(in); 62 | 63 | // When 64 | final String out = mainProcess.process(sqlContent); 65 | 66 | final Report report = mainProcess.getReport(); 67 | 68 | assertEquals(ReportStatus.SUCCESS, report.getReportStatus()); 69 | assertEquals(0, report.getReportLinesForStatus(ReportLineStatus.PARSING_ERROR).size()); 70 | assertEquals(6, report.getReportLinesForStatus(ReportLineStatus.PARSED).size()); 71 | 72 | assertNotNull(out); 73 | } 74 | 75 | @Test 76 | public void testGetDatabase_postgres() throws FileNotFoundException { 77 | // Given 78 | final File file = util.getFileByClassPath("/postgres.sql"); 79 | final InputStream in = new FileInputStream(file); 80 | final String sqlContent = util.read(in); 81 | 82 | // When 83 | final String out = mainProcess.process(sqlContent); 84 | 85 | final Report report = mainProcess.getReport(); 86 | 87 | assertEquals(ReportStatus.SUCCESS, report.getReportStatus()); 88 | assertEquals(0, report.getReportLinesForStatus(ReportLineStatus.PARSING_ERROR).size()); 89 | assertEquals(9, report.getReportLinesForStatus(ReportLineStatus.PARSED).size()); 90 | 91 | assertNotNull(out); 92 | } 93 | 94 | @Test 95 | public void testGetDatabase_oracle1() throws FileNotFoundException { 96 | // Given 97 | final File file = util.getFileByClassPath("/oracle1.sql"); 98 | final InputStream in = new FileInputStream(file); 99 | final String sqlContent = util.read(in); 100 | 101 | // When 102 | final String out = mainProcess.process(sqlContent); 103 | 104 | final Report report = mainProcess.getReport(); 105 | 106 | assertEquals(ReportStatus.SUCCESS, report.getReportStatus()); 107 | assertEquals(0, report.getReportLinesForStatus(ReportLineStatus.PARSING_ERROR).size()); 108 | assertEquals(10, report.getReportLinesForStatus(ReportLineStatus.PARSED).size()); 109 | 110 | assertNotNull(out); 111 | } 112 | 113 | @Test 114 | public void testGetDatabase_oracle2() throws FileNotFoundException { 115 | // Given 116 | final File file = util.getFileByClassPath("/oracle2.sql"); 117 | final InputStream in = new FileInputStream(file); 118 | final String sqlContent = util.read(in); 119 | 120 | // When 121 | final String out = mainProcess.process(sqlContent); 122 | 123 | final Report report = mainProcess.getReport(); 124 | 125 | assertEquals(ReportStatus.SUCCESS, report.getReportStatus()); 126 | assertEquals(0, report.getReportLinesForStatus(ReportLineStatus.PARSING_ERROR).size()); 127 | assertEquals(3, report.getReportLinesForStatus(ReportLineStatus.PARSED).size()); 128 | 129 | assertNotNull(out); 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/test/resources/mysql_mysqldump.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.6.12, for Win64 (x86_64) -- -- Host: localhost Database: test -- ------------------------------------------------------ -- Server version 5.6.12-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `company` -- DROP TABLE IF EXISTS `company`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `company` ( `id` int(11) NOT NULL AUTO_INCREMENT, `duns` varchar(9) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `address` varchar(255) DEFAULT NULL, `zip_code` varchar(5) DEFAULT NULL, `company_creation` date DEFAULT NULL, `website` varchar(255) DEFAULT NULL, `phone_number` varchar(255) DEFAULT NULL, `city` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `duns` (`duns`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `company` -- LOCK TABLES `company` WRITE; /*!40000 ALTER TABLE `company` DISABLE KEYS */; /*!40000 ALTER TABLE `company` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `contact` -- DROP TABLE IF EXISTS `contact`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `contact` ( `id` varchar(255) NOT NULL DEFAULT '', `email` varchar(255) NOT NULL, `age` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `firstname` varchar(255) DEFAULT NULL, `company_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), KEY `company_id` (`company_id`), CONSTRAINT `contact_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `contact` -- LOCK TABLES `contact` WRITE; /*!40000 ALTER TABLE `contact` DISABLE KEYS */; /*!40000 ALTER TABLE `contact` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table1` -- DROP TABLE IF EXISTS `table1`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table1` ( `id` int(11) NOT NULL, `nom` varchar(100) DEFAULT NULL, `dt` date DEFAULT NULL, `num` int(11) DEFAULT NULL, `id_table2` int(11) DEFAULT NULL, `id_table3` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `id_table2` (`id_table2`), KEY `id_table3` (`id_table3`), CONSTRAINT `table1_ibfk_1` FOREIGN KEY (`id_table2`) REFERENCES `table2` (`id`), CONSTRAINT `table1_ibfk_2` FOREIGN KEY (`id_table3`) REFERENCES `table3` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table1` -- LOCK TABLES `table1` WRITE; /*!40000 ALTER TABLE `table1` DISABLE KEYS */; /*!40000 ALTER TABLE `table1` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table2` -- DROP TABLE IF EXISTS `table2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table2` ( `id` int(11) NOT NULL, `nom` varchar(100) DEFAULT NULL, `id_table3` int(11) DEFAULT NULL, `nom_table3` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_table2_table3` (`id_table3`,`nom_table3`), CONSTRAINT `fk_table2_table3` FOREIGN KEY (`id_table3`, `nom_table3`) REFERENCES `table3` (`id`, `nom`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table2` -- LOCK TABLES `table2` WRITE; /*!40000 ALTER TABLE `table2` DISABLE KEYS */; /*!40000 ALTER TABLE `table2` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table3` -- DROP TABLE IF EXISTS `table3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table3` ( `id` int(11) NOT NULL, `nom` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `u_table3` (`id`,`nom`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table3` -- LOCK TABLES `table3` WRITE; /*!40000 ALTER TABLE `table3` DISABLE KEYS */; /*!40000 ALTER TABLE `table3` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2014-09-26 12:07:37 -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/parser/SqlImport.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.parser; 2 | 3 | 4 | import java.util.List; 5 | 6 | import org.antlr.v4.runtime.ANTLRInputStream; 7 | import org.antlr.v4.runtime.BaseErrorListener; 8 | import org.antlr.v4.runtime.CommonTokenStream; 9 | import org.antlr.v4.runtime.RecognitionException; 10 | import org.antlr.v4.runtime.Recognizer; 11 | 12 | import com.restlet.sqlimport.model.sql.Database; 13 | import com.restlet.sqlimport.report.Report; 14 | import com.restlet.sqlimport.report.ReportLine; 15 | import com.restlet.sqlimport.report.ReportLineStatus; 16 | 17 | public class SqlImport { 18 | 19 | /** 20 | * Log activated. 21 | */ 22 | public static final boolean LOG_ACTIVATED = true; 23 | 24 | /** 25 | * Report. 26 | */ 27 | private final Report report; 28 | 29 | /** 30 | * Constructor. 31 | * @param report Report (must not be null) 32 | */ 33 | public SqlImport(final Report report) { 34 | this.report = report; 35 | } 36 | 37 | 38 | /** 39 | * Errors listener which display SQL query. 40 | */ 41 | public class SqlImportErrorListener extends BaseErrorListener { 42 | public String query; 43 | public boolean hasError; 44 | @Override 45 | public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, final int line, final int charPositionInLine, final String msg, final RecognitionException e) { 46 | 47 | hasError = true; 48 | 49 | if(LOG_ACTIVATED) { 50 | System.out.println("------------"); 51 | System.out.println("Error on query : \n"+query); 52 | System.out.println("=> line " + line + " : " + msg); 53 | if(e != null) { 54 | if(e.getMessage() != null) { 55 | System.out.println(e.getMessage()); 56 | } 57 | if(e.getCtx() != null) { 58 | System.out.println("Context : "+e.getCtx()); 59 | } 60 | } 61 | } 62 | 63 | final ReportLine reportLine = getReport().getReportLineForQuery(query); 64 | reportLine.setReportLineStatus(ReportLineStatus.PARSING_ERROR); 65 | final StringBuffer strBuffer = new StringBuffer(); 66 | strBuffer.append("=> line ").append(line).append(" : ").append(msg); 67 | if(e != null) { 68 | if(e.getMessage() != null) { 69 | strBuffer.append(e.getMessage()); 70 | } 71 | if(e.getCtx() != null) { 72 | strBuffer.append("Context : "+e.getCtx()); 73 | } 74 | } 75 | reportLine.setMessage(strBuffer.toString()); 76 | } 77 | } 78 | 79 | /** 80 | * Read input stream to get database schema. 81 | * 82 | * @param content SQL file content 83 | * @return Database schema 84 | */ 85 | public Database getDatabase(final String content) { 86 | if(content == null) { 87 | return null; 88 | } 89 | 90 | final GetSqlQuery getSqlQuery = new GetSqlQuery(getReport()); 91 | final List querys = getSqlQuery.getSqlQuerys(content); 92 | 93 | final Database database = read(querys); 94 | 95 | return database; 96 | } 97 | 98 | /** 99 | * 100 | * @param querys 101 | * @return 102 | */ 103 | public Database read(final List querys) { 104 | 105 | final Database database = new Database(); 106 | 107 | // Add database to the report 108 | report.setDatabase(database); 109 | 110 | for(final String query : querys) { 111 | readOneQuery(database, query); 112 | } 113 | 114 | return database; 115 | } 116 | 117 | /** 118 | * Read SQL statements from string value 119 | * @param database Database schema 120 | * @param txt SQL statements as string value 121 | * @return Database schema 122 | */ 123 | public void readOneQuery(final Database database, final String query) { 124 | if(query == null) { 125 | return; 126 | } 127 | final ANTLRInputStream in = new ANTLRInputStream(query); 128 | 129 | final SqlLexer l = new SqlLexer(in); 130 | final SqlParser p = new SqlParser(new CommonTokenStream(l)); 131 | 132 | // Errors catching 133 | final SqlImportErrorListener listener = new SqlImportErrorListener(); 134 | listener.query = query; 135 | p.addErrorListener(listener); 136 | 137 | if(LOG_ACTIVATED) { 138 | System.out.println("Parse the query : \n"+query); 139 | } 140 | 141 | // Fill database schema from SQL input stream read by ANTLR 142 | if(query.toUpperCase().indexOf("CREATE TABLE") == 0) { 143 | p.addParseListener(new CreateTableParseListener(p, database)); 144 | } 145 | else if(query.toUpperCase().indexOf("ALTER TABLE") == 0) { 146 | p.addParseListener(new AlterTableParseListener(p, database)); 147 | } 148 | else { 149 | throw new RuntimeException("No parse listener for the query : "+query); 150 | } 151 | 152 | try { 153 | p.parse(); 154 | if(!listener.hasError) { 155 | final ReportLine reportLine = getReport().getReportLineForQuery(query); 156 | reportLine.setReportLineStatus(ReportLineStatus.PARSED); 157 | } 158 | } catch(final Exception e) { 159 | final ReportLine reportLine = getReport().getReportLineForQuery(query); 160 | reportLine.setReportLineStatus(ReportLineStatus.PARSING_ERROR); 161 | reportLine.setMessage(e.getMessage()); 162 | } 163 | 164 | } 165 | 166 | /** 167 | * Get report. 168 | * @return report. 169 | */ 170 | public Report getReport() { 171 | return report; 172 | } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/util/Util.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.BufferedWriter; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileNotFoundException; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.InputStreamReader; 12 | import java.io.OutputStream; 13 | import java.io.OutputStreamWriter; 14 | import java.net.URI; 15 | import java.net.URISyntaxException; 16 | import java.net.URL; 17 | import java.util.List; 18 | 19 | public class Util { 20 | 21 | /** 22 | * Search the given file (or folder) using the ClassPath 23 | * @param fileName file name or folder name 24 | * @return 25 | */ 26 | public File getFileByClassPath(final String fileName) { 27 | final URL url = Util.class.getResource(fileName); 28 | if ( url != null ) { 29 | URI uri = null ; 30 | try { 31 | uri = url.toURI(); 32 | } catch (final URISyntaxException e) { 33 | throw new RuntimeException("Cannot convert URL to URI (file '" + fileName + "')"); 34 | } 35 | return new File(uri); 36 | } 37 | else { 38 | throw new RuntimeException("File '" + fileName + "' not found"); 39 | } 40 | } 41 | 42 | /** 43 | * Get input stream for file writing. 44 | * @param filename File name 45 | * @return Input stream 46 | */ 47 | public InputStream getInputStream(final String filename) { 48 | try { 49 | final File file = new File(filename); 50 | final InputStream in = new FileInputStream(file); 51 | return in; 52 | } catch (final FileNotFoundException e) { 53 | System.err.println(e.getMessage()); 54 | System.err.println(e); 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | 59 | /** 60 | * Return output stream for file writing and create directory if not exists. 61 | * @param filename Filename 62 | * @return output stream 63 | */ 64 | public OutputStream getOutputStream(final String filename) { 65 | try { 66 | 67 | final String path = filename.substring(0, filename.lastIndexOf(File.separatorChar)); 68 | final File dir = new File(path); 69 | dir.mkdirs(); 70 | 71 | final File file = new File(filename); 72 | return new FileOutputStream(file); 73 | 74 | } catch (final Exception e) { 75 | System.err.println(e.getMessage()); 76 | System.err.println(e); 77 | throw new RuntimeException(e); 78 | } 79 | } 80 | 81 | /** 82 | * Read input stream and return content 83 | * @param is Input stream 84 | * @return content 85 | */ 86 | public String read(final InputStream is) { 87 | BufferedReader br = null; 88 | final StringBuilder sb = new StringBuilder(); 89 | 90 | String line; 91 | try { 92 | 93 | br = new BufferedReader(new InputStreamReader(is)); 94 | boolean isFirst = true; 95 | while ((line = br.readLine()) != null) { 96 | if(isFirst) { 97 | isFirst = false; 98 | } else { 99 | sb.append("\n"); 100 | } 101 | sb.append(line); 102 | } 103 | 104 | } catch (final IOException e) { 105 | e.printStackTrace(); 106 | } finally { 107 | if (br != null) { 108 | try { 109 | br.close(); 110 | } catch (final IOException e) { 111 | e.printStackTrace(); 112 | } 113 | } 114 | } 115 | 116 | return sb.toString(); 117 | } 118 | 119 | /** 120 | * Write lines to a output stream. 121 | * @param lines Lines 122 | * @param os Output stream 123 | */ 124 | public void write(final List lines, final OutputStream os) { 125 | BufferedWriter bw = null; 126 | 127 | bw = new BufferedWriter(new OutputStreamWriter(os)); 128 | 129 | try { 130 | boolean isFirst = true; 131 | for(final String line : lines) { 132 | if(isFirst) { 133 | isFirst = false; 134 | } else { 135 | bw.write("\n"); 136 | } 137 | bw.write(line); 138 | } 139 | bw.close(); 140 | } catch (final IOException e) { 141 | System.err.println(e.getMessage()); 142 | System.err.println(e); 143 | throw new RuntimeException(e); 144 | } 145 | } 146 | 147 | /** 148 | * Write content to a output stream. 149 | * @param content Content 150 | * @param os Output stream 151 | */ 152 | public void write(final String content, final OutputStream os) { 153 | BufferedWriter bw = null; 154 | 155 | bw = new BufferedWriter(new OutputStreamWriter(os)); 156 | 157 | try { 158 | if(content != null) { 159 | bw.write(content); 160 | } 161 | bw.close(); 162 | } catch (final IOException e) { 163 | System.err.println(e.getMessage()); 164 | System.err.println(e); 165 | throw new RuntimeException(e); 166 | } 167 | } 168 | 169 | /** 170 | * Format name from SQL file. 171 | * @param sqlName Name in SQL file 172 | * @return name 173 | */ 174 | public String unformatSqlName(final String sqlName) { 175 | if(sqlName == null) { 176 | return null; 177 | } 178 | String name = sqlName; 179 | // escape character : " 180 | if(name.length() >= 2) { 181 | if((name.charAt(0) == '"') && (name.charAt(name.length()-1) == '"')) { 182 | name = name.substring(1,name.length()-1); 183 | } 184 | } 185 | // escape character : ` 186 | if(name.length() >= 2) { 187 | if((name.charAt(0) == '`') && (name.charAt(name.length()-1) == '`')) { 188 | name = name.substring(1,name.length()-1); 189 | } 190 | } 191 | return name; 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/test/resources/postgres_pg_dump.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- PostgreSQL database dump 3 | -- 4 | 5 | SET statement_timeout = 0; 6 | SET lock_timeout = 0; 7 | SET client_encoding = 'UTF8'; 8 | SET standard_conforming_strings = on; 9 | SET check_function_bodies = false; 10 | SET client_min_messages = warning; 11 | 12 | -- 13 | -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 14 | -- 15 | 16 | CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; 17 | 18 | 19 | -- 20 | -- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 21 | -- 22 | 23 | COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; 24 | 25 | 26 | SET search_path = public, pg_catalog; 27 | 28 | SET default_tablespace = ''; 29 | 30 | SET default_with_oids = false; 31 | 32 | -- 33 | -- Name: company; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 34 | -- 35 | 36 | CREATE TABLE company ( 37 | id integer NOT NULL, 38 | duns character varying(9), 39 | name character varying(255), 40 | address character varying(255), 41 | zip_code character varying(5), 42 | company_creation date, 43 | website character varying(255), 44 | phone_number character varying(255), 45 | city character varying(255) 46 | ); 47 | 48 | 49 | ALTER TABLE public.company OWNER TO postgres; 50 | 51 | -- 52 | -- Name: contact; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 53 | -- 54 | 55 | CREATE TABLE contact ( 56 | id character varying(255) NOT NULL, 57 | email character varying(255) NOT NULL, 58 | age integer, 59 | name character varying(255), 60 | firstname character varying(255), 61 | company_id integer 62 | ); 63 | 64 | 65 | ALTER TABLE public.contact OWNER TO postgres; 66 | 67 | -- 68 | -- Name: table1; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 69 | -- 70 | 71 | CREATE TABLE table1 ( 72 | id integer NOT NULL, 73 | nom character varying(100) DEFAULT NULL::character varying, 74 | dt date, 75 | num integer, 76 | id_table2 integer, 77 | id_table3 integer 78 | ); 79 | 80 | 81 | ALTER TABLE public.table1 OWNER TO postgres; 82 | 83 | -- 84 | -- Name: table2; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 85 | -- 86 | 87 | CREATE TABLE table2 ( 88 | id integer NOT NULL, 89 | nom character varying(100), 90 | id_table3 integer, 91 | nom_table3 character varying(100) 92 | ); 93 | 94 | 95 | ALTER TABLE public.table2 OWNER TO postgres; 96 | 97 | -- 98 | -- Name: table3; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 99 | -- 100 | 101 | CREATE TABLE table3 ( 102 | id integer NOT NULL, 103 | nom character varying(100) 104 | ); 105 | 106 | 107 | ALTER TABLE public.table3 OWNER TO postgres; 108 | 109 | -- 110 | -- Name: company_duns_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 111 | -- 112 | 113 | ALTER TABLE ONLY company 114 | ADD CONSTRAINT company_duns_key UNIQUE (duns); 115 | 116 | 117 | -- 118 | -- Name: company_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 119 | -- 120 | 121 | ALTER TABLE ONLY company 122 | ADD CONSTRAINT company_pkey PRIMARY KEY (id); 123 | 124 | 125 | -- 126 | -- Name: contact_email_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 127 | -- 128 | 129 | ALTER TABLE ONLY contact 130 | ADD CONSTRAINT contact_email_key UNIQUE (email); 131 | 132 | 133 | -- 134 | -- Name: contact_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 135 | -- 136 | 137 | ALTER TABLE ONLY contact 138 | ADD CONSTRAINT contact_pkey PRIMARY KEY (id); 139 | 140 | 141 | -- 142 | -- Name: table1_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 143 | -- 144 | 145 | ALTER TABLE ONLY table1 146 | ADD CONSTRAINT table1_pkey PRIMARY KEY (id); 147 | 148 | 149 | -- 150 | -- Name: table2_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 151 | -- 152 | 153 | ALTER TABLE ONLY table2 154 | ADD CONSTRAINT table2_pkey PRIMARY KEY (id); 155 | 156 | 157 | -- 158 | -- Name: table3_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 159 | -- 160 | 161 | ALTER TABLE ONLY table3 162 | ADD CONSTRAINT table3_pkey PRIMARY KEY (id); 163 | 164 | 165 | -- 166 | -- Name: u_table3; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 167 | -- 168 | 169 | ALTER TABLE ONLY table3 170 | ADD CONSTRAINT u_table3 UNIQUE (id, nom); 171 | 172 | 173 | -- 174 | -- Name: contact_company_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres 175 | -- 176 | 177 | ALTER TABLE ONLY contact 178 | ADD CONSTRAINT contact_company_id_fkey FOREIGN KEY (company_id) REFERENCES company(id); 179 | 180 | 181 | -- 182 | -- Name: fk_table2_table3; Type: FK CONSTRAINT; Schema: public; Owner: postgres 183 | -- 184 | 185 | ALTER TABLE ONLY table2 186 | ADD CONSTRAINT fk_table2_table3 FOREIGN KEY (id_table3, nom_table3) REFERENCES table3(id, nom) ON UPDATE CASCADE ON DELETE RESTRICT; 187 | 188 | 189 | -- 190 | -- Name: table1_ibfk_1; Type: FK CONSTRAINT; Schema: public; Owner: postgres 191 | -- 192 | 193 | ALTER TABLE ONLY table1 194 | ADD CONSTRAINT table1_ibfk_1 FOREIGN KEY (id_table2) REFERENCES table2(id); 195 | 196 | 197 | -- 198 | -- Name: table1_ibfk_2; Type: FK CONSTRAINT; Schema: public; Owner: postgres 199 | -- 200 | 201 | ALTER TABLE ONLY table1 202 | ADD CONSTRAINT table1_ibfk_2 FOREIGN KEY (id_table3) REFERENCES table3(id) ON DELETE CASCADE; 203 | 204 | 205 | -- 206 | -- Name: public; Type: ACL; Schema: -; Owner: postgres 207 | -- 208 | 209 | REVOKE ALL ON SCHEMA public FROM PUBLIC; 210 | REVOKE ALL ON SCHEMA public FROM postgres; 211 | GRANT ALL ON SCHEMA public TO postgres; 212 | GRANT ALL ON SCHEMA public TO PUBLIC; 213 | 214 | 215 | -- 216 | -- PostgreSQL database dump complete 217 | -- 218 | 219 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/parser/AlterTableParseListener.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.parser; 2 | 3 | import com.restlet.sqlimport.model.sql.Column; 4 | import com.restlet.sqlimport.model.sql.Database; 5 | import com.restlet.sqlimport.model.sql.ForeignKey; 6 | import com.restlet.sqlimport.model.sql.Table; 7 | import com.restlet.sqlimport.parser.SqlParser.Alter_table_add_constraintContext; 8 | import com.restlet.sqlimport.parser.SqlParser.Alter_table_stmtContext; 9 | import com.restlet.sqlimport.parser.SqlParser.Any_nameContext; 10 | import com.restlet.sqlimport.parser.SqlParser.Fk_origin_column_nameContext; 11 | import com.restlet.sqlimport.parser.SqlParser.Fk_target_column_nameContext; 12 | import com.restlet.sqlimport.parser.SqlParser.Foreign_tableContext; 13 | import com.restlet.sqlimport.parser.SqlParser.Indexed_columnContext; 14 | import com.restlet.sqlimport.parser.SqlParser.Source_table_nameContext; 15 | import com.restlet.sqlimport.parser.SqlParser.Table_constraint_foreign_keyContext; 16 | import com.restlet.sqlimport.parser.SqlParser.Table_constraint_primary_keyContext; 17 | import com.restlet.sqlimport.util.Util; 18 | 19 | /** 20 | * Parse Listener only for ALTER TABLE statements parsing. 21 | */ 22 | public class AlterTableParseListener extends SqlBaseListener { 23 | 24 | 25 | /** 26 | * Debug mode to display ANTLR v4 contexts. 27 | */ 28 | private static boolean DEBUG = false; 29 | 30 | /** 31 | * ANTLR Parser 32 | */ 33 | private final SqlParser sqlParser; 34 | 35 | /** 36 | * Database schema 37 | */ 38 | private final Database database; 39 | 40 | Table table; 41 | Column column; 42 | ForeignKey foreignKey; 43 | 44 | boolean inAlter_table_stmt = false; // ALTER TABLE 45 | boolean inAlter_table_add_constraint = false; // ALTER TABLE with ADD CONSTRAINT 46 | boolean inTable_constraint_primary_key = false; // PRIMARY KEY in ALTER TABLE 47 | boolean inTable_constraint_foreign_key = false; // FOREIGN KEY in ALTER TABLE 48 | 49 | /** 50 | * Utils methods. 51 | */ 52 | Util util = new Util(); 53 | 54 | /** 55 | * Constructor. 56 | * @param sqlParser SQL parser 57 | * @param database Database 58 | */ 59 | public AlterTableParseListener(final SqlParser sqlParser, final Database database) { 60 | this.sqlParser = sqlParser; 61 | this.database = database; 62 | } 63 | 64 | /** 65 | * Used only for debug, its called for each token based on the token "name". 66 | */ 67 | @Override 68 | public void exitAny_name(final Any_nameContext ctx) { 69 | if(DEBUG) { 70 | System.out.println(ctx.getText() + " - ctx : " + ctx.toInfoString(sqlParser)); 71 | } 72 | } 73 | 74 | //--- ALTER TABLE 75 | 76 | @Override 77 | public void enterAlter_table_stmt(final Alter_table_stmtContext ctx) { 78 | inAlter_table_stmt = true; 79 | } 80 | 81 | @Override 82 | public void exitAlter_table_stmt(final Alter_table_stmtContext ctx) { 83 | inAlter_table_stmt = false; 84 | } 85 | 86 | @Override 87 | public void exitSource_table_name(final Source_table_nameContext ctx) { 88 | if(inAlter_table_stmt) { 89 | table = database.getTableForName(util.unformatSqlName(ctx.getText())); 90 | } 91 | } 92 | 93 | //--- Add constraint 94 | 95 | @Override 96 | public void enterAlter_table_add_constraint( 97 | final Alter_table_add_constraintContext ctx) { 98 | inAlter_table_add_constraint = true; 99 | } 100 | 101 | @Override 102 | public void exitAlter_table_add_constraint( 103 | final Alter_table_add_constraintContext ctx) { 104 | inAlter_table_add_constraint = false; 105 | } 106 | 107 | //--- Constraints 108 | 109 | //--- Primary Key in ALTER TABLE 110 | 111 | @Override 112 | public void enterTable_constraint_primary_key( 113 | final Table_constraint_primary_keyContext ctx) { 114 | inTable_constraint_primary_key = true; 115 | } 116 | 117 | @Override 118 | public void exitTable_constraint_primary_key( 119 | final Table_constraint_primary_keyContext ctx) { 120 | inTable_constraint_primary_key = false; 121 | } 122 | 123 | @Override 124 | public void exitIndexed_column(final Indexed_columnContext ctx) { 125 | if(inAlter_table_stmt && inTable_constraint_primary_key) { 126 | final String columnName = util.unformatSqlName(ctx.getText()); 127 | table.getPrimaryKey().getColumnNames().add(columnName); 128 | } 129 | } 130 | 131 | //--- Foreign Key in CREATE TABLE or in ALTER TABLE 132 | 133 | @Override 134 | public void enterTable_constraint_foreign_key( 135 | final Table_constraint_foreign_keyContext ctx) { 136 | inTable_constraint_foreign_key = true; 137 | if(inAlter_table_stmt) { 138 | foreignKey = new ForeignKey(); 139 | foreignKey.setTableNameOrigin(table.getName()); 140 | } 141 | } 142 | 143 | @Override 144 | public void exitTable_constraint_foreign_key( 145 | final Table_constraint_foreign_keyContext ctx) { 146 | if(inAlter_table_stmt) { 147 | foreignKey.setTableNameOrigin(table.getName()); 148 | table.getForeignKeys().add(foreignKey); 149 | foreignKey = null; 150 | } 151 | inTable_constraint_foreign_key = false; 152 | } 153 | 154 | @Override 155 | public void exitForeign_table(final Foreign_tableContext ctx) { 156 | if(inTable_constraint_foreign_key) { 157 | foreignKey.setTableNameTarget(util.unformatSqlName(ctx.getText())); 158 | } 159 | } 160 | 161 | @Override 162 | public void exitFk_origin_column_name( 163 | final Fk_origin_column_nameContext ctx) { 164 | if(inTable_constraint_foreign_key) { 165 | foreignKey.getColumnNameOrigins().add(util.unformatSqlName(ctx.getText())); 166 | } 167 | } 168 | 169 | @Override 170 | public void exitFk_target_column_name( 171 | final Fk_target_column_nameContext ctx) { 172 | if(inTable_constraint_foreign_key) { 173 | foreignKey.getColumnNameTargets().add(util.unformatSqlName(ctx.getText())); 174 | } 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /samples/mysql.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; 2 | USE `test`; 3 | -- MySQL dump 10.13 Distrib 5.6.17, for Win32 (x86) 4 | -- 5 | -- Host: localhost Database: test 6 | -- ------------------------------------------------------ 7 | -- Server version 5.6.12-log 8 | 9 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 10 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 11 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 12 | /*!40101 SET NAMES utf8 */; 13 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 14 | /*!40103 SET TIME_ZONE='+00:00' */; 15 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 16 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 17 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 18 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 19 | 20 | -- 21 | -- Table structure for table `company` 22 | -- 23 | 24 | DROP TABLE IF EXISTS `company`; 25 | /*!40101 SET @saved_cs_client = @@character_set_client */; 26 | /*!40101 SET character_set_client = utf8 */; 27 | CREATE TABLE `company` ( 28 | `id` int(11) NOT NULL AUTO_INCREMENT, 29 | `duns` varchar(9) DEFAULT NULL, 30 | `name` varchar(255) DEFAULT NULL, 31 | `address` varchar(255) DEFAULT NULL, 32 | `zip_code` varchar(5) DEFAULT NULL, 33 | `company_creation` date DEFAULT NULL, 34 | `website` varchar(255) DEFAULT NULL, 35 | `phone_number` varchar(255) DEFAULT NULL, 36 | `city` varchar(255) DEFAULT NULL, 37 | PRIMARY KEY (`id`), 38 | UNIQUE KEY `duns` (`duns`) 39 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 40 | /*!40101 SET character_set_client = @saved_cs_client */; 41 | 42 | -- 43 | -- Dumping data for table `company` 44 | -- 45 | 46 | LOCK TABLES `company` WRITE; 47 | /*!40000 ALTER TABLE `company` DISABLE KEYS */; 48 | /*!40000 ALTER TABLE `company` ENABLE KEYS */; 49 | UNLOCK TABLES; 50 | 51 | -- 52 | -- Table structure for table `contact` 53 | -- 54 | 55 | DROP TABLE IF EXISTS `contact`; 56 | /*!40101 SET @saved_cs_client = @@character_set_client */; 57 | /*!40101 SET character_set_client = utf8 */; 58 | CREATE TABLE `contact` ( 59 | `id` varchar(255) NOT NULL DEFAULT '', 60 | `email` varchar(255) NOT NULL, 61 | `age` int(11) DEFAULT NULL, 62 | `name` varchar(255) DEFAULT NULL, 63 | `firstname` varchar(255) DEFAULT NULL, 64 | `company_id` int(11) DEFAULT NULL, 65 | PRIMARY KEY (`id`), 66 | UNIQUE KEY `email` (`email`), 67 | KEY `company_id` (`company_id`), 68 | CONSTRAINT `contact_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) 69 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 70 | /*!40101 SET character_set_client = @saved_cs_client */; 71 | 72 | -- 73 | -- Dumping data for table `contact` 74 | -- 75 | 76 | LOCK TABLES `contact` WRITE; 77 | /*!40000 ALTER TABLE `contact` DISABLE KEYS */; 78 | /*!40000 ALTER TABLE `contact` ENABLE KEYS */; 79 | UNLOCK TABLES; 80 | 81 | -- 82 | -- Table structure for table `table1` 83 | -- 84 | 85 | DROP TABLE IF EXISTS `table1`; 86 | /*!40101 SET @saved_cs_client = @@character_set_client */; 87 | /*!40101 SET character_set_client = utf8 */; 88 | CREATE TABLE `table1` ( 89 | `id` int(11) NOT NULL, 90 | `nom` varchar(100) DEFAULT NULL, 91 | `dt` date DEFAULT NULL, 92 | `num` int(11) DEFAULT NULL, 93 | `id_table2` int(11) DEFAULT NULL, 94 | `id_table3` int(11) DEFAULT NULL, 95 | PRIMARY KEY (`id`), 96 | KEY `id_table2` (`id_table2`), 97 | KEY `id_table3` (`id_table3`), 98 | CONSTRAINT `table1_ibfk_1` FOREIGN KEY (`id_table2`) REFERENCES `table2` (`id`), 99 | CONSTRAINT `table1_ibfk_2` FOREIGN KEY (`id_table3`) REFERENCES `table3` (`id`) ON DELETE CASCADE 100 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 101 | /*!40101 SET character_set_client = @saved_cs_client */; 102 | 103 | -- 104 | -- Dumping data for table `table1` 105 | -- 106 | 107 | LOCK TABLES `table1` WRITE; 108 | /*!40000 ALTER TABLE `table1` DISABLE KEYS */; 109 | /*!40000 ALTER TABLE `table1` ENABLE KEYS */; 110 | UNLOCK TABLES; 111 | 112 | -- 113 | -- Table structure for table `table2` 114 | -- 115 | 116 | DROP TABLE IF EXISTS `table2`; 117 | /*!40101 SET @saved_cs_client = @@character_set_client */; 118 | /*!40101 SET character_set_client = utf8 */; 119 | CREATE TABLE `table2` ( 120 | `id` int(11) NOT NULL, 121 | `nom` varchar(100) DEFAULT NULL, 122 | `id_table3` int(11) DEFAULT NULL, 123 | `nom_table3` varchar(100) DEFAULT NULL, 124 | PRIMARY KEY (`id`), 125 | KEY `fk_table2_table3` (`id_table3`,`nom_table3`), 126 | CONSTRAINT `fk_table2_table3` FOREIGN KEY (`id_table3`, `nom_table3`) REFERENCES `table3` (`id`, `nom`) ON UPDATE CASCADE 127 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 128 | /*!40101 SET character_set_client = @saved_cs_client */; 129 | 130 | -- 131 | -- Dumping data for table `table2` 132 | -- 133 | 134 | LOCK TABLES `table2` WRITE; 135 | /*!40000 ALTER TABLE `table2` DISABLE KEYS */; 136 | /*!40000 ALTER TABLE `table2` ENABLE KEYS */; 137 | UNLOCK TABLES; 138 | 139 | -- 140 | -- Table structure for table `table3` 141 | -- 142 | 143 | DROP TABLE IF EXISTS `table3`; 144 | /*!40101 SET @saved_cs_client = @@character_set_client */; 145 | /*!40101 SET character_set_client = utf8 */; 146 | CREATE TABLE `table3` ( 147 | `id` int(11) NOT NULL, 148 | `nom` varchar(100) DEFAULT NULL, 149 | PRIMARY KEY (`id`), 150 | UNIQUE KEY `u_table3` (`id`,`nom`) 151 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 152 | /*!40101 SET character_set_client = @saved_cs_client */; 153 | 154 | -- 155 | -- Dumping data for table `table3` 156 | -- 157 | 158 | LOCK TABLES `table3` WRITE; 159 | /*!40000 ALTER TABLE `table3` DISABLE KEYS */; 160 | /*!40000 ALTER TABLE `table3` ENABLE KEYS */; 161 | UNLOCK TABLES; 162 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 163 | 164 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 165 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 166 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 167 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 168 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 169 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 170 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 171 | 172 | -- Dump completed on 2014-09-25 18:31:36 173 | -------------------------------------------------------------------------------- /src/test/resources/mysql_mysqlworkbench.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; 2 | USE `test`; 3 | -- MySQL dump 10.13 Distrib 5.6.17, for Win32 (x86) 4 | -- 5 | -- Host: localhost Database: test 6 | -- ------------------------------------------------------ 7 | -- Server version 5.6.12-log 8 | 9 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 10 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 11 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 12 | /*!40101 SET NAMES utf8 */; 13 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 14 | /*!40103 SET TIME_ZONE='+00:00' */; 15 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 16 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 17 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 18 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 19 | 20 | -- 21 | -- Table structure for table `company` 22 | -- 23 | 24 | DROP TABLE IF EXISTS `company`; 25 | /*!40101 SET @saved_cs_client = @@character_set_client */; 26 | /*!40101 SET character_set_client = utf8 */; 27 | CREATE TABLE `company` ( 28 | `id` int(11) NOT NULL AUTO_INCREMENT, 29 | `duns` varchar(9) DEFAULT NULL, 30 | `name` varchar(255) DEFAULT NULL, 31 | `address` varchar(255) DEFAULT NULL, 32 | `zip_code` varchar(5) DEFAULT NULL, 33 | `company_creation` date DEFAULT NULL, 34 | `website` varchar(255) DEFAULT NULL, 35 | `phone_number` varchar(255) DEFAULT NULL, 36 | `city` varchar(255) DEFAULT NULL, 37 | PRIMARY KEY (`id`), 38 | UNIQUE KEY `duns` (`duns`) 39 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 40 | /*!40101 SET character_set_client = @saved_cs_client */; 41 | 42 | -- 43 | -- Dumping data for table `company` 44 | -- 45 | 46 | LOCK TABLES `company` WRITE; 47 | /*!40000 ALTER TABLE `company` DISABLE KEYS */; 48 | /*!40000 ALTER TABLE `company` ENABLE KEYS */; 49 | UNLOCK TABLES; 50 | 51 | -- 52 | -- Table structure for table `contact` 53 | -- 54 | 55 | DROP TABLE IF EXISTS `contact`; 56 | /*!40101 SET @saved_cs_client = @@character_set_client */; 57 | /*!40101 SET character_set_client = utf8 */; 58 | CREATE TABLE `contact` ( 59 | `id` varchar(255) NOT NULL DEFAULT '', 60 | `email` varchar(255) NOT NULL, 61 | `age` int(11) DEFAULT NULL, 62 | `name` varchar(255) DEFAULT NULL, 63 | `firstname` varchar(255) DEFAULT NULL, 64 | `company_id` int(11) DEFAULT NULL, 65 | PRIMARY KEY (`id`), 66 | UNIQUE KEY `email` (`email`), 67 | KEY `company_id` (`company_id`), 68 | CONSTRAINT `contact_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) 69 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 70 | /*!40101 SET character_set_client = @saved_cs_client */; 71 | 72 | -- 73 | -- Dumping data for table `contact` 74 | -- 75 | 76 | LOCK TABLES `contact` WRITE; 77 | /*!40000 ALTER TABLE `contact` DISABLE KEYS */; 78 | /*!40000 ALTER TABLE `contact` ENABLE KEYS */; 79 | UNLOCK TABLES; 80 | 81 | -- 82 | -- Table structure for table `table1` 83 | -- 84 | 85 | DROP TABLE IF EXISTS `table1`; 86 | /*!40101 SET @saved_cs_client = @@character_set_client */; 87 | /*!40101 SET character_set_client = utf8 */; 88 | CREATE TABLE `table1` ( 89 | `id` int(11) NOT NULL, 90 | `nom` varchar(100) DEFAULT NULL, 91 | `dt` date DEFAULT NULL, 92 | `num` int(11) DEFAULT NULL, 93 | `id_table2` int(11) DEFAULT NULL, 94 | `id_table3` int(11) DEFAULT NULL, 95 | PRIMARY KEY (`id`), 96 | KEY `id_table2` (`id_table2`), 97 | KEY `id_table3` (`id_table3`), 98 | CONSTRAINT `table1_ibfk_1` FOREIGN KEY (`id_table2`) REFERENCES `table2` (`id`), 99 | CONSTRAINT `table1_ibfk_2` FOREIGN KEY (`id_table3`) REFERENCES `table3` (`id`) ON DELETE CASCADE 100 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 101 | /*!40101 SET character_set_client = @saved_cs_client */; 102 | 103 | -- 104 | -- Dumping data for table `table1` 105 | -- 106 | 107 | LOCK TABLES `table1` WRITE; 108 | /*!40000 ALTER TABLE `table1` DISABLE KEYS */; 109 | /*!40000 ALTER TABLE `table1` ENABLE KEYS */; 110 | UNLOCK TABLES; 111 | 112 | -- 113 | -- Table structure for table `table2` 114 | -- 115 | 116 | DROP TABLE IF EXISTS `table2`; 117 | /*!40101 SET @saved_cs_client = @@character_set_client */; 118 | /*!40101 SET character_set_client = utf8 */; 119 | CREATE TABLE `table2` ( 120 | `id` int(11) NOT NULL, 121 | `nom` varchar(100) DEFAULT NULL, 122 | `id_table3` int(11) DEFAULT NULL, 123 | `nom_table3` varchar(100) DEFAULT NULL, 124 | PRIMARY KEY (`id`), 125 | KEY `fk_table2_table3` (`id_table3`,`nom_table3`), 126 | CONSTRAINT `fk_table2_table3` FOREIGN KEY (`id_table3`, `nom_table3`) REFERENCES `table3` (`id`, `nom`) ON UPDATE CASCADE 127 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 128 | /*!40101 SET character_set_client = @saved_cs_client */; 129 | 130 | -- 131 | -- Dumping data for table `table2` 132 | -- 133 | 134 | LOCK TABLES `table2` WRITE; 135 | /*!40000 ALTER TABLE `table2` DISABLE KEYS */; 136 | /*!40000 ALTER TABLE `table2` ENABLE KEYS */; 137 | UNLOCK TABLES; 138 | 139 | -- 140 | -- Table structure for table `table3` 141 | -- 142 | 143 | DROP TABLE IF EXISTS `table3`; 144 | /*!40101 SET @saved_cs_client = @@character_set_client */; 145 | /*!40101 SET character_set_client = utf8 */; 146 | CREATE TABLE `table3` ( 147 | `id` int(11) NOT NULL, 148 | `nom` varchar(100) DEFAULT NULL, 149 | PRIMARY KEY (`id`), 150 | UNIQUE KEY `u_table3` (`id`,`nom`) 151 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 152 | /*!40101 SET character_set_client = @saved_cs_client */; 153 | 154 | -- 155 | -- Dumping data for table `table3` 156 | -- 157 | 158 | LOCK TABLES `table3` WRITE; 159 | /*!40000 ALTER TABLE `table3` DISABLE KEYS */; 160 | /*!40000 ALTER TABLE `table3` ENABLE KEYS */; 161 | UNLOCK TABLES; 162 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 163 | 164 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 165 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 166 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 167 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 168 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 169 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 170 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 171 | 172 | -- Dump completed on 2014-09-25 18:31:36 173 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/parser/GetSqlQuery.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.parser; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.restlet.sqlimport.report.Report; 7 | import com.restlet.sqlimport.report.ReportLine; 8 | import com.restlet.sqlimport.report.ReportLineStatus; 9 | 10 | /** 11 | * Parse SQL file and returns the list of SQL queries. 12 | */ 13 | public class GetSqlQuery { 14 | 15 | /** 16 | * Report. 17 | */ 18 | private final Report report; 19 | 20 | /** 21 | * Constructor. 22 | * @param report Report (must not be null) 23 | */ 24 | public GetSqlQuery(final Report report) { 25 | this.report = report; 26 | } 27 | 28 | /** 29 | * Indicates if the query is correct 30 | * @param query Query 31 | * @return boolean 32 | */ 33 | public boolean isQueryFiltered(final String query) { 34 | final String queryUpperCase = query.toUpperCase(); 35 | if(queryUpperCase.indexOf("CREATE TABLE") == 0) { 36 | return false; 37 | } 38 | // support ALTER TABLE with ADD CONSTRAINT 39 | if(queryUpperCase.indexOf("ALTER TABLE") == 0) { 40 | if(queryUpperCase.indexOf("ADD CONSTRAINT") != -1) { 41 | if((queryUpperCase.indexOf("PRIMARY KEY") != -1) || (queryUpperCase.indexOf("FOREIGN KEY") != -1)) { 42 | return false; 43 | } 44 | } 45 | if(queryUpperCase.indexOf("ADD PRIMARY KEY") != -1) { 46 | return false; 47 | } 48 | if(queryUpperCase.indexOf("ADD FOREIGN KEY") != -1) { 49 | return false; 50 | } 51 | } 52 | 53 | return true; 54 | } 55 | 56 | /** 57 | * Return the liste of SQL queries to parse 58 | * @param content SQL file content 59 | * @return SQL queries 60 | */ 61 | public List getSqlQuerys(final String content) { 62 | final List querys = new ArrayList(); 63 | 64 | int posStart = getPosStartQuery(content, 0); 65 | int posEnd = getPosEndQuery(content, posStart); 66 | while((posStart != -1) && (posStart < content.length()) && (posEnd < content.length())) { 67 | 68 | final String query = content.substring(posStart, posEnd); 69 | 70 | final boolean isFiltered = isQueryFiltered(query); 71 | if(!isFiltered) { 72 | querys.add(query); 73 | } 74 | 75 | final ReportLine reportLine = new ReportLine(); 76 | reportLine.setQuery(query); 77 | if(isFiltered) { 78 | reportLine.setReportLineStatus(ReportLineStatus.IGNORED); 79 | } else { 80 | reportLine.setReportLineStatus(ReportLineStatus.TO_PARSE); 81 | } 82 | getReport().add(reportLine); 83 | 84 | if((posEnd + 1) >= content.length()) { 85 | posStart = -1; 86 | } else { 87 | posStart = getPosStartQuery(content,posEnd+1); 88 | posEnd = getPosEndQuery(content, posStart); 89 | } 90 | } 91 | 92 | return querys; 93 | } 94 | 95 | /** 96 | * Return the position of the beginning character of the next SQL query. 97 | * @param content SQL content 98 | * @param pos Current position in the SQL content 99 | * @return Position of the beginning character of the next SQL query 100 | */ 101 | private int getPosStartQuery(final String content, int pos) { 102 | 103 | boolean inLineComment = false; 104 | boolean inMultiLineComment = false; 105 | boolean inStringValue = false; 106 | 107 | while(pos < content.length()) { 108 | final char character = content.charAt(pos); 109 | if(character == '/') { 110 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 111 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '*')) { 112 | inMultiLineComment = true; 113 | pos = pos+2; 114 | continue; 115 | } 116 | } 117 | } 118 | if(character == '*') { 119 | if(!inStringValue && !inLineComment && inMultiLineComment) { 120 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '/')) { 121 | inMultiLineComment = false; 122 | pos = pos+2; 123 | continue; 124 | } 125 | } 126 | } 127 | if(character == '"') { 128 | if(!inLineComment && !inMultiLineComment) { 129 | inStringValue = !inStringValue; 130 | } 131 | } 132 | if(character == '-') { 133 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 134 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '-')) { 135 | inLineComment = true; 136 | pos = pos + 2; 137 | continue; 138 | } 139 | } 140 | } 141 | if((character == '\n') || (character == '\r') ) { 142 | if(inLineComment) { 143 | inLineComment = false; 144 | } 145 | } 146 | if(((character >= 'a') && (character <= 'z')) ||((character >= 'A') && (character <= 'Z'))) { 147 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 148 | break; 149 | } 150 | } 151 | pos++; 152 | } 153 | 154 | return pos; 155 | } 156 | 157 | /** 158 | * Return the position of the end of the current SQL query. 159 | * @param content SQL content 160 | * @param pos Current position in the SQL content 161 | * @return Position of the end of the current SQL query 162 | */ 163 | private int getPosEndQuery(final String content, int pos) { 164 | 165 | boolean inLineComment = false; 166 | boolean inMultiLineComment = false; 167 | boolean inStringValue = false; 168 | 169 | while(pos < content.length()) { 170 | final char character = content.charAt(pos); 171 | if(character == '/') { 172 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 173 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '*')) { 174 | inMultiLineComment = true; 175 | pos = pos+2; 176 | continue; 177 | } 178 | } 179 | } 180 | if(character == '*') { 181 | if(!inStringValue && !inLineComment && inMultiLineComment) { 182 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '/')) { 183 | inMultiLineComment = false; 184 | pos = pos+2; 185 | continue; 186 | } 187 | } 188 | } 189 | if(character == '"') { 190 | if(!inLineComment && !inMultiLineComment) { 191 | inStringValue = !inStringValue; 192 | } 193 | } 194 | if(character == '-') { 195 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 196 | if(((pos+1) < content.length()) && (content.charAt(pos+1) == '-')) { 197 | inLineComment = true; 198 | pos = pos + 2; 199 | continue; 200 | } 201 | } 202 | } 203 | if((character == '\n') || (character == '\r') ) { 204 | if(inLineComment) { 205 | inLineComment = false; 206 | } 207 | } 208 | if(character == ';') { 209 | if(!inStringValue && !inLineComment && !inMultiLineComment) { 210 | break; 211 | } 212 | } 213 | pos++; 214 | } 215 | 216 | return pos; 217 | } 218 | 219 | /** 220 | * Get report 221 | * @return report 222 | */ 223 | public Report getReport() { 224 | return report; 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/type/TypeConverterTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.type; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import org.junit.Test; 7 | 8 | import com.restlet.sqlimport.report.Report; 9 | import com.restlet.sqlimport.report.ReportLineStatus; 10 | import com.restlet.sqlimport.type.TypeConverter; 11 | 12 | 13 | public class TypeConverterTest { 14 | 15 | @Test 16 | public void testConvertTypeFromSQLToEntityStore() { 17 | final Report report = new Report(); 18 | final TypeConverter typeConverter = new TypeConverter(report); 19 | 20 | // null 21 | final String sqlType = null; 22 | assertNull(typeConverter.convertTypeFromSQLToEntityStore(sqlType)); 23 | 24 | // unknown 25 | assertEquals(0, report.getReportLines().size()); 26 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore("UNKNOWN")); 27 | assertEquals(1, report.getReportLines().size()); 28 | assertEquals(ReportLineStatus.UNKNOWN_SQL_TYPE, report.getReportLines().get(0).getReportLineStatus()); 29 | assertEquals("UNKNOWN", report.getReportLines().get(0).getMessage()); 30 | 31 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" bfile ")); 32 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" bigint ")); 33 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" bigserial ")); 34 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" binary ")); 35 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" binary_double ")); 36 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" binary_float ")); 37 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" bit ")); 38 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" bit varying ")); 39 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" blob ")); 40 | assertEquals("Boolean", typeConverter.convertTypeFromSQLToEntityStore(" bool ")); 41 | assertEquals("Boolean", typeConverter.convertTypeFromSQLToEntityStore(" boolean ")); 42 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" bytea ")); 43 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" char ")); 44 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" character ")); 45 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" character varying ")); 46 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" clob ")); 47 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" date ")); 48 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" datetime ")); 49 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" dec ")); 50 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" decimal ")); 51 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" double ")); 52 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" double precision ")); 53 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" enum ")); 54 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" fixed ")); 55 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" float ")); 56 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" int ")); 57 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" integer ")); 58 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" interval ")); 59 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" interval day [day_precision] to second [fractional seconds] ")); 60 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" interval year [year_precision] to month ")); 61 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" long ")); 62 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" long raw ")); 63 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" longblob ")); 64 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" longtext ")); 65 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" mediumblob ")); 66 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" mediumint ")); 67 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" mediumtext ")); 68 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" money ")); 69 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" national character ")); 70 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" national character varying ")); 71 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" nchar ")); 72 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" nclob ")); 73 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" number ")); 74 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" numeric ")); 75 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" nvarchar ")); 76 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" nvarchar2 ")); 77 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" raw ")); 78 | assertEquals("Float", typeConverter.convertTypeFromSQLToEntityStore(" real ")); 79 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" rowid ")); 80 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" serial ")); 81 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" set ")); 82 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" smallint ")); 83 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" smallserial ")); 84 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" text ")); 85 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" time ")); 86 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" time with time zone ")); 87 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" timestamp ")); 88 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" timestamp with time zone ")); 89 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" timestamptz ")); 90 | assertEquals("Date", typeConverter.convertTypeFromSQLToEntityStore(" timetz ")); 91 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" tinyblob ")); 92 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" tinyint ")); 93 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" tinytext ")); 94 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" urowid ")); 95 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" uuid ")); 96 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" varbinary ")); 97 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" varchar ")); 98 | assertEquals("String", typeConverter.convertTypeFromSQLToEntityStore(" varchar2 ")); 99 | assertEquals("Integer", typeConverter.convertTypeFromSQLToEntityStore(" year ")); 100 | 101 | assertEquals(1, report.getReportLines().size()); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /samples/postgres.backup: -------------------------------------------------------------------------------- 1 | -- 2 | -- PostgreSQL database dump 3 | -- 4 | 5 | -- Dumped from database version 9.3.1 6 | -- Dumped by pg_dump version 9.3.1 7 | -- Started on 2014-09-25 15:26:38 8 | 9 | SET statement_timeout = 0; 10 | SET lock_timeout = 0; 11 | SET client_encoding = 'UTF8'; 12 | SET standard_conforming_strings = on; 13 | SET check_function_bodies = false; 14 | SET client_min_messages = warning; 15 | 16 | -- 17 | -- TOC entry 175 (class 3079 OID 11750) 18 | -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 19 | -- 20 | 21 | CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; 22 | 23 | 24 | -- 25 | -- TOC entry 1979 (class 0 OID 0) 26 | -- Dependencies: 175 27 | -- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 28 | -- 29 | 30 | COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; 31 | 32 | 33 | SET search_path = public, pg_catalog; 34 | 35 | SET default_tablespace = ''; 36 | 37 | SET default_with_oids = false; 38 | 39 | -- 40 | -- TOC entry 170 (class 1259 OID 41339) 41 | -- Name: company; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 42 | -- 43 | 44 | CREATE TABLE company ( 45 | id integer NOT NULL, 46 | duns character varying(9), 47 | name character varying(255), 48 | address character varying(255), 49 | zip_code character varying(5), 50 | company_creation date, 51 | website character varying(255), 52 | phone_number character varying(255), 53 | city character varying(255) 54 | ); 55 | 56 | 57 | ALTER TABLE public.company OWNER TO postgres; 58 | 59 | -- 60 | -- TOC entry 171 (class 1259 OID 41349) 61 | -- Name: contact; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 62 | -- 63 | 64 | CREATE TABLE contact ( 65 | id character varying(255) NOT NULL, 66 | email character varying(255) NOT NULL, 67 | age integer, 68 | name character varying(255), 69 | firstname character varying(255), 70 | company_id integer 71 | ); 72 | 73 | 74 | ALTER TABLE public.contact OWNER TO postgres; 75 | 76 | -- 77 | -- TOC entry 174 (class 1259 OID 41384) 78 | -- Name: table1; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 79 | -- 80 | 81 | CREATE TABLE table1 ( 82 | id integer NOT NULL, 83 | nom character varying(100) DEFAULT NULL::character varying, 84 | dt date, 85 | num integer, 86 | id_table2 integer, 87 | id_table3 integer 88 | ); 89 | 90 | 91 | ALTER TABLE public.table1 OWNER TO postgres; 92 | 93 | -- 94 | -- TOC entry 173 (class 1259 OID 41379) 95 | -- Name: table2; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 96 | -- 97 | 98 | CREATE TABLE table2 ( 99 | id integer NOT NULL, 100 | nom character varying(100), 101 | id_table3 integer, 102 | nom_table3 character varying(100) 103 | ); 104 | 105 | 106 | ALTER TABLE public.table2 OWNER TO postgres; 107 | 108 | -- 109 | -- TOC entry 172 (class 1259 OID 41374) 110 | -- Name: table3; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 111 | -- 112 | 113 | CREATE TABLE table3 ( 114 | id integer NOT NULL, 115 | nom character varying(100) 116 | ); 117 | 118 | 119 | ALTER TABLE public.table3 OWNER TO postgres; 120 | 121 | -- 122 | -- TOC entry 1967 (class 0 OID 41339) 123 | -- Dependencies: 170 124 | -- Data for Name: company; Type: TABLE DATA; Schema: public; Owner: postgres 125 | -- 126 | 127 | COPY company (id, duns, name, address, zip_code, company_creation, website, phone_number, city) FROM stdin; 128 | \. 129 | 130 | 131 | -- 132 | -- TOC entry 1968 (class 0 OID 41349) 133 | -- Dependencies: 171 134 | -- Data for Name: contact; Type: TABLE DATA; Schema: public; Owner: postgres 135 | -- 136 | 137 | COPY contact (id, email, age, name, firstname, company_id) FROM stdin; 138 | \. 139 | 140 | 141 | -- 142 | -- TOC entry 1971 (class 0 OID 41384) 143 | -- Dependencies: 174 144 | -- Data for Name: table1; Type: TABLE DATA; Schema: public; Owner: postgres 145 | -- 146 | 147 | COPY table1 (id, nom, dt, num, id_table2, id_table3) FROM stdin; 148 | \. 149 | 150 | 151 | -- 152 | -- TOC entry 1970 (class 0 OID 41379) 153 | -- Dependencies: 173 154 | -- Data for Name: table2; Type: TABLE DATA; Schema: public; Owner: postgres 155 | -- 156 | 157 | COPY table2 (id, nom, id_table3, nom_table3) FROM stdin; 158 | \. 159 | 160 | 161 | -- 162 | -- TOC entry 1969 (class 0 OID 41374) 163 | -- Dependencies: 172 164 | -- Data for Name: table3; Type: TABLE DATA; Schema: public; Owner: postgres 165 | -- 166 | 167 | COPY table3 (id, nom) FROM stdin; 168 | \. 169 | 170 | 171 | -- 172 | -- TOC entry 1841 (class 2606 OID 41348) 173 | -- Name: company_duns_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 174 | -- 175 | 176 | ALTER TABLE ONLY company 177 | ADD CONSTRAINT company_duns_key UNIQUE (duns); 178 | 179 | 180 | -- 181 | -- TOC entry 1843 (class 2606 OID 41346) 182 | -- Name: company_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 183 | -- 184 | 185 | ALTER TABLE ONLY company 186 | ADD CONSTRAINT company_pkey PRIMARY KEY (id); 187 | 188 | 189 | -- 190 | -- TOC entry 1845 (class 2606 OID 41358) 191 | -- Name: contact_email_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 192 | -- 193 | 194 | ALTER TABLE ONLY contact 195 | ADD CONSTRAINT contact_email_key UNIQUE (email); 196 | 197 | 198 | -- 199 | -- TOC entry 1847 (class 2606 OID 41356) 200 | -- Name: contact_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 201 | -- 202 | 203 | ALTER TABLE ONLY contact 204 | ADD CONSTRAINT contact_pkey PRIMARY KEY (id); 205 | 206 | 207 | -- 208 | -- TOC entry 1855 (class 2606 OID 41389) 209 | -- Name: table1_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 210 | -- 211 | 212 | ALTER TABLE ONLY table1 213 | ADD CONSTRAINT table1_pkey PRIMARY KEY (id); 214 | 215 | 216 | -- 217 | -- TOC entry 1853 (class 2606 OID 41383) 218 | -- Name: table2_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 219 | -- 220 | 221 | ALTER TABLE ONLY table2 222 | ADD CONSTRAINT table2_pkey PRIMARY KEY (id); 223 | 224 | 225 | -- 226 | -- TOC entry 1849 (class 2606 OID 41378) 227 | -- Name: table3_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 228 | -- 229 | 230 | ALTER TABLE ONLY table3 231 | ADD CONSTRAINT table3_pkey PRIMARY KEY (id); 232 | 233 | 234 | -- 235 | -- TOC entry 1851 (class 2606 OID 41401) 236 | -- Name: u_table3; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 237 | -- 238 | 239 | ALTER TABLE ONLY table3 240 | ADD CONSTRAINT u_table3 UNIQUE (id, nom); 241 | 242 | 243 | -- 244 | -- TOC entry 1856 (class 2606 OID 41359) 245 | -- Name: contact_company_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres 246 | -- 247 | 248 | ALTER TABLE ONLY contact 249 | ADD CONSTRAINT contact_company_id_fkey FOREIGN KEY (company_id) REFERENCES company(id); 250 | 251 | 252 | -- 253 | -- TOC entry 1857 (class 2606 OID 41402) 254 | -- Name: fk_table2_table3; Type: FK CONSTRAINT; Schema: public; Owner: postgres 255 | -- 256 | 257 | ALTER TABLE ONLY table2 258 | ADD CONSTRAINT fk_table2_table3 FOREIGN KEY (id_table3, nom_table3) REFERENCES table3(id, nom) ON UPDATE CASCADE ON DELETE RESTRICT; 259 | 260 | 261 | -- 262 | -- TOC entry 1858 (class 2606 OID 41390) 263 | -- Name: table1_ibfk_1; Type: FK CONSTRAINT; Schema: public; Owner: postgres 264 | -- 265 | 266 | ALTER TABLE ONLY table1 267 | ADD CONSTRAINT table1_ibfk_1 FOREIGN KEY (id_table2) REFERENCES table2(id); 268 | 269 | 270 | -- 271 | -- TOC entry 1859 (class 2606 OID 41395) 272 | -- Name: table1_ibfk_2; Type: FK CONSTRAINT; Schema: public; Owner: postgres 273 | -- 274 | 275 | ALTER TABLE ONLY table1 276 | ADD CONSTRAINT table1_ibfk_2 FOREIGN KEY (id_table3) REFERENCES table3(id) ON DELETE CASCADE; 277 | 278 | 279 | -- 280 | -- TOC entry 1978 (class 0 OID 0) 281 | -- Dependencies: 5 282 | -- Name: public; Type: ACL; Schema: -; Owner: postgres 283 | -- 284 | 285 | REVOKE ALL ON SCHEMA public FROM PUBLIC; 286 | REVOKE ALL ON SCHEMA public FROM postgres; 287 | GRANT ALL ON SCHEMA public TO postgres; 288 | GRANT ALL ON SCHEMA public TO PUBLIC; 289 | 290 | 291 | -- Completed on 2014-09-25 15:26:39 292 | 293 | -- 294 | -- PostgreSQL database dump complete 295 | -- 296 | 297 | -------------------------------------------------------------------------------- /src/test/resources/postgres.backup: -------------------------------------------------------------------------------- 1 | -- 2 | -- PostgreSQL database dump 3 | -- 4 | 5 | -- Dumped from database version 9.3.1 6 | -- Dumped by pg_dump version 9.3.1 7 | -- Started on 2014-09-25 15:26:38 8 | 9 | SET statement_timeout = 0; 10 | SET lock_timeout = 0; 11 | SET client_encoding = 'UTF8'; 12 | SET standard_conforming_strings = on; 13 | SET check_function_bodies = false; 14 | SET client_min_messages = warning; 15 | 16 | -- 17 | -- TOC entry 175 (class 3079 OID 11750) 18 | -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 19 | -- 20 | 21 | CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; 22 | 23 | 24 | -- 25 | -- TOC entry 1979 (class 0 OID 0) 26 | -- Dependencies: 175 27 | -- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 28 | -- 29 | 30 | COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; 31 | 32 | 33 | SET search_path = public, pg_catalog; 34 | 35 | SET default_tablespace = ''; 36 | 37 | SET default_with_oids = false; 38 | 39 | -- 40 | -- TOC entry 170 (class 1259 OID 41339) 41 | -- Name: company; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 42 | -- 43 | 44 | CREATE TABLE company ( 45 | id integer NOT NULL, 46 | duns character varying(9), 47 | name character varying(255), 48 | address character varying(255), 49 | zip_code character varying(5), 50 | company_creation date, 51 | website character varying(255), 52 | phone_number character varying(255), 53 | city character varying(255) 54 | ); 55 | 56 | 57 | ALTER TABLE public.company OWNER TO postgres; 58 | 59 | -- 60 | -- TOC entry 171 (class 1259 OID 41349) 61 | -- Name: contact; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 62 | -- 63 | 64 | CREATE TABLE contact ( 65 | id character varying(255) NOT NULL, 66 | email character varying(255) NOT NULL, 67 | age integer, 68 | name character varying(255), 69 | firstname character varying(255), 70 | company_id integer 71 | ); 72 | 73 | 74 | ALTER TABLE public.contact OWNER TO postgres; 75 | 76 | -- 77 | -- TOC entry 174 (class 1259 OID 41384) 78 | -- Name: table1; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 79 | -- 80 | 81 | CREATE TABLE table1 ( 82 | id integer NOT NULL, 83 | nom character varying(100) DEFAULT NULL::character varying, 84 | dt date, 85 | num integer, 86 | id_table2 integer, 87 | id_table3 integer 88 | ); 89 | 90 | 91 | ALTER TABLE public.table1 OWNER TO postgres; 92 | 93 | -- 94 | -- TOC entry 173 (class 1259 OID 41379) 95 | -- Name: table2; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 96 | -- 97 | 98 | CREATE TABLE table2 ( 99 | id integer NOT NULL, 100 | nom character varying(100), 101 | id_table3 integer, 102 | nom_table3 character varying(100) 103 | ); 104 | 105 | 106 | ALTER TABLE public.table2 OWNER TO postgres; 107 | 108 | -- 109 | -- TOC entry 172 (class 1259 OID 41374) 110 | -- Name: table3; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 111 | -- 112 | 113 | CREATE TABLE table3 ( 114 | id integer NOT NULL, 115 | nom character varying(100) 116 | ); 117 | 118 | 119 | ALTER TABLE public.table3 OWNER TO postgres; 120 | 121 | -- 122 | -- TOC entry 1967 (class 0 OID 41339) 123 | -- Dependencies: 170 124 | -- Data for Name: company; Type: TABLE DATA; Schema: public; Owner: postgres 125 | -- 126 | 127 | COPY company (id, duns, name, address, zip_code, company_creation, website, phone_number, city) FROM stdin; 128 | \. 129 | 130 | 131 | -- 132 | -- TOC entry 1968 (class 0 OID 41349) 133 | -- Dependencies: 171 134 | -- Data for Name: contact; Type: TABLE DATA; Schema: public; Owner: postgres 135 | -- 136 | 137 | COPY contact (id, email, age, name, firstname, company_id) FROM stdin; 138 | \. 139 | 140 | 141 | -- 142 | -- TOC entry 1971 (class 0 OID 41384) 143 | -- Dependencies: 174 144 | -- Data for Name: table1; Type: TABLE DATA; Schema: public; Owner: postgres 145 | -- 146 | 147 | COPY table1 (id, nom, dt, num, id_table2, id_table3) FROM stdin; 148 | \. 149 | 150 | 151 | -- 152 | -- TOC entry 1970 (class 0 OID 41379) 153 | -- Dependencies: 173 154 | -- Data for Name: table2; Type: TABLE DATA; Schema: public; Owner: postgres 155 | -- 156 | 157 | COPY table2 (id, nom, id_table3, nom_table3) FROM stdin; 158 | \. 159 | 160 | 161 | -- 162 | -- TOC entry 1969 (class 0 OID 41374) 163 | -- Dependencies: 172 164 | -- Data for Name: table3; Type: TABLE DATA; Schema: public; Owner: postgres 165 | -- 166 | 167 | COPY table3 (id, nom) FROM stdin; 168 | \. 169 | 170 | 171 | -- 172 | -- TOC entry 1841 (class 2606 OID 41348) 173 | -- Name: company_duns_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 174 | -- 175 | 176 | ALTER TABLE ONLY company 177 | ADD CONSTRAINT company_duns_key UNIQUE (duns); 178 | 179 | 180 | -- 181 | -- TOC entry 1843 (class 2606 OID 41346) 182 | -- Name: company_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 183 | -- 184 | 185 | ALTER TABLE ONLY company 186 | ADD CONSTRAINT company_pkey PRIMARY KEY (id); 187 | 188 | 189 | -- 190 | -- TOC entry 1845 (class 2606 OID 41358) 191 | -- Name: contact_email_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 192 | -- 193 | 194 | ALTER TABLE ONLY contact 195 | ADD CONSTRAINT contact_email_key UNIQUE (email); 196 | 197 | 198 | -- 199 | -- TOC entry 1847 (class 2606 OID 41356) 200 | -- Name: contact_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 201 | -- 202 | 203 | ALTER TABLE ONLY contact 204 | ADD CONSTRAINT contact_pkey PRIMARY KEY (id); 205 | 206 | 207 | -- 208 | -- TOC entry 1855 (class 2606 OID 41389) 209 | -- Name: table1_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 210 | -- 211 | 212 | ALTER TABLE ONLY table1 213 | ADD CONSTRAINT table1_pkey PRIMARY KEY (id); 214 | 215 | 216 | -- 217 | -- TOC entry 1853 (class 2606 OID 41383) 218 | -- Name: table2_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 219 | -- 220 | 221 | ALTER TABLE ONLY table2 222 | ADD CONSTRAINT table2_pkey PRIMARY KEY (id); 223 | 224 | 225 | -- 226 | -- TOC entry 1849 (class 2606 OID 41378) 227 | -- Name: table3_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 228 | -- 229 | 230 | ALTER TABLE ONLY table3 231 | ADD CONSTRAINT table3_pkey PRIMARY KEY (id); 232 | 233 | 234 | -- 235 | -- TOC entry 1851 (class 2606 OID 41401) 236 | -- Name: u_table3; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 237 | -- 238 | 239 | ALTER TABLE ONLY table3 240 | ADD CONSTRAINT u_table3 UNIQUE (id, nom); 241 | 242 | 243 | -- 244 | -- TOC entry 1856 (class 2606 OID 41359) 245 | -- Name: contact_company_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres 246 | -- 247 | 248 | ALTER TABLE ONLY contact 249 | ADD CONSTRAINT contact_company_id_fkey FOREIGN KEY (company_id) REFERENCES company(id); 250 | 251 | 252 | -- 253 | -- TOC entry 1857 (class 2606 OID 41402) 254 | -- Name: fk_table2_table3; Type: FK CONSTRAINT; Schema: public; Owner: postgres 255 | -- 256 | 257 | ALTER TABLE ONLY table2 258 | ADD CONSTRAINT fk_table2_table3 FOREIGN KEY (id_table3, nom_table3) REFERENCES table3(id, nom) ON UPDATE CASCADE ON DELETE RESTRICT; 259 | 260 | 261 | -- 262 | -- TOC entry 1858 (class 2606 OID 41390) 263 | -- Name: table1_ibfk_1; Type: FK CONSTRAINT; Schema: public; Owner: postgres 264 | -- 265 | 266 | ALTER TABLE ONLY table1 267 | ADD CONSTRAINT table1_ibfk_1 FOREIGN KEY (id_table2) REFERENCES table2(id); 268 | 269 | 270 | -- 271 | -- TOC entry 1859 (class 2606 OID 41395) 272 | -- Name: table1_ibfk_2; Type: FK CONSTRAINT; Schema: public; Owner: postgres 273 | -- 274 | 275 | ALTER TABLE ONLY table1 276 | ADD CONSTRAINT table1_ibfk_2 FOREIGN KEY (id_table3) REFERENCES table3(id) ON DELETE CASCADE; 277 | 278 | 279 | -- 280 | -- TOC entry 1978 (class 0 OID 0) 281 | -- Dependencies: 5 282 | -- Name: public; Type: ACL; Schema: -; Owner: postgres 283 | -- 284 | 285 | REVOKE ALL ON SCHEMA public FROM PUBLIC; 286 | REVOKE ALL ON SCHEMA public FROM postgres; 287 | GRANT ALL ON SCHEMA public TO postgres; 288 | GRANT ALL ON SCHEMA public TO PUBLIC; 289 | 290 | 291 | -- Completed on 2014-09-25 15:26:39 292 | 293 | -- 294 | -- PostgreSQL database dump complete 295 | -- 296 | 297 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/export/ExportToPivotFormatTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.export; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import com.restlet.sqlimport.model.resdef.Resdef; 8 | import com.restlet.sqlimport.model.sql.Column; 9 | import com.restlet.sqlimport.model.sql.Database; 10 | import com.restlet.sqlimport.model.sql.ForeignKey; 11 | import com.restlet.sqlimport.model.sql.Table; 12 | 13 | 14 | public class ExportToPivotFormatTest { 15 | 16 | private DatabaseToResdef databaseToResdef = new DatabaseToResdef(); 17 | private ResdefToJson resdefToJson = new ResdefToJson(); 18 | 19 | @Test 20 | public void getLines1() { 21 | // Given 22 | final Database database = new Database(); 23 | 24 | // When 25 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 26 | final String content = resdefToJson.resdefToJson(resdef); 27 | 28 | // Then 29 | assertEquals("[]", content); 30 | } 31 | 32 | @Test 33 | public void getLines2() { 34 | // Given 35 | final Database database = new Database(); 36 | final Table table1 = new Table(); 37 | database.getTables().add(table1); 38 | table1.setName("table 1"); 39 | 40 | // When 41 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 42 | final String content = resdefToJson.resdefToJson(resdef); 43 | 44 | // Then 45 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true}]}]", content); 46 | } 47 | 48 | @Test 49 | public void getLines3() { 50 | // Given 51 | final Database database = new Database(); 52 | final Table table1 = new Table(); 53 | database.getTables().add(table1); 54 | table1.setName("table 1"); 55 | final Column column1 = new Column(); 56 | column1.setName("column 1"); 57 | table1.getColumnByNames().put(column1.getName(), column1); 58 | 59 | // When 60 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 61 | final String content = resdefToJson.resdefToJson(resdef); 62 | 63 | // Then 64 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"nullable\":true}]}]", content); 65 | } 66 | 67 | @Test 68 | public void getLines4_primaryKey() { 69 | // Given 70 | final Database database = new Database(); 71 | final Table table1 = new Table(); 72 | database.getTables().add(table1); 73 | table1.setName("table 1"); 74 | final Column column1 = new Column(); 75 | column1.setName("column 1"); 76 | table1.getColumnByNames().put(column1.getName(), column1); 77 | table1.getPrimaryKey().getColumnNames().add("column 1"); 78 | 79 | // When 80 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 81 | final String content = resdefToJson.resdefToJson(resdef); 82 | 83 | // Then 84 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"column 1\",\"isPrimaryKey\":true,\"nullable\":true}]}]", content); 85 | } 86 | 87 | @Test 88 | public void getLines5_primaryKey_with_more_than_one_column() { 89 | // Given 90 | final Database database = new Database(); 91 | final Table table1 = new Table(); 92 | database.getTables().add(table1); 93 | table1.setName("table 1"); 94 | final Column column1 = new Column(); 95 | column1.setName("column 1"); 96 | table1.getColumnByNames().put(column1.getName(), column1); 97 | table1.getPrimaryKey().getColumnNames().add("column 1"); 98 | table1.getPrimaryKey().getColumnNames().add("column 2"); 99 | 100 | // When 101 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 102 | final String content = resdefToJson.resdefToJson(resdef); 103 | 104 | // Then 105 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"nullable\":true}]}]", content); 106 | } 107 | 108 | @Test 109 | public void getLines_foreignKey() { 110 | // Given 111 | final Database database = new Database(); 112 | final Table table1 = new Table(); 113 | database.getTables().add(table1); 114 | table1.setName("table 1"); 115 | final Column column1 = new Column(); 116 | column1.setName("column 1"); 117 | table1.getColumnByNames().put(column1.getName(), column1); 118 | final ForeignKey foreignKey = new ForeignKey(); 119 | foreignKey.setTableNameOrigin("tableNameOrigin"); 120 | foreignKey.setTableNameTarget("tableNameTarget"); 121 | foreignKey.getColumnNameOrigins().add("column 1"); 122 | foreignKey.getColumnNameTargets().add("columnNameTarget"); 123 | table1.getForeignKeys().add(foreignKey); 124 | 125 | // When 126 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 127 | final String content = resdefToJson.resdefToJson(resdef); 128 | 129 | // Then 130 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"tableNameTarget\",\"nullable\":true,\"minOccurs\":0,\"maxOccurs\":\"*\"}]}]", content); 131 | } 132 | 133 | @Test 134 | public void getLines6() { 135 | // Given 136 | final Database database = new Database(); 137 | final Table table1 = new Table(); 138 | database.getTables().add(table1); 139 | table1.setName("table 1"); 140 | final Column column1 = new Column(); 141 | table1.getColumnByNames().put(column1.getName(), column1); 142 | column1.setName("column 1"); 143 | column1.setType("type"); 144 | column1.setConvertedType("convertedType"); 145 | column1.setLength("length"); 146 | column1.setIsNotNull(true); 147 | column1.setDefaultValue("default"); 148 | 149 | // When 150 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 151 | final String content = resdefToJson.resdefToJson(resdef); 152 | 153 | // Then 154 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"convertedType\",\"nullable\":false,\"defaultValue\":\"default\"}]}]", content); 155 | } 156 | 157 | @Test 158 | public void getLines7() { 159 | // Given 160 | final Database database = new Database(); 161 | final Table table1 = new Table(); 162 | database.getTables().add(table1); 163 | table1.setName("table 1"); 164 | final Column column1 = new Column(); 165 | table1.getColumnByNames().put(column1.getName(), column1); 166 | column1.setName("column 1"); 167 | column1.setType("type"); 168 | column1.setConvertedType("convertedType"); 169 | column1.setLength("length"); 170 | column1.setIsNotNull(false); 171 | column1.setDefaultValue("default"); 172 | 173 | // When 174 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 175 | final String content = resdefToJson.resdefToJson(resdef); 176 | 177 | // Then 178 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"convertedType\",\"nullable\":true,\"defaultValue\":\"default\"}]}]", content); 179 | } 180 | 181 | @Test 182 | public void getLines8() { 183 | // Given 184 | final Database database = new Database(); 185 | final Table table1 = new Table(); 186 | database.getTables().add(table1); 187 | table1.setName("table 1"); 188 | final Column column1 = new Column(); 189 | table1.getColumnByNames().put(column1.getName(), column1); 190 | column1.setName("column 1"); 191 | column1.setType("type"); 192 | column1.setConvertedType("convertedType"); 193 | column1.setLength("length"); 194 | column1.setIsNotNull(false); 195 | column1.setDefaultValue("default"); 196 | final ForeignKey foreignKey = new ForeignKey(); 197 | foreignKey.setTableNameOrigin("tableNameOrigin"); 198 | foreignKey.setTableNameTarget("tableNameTarget"); 199 | foreignKey.getColumnNameOrigins().add("column 1"); 200 | foreignKey.getColumnNameTargets().add("columnNameTarget"); 201 | table1.getForeignKeys().add(foreignKey); 202 | 203 | // When 204 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 205 | final String content = resdefToJson.resdefToJson(resdef); 206 | 207 | // Then 208 | assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"type\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"tableNameTarget\",\"nullable\":true,\"defaultValue\":\"default\",\"minOccurs\":0,\"maxOccurs\":\"*\"}]}]", content); 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /src/test/resources/oracle_sqldeveloper.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------- 2 | -- File created - Monday-September-29-2014 3 | -------------------------------------------------------- 4 | -------------------------------------------------------- 5 | -- DDL for Table TABLE1 6 | -------------------------------------------------------- 7 | 8 | CREATE TABLE "SYSTEM"."TABLE1" 9 | ( "ID" NUMBER(*,0), 10 | "NOM" VARCHAR2(100 BYTE), 11 | "DT" DATE, 12 | "NUM" NUMBER(*,0) DEFAULT 1, 13 | "ID_TABLE2" NUMBER(*,0), 14 | "ID_TABLE3" NUMBER(*,0) 15 | ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 16 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 17 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 18 | TABLESPACE "SYSTEM" ; 19 | -------------------------------------------------------- 20 | -- DDL for Table TABLE2 21 | -------------------------------------------------------- 22 | 23 | CREATE TABLE "SYSTEM"."TABLE2" 24 | ( "ID" NUMBER(*,0), 25 | "NOM" VARCHAR2(100 BYTE), 26 | "ID_TABLE3" NUMBER(*,0), 27 | "NOM_TABLE3" VARCHAR2(100 BYTE) 28 | ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 29 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 30 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 31 | TABLESPACE "SYSTEM" ; 32 | -------------------------------------------------------- 33 | -- DDL for Table TABLE3 34 | -------------------------------------------------------- 35 | 36 | CREATE TABLE "SYSTEM"."TABLE3" 37 | ( "ID" NUMBER(*,0), 38 | "NOM" VARCHAR2(100 BYTE) 39 | ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 40 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 41 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 42 | TABLESPACE "SYSTEM" ; 43 | -------------------------------------------------------- 44 | -- DDL for Table COMPANY 45 | -------------------------------------------------------- 46 | 47 | CREATE TABLE "SYSTEM"."COMPANY" 48 | ( "ID" NUMBER(*,0), 49 | "DUNS" VARCHAR2(9 BYTE), 50 | "NAME" VARCHAR2(255 BYTE), 51 | "ADDRESS" VARCHAR2(255 BYTE), 52 | "ZIP_CODE" VARCHAR2(5 BYTE), 53 | "COMPANY_CREATION" DATE, 54 | "WEBSITE" VARCHAR2(255 BYTE), 55 | "PHONE_NUMBER" VARCHAR2(255 BYTE), 56 | "CITY" VARCHAR2(255 BYTE) 57 | ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 58 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 59 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 60 | TABLESPACE "SYSTEM" ; 61 | -------------------------------------------------------- 62 | -- DDL for Table CONTACT 63 | -------------------------------------------------------- 64 | 65 | CREATE TABLE "SYSTEM"."CONTACT" 66 | ( "ID" VARCHAR2(255 BYTE), 67 | "EMAIL" VARCHAR2(255 BYTE), 68 | "AGE" NUMBER(*,0), 69 | "NAME" VARCHAR2(255 BYTE), 70 | "FIRSTNAME" VARCHAR2(255 BYTE), 71 | "COMPANY_ID" NUMBER(*,0) 72 | ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 73 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 74 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 75 | TABLESPACE "SYSTEM" ; 76 | REM INSERTING into SYSTEM.TABLE1 77 | SET DEFINE OFF; 78 | REM INSERTING into SYSTEM.TABLE2 79 | SET DEFINE OFF; 80 | REM INSERTING into SYSTEM.TABLE3 81 | SET DEFINE OFF; 82 | REM INSERTING into SYSTEM.COMPANY 83 | SET DEFINE OFF; 84 | REM INSERTING into SYSTEM.CONTACT 85 | SET DEFINE OFF; 86 | -------------------------------------------------------- 87 | -- Constraints for Table TABLE1 88 | -------------------------------------------------------- 89 | 90 | ALTER TABLE "SYSTEM"."TABLE1" ADD PRIMARY KEY ("ID") 91 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 92 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 93 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 94 | TABLESPACE "SYSTEM" ENABLE; 95 | ALTER TABLE "SYSTEM"."TABLE1" MODIFY ("DT" NOT NULL ENABLE); 96 | ALTER TABLE "SYSTEM"."TABLE1" MODIFY ("ID" NOT NULL ENABLE); 97 | -------------------------------------------------------- 98 | -- Constraints for Table TABLE2 99 | -------------------------------------------------------- 100 | 101 | ALTER TABLE "SYSTEM"."TABLE2" ADD PRIMARY KEY ("ID") 102 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 103 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 104 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 105 | TABLESPACE "SYSTEM" ENABLE; 106 | ALTER TABLE "SYSTEM"."TABLE2" MODIFY ("ID" NOT NULL ENABLE); 107 | -------------------------------------------------------- 108 | -- Constraints for Table TABLE3 109 | -------------------------------------------------------- 110 | 111 | ALTER TABLE "SYSTEM"."TABLE3" ADD CONSTRAINT "U_TABLE3" UNIQUE ("ID", "NOM") 112 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 113 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 114 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 115 | TABLESPACE "SYSTEM" ENABLE; 116 | ALTER TABLE "SYSTEM"."TABLE3" ADD PRIMARY KEY ("ID") 117 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 118 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 119 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 120 | TABLESPACE "SYSTEM" ENABLE; 121 | ALTER TABLE "SYSTEM"."TABLE3" MODIFY ("ID" NOT NULL ENABLE); 122 | -------------------------------------------------------- 123 | -- Constraints for Table COMPANY 124 | -------------------------------------------------------- 125 | 126 | ALTER TABLE "SYSTEM"."COMPANY" ADD UNIQUE ("DUNS") 127 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 128 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 129 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 130 | TABLESPACE "SYSTEM" ENABLE; 131 | ALTER TABLE "SYSTEM"."COMPANY" ADD PRIMARY KEY ("ID") 132 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 133 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 134 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 135 | TABLESPACE "SYSTEM" ENABLE; 136 | ALTER TABLE "SYSTEM"."COMPANY" MODIFY ("ID" NOT NULL ENABLE); 137 | -------------------------------------------------------- 138 | -- Constraints for Table CONTACT 139 | -------------------------------------------------------- 140 | 141 | ALTER TABLE "SYSTEM"."CONTACT" ADD UNIQUE ("EMAIL") 142 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 143 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 144 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 145 | TABLESPACE "SYSTEM" ENABLE; 146 | ALTER TABLE "SYSTEM"."CONTACT" ADD PRIMARY KEY ("ID") 147 | USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 148 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 149 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 150 | TABLESPACE "SYSTEM" ENABLE; 151 | ALTER TABLE "SYSTEM"."CONTACT" MODIFY ("EMAIL" NOT NULL ENABLE); 152 | -------------------------------------------------------- 153 | -- Ref Constraints for Table TABLE1 154 | -------------------------------------------------------- 155 | 156 | ALTER TABLE "SYSTEM"."TABLE1" ADD CONSTRAINT "SYS_C007004" FOREIGN KEY ("ID_TABLE2") 157 | REFERENCES "SYSTEM"."TABLE2" ("ID") ON DELETE CASCADE ENABLE; 158 | ALTER TABLE "SYSTEM"."TABLE1" ADD FOREIGN KEY ("ID_TABLE3") 159 | REFERENCES "SYSTEM"."TABLE3" ("ID") ON DELETE CASCADE ENABLE; 160 | -------------------------------------------------------- 161 | -- Ref Constraints for Table TABLE2 162 | -------------------------------------------------------- 163 | 164 | ALTER TABLE "SYSTEM"."TABLE2" ADD CONSTRAINT "FK_TABLE2_TABLE3" FOREIGN KEY ("ID_TABLE3", "NOM_TABLE3") 165 | REFERENCES "SYSTEM"."TABLE3" ("ID", "NOM") ON DELETE CASCADE ENABLE; 166 | -------------------------------------------------------- 167 | -- Ref Constraints for Table CONTACT 168 | -------------------------------------------------------- 169 | 170 | ALTER TABLE "SYSTEM"."CONTACT" ADD FOREIGN KEY ("COMPANY_ID") 171 | REFERENCES "SYSTEM"."COMPANY" ("ID") ENABLE; 172 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/parser/CreateTableParseListener.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.parser; 2 | 3 | import com.restlet.sqlimport.model.sql.Column; 4 | import com.restlet.sqlimport.model.sql.Database; 5 | import com.restlet.sqlimport.model.sql.ForeignKey; 6 | import com.restlet.sqlimport.model.sql.Table; 7 | import com.restlet.sqlimport.parser.SqlParser.Any_nameContext; 8 | import com.restlet.sqlimport.parser.SqlParser.Column_constraint_not_nullContext; 9 | import com.restlet.sqlimport.parser.SqlParser.Column_constraint_primary_keyContext; 10 | import com.restlet.sqlimport.parser.SqlParser.Column_defContext; 11 | import com.restlet.sqlimport.parser.SqlParser.Column_default_valueContext; 12 | import com.restlet.sqlimport.parser.SqlParser.Column_nameContext; 13 | import com.restlet.sqlimport.parser.SqlParser.Create_table_stmtContext; 14 | import com.restlet.sqlimport.parser.SqlParser.Fk_origin_column_nameContext; 15 | import com.restlet.sqlimport.parser.SqlParser.Fk_target_column_nameContext; 16 | import com.restlet.sqlimport.parser.SqlParser.Foreign_key_clauseContext; 17 | import com.restlet.sqlimport.parser.SqlParser.Foreign_tableContext; 18 | import com.restlet.sqlimport.parser.SqlParser.Indexed_columnContext; 19 | import com.restlet.sqlimport.parser.SqlParser.NameContext; 20 | import com.restlet.sqlimport.parser.SqlParser.Table_constraint_foreign_keyContext; 21 | import com.restlet.sqlimport.parser.SqlParser.Table_constraint_primary_keyContext; 22 | import com.restlet.sqlimport.parser.SqlParser.Table_nameContext; 23 | import com.restlet.sqlimport.parser.SqlParser.Type_nameContext; 24 | import com.restlet.sqlimport.parser.SqlParser.UnknownContext; 25 | import com.restlet.sqlimport.util.Util; 26 | 27 | /** 28 | * Parse Listener only for CREATE TABLE statements parsing. 29 | */ 30 | public class CreateTableParseListener extends SqlBaseListener { 31 | 32 | /** 33 | * Debug mode to display ANTLR v4 contexts. 34 | */ 35 | private static boolean DEBUG = true; 36 | 37 | /** 38 | * ANTLR Parser 39 | */ 40 | private final SqlParser sqlParser; 41 | 42 | /** 43 | * Database schema 44 | */ 45 | private final Database database; 46 | 47 | private Table table; 48 | private Column column; 49 | private ForeignKey foreignKey; 50 | 51 | /** Positions */ 52 | private boolean inCreateTable = false; // CREATE TABLE 53 | private boolean inColumnDef = false; // Column definition 54 | private boolean inTypeName = false; // Column type in the column definition 55 | private boolean inTable_constraint_primary_key = false; // PRIMARY KEY 56 | private boolean inTable_constraint_foreign_key = false; // FOREIGN KEY 57 | 58 | /** 59 | * Utils methods. 60 | */ 61 | Util util = new Util(); 62 | 63 | /** 64 | * Constructor. 65 | * @param sqlParser SQL parser 66 | * @param database Database 67 | */ 68 | public CreateTableParseListener(final SqlParser sqlParser, final Database database) { 69 | this.sqlParser = sqlParser; 70 | this.database = database; 71 | } 72 | 73 | /** 74 | * Used only for debug, its called for each token based on the token "name". 75 | */ 76 | @Override 77 | public void exitAny_name(final Any_nameContext ctx) { 78 | if(DEBUG) { 79 | System.out.println(ctx.getText() + " - ctx : " + ctx.toInfoString(sqlParser)); 80 | } 81 | } 82 | 83 | @Override 84 | public void exitUnknown(final UnknownContext ctx) { 85 | if(DEBUG) { 86 | System.out.println(ctx.getText() + " - ctx : " + ctx.toInfoString(sqlParser)); 87 | } 88 | } 89 | 90 | //--- CREATE TABLE 91 | 92 | /** 93 | * enter CREATE TABLE 94 | */ 95 | @Override 96 | public void enterCreate_table_stmt(final Create_table_stmtContext ctx) { 97 | inCreateTable = true; 98 | table = new Table(); 99 | } 100 | 101 | /** 102 | * exit CREATE TABLE 103 | */ 104 | @Override 105 | public void exitCreate_table_stmt(final Create_table_stmtContext ctx) { 106 | database.getTables().add(table); 107 | table = null; 108 | inCreateTable = false; 109 | } 110 | 111 | /** 112 | * Table name 113 | */ 114 | @Override 115 | public void exitTable_name(final Table_nameContext ctx) { 116 | if(inCreateTable) { 117 | table.setName(util.unformatSqlName(ctx.getText())); 118 | } 119 | } 120 | 121 | //--- Column definition 122 | 123 | /** 124 | * enter Column definition 125 | */ 126 | @Override 127 | public void enterColumn_def(final Column_defContext ctx) { 128 | inColumnDef = true; 129 | if(inCreateTable) { 130 | column = new Column(); 131 | } 132 | } 133 | 134 | /** 135 | * exit Column definition 136 | */ 137 | @Override 138 | public void exitColumn_def(final Column_defContext ctx) { 139 | if(inCreateTable) { 140 | if((column != null) && (column.getName() != null)) { 141 | table.getColumnByNames().put(column.getName(), column); 142 | } 143 | column = null; 144 | } 145 | inColumnDef = false; 146 | } 147 | 148 | /** 149 | * Column name 150 | */ 151 | @Override 152 | public void exitColumn_name(final Column_nameContext ctx) { 153 | if(inCreateTable && inColumnDef) { 154 | column.setName(util.unformatSqlName(ctx.getText())); 155 | } 156 | } 157 | 158 | //--- Column type 159 | 160 | /** 161 | * enter Column type 162 | */ 163 | @Override 164 | public void enterType_name(final Type_nameContext ctx) { 165 | inTypeName = true; 166 | } 167 | 168 | /** 169 | * exit column type 170 | */ 171 | @Override 172 | public void exitType_name(final Type_nameContext ctx) { 173 | inTypeName = false; 174 | } 175 | 176 | /** 177 | * Name. It could be :
178 | * - type name 179 | */ 180 | @Override 181 | public void exitName(final NameContext ctx) { 182 | if(inCreateTable && inColumnDef && inTypeName) { 183 | if(column.getType() == null) { 184 | column.setType(util.unformatSqlName(ctx.getText())); 185 | } else { 186 | column.setType(column.getType() + " " + util.unformatSqlName(ctx.getText())); 187 | } 188 | } 189 | } 190 | 191 | //--- Constraints 192 | 193 | //--- Default 194 | 195 | @Override 196 | public void exitColumn_default_value(final Column_default_valueContext ctx) { 197 | if(inCreateTable && inColumnDef) { 198 | column.setDefaultValue(util.unformatSqlName(ctx.getText())); 199 | } 200 | } 201 | 202 | //--- Not Null 203 | 204 | @Override 205 | public void exitColumn_constraint_not_null( 206 | final Column_constraint_not_nullContext ctx) { 207 | if(inCreateTable && inColumnDef) { 208 | column.setIsNotNull(true); 209 | } 210 | } 211 | 212 | //--- Primary Key in Column definition 213 | 214 | @Override 215 | public void exitColumn_constraint_primary_key( 216 | final Column_constraint_primary_keyContext ctx) { 217 | if(inCreateTable && inColumnDef) { 218 | table.getPrimaryKey().getColumnNames().add(column.getName()); 219 | } 220 | } 221 | 222 | //--- Primary Key in CREATE TABLE or in ALTER TABLE 223 | 224 | @Override 225 | public void enterTable_constraint_primary_key( 226 | final Table_constraint_primary_keyContext ctx) { 227 | inTable_constraint_primary_key = true; 228 | } 229 | 230 | @Override 231 | public void exitTable_constraint_primary_key( 232 | final Table_constraint_primary_keyContext ctx) { 233 | inTable_constraint_primary_key = false; 234 | } 235 | 236 | @Override 237 | public void exitIndexed_column(final Indexed_columnContext ctx) { 238 | if(inCreateTable && inTable_constraint_primary_key) { 239 | final String columnName = util.unformatSqlName(ctx.getText()); 240 | table.getPrimaryKey().getColumnNames().add(columnName); 241 | } 242 | } 243 | 244 | //--- Foreign Key in CREATE TABLE or in ALTER TABLE 245 | 246 | @Override 247 | public void enterTable_constraint_foreign_key( 248 | final Table_constraint_foreign_keyContext ctx) { 249 | inTable_constraint_foreign_key = true; 250 | if(inCreateTable) { 251 | foreignKey = new ForeignKey(); 252 | foreignKey.setTableNameOrigin(table.getName()); 253 | } 254 | } 255 | 256 | @Override 257 | public void exitTable_constraint_foreign_key( 258 | final Table_constraint_foreign_keyContext ctx) { 259 | if(inCreateTable) { 260 | foreignKey.setTableNameOrigin(table.getName()); 261 | table.getForeignKeys().add(foreignKey); 262 | foreignKey = null; 263 | } 264 | inTable_constraint_foreign_key = false; 265 | } 266 | 267 | @Override 268 | public void enterForeign_key_clause(final Foreign_key_clauseContext ctx) { 269 | if(inCreateTable && inColumnDef) { 270 | foreignKey = new ForeignKey(); 271 | foreignKey.setTableNameOrigin(table.getName()); 272 | foreignKey.getColumnNameOrigins().add(column.getName()); 273 | } 274 | } 275 | 276 | @Override 277 | public void exitForeign_key_clause(final Foreign_key_clauseContext ctx) { 278 | if(inCreateTable && inColumnDef) { 279 | foreignKey.setTableNameOrigin(table.getName()); 280 | table.getForeignKeys().add(foreignKey); 281 | foreignKey = null; 282 | } 283 | } 284 | 285 | @Override 286 | public void exitForeign_table(final Foreign_tableContext ctx) { 287 | if(inCreateTable) { 288 | foreignKey.setTableNameTarget(util.unformatSqlName(ctx.getText())); 289 | } 290 | } 291 | 292 | @Override 293 | public void exitFk_origin_column_name( 294 | final Fk_origin_column_nameContext ctx) { 295 | if(foreignKey != null) { 296 | foreignKey.getColumnNameOrigins().add(util.unformatSqlName(ctx.getText())); 297 | } 298 | } 299 | 300 | @Override 301 | public void exitFk_target_column_name( 302 | final Fk_target_column_nameContext ctx) { 303 | if(inCreateTable) { 304 | foreignKey.getColumnNameTargets().add(util.unformatSqlName(ctx.getText())); 305 | } 306 | } 307 | 308 | } 309 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/report/Report.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.report; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.ArrayList; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | import com.restlet.sqlimport.model.resdef.Resdef; 9 | import com.restlet.sqlimport.model.sql.Database; 10 | import com.restlet.sqlimport.model.sql.Table; 11 | 12 | /** 13 | * Report. 14 | */ 15 | public class Report { 16 | 17 | /** 18 | * Date. 19 | */ 20 | private final Date date = new Date(); 21 | 22 | /** 23 | * Global status. 24 | */ 25 | private ReportStatus reportStatus; 26 | 27 | /** 28 | * Report lines. 29 | */ 30 | private List reportLines = new ArrayList(); 31 | 32 | /** 33 | * Number of created entities 34 | */ 35 | private int nbCreatedEntity; 36 | 37 | /** 38 | * Database schema. 39 | */ 40 | private Database database; 41 | 42 | /** 43 | * Resdef used for JSON export 44 | */ 45 | private Resdef resdef; 46 | 47 | @Override 48 | public String toString() { 49 | final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm"); 50 | 51 | final StringBuffer out = new StringBuffer(); 52 | 53 | // starting sql import process 54 | out.append("\n--------------------"); 55 | out.append("\nTrace : "); 56 | out.append("\n - Location : Starting sql import process"); 57 | out.append("\n - Content : Starting sql import process"); 58 | out.append("\n - Date : ").append(sdf.format(date)); 59 | out.append("\n - Type : SQL schema import"); 60 | out.append("\n"); 61 | 62 | // sql parsing 63 | out.append("\n--------------------"); 64 | out.append("\nTrace : "); 65 | out.append("\n - Location : SQL parsing"); 66 | boolean hasParsingError = false; 67 | for(final ReportLine reportLine : reportLines) { 68 | if(reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) { 69 | hasParsingError = true; 70 | } 71 | } 72 | if(hasParsingError) { 73 | out.append("\n - Level : Error"); 74 | } else { 75 | out.append("\n - Level : Info"); 76 | } 77 | out.append("\n - Date : ").append(sdf.format(date)); 78 | out.append("\n - Content : "); 79 | for(final ReportLine reportLine : reportLines) { 80 | if( (reportLine.getReportLineStatus() == ReportLineStatus.IGNORED) 81 | || (reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) 82 | || (reportLine.getReportLineStatus() == ReportLineStatus.PARSED) ) { 83 | final String begin = "["+reportLine.getReportLineStatus()+"] : "; 84 | out.append("\n").append(begin); 85 | final StringBuffer spaces = new StringBuffer("\n"); 86 | out.append(reportLine.getQuery().replace("\n",spaces.toString())); 87 | if(reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) { 88 | out.append(spaces).append("Error : ").append(reportLine.getMessage()); 89 | } 90 | } 91 | } 92 | 93 | // checking database structure 94 | out.append("\n"); 95 | out.append("\n--------------------"); 96 | out.append("\nTrace : "); 97 | out.append("\n - Location : Checking database structure"); 98 | boolean hasValidationWarning = false; 99 | for(final ReportLine reportLine : reportLines) { 100 | if((reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) 101 | || (reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) 102 | || (reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN)) { 103 | hasValidationWarning = true; 104 | } 105 | } 106 | if(hasValidationWarning) { 107 | out.append("\n - Level : Warning"); 108 | } else { 109 | out.append("\n - Level : Info"); 110 | } 111 | out.append("\n - Date : ").append(sdf.format(date)); 112 | out.append("\n - Content : "); 113 | if(!hasValidationWarning) { 114 | out.append("The database is imported with no warning"); 115 | } else { 116 | for(final ReportLine reportLine : reportLines) { 117 | if((reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) 118 | || (reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) 119 | || (reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN)) { 120 | out.append("\n[WARNING] : "); 121 | if(reportLine.getTable() != null) { 122 | out.append("Table : "+reportLine.getTable()+" - "); 123 | } 124 | if(reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) { 125 | out.append("Composite primary key is not supported : created a new primary key named \"id\""); 126 | } 127 | if(reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN) { 128 | out.append("Foreign key on several columns is not supported and is ignored"); 129 | } 130 | if(reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) { 131 | out.append("The SQL type \""+reportLine.getMessage()+"\" is not supported and replaced by the “String” type"); 132 | } 133 | } 134 | } 135 | } 136 | 137 | // configuring entity store 138 | out.append("\n--------------------"); 139 | out.append("\nTrace : "); 140 | out.append("\n - Location : Configuring entity store"); 141 | out.append("\n - Content : Configuring entity store"); 142 | out.append("\n - Date : ").append(sdf.format(date)); 143 | out.append("\n - Type : SQL schema import"); 144 | out.append("\n"); 145 | 146 | // generating entity store 147 | out.append("\n--------------------"); 148 | out.append("\nTrace : "); 149 | out.append("\n - Location : Generating entity store"); 150 | out.append("\n - Content : Generating entity store"); 151 | out.append("\n - Date : ").append(sdf.format(date)); 152 | out.append("\n - Type : SQL schema import"); 153 | out.append("\n"); 154 | 155 | // SQL schema imported : summary 156 | out.append("\n--------------------"); 157 | out.append("\nTrace : "); 158 | if(reportStatus == ReportStatus.SUCCESS) { 159 | out.append("\n - Location : SQL schema successfully imported : "+nbCreatedEntity+" entities created"); 160 | out.append("\n - Content : "+nbCreatedEntity+" entities successfully created :"); 161 | if(database != null) { 162 | for(final Table table : database.getTables()) { 163 | out.append("\n - ").append(table.getName()); 164 | } 165 | } 166 | } 167 | if(reportStatus == ReportStatus.EMPTY_DATABASE) { 168 | out.append("\n - Location : SQL schema import failed : no table definition found in the SQL file content"); 169 | out.append("\n - Content : No entity created"); 170 | } 171 | out.append("\n - Date : ").append(sdf.format(date)); 172 | out.append("\n - Type : SQL schema import"); 173 | out.append("\n"); 174 | /* 175 | out.append("\n"); 176 | for(final Table table : database.getTables()) { 177 | out.append("\n- entity : ").append(table.getName()); 178 | out.append("\n - fields : [").append(table.getName()); 179 | for(final Column column : table.getColumnByNames()) { 180 | out.append("\n - {name:").append(.getName()); 181 | } 182 | } 183 | */ 184 | return out.toString(); 185 | } 186 | 187 | /** 188 | * Add report for the query. 189 | * @param reportLine Report line 190 | */ 191 | public void add(final ReportLine reportLine) { 192 | reportLines.add(reportLine); 193 | } 194 | 195 | /** 196 | * Get report lines belongs their status 197 | * @param reportStatus Report status 198 | * @return Number of report lines 199 | */ 200 | public List getReportLinesForStatus(final ReportLineStatus reportLineStatus) { 201 | final List reportLines = new ArrayList(); 202 | 203 | for(final ReportLine reportLine : getReportLines()) { 204 | if(reportLine.getReportLineStatus() == reportLineStatus) { 205 | reportLines.add(reportLine); 206 | } 207 | } 208 | 209 | return reportLines; 210 | } 211 | 212 | /** 213 | * Return report line corresponding to a query 214 | * @param query SQL Query 215 | * @return report line 216 | */ 217 | public ReportLine getReportLineForQuery(final String query) { 218 | if(query == null) { 219 | return null; 220 | } 221 | for(final ReportLine reportLine : reportLines) { 222 | if(query.equals(reportLine.getQuery())) { 223 | return reportLine; 224 | } 225 | } 226 | return null; 227 | } 228 | 229 | /** 230 | * Add message. 231 | * @param reportStatus Status 232 | * @param message Message 233 | */ 234 | public void addMessage(final ReportLineStatus reportLineStatus, final String message) { 235 | final ReportLine reportLine = new ReportLine(); 236 | reportLine.setReportLineStatus(reportLineStatus); 237 | reportLine.setMessage(message); 238 | reportLines.add(reportLine); 239 | } 240 | 241 | public List getReportLines() { 242 | return reportLines; 243 | } 244 | 245 | public void setReportLines(final List messages) { 246 | this.reportLines = messages; 247 | } 248 | 249 | public ReportStatus getReportStatus() { 250 | return reportStatus; 251 | } 252 | 253 | public void setReportStatus(final ReportStatus reportStatus) { 254 | this.reportStatus = reportStatus; 255 | } 256 | 257 | public void setNbCreatedEntity(final int nbCreatedEntity) { 258 | this.nbCreatedEntity = nbCreatedEntity; 259 | } 260 | 261 | public int getNbCreatedEntity() { 262 | return nbCreatedEntity; 263 | } 264 | 265 | public Date getDate() { 266 | return date; 267 | } 268 | 269 | public Database getDatabase() { 270 | return database; 271 | } 272 | 273 | public void setDatabase(final Database database) { 274 | this.database = database; 275 | } 276 | 277 | public Resdef getResdef() { 278 | return resdef; 279 | } 280 | 281 | public void setResdef(final Resdef resdef) { 282 | this.resdef = resdef; 283 | } 284 | 285 | } 286 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/type/TypeConverter.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.type; 2 | 3 | import com.restlet.sqlimport.model.sql.Column; 4 | import com.restlet.sqlimport.model.sql.Database; 5 | import com.restlet.sqlimport.model.sql.Table; 6 | import com.restlet.sqlimport.report.Report; 7 | import com.restlet.sqlimport.report.ReportLineStatus; 8 | 9 | /** 10 | * Conversion of types from SQL to Entity store 11 | */ 12 | public class TypeConverter { 13 | 14 | public static final String TYPE_STRING = "String"; 15 | public static final String TYPE_FLOAT = "Float"; 16 | public static final String TYPE_INTEGER = "Integer"; 17 | public static final String TYPE_BOOLEAN = "Boolean"; 18 | public static final String TYPE_DATE = "Date"; 19 | 20 | private final Report report; 21 | 22 | /** 23 | * Constructor. 24 | * @param report Report (must not be null) 25 | */ 26 | public TypeConverter(final Report report) { 27 | this.report = report; 28 | } 29 | 30 | /** 31 | * Convert SQL type to Entity store type for all columns of the database. 32 | * @param database Database 33 | */ 34 | public void convertTypeFromSQLToEntityStore(final Database database) { 35 | for(final Table table : database.getTables()) { 36 | for(final Column column : table.getColumnByNames().values()) { 37 | if(column.getType() == null) { 38 | column.setConvertedType(""); 39 | } else { 40 | final String sqlType = column.getType().trim().toUpperCase(); 41 | column.setConvertedType( 42 | convertTypeFromSQLToEntityStore(sqlType)); 43 | } 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * Convert SQL type to Entity store type. 50 | * @param sqlType SQL type 51 | * @return Entity store type 52 | */ 53 | public String convertTypeFromSQLToEntityStore(String sqlType) { 54 | if(sqlType == null) { 55 | return null; 56 | } 57 | 58 | // format sql type for string comparaison 59 | sqlType = sqlType.trim().toUpperCase(); 60 | 61 | if(sqlType.equals("BFILE") || (sqlType.indexOf("BFILE ") == 0)) { 62 | return TYPE_STRING; 63 | } 64 | if(sqlType.equals("BIGINT") || (sqlType.indexOf("BIGINT ") == 0)) { 65 | return TYPE_INTEGER; 66 | } 67 | if(sqlType.equals("BIGSERIAL") || (sqlType.indexOf("BIGSERIAL ") == 0)) { 68 | return TYPE_INTEGER; 69 | } 70 | if(sqlType.equals("BINARY") || (sqlType.indexOf("BINARY ") == 0)) { 71 | return TYPE_STRING; 72 | } 73 | if(sqlType.equals("BINARY_DOUBLE") || (sqlType.indexOf("BINARY_DOUBLE ") == 0)) { 74 | return TYPE_FLOAT; 75 | } 76 | if(sqlType.equals("BINARY_FLOAT") || (sqlType.indexOf("BINARY_FLOAT ") == 0)) { 77 | return TYPE_FLOAT; 78 | } 79 | if(sqlType.equals("BIT VARYING") || (sqlType.indexOf("BIT VARYING ") == 0)) { 80 | return TYPE_STRING; 81 | } 82 | if(sqlType.equals("BIT") || (sqlType.indexOf("BIT ") == 0)) { 83 | return TYPE_STRING; 84 | } 85 | if(sqlType.equals("BLOB") || (sqlType.indexOf("BLOB ") == 0)) { 86 | return TYPE_STRING; 87 | } 88 | if(sqlType.equals("BOOL") || (sqlType.indexOf("BOOL ") == 0)) { 89 | return TYPE_BOOLEAN; 90 | } 91 | if(sqlType.equals("BOOLEAN") || (sqlType.indexOf("BOOLEAN ") == 0)) { 92 | return TYPE_BOOLEAN; 93 | } 94 | if(sqlType.equals("BYTEA") || (sqlType.indexOf("BYTEA ") == 0)) { 95 | return TYPE_STRING; 96 | } 97 | if(sqlType.equals("CHAR") || (sqlType.indexOf("CHAR ") == 0)) { 98 | return TYPE_STRING; 99 | } 100 | if(sqlType.equals("CHARACTER VARYING") || (sqlType.indexOf("CHARACTER VARYING ") == 0)) { 101 | return TYPE_STRING; 102 | } 103 | if(sqlType.equals("CHARACTER") || (sqlType.indexOf("CHARACTER ") == 0)) { 104 | return TYPE_STRING; 105 | } 106 | if(sqlType.equals("CLOB") || (sqlType.indexOf("CLOB ") == 0)) { 107 | return TYPE_STRING; 108 | } 109 | if(sqlType.equals("DATE") || (sqlType.indexOf("DATE ") == 0)) { 110 | return TYPE_DATE; 111 | } 112 | if(sqlType.equals("DATETIME") || (sqlType.indexOf("DATETIME ") == 0)) { 113 | return TYPE_DATE; 114 | } 115 | if(sqlType.equals("DEC") || (sqlType.indexOf("DEC ") == 0)) { 116 | return TYPE_FLOAT; 117 | } 118 | if(sqlType.equals("DECIMAL") || (sqlType.indexOf("DECIMAL ") == 0)) { 119 | return TYPE_FLOAT; 120 | } 121 | if(sqlType.equals("DOUBLE PRECISION") || (sqlType.indexOf("DOUBLE PRECISION ") == 0)) { 122 | return TYPE_FLOAT; 123 | } 124 | if(sqlType.equals("DOUBLE") || (sqlType.indexOf("DOUBLE ") == 0)) { 125 | return TYPE_FLOAT; 126 | } 127 | if(sqlType.equals("ENUM") || (sqlType.indexOf("ENUM ") == 0)) { 128 | return TYPE_STRING; 129 | } 130 | if(sqlType.equals("FIXED") || (sqlType.indexOf("FIXED ") == 0)) { 131 | return TYPE_FLOAT; 132 | } 133 | if(sqlType.equals("FLOAT") || (sqlType.indexOf("FLOAT ") == 0)) { 134 | return TYPE_FLOAT; 135 | } 136 | if(sqlType.equals("INT") || (sqlType.indexOf("INT ") == 0)) { 137 | return TYPE_INTEGER; 138 | } 139 | if(sqlType.equals("INTEGER") || (sqlType.indexOf("INTEGER ") == 0)) { 140 | return TYPE_INTEGER; 141 | } 142 | if(sqlType.equals("INTERVAL DAY") || (sqlType.indexOf("INTERVAL DAY ") == 0)) { 143 | return TYPE_INTEGER; 144 | } 145 | if(sqlType.equals("INTERVAL YEAR") || (sqlType.indexOf("INTERVAL YEAR ") == 0)) { 146 | return TYPE_INTEGER; 147 | } 148 | if(sqlType.equals("INTERVAL") || (sqlType.indexOf("INTERVAL ") == 0)) { 149 | return TYPE_STRING; 150 | } 151 | if(sqlType.equals("LONG RAW") || (sqlType.indexOf("LONG RAW ") == 0)) { 152 | return TYPE_STRING; 153 | } 154 | if(sqlType.equals("LONG") || (sqlType.indexOf("LONG ") == 0)) { 155 | return TYPE_INTEGER; 156 | } 157 | if(sqlType.equals("LONGBLOB") || (sqlType.indexOf("LONGBLOB ") == 0)) { 158 | return TYPE_STRING; 159 | } 160 | if(sqlType.equals("LONGTEXT") || (sqlType.indexOf("LONGTEXT ") == 0)) { 161 | return TYPE_STRING; 162 | } 163 | if(sqlType.equals("MEDIUMBLOB") || (sqlType.indexOf("MEDIUMBLOB ") == 0)) { 164 | return TYPE_STRING; 165 | } 166 | if(sqlType.equals("MEDIUMINT") || (sqlType.indexOf("MEDIUMINT ") == 0)) { 167 | return TYPE_INTEGER; 168 | } 169 | if(sqlType.equals("MEDIUMTEXT") || (sqlType.indexOf("MEDIUMTEXT ") == 0)) { 170 | return TYPE_STRING; 171 | } 172 | if(sqlType.equals("MONEY") || (sqlType.indexOf("MONEY ") == 0)) { 173 | return TYPE_FLOAT; 174 | } 175 | if(sqlType.equals("NATIONAL CHARACTER VARYING") || (sqlType.indexOf("NATIONAL CHARACTER VARYING ") == 0)) { 176 | return TYPE_STRING; 177 | } 178 | if(sqlType.equals("NATIONAL CHARACTER") || (sqlType.indexOf("NATIONAL CHARACTER ") == 0)) { 179 | return TYPE_STRING; 180 | } 181 | if(sqlType.equals("NCHAR") || (sqlType.indexOf("NCHAR ") == 0)) { 182 | return TYPE_STRING; 183 | } 184 | if(sqlType.equals("NCLOB") || (sqlType.indexOf("NCLOB ") == 0)) { 185 | return TYPE_STRING; 186 | } 187 | if(sqlType.equals("NUMBER") || (sqlType.indexOf("NUMBER ") == 0)) { 188 | return TYPE_FLOAT; 189 | } 190 | if(sqlType.equals("NUMERIC") || (sqlType.indexOf("NUMERIC ") == 0)) { 191 | return TYPE_FLOAT; 192 | } 193 | if(sqlType.equals("NVARCHAR") || (sqlType.indexOf("NVARCHAR ") == 0)) { 194 | return TYPE_STRING; 195 | } 196 | if(sqlType.equals("NVARCHAR2") || (sqlType.indexOf("NVARCHAR2 ") == 0)) { 197 | return TYPE_STRING; 198 | } 199 | if(sqlType.equals("RAW") || (sqlType.indexOf("RAW ") == 0)) { 200 | return TYPE_STRING; 201 | } 202 | if(sqlType.equals("REAL") || (sqlType.indexOf("REAL ") == 0)) { 203 | return TYPE_FLOAT; 204 | } 205 | if(sqlType.equals("ROWID") || (sqlType.indexOf("ROWID ") == 0)) { 206 | return TYPE_STRING; 207 | } 208 | if(sqlType.equals("SERIAL") || (sqlType.indexOf("SERIAL ") == 0)) { 209 | return TYPE_INTEGER; 210 | } 211 | if(sqlType.equals("SET") || (sqlType.indexOf("SET ") == 0)) { 212 | return TYPE_STRING; 213 | } 214 | if(sqlType.equals("SMALLINT") || (sqlType.indexOf("SMALLINT ") == 0)) { 215 | return TYPE_INTEGER; 216 | } 217 | if(sqlType.equals("SMALLSERIAL") || (sqlType.indexOf("SMALLSERIAL ") == 0)) { 218 | return TYPE_INTEGER; 219 | } 220 | if(sqlType.equals("TEXT") || (sqlType.indexOf("TEXT ") == 0)) { 221 | return TYPE_STRING; 222 | } 223 | if(sqlType.equals("TIME WITH TIME ZONE") || (sqlType.indexOf("TIME WITH TIME ZONE ") == 0)) { 224 | return TYPE_DATE; 225 | } 226 | if(sqlType.equals("TIME") || (sqlType.indexOf("TIME ") == 0)) { 227 | return TYPE_DATE; 228 | } 229 | if(sqlType.equals("TIMESTAMP WITH TIME ZONE") || (sqlType.indexOf("TIMESTAMP WITH TIME ZONE ") == 0)) { 230 | return TYPE_DATE; 231 | } 232 | if(sqlType.equals("TIMESTAMP") || (sqlType.indexOf("TIMESTAMP ") == 0)) { 233 | return TYPE_DATE; 234 | } 235 | if(sqlType.equals("TIMESTAMPTZ") || (sqlType.indexOf("TIMESTAMPTZ ") == 0)) { 236 | return TYPE_DATE; 237 | } 238 | if(sqlType.equals("TIMETZ") || (sqlType.indexOf("TIMETZ ") == 0)) { 239 | return TYPE_DATE; 240 | } 241 | if(sqlType.equals("TINYBLOB") || (sqlType.indexOf("TINYBLOB ") == 0)) { 242 | return TYPE_STRING; 243 | } 244 | if(sqlType.equals("TINYINT") || (sqlType.indexOf("TINYINT ") == 0)) { 245 | return TYPE_INTEGER; 246 | } 247 | if(sqlType.equals("TINYTEXT") || (sqlType.indexOf("TINYTEXT ") == 0)) { 248 | return TYPE_STRING; 249 | } 250 | if(sqlType.equals("UROWID") || (sqlType.indexOf("UROWID ") == 0)) { 251 | return TYPE_STRING; 252 | } 253 | if(sqlType.equals("UUID") || (sqlType.indexOf("UUID ") == 0)) { 254 | return TYPE_STRING; 255 | } 256 | if(sqlType.equals("VARBINARY") || (sqlType.indexOf("VARBINARY ") == 0)) { 257 | return TYPE_STRING; 258 | } 259 | if(sqlType.equals("VARCHAR") || (sqlType.indexOf("VARCHAR ") == 0)) { 260 | return TYPE_STRING; 261 | } 262 | if(sqlType.equals("VARCHAR2") || (sqlType.indexOf("VARCHAR2 ") == 0)) { 263 | return TYPE_STRING; 264 | } 265 | if(sqlType.equals("YEAR") || (sqlType.indexOf("YEAR ") == 0)) { 266 | return TYPE_INTEGER; 267 | } 268 | 269 | report.addMessage(ReportLineStatus.UNKNOWN_SQL_TYPE, sqlType); 270 | return TYPE_STRING; 271 | } 272 | 273 | } 274 | -------------------------------------------------------------------------------- /src/main/java/com/restlet/sqlimport/report/ReportManager.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.report; 2 | 3 | import java.text.SimpleDateFormat; 4 | 5 | import com.restlet.sqlimport.model.resdef.Entity; 6 | import com.restlet.sqlimport.model.resdef.Field; 7 | import com.restlet.sqlimport.model.sql.Column; 8 | import com.restlet.sqlimport.model.sql.Database; 9 | import com.restlet.sqlimport.model.sql.ForeignKey; 10 | import com.restlet.sqlimport.model.sql.Table; 11 | 12 | /** 13 | * Report manager 14 | */ 15 | public class ReportManager { 16 | 17 | private final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm"); 18 | 19 | /** 20 | * Export report 21 | * @param report Report 22 | * @return String 23 | */ 24 | public String toString(final Report report) { 25 | final StringBuffer out = new StringBuffer(); 26 | 27 | out.append(getTrace1(report)); 28 | out.append(getTrace2(report)); 29 | out.append(getTrace3(report)); 30 | out.append(getTrace4(report)); 31 | out.append(getTrace5(report)); 32 | out.append(getTrace6(report)); 33 | 34 | return out.toString(); 35 | } 36 | 37 | /** 38 | * Trace : Starting sql import process 39 | * @param report Report 40 | * @return String 41 | */ 42 | public String getTrace1(final Report report) { 43 | 44 | final StringBuffer out = new StringBuffer(); 45 | 46 | // starting sql import process 47 | out.append("\n--------------------"); 48 | out.append("\nTrace : "); 49 | out.append("\n - Location : Starting sql import process"); 50 | out.append("\n - Content : Starting sql import process"); 51 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 52 | out.append("\n - Type : SQL schema import"); 53 | out.append("\n"); 54 | 55 | return out.toString(); 56 | } 57 | 58 | /** 59 | * Trace : SQL parsing 60 | * @param report Report 61 | * @return String 62 | */ 63 | public String getTrace2(final Report report) { 64 | 65 | final StringBuffer out = new StringBuffer(); 66 | 67 | // sql parsing 68 | out.append("\n--------------------"); 69 | out.append("\nTrace : "); 70 | out.append("\n - Location : SQL parsing"); 71 | boolean hasParsingError = false; 72 | for(final ReportLine reportLine : report.getReportLines()) { 73 | if(reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) { 74 | hasParsingError = true; 75 | } 76 | } 77 | if(hasParsingError) { 78 | out.append("\n - Level : Error"); 79 | } else { 80 | out.append("\n - Level : Info"); 81 | } 82 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 83 | out.append("\n - Content : "); 84 | for(final ReportLine reportLine : report.getReportLines()) { 85 | if( (reportLine.getReportLineStatus() == ReportLineStatus.IGNORED) 86 | || (reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) 87 | || (reportLine.getReportLineStatus() == ReportLineStatus.PARSED) ) { 88 | final String begin = "["+reportLine.getReportLineStatus()+"] : "; 89 | out.append("\n").append(begin); 90 | final StringBuffer spaces = new StringBuffer("\n"); 91 | out.append(reportLine.getQuery().replace("\n",spaces.toString())); 92 | if(reportLine.getReportLineStatus() == ReportLineStatus.PARSING_ERROR) { 93 | out.append(spaces).append("Error : ").append(reportLine.getMessage()); 94 | } 95 | } 96 | } 97 | 98 | return out.toString(); 99 | } 100 | 101 | /** 102 | * Trace : Checking database structure 103 | * @param report Report 104 | * @return String 105 | */ 106 | public String getTrace3(final Report report) { 107 | 108 | final StringBuffer out = new StringBuffer(); 109 | 110 | // checking database structure 111 | out.append("\n"); 112 | out.append("\n--------------------"); 113 | out.append("\nTrace : "); 114 | out.append("\n - Location : Checking database structure"); 115 | boolean hasValidationWarning = false; 116 | for(final ReportLine reportLine : report.getReportLines()) { 117 | if((reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) 118 | || (reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) 119 | || (reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN)) { 120 | hasValidationWarning = true; 121 | } 122 | } 123 | if(hasValidationWarning) { 124 | out.append("\n - Level : Warning"); 125 | } else { 126 | out.append("\n - Level : Info"); 127 | } 128 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 129 | out.append("\n - Content : "); 130 | if(!hasValidationWarning) { 131 | out.append("The database is imported with no warning"); 132 | } else { 133 | for(final ReportLine reportLine : report.getReportLines()) { 134 | if((reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) 135 | || (reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) 136 | || (reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN)) { 137 | out.append("\n[WARNING] : "); 138 | if(reportLine.getTable() != null) { 139 | out.append("Table : "+reportLine.getTable()+" - "); 140 | } 141 | if(reportLine.getReportLineStatus() == ReportLineStatus.PRIMARY_KEY_MORE_THAN_ONE_COLUMN) { 142 | out.append("Composite primary key is not supported : created a new primary key named \"id\""); 143 | } 144 | if(reportLine.getReportLineStatus() == ReportLineStatus.FOREIGN_KEY_MORE_THAN_ONE_COLUMN) { 145 | out.append("Foreign key on several columns is not supported and is ignored"); 146 | } 147 | if(reportLine.getReportLineStatus() == ReportLineStatus.UNKNOWN_SQL_TYPE) { 148 | out.append("The SQL type \""+reportLine.getMessage()+"\" is not supported and replaced by the “String” type"); 149 | } 150 | } 151 | } 152 | } 153 | 154 | return out.toString(); 155 | } 156 | 157 | /** 158 | * Trace : Configuring entity store 159 | * @param report Report 160 | * @return String 161 | */ 162 | public String getTrace4(final Report report) { 163 | 164 | final StringBuffer out = new StringBuffer(); 165 | 166 | 167 | // configuring entity store 168 | out.append("\n--------------------"); 169 | out.append("\nTrace : "); 170 | out.append("\n - Location : Configuring entity store"); 171 | out.append("\n - Content : Configuring entity store"); 172 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 173 | out.append("\n - Type : SQL schema import"); 174 | out.append("\n"); 175 | 176 | return out.toString(); 177 | } 178 | 179 | /** 180 | * Trace : Generating entity store 181 | * @param report Report 182 | * @return String 183 | */ 184 | public String getTrace5(final Report report) { 185 | 186 | final StringBuffer out = new StringBuffer(); 187 | 188 | 189 | // generating entity store 190 | out.append("\n--------------------"); 191 | out.append("\nTrace : "); 192 | out.append("\n - Location : Generating entity store"); 193 | out.append("\n - Content : Generating entity store"); 194 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 195 | out.append("\n - Type : SQL schema import"); 196 | out.append("\n"); 197 | 198 | return out.toString(); 199 | } 200 | 201 | /** 202 | * Trace : SQL schema imported : summary 203 | * @param report Report 204 | * @return String 205 | */ 206 | public String getTrace6(final Report report) { 207 | 208 | final StringBuffer out = new StringBuffer(); 209 | 210 | final ReportStatus reportStatus = report.getReportStatus(); 211 | 212 | final Database database = report.getDatabase(); 213 | 214 | // SQL schema imported : summary 215 | out.append("\n--------------------"); 216 | out.append("\nTrace : "); 217 | if(reportStatus == ReportStatus.SUCCESS) { 218 | out.append("\n - Location : SQL schema successfully imported : "+report.getNbCreatedEntity()+" entities created"); 219 | out.append("\n - Content : "+report.getNbCreatedEntity()+" entities successfully created :"); 220 | if(database != null) { 221 | for(final Table table : database.getTables()) { 222 | out.append("\n - ").append(table.getName()); 223 | } 224 | } 225 | } 226 | if(reportStatus == ReportStatus.EMPTY_DATABASE) { 227 | out.append("\n - Location : SQL schema import failed : no table definition found in the SQL file content"); 228 | out.append("\n - Content : No entity created"); 229 | } 230 | out.append("\n - Date : ").append(sdf.format(report.getDate())); 231 | out.append("\n - Type : SQL schema import"); 232 | out.append("\n"); 233 | 234 | return out.toString(); 235 | } 236 | 237 | public String toStringSchema(final Report report) { 238 | final StringBuffer out = new StringBuffer(); 239 | 240 | for(final Table table : report.getDatabase().getTables()) { 241 | final Entity entity = report.getResdef().getEntityForName(table.getName()); 242 | out.append("\n* Table : ").append(table.getName()).append(" -> Entity : ").append(entity.getName()); 243 | if(entity != null) { 244 | for(final Column column : table.getColumnByNames().values()) { 245 | final Field field = entity.getFieldForName(column.getName()); 246 | out.append("\n - Column : ").append(column.getName()).append(" -> Field : ").append(field.getName()); 247 | out.append("\n - Type : ").append(column.getType()).append(" -> Type : ").append(field.getType()); 248 | out.append("\n - NotNull : ").append((column.getIsNotNull()==null)?"<>":column.getIsNotNull()).append(" -> Nullable : ").append(field.getNullable()); 249 | } 250 | // primary key 251 | out.append("\n - Primary key : ["); 252 | boolean isFirst = true; 253 | for(final String columnName : table.getPrimaryKey().getColumnNames()) { 254 | if(isFirst) {isFirst = false;} else {out.append(", ");} 255 | out.append(columnName); 256 | } 257 | out.append("] -> Entity primary key : ["); 258 | isFirst = true; 259 | for(final Field field : entity.getFields()) { 260 | if((field.getIsPrimaryKey() != null) && field.getIsPrimaryKey()) { 261 | if(isFirst) {isFirst = false;} else {out.append(", ");} 262 | out.append(field.getName()); 263 | } 264 | } 265 | out.append("]"); 266 | // foreign key 267 | out.append("\n - Foreign keys : "); 268 | for(final ForeignKey foreignKey : table.getForeignKeys()) { 269 | out.append("\n - table source : "); 270 | out.append(foreignKey.getTableNameOrigin()); 271 | for(final String columnName : foreignKey.getColumnNameOrigins()) { 272 | out.append("\n - column : "); 273 | out.append(columnName); 274 | } 275 | out.append("\n - table target : "); 276 | out.append(foreignKey.getTableNameTarget()); 277 | for(final String columnName : foreignKey.getColumnNameTargets()) { 278 | out.append("\n - column : "); 279 | out.append(columnName); 280 | } 281 | } 282 | } 283 | } 284 | 285 | return out.toString(); 286 | } 287 | 288 | } 289 | -------------------------------------------------------------------------------- /src/test/java/com/restlet/sqlimport/export/DatabaseToResdefTest.java: -------------------------------------------------------------------------------- 1 | package com.restlet.sqlimport.export; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import org.junit.Test; 8 | 9 | import com.restlet.sqlimport.model.resdef.Entity; 10 | import com.restlet.sqlimport.model.resdef.Field; 11 | import com.restlet.sqlimport.model.resdef.Resdef; 12 | import com.restlet.sqlimport.model.sql.Column; 13 | import com.restlet.sqlimport.model.sql.Database; 14 | import com.restlet.sqlimport.model.sql.ForeignKey; 15 | import com.restlet.sqlimport.model.sql.Table; 16 | 17 | 18 | public class DatabaseToResdefTest { 19 | 20 | private DatabaseToResdef databaseToResdef = new DatabaseToResdef(); 21 | 22 | @Test 23 | public void getLines1() { 24 | // Given 25 | final Database database = new Database(); 26 | 27 | // When 28 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 29 | 30 | // Then 31 | assertTrue(resdef.getEntities().isEmpty()); 32 | } 33 | 34 | @Test 35 | public void getLines2() { 36 | // Given 37 | final Database database = new Database(); 38 | final Table table1 = new Table(); 39 | database.getTables().add(table1); 40 | table1.setName("table 1"); 41 | 42 | // When 43 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 44 | 45 | // Then 46 | assertEquals(1, resdef.getEntities().size()); 47 | final Entity entity = resdef.getEntities().get(0); 48 | assertEquals("table 1", entity.getName()); 49 | assertEquals("user_generated_value", entity.getPkPolicy()); 50 | assertEquals(1, entity.getFields().size()); 51 | final Field id = entity.getFields().get(0); 52 | assertEquals("id", id.getName()); 53 | assertEquals("string", id.getType()); 54 | assertEquals(true, id.getIsPrimaryKey()); 55 | assertNull(id.getNullable()); 56 | assertNull(id.getDefaultValue()); 57 | assertNull(id.getMinOccurs()); 58 | assertNull(id.getMaxOccurs()); 59 | } 60 | 61 | @Test 62 | public void getLines3() { 63 | // Given 64 | final Database database = new Database(); 65 | final Table table1 = new Table(); 66 | database.getTables().add(table1); 67 | table1.setName("table 1"); 68 | final Column column1 = new Column(); 69 | column1.setName("column 1"); 70 | table1.getColumnByNames().put(column1.getName(), column1); 71 | 72 | // When 73 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 74 | 75 | // Then 76 | assertEquals(1, resdef.getEntities().size()); 77 | final Entity entity = resdef.getEntities().get(0); 78 | assertEquals("table 1", entity.getName()); 79 | assertEquals("user_generated_value", entity.getPkPolicy()); 80 | assertEquals(2, entity.getFields().size()); 81 | final Field id = entity.getFields().get(0); 82 | assertEquals("id", id.getName()); 83 | assertEquals("string", id.getType()); 84 | assertEquals(true, id.getIsPrimaryKey()); 85 | assertNull(id.getNullable()); 86 | assertNull(id.getDefaultValue()); 87 | assertNull(id.getMinOccurs()); 88 | assertNull(id.getMaxOccurs()); 89 | final Field field1 = entity.getFields().get(1); 90 | assertEquals("column 1", field1.getName()); 91 | assertNull(field1.getType()); 92 | assertNull(field1.getIsPrimaryKey()); 93 | assertTrue(field1.getNullable()); 94 | assertNull(field1.getDefaultValue()); 95 | assertNull(field1.getMinOccurs()); 96 | assertNull(field1.getMaxOccurs()); 97 | } 98 | 99 | @Test 100 | public void getLines4_primaryKey() { 101 | // Given 102 | final Database database = new Database(); 103 | final Table table1 = new Table(); 104 | database.getTables().add(table1); 105 | table1.setName("table 1"); 106 | final Column column1 = new Column(); 107 | column1.setName("column 1"); 108 | table1.getColumnByNames().put(column1.getName(), column1); 109 | table1.getPrimaryKey().getColumnNames().add("column 1"); 110 | 111 | // When 112 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 113 | 114 | // Then 115 | assertEquals(1, resdef.getEntities().size()); 116 | final Entity entity = resdef.getEntities().get(0); 117 | assertEquals("table 1", entity.getName()); 118 | assertEquals("user_generated_value", entity.getPkPolicy()); 119 | assertEquals(1, entity.getFields().size()); 120 | final Field field1 = entity.getFields().get(0); 121 | assertEquals("column 1", field1.getName()); 122 | assertNull(field1.getType()); 123 | assertEquals(true, field1.getIsPrimaryKey()); 124 | assertTrue(field1.getNullable()); 125 | assertNull(field1.getDefaultValue()); 126 | assertNull(field1.getMinOccurs()); 127 | assertNull(field1.getMaxOccurs()); 128 | } 129 | 130 | @Test 131 | public void getLines5_primaryKey_with_more_than_one_column() { 132 | // Given 133 | final Database database = new Database(); 134 | final Table table1 = new Table(); 135 | database.getTables().add(table1); 136 | table1.setName("table 1"); 137 | final Column column1 = new Column(); 138 | column1.setName("column 1"); 139 | table1.getColumnByNames().put(column1.getName(), column1); 140 | table1.getPrimaryKey().getColumnNames().add("column 1"); 141 | table1.getPrimaryKey().getColumnNames().add("column 2"); 142 | 143 | // When 144 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 145 | 146 | // Then 147 | assertEquals(1, resdef.getEntities().size()); 148 | final Entity entity = resdef.getEntities().get(0); 149 | assertEquals("table 1", entity.getName()); 150 | assertEquals("user_generated_value", entity.getPkPolicy()); 151 | assertEquals(2, entity.getFields().size()); 152 | final Field id = entity.getFields().get(0); 153 | assertEquals("id", id.getName()); 154 | assertEquals("string", id.getType()); 155 | assertEquals(true, id.getIsPrimaryKey()); 156 | assertNull(id.getNullable()); 157 | assertNull(id.getDefaultValue()); 158 | assertNull(id.getMinOccurs()); 159 | assertNull(id.getMaxOccurs()); 160 | final Field field1 = entity.getFields().get(1); 161 | assertEquals("column 1", field1.getName()); 162 | assertNull(field1.getType()); 163 | assertNull(field1.getIsPrimaryKey()); 164 | assertTrue(field1.getNullable()); 165 | assertNull(field1.getDefaultValue()); 166 | assertNull(field1.getMinOccurs()); 167 | assertNull(field1.getMaxOccurs()); 168 | } 169 | 170 | @Test 171 | public void getLines_foreignKey() { 172 | // Given 173 | final Database database = new Database(); 174 | final Table table1 = new Table(); 175 | database.getTables().add(table1); 176 | table1.setName("table 1"); 177 | final Column column1 = new Column(); 178 | column1.setName("column 1"); 179 | table1.getColumnByNames().put(column1.getName(), column1); 180 | final ForeignKey foreignKey = new ForeignKey(); 181 | foreignKey.setTableNameOrigin("tableNameOrigin"); 182 | foreignKey.setTableNameTarget("tableNameTarget"); 183 | foreignKey.getColumnNameOrigins().add("column 1"); 184 | foreignKey.getColumnNameTargets().add("columnNameTarget"); 185 | table1.getForeignKeys().add(foreignKey); 186 | 187 | // When 188 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 189 | 190 | // Then 191 | //assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"key\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"tableNameTarget\",\"minOccurs\":0,\"maxOccurs\":\"*\",\"nullable\":true}]}]", content); 192 | assertEquals(1, resdef.getEntities().size()); 193 | final Entity entity = resdef.getEntities().get(0); 194 | assertEquals("table 1", entity.getName()); 195 | assertEquals("user_generated_value", entity.getPkPolicy()); 196 | assertEquals(2, entity.getFields().size()); 197 | final Field id = entity.getFields().get(0); 198 | assertEquals("id", id.getName()); 199 | assertEquals("string", id.getType()); 200 | assertEquals(true, id.getIsPrimaryKey()); 201 | assertNull(id.getNullable()); 202 | assertNull(id.getDefaultValue()); 203 | assertNull(id.getMinOccurs()); 204 | assertNull(id.getMaxOccurs()); 205 | final Field field1 = entity.getFields().get(1); 206 | assertEquals("column 1", field1.getName()); 207 | assertEquals("tableNameTarget",field1.getType()); 208 | assertNull(field1.getIsPrimaryKey()); 209 | assertTrue(field1.getNullable()); 210 | assertNull(field1.getDefaultValue()); 211 | assertEquals(Integer.valueOf(0),field1.getMinOccurs()); 212 | assertEquals("*",field1.getMaxOccurs()); 213 | } 214 | 215 | @Test 216 | public void getLines6() { 217 | // Given 218 | final Database database = new Database(); 219 | final Table table1 = new Table(); 220 | database.getTables().add(table1); 221 | table1.setName("table 1"); 222 | final Column column1 = new Column(); 223 | table1.getColumnByNames().put(column1.getName(), column1); 224 | column1.setName("column 1"); 225 | column1.setType("type"); 226 | column1.setConvertedType("convertedType"); 227 | column1.setLength("length"); 228 | column1.setIsNotNull(true); 229 | column1.setDefaultValue("default"); 230 | 231 | // When 232 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 233 | 234 | // Then 235 | assertEquals(1, resdef.getEntities().size()); 236 | final Entity entity = resdef.getEntities().get(0); 237 | assertEquals("table 1", entity.getName()); 238 | assertEquals("user_generated_value", entity.getPkPolicy()); 239 | assertEquals(2, entity.getFields().size()); 240 | final Field id = entity.getFields().get(0); 241 | assertEquals("id", id.getName()); 242 | assertEquals("string", id.getType()); 243 | assertEquals(true, id.getIsPrimaryKey()); 244 | assertNull(id.getNullable()); 245 | assertNull(id.getDefaultValue()); 246 | assertNull(id.getMinOccurs()); 247 | assertNull(id.getMaxOccurs()); 248 | final Field field1 = entity.getFields().get(1); 249 | assertEquals("column 1", field1.getName()); 250 | assertEquals("convertedType",field1.getType()); 251 | assertNull(field1.getIsPrimaryKey()); 252 | assertEquals(false,field1.getNullable()); 253 | assertEquals("default",field1.getDefaultValue()); 254 | assertNull(field1.getMinOccurs()); 255 | assertNull(field1.getMaxOccurs()); 256 | } 257 | 258 | @Test 259 | public void getLines7() { 260 | // Given 261 | final Database database = new Database(); 262 | final Table table1 = new Table(); 263 | database.getTables().add(table1); 264 | table1.setName("table 1"); 265 | final Column column1 = new Column(); 266 | table1.getColumnByNames().put(column1.getName(), column1); 267 | column1.setName("column 1"); 268 | column1.setType("type"); 269 | column1.setConvertedType("convertedType"); 270 | column1.setLength("length"); 271 | column1.setIsNotNull(false); 272 | column1.setDefaultValue("default"); 273 | 274 | // When 275 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 276 | 277 | // Then 278 | //assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"key\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"convertedType\",\"nullable\":true,\"defaultValue\":\"default\"}]}]", content); 279 | assertEquals(1, resdef.getEntities().size()); 280 | final Entity entity = resdef.getEntities().get(0); 281 | assertEquals("table 1", entity.getName()); 282 | assertEquals("user_generated_value", entity.getPkPolicy()); 283 | assertEquals(2, entity.getFields().size()); 284 | final Field id = entity.getFields().get(0); 285 | assertEquals("id", id.getName()); 286 | assertEquals("string", id.getType()); 287 | assertEquals(true, id.getIsPrimaryKey()); 288 | assertNull(id.getNullable()); 289 | assertNull(id.getDefaultValue()); 290 | assertNull(id.getMinOccurs()); 291 | assertNull(id.getMaxOccurs()); 292 | final Field field1 = entity.getFields().get(1); 293 | assertEquals("column 1", field1.getName()); 294 | assertEquals("convertedType",field1.getType()); 295 | assertNull(field1.getIsPrimaryKey()); 296 | assertEquals(true,field1.getNullable()); 297 | assertEquals("default",field1.getDefaultValue()); 298 | assertNull(field1.getMinOccurs()); 299 | assertNull(field1.getMaxOccurs()); 300 | } 301 | 302 | @Test 303 | public void getLines8() { 304 | // Given 305 | final Database database = new Database(); 306 | final Table table1 = new Table(); 307 | database.getTables().add(table1); 308 | table1.setName("table 1"); 309 | final Column column1 = new Column(); 310 | table1.getColumnByNames().put(column1.getName(), column1); 311 | column1.setName("column 1"); 312 | column1.setType("type"); 313 | column1.setConvertedType("convertedType"); 314 | column1.setLength("length"); 315 | column1.setIsNotNull(false); 316 | column1.setDefaultValue("default"); 317 | final ForeignKey foreignKey = new ForeignKey(); 318 | foreignKey.setTableNameOrigin("tableNameOrigin"); 319 | foreignKey.setTableNameTarget("tableNameTarget"); 320 | foreignKey.getColumnNameOrigins().add("column 1"); 321 | foreignKey.getColumnNameTargets().add("columnNameTarget"); 322 | table1.getForeignKeys().add(foreignKey); 323 | 324 | // When 325 | final Resdef resdef = databaseToResdef.databaseToResdef(database); 326 | 327 | // Then 328 | // assertEquals("[{\"name\":\"table 1\",\"pkPolicy\":\"user_generated_value\",\"fields\":[{\"name\":\"id\",\"key\":\"string\",\"isPrimaryKey\":true},{\"name\":\"column 1\",\"type\":\"tableNameTarget\",\"minOccurs\":0,\"maxOccurs\":\"*\",\"nullable\":true,\"defaultValue\":\"default\"}]}]", content); 329 | assertEquals(1, resdef.getEntities().size()); 330 | final Entity entity = resdef.getEntities().get(0); 331 | assertEquals("table 1", entity.getName()); 332 | assertEquals("user_generated_value", entity.getPkPolicy()); 333 | assertEquals(2, entity.getFields().size()); 334 | final Field id = entity.getFields().get(0); 335 | assertEquals("id", id.getName()); 336 | assertEquals("string", id.getType()); 337 | assertEquals(true, id.getIsPrimaryKey()); 338 | assertNull(id.getNullable()); 339 | assertNull(id.getDefaultValue()); 340 | assertNull(id.getMinOccurs()); 341 | assertNull(id.getMaxOccurs()); 342 | final Field field1 = entity.getFields().get(1); 343 | assertEquals("column 1", field1.getName()); 344 | assertEquals("tableNameTarget",field1.getType()); 345 | assertNull(field1.getIsPrimaryKey()); 346 | assertEquals(true,field1.getNullable()); 347 | assertEquals("default",field1.getDefaultValue()); 348 | assertEquals(Integer.valueOf(0),field1.getMinOccurs()); 349 | assertEquals("*",field1.getMaxOccurs()); 350 | } 351 | 352 | } 353 | -------------------------------------------------------------------------------- /src/main/antlr4/com/restlet/sqlimport/parser/Sql.g4.old: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 by Bart Kiers 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | * 27 | * Project : sqlite-parser; an ANTLR4 grammar for SQLite 28 | * https://github.com/bkiers/sqlite-parser 29 | * Developed by : Bart Kiers, bart@big-o.nl 30 | */ 31 | grammar Sql; 32 | 33 | parse 34 | : ( sql_stmt_list | error )* EOF 35 | ; 36 | 37 | error 38 | : UNEXPECTED_CHAR 39 | { 40 | throw new RuntimeException("UNEXPECTED_CHAR=" + $UNEXPECTED_CHAR.text); 41 | } 42 | ; 43 | 44 | sql_stmt_list 45 | : ';'* sql_stmt ( ';'+ sql_stmt )* ';'* 46 | ; 47 | 48 | sql_stmt 49 | : ( K_EXPLAIN ( K_QUERY K_PLAN )? )? ( alter_table_stmt 50 | | analyze_stmt 51 | | attach_stmt 52 | | begin_stmt 53 | | commit_stmt 54 | | compound_select_stmt 55 | | create_index_stmt 56 | | create_table_stmt 57 | | create_trigger_stmt 58 | | create_view_stmt 59 | | create_virtual_table_stmt 60 | | delete_stmt 61 | | delete_stmt_limited 62 | | detach_stmt 63 | | drop_index_stmt 64 | | drop_table_stmt 65 | | drop_trigger_stmt 66 | | drop_view_stmt 67 | | factored_select_stmt 68 | | insert_stmt 69 | | pragma_stmt 70 | | reindex_stmt 71 | | release_stmt 72 | | rollback_stmt 73 | | savepoint_stmt 74 | | simple_select_stmt 75 | | select_stmt 76 | | update_stmt 77 | | update_stmt_limited 78 | | vacuum_stmt ) 79 | ; 80 | 81 | alter_table_stmt 82 | : K_ALTER K_TABLE ( database_name '.' )? table_name 83 | ( K_RENAME K_TO new_table_name 84 | | K_ADD K_COLUMN? column_def 85 | ) 86 | ; 87 | 88 | analyze_stmt 89 | : K_ANALYZE ( database_name | table_or_index_name | database_name '.' table_or_index_name )? 90 | ; 91 | 92 | attach_stmt 93 | : K_ATTACH K_DATABASE? expr K_AS database_name 94 | ; 95 | 96 | begin_stmt 97 | : K_BEGIN ( K_DEFERRED | K_IMMEDIATE | K_EXCLUSIVE )? ( K_TRANSACTION transaction_name? )? 98 | ; 99 | 100 | commit_stmt 101 | : ( K_COMMIT | K_END ) ( K_TRANSACTION transaction_name? )? 102 | ; 103 | 104 | compound_select_stmt 105 | : ( K_WITH K_RECURSIVE? common_table_expression ( ',' common_table_expression )* )? 106 | select_core ( ( K_UNION K_ALL? | K_INTERSECT | K_EXCEPT ) select_core )+ 107 | ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 108 | ( K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? )? 109 | ; 110 | 111 | create_index_stmt 112 | : K_CREATE K_UNIQUE? K_INDEX ( K_IF K_NOT K_EXISTS )? 113 | ( database_name '.' )? index_name K_ON table_name '(' indexed_column ( ',' indexed_column )* ')' 114 | ( K_WHERE expr )? 115 | ; 116 | 117 | create_table_stmt 118 | : K_CREATE ( K_TEMP | K_TEMPORARY )? K_TABLE ( K_IF K_NOT K_EXISTS )? 119 | ( database_name '.' )? table_name 120 | ( '(' column_def ( ',' column_def )* ( ',' table_constraint )* ')' ( K_WITHOUT IDENTIFIER )? 121 | | K_AS select_stmt 122 | ) 123 | ; 124 | 125 | create_trigger_stmt 126 | : K_CREATE ( K_TEMP | K_TEMPORARY )? K_TRIGGER ( K_IF K_NOT K_EXISTS )? 127 | ( database_name '.' )? trigger_name ( K_BEFORE | K_AFTER | K_INSTEAD K_OF )? 128 | ( K_DELETE | K_INSERT | K_UPDATE ( K_OF column_name ( ',' column_name )* )? ) K_ON ( database_name '.' )? table_name 129 | ( K_FOR K_EACH K_ROW )? ( K_WHEN expr )? 130 | K_BEGIN ( ( update_stmt | insert_stmt | delete_stmt | select_stmt ) ';' )+ K_END 131 | ; 132 | 133 | create_view_stmt 134 | : K_CREATE ( K_TEMP | K_TEMPORARY )? K_VIEW ( K_IF K_NOT K_EXISTS )? 135 | ( database_name '.' )? view_name K_AS select_stmt 136 | ; 137 | 138 | create_virtual_table_stmt 139 | : K_CREATE K_VIRTUAL K_TABLE ( K_IF K_NOT K_EXISTS )? 140 | ( database_name '.' )? table_name 141 | K_USING module_name ( '(' module_argument ( ',' module_argument )* ')' )? 142 | ; 143 | 144 | delete_stmt 145 | : with_clause? K_DELETE K_FROM qualified_table_name 146 | ( K_WHERE expr )? 147 | ; 148 | 149 | delete_stmt_limited 150 | : with_clause? K_DELETE K_FROM qualified_table_name 151 | ( K_WHERE expr )? 152 | ( ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 153 | K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? 154 | )? 155 | ; 156 | 157 | detach_stmt 158 | : K_DETACH K_DATABASE? database_name 159 | ; 160 | 161 | drop_index_stmt 162 | : K_DROP K_INDEX ( K_IF K_EXISTS )? ( database_name '.' )? index_name 163 | ; 164 | 165 | drop_table_stmt 166 | : K_DROP K_TABLE ( K_IF K_EXISTS )? ( database_name '.' )? table_name 167 | ; 168 | 169 | drop_trigger_stmt 170 | : K_DROP K_TRIGGER ( K_IF K_EXISTS )? ( database_name '.' )? trigger_name 171 | ; 172 | 173 | drop_view_stmt 174 | : K_DROP K_VIEW ( K_IF K_EXISTS )? ( database_name '.' )? view_name 175 | ; 176 | 177 | factored_select_stmt 178 | : ( K_WITH K_RECURSIVE? common_table_expression ( ',' common_table_expression )* )? 179 | select_core ( compound_operator select_core )* 180 | ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 181 | ( K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? )? 182 | ; 183 | 184 | insert_stmt 185 | : with_clause? ( K_INSERT 186 | | K_REPLACE 187 | | K_INSERT K_OR K_REPLACE 188 | | K_INSERT K_OR K_ROLLBACK 189 | | K_INSERT K_OR K_ABORT 190 | | K_INSERT K_OR K_FAIL 191 | | K_INSERT K_OR K_IGNORE ) K_INTO 192 | ( database_name '.' )? table_name ( '(' column_name ( ',' column_name )* ')' )? 193 | ( K_VALUES '(' expr ( ',' expr )* ')' ( ',' '(' expr ( ',' expr )* ')' )* 194 | | select_stmt 195 | | K_DEFAULT K_VALUES 196 | ) 197 | ; 198 | 199 | pragma_stmt 200 | : K_PRAGMA ( database_name '.' )? pragma_name ( '=' pragma_value 201 | | '(' pragma_value ')' )? 202 | ; 203 | 204 | reindex_stmt 205 | : K_REINDEX ( collation_name 206 | | ( database_name '.' )? ( table_name | index_name ) 207 | )? 208 | ; 209 | 210 | release_stmt 211 | : K_RELEASE K_SAVEPOINT? savepoint_name 212 | ; 213 | 214 | rollback_stmt 215 | : K_ROLLBACK ( K_TRANSACTION transaction_name? )? ( K_TO K_SAVEPOINT? savepoint_name )? 216 | ; 217 | 218 | savepoint_stmt 219 | : K_SAVEPOINT savepoint_name 220 | ; 221 | 222 | simple_select_stmt 223 | : ( K_WITH K_RECURSIVE? common_table_expression ( ',' common_table_expression )* )? 224 | select_core ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 225 | ( K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? )? 226 | ; 227 | 228 | select_stmt 229 | : ( K_WITH K_RECURSIVE? common_table_expression ( ',' common_table_expression )* )? 230 | select_or_values ( compound_operator select_or_values )* 231 | ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 232 | ( K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? )? 233 | ; 234 | 235 | select_or_values 236 | : K_SELECT ( K_DISTINCT | K_ALL )? result_column ( ',' result_column )* 237 | ( K_FROM ( table_or_subquery ( ',' table_or_subquery )* | join_clause ) )? 238 | ( K_WHERE expr )? 239 | ( K_GROUP K_BY expr ( ',' expr )* ( K_HAVING expr )? )? 240 | | K_VALUES '(' expr ( ',' expr )* ')' ( ',' '(' expr ( ',' expr )* ')' )* 241 | ; 242 | 243 | update_stmt 244 | : with_clause? K_UPDATE ( K_OR K_ROLLBACK 245 | | K_OR K_ABORT 246 | | K_OR K_REPLACE 247 | | K_OR K_FAIL 248 | | K_OR K_IGNORE )? qualified_table_name 249 | K_SET column_name '=' expr ( ',' column_name '=' expr )* ( K_WHERE expr )? 250 | ; 251 | 252 | update_stmt_limited 253 | : with_clause? K_UPDATE ( K_OR K_ROLLBACK 254 | | K_OR K_ABORT 255 | | K_OR K_REPLACE 256 | | K_OR K_FAIL 257 | | K_OR K_IGNORE )? qualified_table_name 258 | K_SET column_name '=' expr ( ',' column_name '=' expr )* ( K_WHERE expr )? 259 | ( ( K_ORDER K_BY ordering_term ( ',' ordering_term )* )? 260 | K_LIMIT expr ( ( K_OFFSET | ',' ) expr )? 261 | )? 262 | ; 263 | 264 | vacuum_stmt 265 | : K_VACUUM 266 | ; 267 | 268 | column_def 269 | : column_name type_name? column_constraint* 270 | ; 271 | 272 | type_name 273 | : name+ ( '(' signed_number ')' 274 | | '(' signed_number ',' signed_number ')' )? 275 | ; 276 | 277 | column_constraint 278 | : ( K_CONSTRAINT name )? 279 | ( K_PRIMARY K_KEY ( K_ASC | K_DESC )? conflict_clause K_AUTOINCREMENT? 280 | | K_NOT? K_NULL conflict_clause 281 | | K_UNIQUE conflict_clause 282 | | K_CHECK '(' expr ')' 283 | | K_DEFAULT (signed_number | literal_value | '(' expr ')') 284 | | K_COLLATE collation_name 285 | | foreign_key_clause 286 | ) 287 | ; 288 | 289 | conflict_clause 290 | : ( K_ON K_CONFLICT ( K_ROLLBACK 291 | | K_ABORT 292 | | K_FAIL 293 | | K_IGNORE 294 | | K_REPLACE 295 | ) 296 | )? 297 | ; 298 | 299 | /* 300 | SQLite understands the following binary operators, in order from highest to 301 | lowest precedence: 302 | 303 | || 304 | * / % 305 | + - 306 | << >> & | 307 | < <= > >= 308 | = == != <> IS IS NOT IN LIKE GLOB MATCH REGEXP 309 | AND 310 | OR 311 | */ 312 | expr 313 | : literal_value 314 | | BIND_PARAMETER 315 | | ( ( database_name '.' )? table_name '.' )? column_name 316 | | unary_operator expr 317 | | expr '||' expr 318 | | expr ( '*' | '/' | '%' ) expr 319 | | expr ( '+' | '-' ) expr 320 | | expr ( '<<' | '>>' | '&' | '|' ) expr 321 | | expr ( '<' | '<=' | '>' | '>=' ) expr 322 | | expr ( '=' | '==' | '!=' | '<>' | K_IS | K_IS K_NOT | K_IN | K_LIKE | K_GLOB | K_MATCH | K_REGEXP ) expr 323 | | expr K_AND expr 324 | | expr K_OR expr 325 | | function_name '(' ( K_DISTINCT? expr ( ',' expr )* | '*' )? ')' 326 | | '(' expr ')' 327 | | K_CAST '(' expr K_AS type_name ')' 328 | | expr K_COLLATE collation_name 329 | | expr K_NOT? ( K_LIKE | K_GLOB | K_REGEXP | K_MATCH ) expr ( K_ESCAPE expr )? 330 | | expr ( K_ISNULL | K_NOTNULL | K_NOT K_NULL ) 331 | | expr K_IS K_NOT? expr 332 | | expr K_NOT? K_BETWEEN expr K_AND expr 333 | | expr K_NOT? K_IN ( '(' ( select_stmt 334 | | expr ( ',' expr )* 335 | )? 336 | ')' 337 | | ( database_name '.' )? table_name ) 338 | | ( ( K_NOT )? K_EXISTS )? '(' select_stmt ')' 339 | | K_CASE expr? ( K_WHEN expr K_THEN expr )+ ( K_ELSE expr )? K_END 340 | | raise_function 341 | ; 342 | 343 | foreign_key_clause 344 | : K_REFERENCES foreign_table ( '(' column_name ( ',' column_name )* ')' )? 345 | ( ( K_ON ( K_DELETE | K_UPDATE ) ( K_SET K_NULL 346 | | K_SET K_DEFAULT 347 | | K_CASCADE 348 | | K_RESTRICT 349 | | K_NO K_ACTION ) 350 | | K_MATCH name 351 | ) 352 | )* 353 | ( K_NOT? K_DEFERRABLE ( K_INITIALLY K_DEFERRED | K_INITIALLY K_IMMEDIATE )? )? 354 | ; 355 | 356 | raise_function 357 | : K_RAISE '(' ( K_IGNORE 358 | | ( K_ROLLBACK | K_ABORT | K_FAIL ) ',' error_message ) 359 | ')' 360 | ; 361 | 362 | indexed_column 363 | : column_name ( K_COLLATE collation_name )? ( K_ASC | K_DESC )? 364 | ; 365 | 366 | table_constraint 367 | : ( K_CONSTRAINT name )? 368 | ( ( K_PRIMARY K_KEY | K_UNIQUE ) '(' indexed_column ( ',' indexed_column )* ')' conflict_clause 369 | | K_CHECK '(' expr ')' 370 | | K_FOREIGN K_KEY '(' column_name ( ',' column_name )* ')' foreign_key_clause 371 | ) 372 | ; 373 | 374 | with_clause 375 | : K_WITH K_RECURSIVE? cte_table_name K_AS '(' select_stmt ')' ( ',' cte_table_name K_AS '(' select_stmt ')' )* 376 | ; 377 | 378 | qualified_table_name 379 | : ( database_name '.' )? table_name ( K_INDEXED K_BY index_name 380 | | K_NOT K_INDEXED )? 381 | ; 382 | 383 | ordering_term 384 | : expr ( K_COLLATE collation_name )? ( K_ASC | K_DESC )? 385 | ; 386 | 387 | pragma_value 388 | : signed_number 389 | | name 390 | | STRING_LITERAL 391 | ; 392 | 393 | common_table_expression 394 | : table_name ( '(' column_name ( ',' column_name )* ')' )? K_AS '(' select_stmt ')' 395 | ; 396 | 397 | result_column 398 | : '*' 399 | | table_name '.' '*' 400 | | expr ( K_AS? column_alias )? 401 | ; 402 | 403 | table_or_subquery 404 | : ( database_name '.' )? table_name ( K_AS? table_alias )? 405 | ( K_INDEXED K_BY index_name 406 | | K_NOT K_INDEXED )? 407 | | '(' ( table_or_subquery ( ',' table_or_subquery )* 408 | | join_clause ) 409 | ')' ( K_AS? table_alias )? 410 | | '(' select_stmt ')' ( K_AS? table_alias )? 411 | ; 412 | 413 | join_clause 414 | : table_or_subquery ( join_operator table_or_subquery join_constraint )* 415 | ; 416 | 417 | join_operator 418 | : ',' 419 | | K_NATURAL? ( K_LEFT K_OUTER? | K_INNER | K_CROSS )? K_JOIN 420 | ; 421 | 422 | join_constraint 423 | : ( K_ON expr 424 | | K_USING '(' column_name ( ',' column_name )* ')' )? 425 | ; 426 | 427 | select_core 428 | : K_SELECT ( K_DISTINCT | K_ALL )? result_column ( ',' result_column )* 429 | ( K_FROM ( table_or_subquery ( ',' table_or_subquery )* | join_clause ) )? 430 | ( K_WHERE expr )? 431 | ( K_GROUP K_BY expr ( ',' expr )* ( K_HAVING expr )? )? 432 | | K_VALUES '(' expr ( ',' expr )* ')' ( ',' '(' expr ( ',' expr )* ')' )* 433 | ; 434 | 435 | compound_operator 436 | : K_UNION 437 | | K_UNION K_ALL 438 | | K_INTERSECT 439 | | K_EXCEPT 440 | ; 441 | 442 | cte_table_name 443 | : table_name ( '(' column_name ( ',' column_name )* ')' )? 444 | ; 445 | 446 | signed_number 447 | : ( '+' | '-' )? NUMERIC_LITERAL 448 | ; 449 | 450 | literal_value 451 | : NUMERIC_LITERAL 452 | | STRING_LITERAL 453 | | BLOB_LITERAL 454 | | K_NULL 455 | | K_CURRENT_TIME 456 | | K_CURRENT_DATE 457 | | K_CURRENT_TIMESTAMP 458 | ; 459 | 460 | unary_operator 461 | : '-' 462 | | '+' 463 | | '~' 464 | | K_NOT 465 | ; 466 | 467 | error_message 468 | : STRING_LITERAL 469 | ; 470 | 471 | module_argument // TODO check what exactly is permitted here 472 | : expr 473 | | column_def 474 | ; 475 | 476 | column_alias 477 | : IDENTIFIER 478 | | STRING_LITERAL 479 | ; 480 | 481 | keyword 482 | : K_ABORT 483 | | K_ACTION 484 | | K_ADD 485 | | K_AFTER 486 | | K_ALL 487 | | K_ALTER 488 | | K_ANALYZE 489 | | K_AND 490 | | K_AS 491 | | K_ASC 492 | | K_ATTACH 493 | | K_AUTOINCREMENT 494 | | K_BEFORE 495 | | K_BEGIN 496 | | K_BETWEEN 497 | | K_BY 498 | | K_CASCADE 499 | | K_CASE 500 | | K_CAST 501 | | K_CHECK 502 | | K_COLLATE 503 | | K_COLUMN 504 | | K_COMMIT 505 | | K_CONFLICT 506 | | K_CONSTRAINT 507 | | K_CREATE 508 | | K_CROSS 509 | | K_CURRENT_DATE 510 | | K_CURRENT_TIME 511 | | K_CURRENT_TIMESTAMP 512 | | K_DATABASE 513 | | K_DEFAULT 514 | | K_DEFERRABLE 515 | | K_DEFERRED 516 | | K_DELETE 517 | | K_DESC 518 | | K_DETACH 519 | | K_DISTINCT 520 | | K_DROP 521 | | K_EACH 522 | | K_ELSE 523 | | K_END 524 | | K_ESCAPE 525 | | K_EXCEPT 526 | | K_EXCLUSIVE 527 | | K_EXISTS 528 | | K_EXPLAIN 529 | | K_FAIL 530 | | K_FOR 531 | | K_FOREIGN 532 | | K_FROM 533 | | K_FULL 534 | | K_GLOB 535 | | K_GROUP 536 | | K_HAVING 537 | | K_IF 538 | | K_IGNORE 539 | | K_IMMEDIATE 540 | | K_IN 541 | | K_INDEX 542 | | K_INDEXED 543 | | K_INITIALLY 544 | | K_INNER 545 | | K_INSERT 546 | | K_INSTEAD 547 | | K_INTERSECT 548 | | K_INTO 549 | | K_IS 550 | | K_ISNULL 551 | | K_JOIN 552 | | K_KEY 553 | | K_LEFT 554 | | K_LIKE 555 | | K_LIMIT 556 | | K_MATCH 557 | | K_NATURAL 558 | | K_NO 559 | | K_NOT 560 | | K_NOTNULL 561 | | K_NULL 562 | | K_OF 563 | | K_OFFSET 564 | | K_ON 565 | | K_OR 566 | | K_ORDER 567 | | K_OUTER 568 | | K_PLAN 569 | | K_PRAGMA 570 | | K_PRIMARY 571 | | K_QUERY 572 | | K_RAISE 573 | | K_RECURSIVE 574 | | K_REFERENCES 575 | | K_REGEXP 576 | | K_REINDEX 577 | | K_RELEASE 578 | | K_RENAME 579 | | K_REPLACE 580 | | K_RESTRICT 581 | | K_RIGHT 582 | | K_ROLLBACK 583 | | K_ROW 584 | | K_SAVEPOINT 585 | | K_SELECT 586 | | K_SET 587 | | K_TABLE 588 | | K_TEMP 589 | | K_TEMPORARY 590 | | K_THEN 591 | | K_TO 592 | | K_TRANSACTION 593 | | K_TRIGGER 594 | | K_UNION 595 | | K_UNIQUE 596 | | K_UPDATE 597 | | K_USING 598 | | K_VACUUM 599 | | K_VALUES 600 | | K_VIEW 601 | | K_VIRTUAL 602 | | K_WHEN 603 | | K_WHERE 604 | | K_WITH 605 | | K_WITHOUT 606 | ; 607 | 608 | // TODO check all names below 609 | 610 | name 611 | : any_name 612 | ; 613 | 614 | function_name 615 | : any_name 616 | ; 617 | 618 | database_name 619 | : any_name 620 | ; 621 | 622 | table_name 623 | : any_name 624 | ; 625 | 626 | table_or_index_name 627 | : any_name 628 | ; 629 | 630 | new_table_name 631 | : any_name 632 | ; 633 | 634 | column_name 635 | : any_name 636 | ; 637 | 638 | collation_name 639 | : any_name 640 | ; 641 | 642 | foreign_table 643 | : any_name 644 | ; 645 | 646 | index_name 647 | : any_name 648 | ; 649 | 650 | trigger_name 651 | : any_name 652 | ; 653 | 654 | view_name 655 | : any_name 656 | ; 657 | 658 | module_name 659 | : any_name 660 | ; 661 | 662 | pragma_name 663 | : any_name 664 | ; 665 | 666 | savepoint_name 667 | : any_name 668 | ; 669 | 670 | table_alias 671 | : any_name 672 | ; 673 | 674 | transaction_name 675 | : any_name 676 | ; 677 | 678 | any_name 679 | : IDENTIFIER 680 | | keyword 681 | | STRING_LITERAL 682 | | '(' any_name ')' 683 | ; 684 | 685 | SCOL : ';'; 686 | DOT : '.'; 687 | OPEN_PAR : '('; 688 | CLOSE_PAR : ')'; 689 | COMMA : ','; 690 | ASSIGN : '='; 691 | STAR : '*'; 692 | PLUS : '+'; 693 | MINUS : '-'; 694 | TILDE : '~'; 695 | PIPE2 : '||'; 696 | DIV : '/'; 697 | MOD : '%'; 698 | LT2 : '<<'; 699 | GT2 : '>>'; 700 | AMP : '&'; 701 | PIPE : '|'; 702 | LT : '<'; 703 | LT_EQ : '<='; 704 | GT : '>'; 705 | GT_EQ : '>='; 706 | EQ : '=='; 707 | NOT_EQ1 : '!='; 708 | NOT_EQ2 : '<>'; 709 | 710 | // http://www.sqlite.org/lang_keywords.html 711 | K_ABORT : A B O R T; 712 | K_ACTION : A C T I O N; 713 | K_ADD : A D D; 714 | K_AFTER : A F T E R; 715 | K_ALL : A L L; 716 | K_ALTER : A L T E R; 717 | K_ANALYZE : A N A L Y Z E; 718 | K_AND : A N D; 719 | K_AS : A S; 720 | K_ASC : A S C; 721 | K_ATTACH : A T T A C H; 722 | K_AUTOINCREMENT : A U T O I N C R E M E N T; 723 | K_BEFORE : B E F O R E; 724 | K_BEGIN : B E G I N; 725 | K_BETWEEN : B E T W E E N; 726 | K_BY : B Y; 727 | K_CASCADE : C A S C A D E; 728 | K_CASE : C A S E; 729 | K_CAST : C A S T; 730 | K_CHECK : C H E C K; 731 | K_COLLATE : C O L L A T E; 732 | K_COLUMN : C O L U M N; 733 | K_COMMIT : C O M M I T; 734 | K_CONFLICT : C O N F L I C T; 735 | K_CONSTRAINT : C O N S T R A I N T; 736 | K_CREATE : C R E A T E; 737 | K_CROSS : C R O S S; 738 | K_CURRENT_DATE : C U R R E N T '_' D A T E; 739 | K_CURRENT_TIME : C U R R E N T '_' T I M E; 740 | K_CURRENT_TIMESTAMP : C U R R E N T '_' T I M E S T A M P; 741 | K_DATABASE : D A T A B A S E; 742 | K_DEFAULT : D E F A U L T; 743 | K_DEFERRABLE : D E F E R R A B L E; 744 | K_DEFERRED : D E F E R R E D; 745 | K_DELETE : D E L E T E; 746 | K_DESC : D E S C; 747 | K_DETACH : D E T A C H; 748 | K_DISTINCT : D I S T I N C T; 749 | K_DROP : D R O P; 750 | K_EACH : E A C H; 751 | K_ELSE : E L S E; 752 | K_END : E N D; 753 | K_ESCAPE : E S C A P E; 754 | K_EXCEPT : E X C E P T; 755 | K_EXCLUSIVE : E X C L U S I V E; 756 | K_EXISTS : E X I S T S; 757 | K_EXPLAIN : E X P L A I N; 758 | K_FAIL : F A I L; 759 | K_FOR : F O R; 760 | K_FOREIGN : F O R E I G N; 761 | K_FROM : F R O M; 762 | K_FULL : F U L L; 763 | K_GLOB : G L O B; 764 | K_GROUP : G R O U P; 765 | K_HAVING : H A V I N G; 766 | K_IF : I F; 767 | K_IGNORE : I G N O R E; 768 | K_IMMEDIATE : I M M E D I A T E; 769 | K_IN : I N; 770 | K_INDEX : I N D E X; 771 | K_INDEXED : I N D E X E D; 772 | K_INITIALLY : I N I T I A L L Y; 773 | K_INNER : I N N E R; 774 | K_INSERT : I N S E R T; 775 | K_INSTEAD : I N S T E A D; 776 | K_INTERSECT : I N T E R S E C T; 777 | K_INTO : I N T O; 778 | K_IS : I S; 779 | K_ISNULL : I S N U L L; 780 | K_JOIN : J O I N; 781 | K_KEY : K E Y; 782 | K_LEFT : L E F T; 783 | K_LIKE : L I K E; 784 | K_LIMIT : L I M I T; 785 | K_MATCH : M A T C H; 786 | K_NATURAL : N A T U R A L; 787 | K_NO : N O; 788 | K_NOT : N O T; 789 | K_NOTNULL : N O T N U L L; 790 | K_NULL : N U L L; 791 | K_OF : O F; 792 | K_OFFSET : O F F S E T; 793 | K_ON : O N; 794 | K_OR : O R; 795 | K_ORDER : O R D E R; 796 | K_OUTER : O U T E R; 797 | K_PLAN : P L A N; 798 | K_PRAGMA : P R A G M A; 799 | K_PRIMARY : P R I M A R Y; 800 | K_QUERY : Q U E R Y; 801 | K_RAISE : R A I S E; 802 | K_RECURSIVE : R E C U R S I V E; 803 | K_REFERENCES : R E F E R E N C E S; 804 | K_REGEXP : R E G E X P; 805 | K_REINDEX : R E I N D E X; 806 | K_RELEASE : R E L E A S E; 807 | K_RENAME : R E N A M E; 808 | K_REPLACE : R E P L A C E; 809 | K_RESTRICT : R E S T R I C T; 810 | K_RIGHT : R I G H T; 811 | K_ROLLBACK : R O L L B A C K; 812 | K_ROW : R O W; 813 | K_SAVEPOINT : S A V E P O I N T; 814 | K_SELECT : S E L E C T; 815 | K_SET : S E T; 816 | K_TABLE : T A B L E; 817 | K_TEMP : T E M P; 818 | K_TEMPORARY : T E M P O R A R Y; 819 | K_THEN : T H E N; 820 | K_TO : T O; 821 | K_TRANSACTION : T R A N S A C T I O N; 822 | K_TRIGGER : T R I G G E R; 823 | K_UNION : U N I O N; 824 | K_UNIQUE : U N I Q U E; 825 | K_UPDATE : U P D A T E; 826 | K_USING : U S I N G; 827 | K_VACUUM : V A C U U M; 828 | K_VALUES : V A L U E S; 829 | K_VIEW : V I E W; 830 | K_VIRTUAL : V I R T U A L; 831 | K_WHEN : W H E N; 832 | K_WHERE : W H E R E; 833 | K_WITH : W I T H; 834 | K_WITHOUT : W I T H O U T; 835 | 836 | IDENTIFIER 837 | : '"' (~'"' | '""')* '"' 838 | | '`' (~'`' | '``')* '`' 839 | | '[' ~']'* ']' 840 | | [a-zA-Z_] [a-zA-Z_0-9]* // TODO check: needs more chars in set 841 | ; 842 | 843 | NUMERIC_LITERAL 844 | : DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )? 845 | | '.' DIGIT+ ( E [-+]? DIGIT+ )? 846 | ; 847 | 848 | BIND_PARAMETER 849 | : '?' DIGIT* 850 | | [:@$] IDENTIFIER 851 | ; 852 | 853 | STRING_LITERAL 854 | : '\'' ( ~'\'' | '\'\'' )* '\'' 855 | ; 856 | 857 | BLOB_LITERAL 858 | : X STRING_LITERAL 859 | ; 860 | 861 | SINGLE_LINE_COMMENT 862 | : '--' ~[\r\n]* -> channel(HIDDEN) 863 | ; 864 | 865 | MULTILINE_COMMENT 866 | : '/*' .*? ( '*/' | EOF ) -> channel(HIDDEN) 867 | ; 868 | 869 | SPACES 870 | : [ \u000B\t\r\n] -> channel(HIDDEN) 871 | ; 872 | 873 | UNEXPECTED_CHAR 874 | : . 875 | ; 876 | 877 | fragment DIGIT : [0-9]; 878 | 879 | fragment A : [aA]; 880 | fragment B : [bB]; 881 | fragment C : [cC]; 882 | fragment D : [dD]; 883 | fragment E : [eE]; 884 | fragment F : [fF]; 885 | fragment G : [gG]; 886 | fragment H : [hH]; 887 | fragment I : [iI]; 888 | fragment J : [jJ]; 889 | fragment K : [kK]; 890 | fragment L : [lL]; 891 | fragment M : [mM]; 892 | fragment N : [nN]; 893 | fragment O : [oO]; 894 | fragment P : [pP]; 895 | fragment Q : [qQ]; 896 | fragment R : [rR]; 897 | fragment S : [sS]; 898 | fragment T : [tT]; 899 | fragment U : [uU]; 900 | fragment V : [vV]; 901 | fragment W : [wW]; 902 | fragment X : [xX]; 903 | fragment Y : [yY]; 904 | fragment Z : [zZ]; 905 | --------------------------------------------------------------------------------