1 package org.kuali.student.sonar.database.utility;
2
3 import java.io.File;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.kuali.common.util.LocationUtils;
11 import org.kuali.student.sonar.database.exception.ColumnTypeIncompatException;
12 import org.kuali.student.sonar.database.exception.FKConstraintException;
13 import org.kuali.student.sonar.database.exception.FieldMappingException;
14 import org.kuali.student.sonar.database.exception.InvalidConstraintException;
15 import org.kuali.student.sonar.database.exception.NonPKMappingException;
16 import org.kuali.student.sonar.database.exception.ParentKeysMissingException;
17 import org.kuali.student.sonar.database.exception.TableMappingException;
18 import org.kuali.student.sonar.database.exception.UnknownFKExecption;
19 import org.kuali.student.sonar.database.plugin.ForeignKeyConstraint;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import org.sonar.api.scan.filesystem.PathResolver;
23
24 public class FKConstraintValidator {
25 private static final Logger LOG = LoggerFactory.getLogger(FKConstraintValidator.class);
26
27 protected static final String OWNER_KEY = "owner";
28
29 protected static final String CONSTRAINT_NAME_KEY = "constraint_name";
30
31 protected ForeignKeyValidationContext context;
32
33 public ForeignKeyValidationContext getContext() {
34 return context;
35 }
36
37 public void setContext(ForeignKeyValidationContext context) {
38 this.context = context;
39 }
40
41 public FKConstraintReport runFKSQL(ClassLoader classLoader) throws SQLException {
42
43 String sql = LocationUtils.toString(new PathResolver().relativeFile(new File(context.getQueryFilePath()), context.getQueryFileName()));
44
45 Statement stmt = null;
46 ResultSet result = null;
47
48 ArrayList<ForeignKeyConstraint> newConstraintList = new ArrayList<ForeignKeyConstraint>();
49 FKConstraintReport report = new FKConstraintReport();
50
51
52 try {
53
54 stmt = context.getConnection().createStatement();
55 result = stmt.executeQuery(sql);
56
57 while (result.next()) {
58 ForeignKeyConstraint constraint = new ForeignKeyConstraint(result);
59 constraint.constraintName = FKGenerationUtil.getNextConstraintName();
60 if (result.getString(OWNER_KEY) == null) {
61 report.addException(new FieldMappingException(constraint));
62 } else if (result.getString(CONSTRAINT_NAME_KEY) == null) {
63 newConstraintList.add(constraint);
64 }
65 }
66
67 LOG.debug("**** Done Compiling Field Mappings ****");
68 } catch (SQLException e) {
69 throw new SQLException("error running missing FK sql. ", e);
70 } finally {
71 if (stmt != null) {
72 stmt.close();
73 }
74 if (result != null) {
75 result.close();
76 }
77 }
78
79 LOG.debug("Adding constraints and detecting issues");
80 for (ForeignKeyConstraint constraint : newConstraintList) {
81 try {
82 constraint.addFKConstraint(context.getConnection());
83 } catch (FKConstraintException fkce) {
84 report.addException(fkce);
85 }
86 }
87
88 return report;
89 }
90
91 public void revert() throws InvalidConstraintException, SQLException {
92 List<ForeignKeyConstraint> constraintList = null;
93 try {
94 constraintList = FKGenerationUtil.getGeneratedFKConstraints(context.getConnection());
95 } catch (SQLException e) {
96 LOG.error("error retrieving generated constraints: " + e.getErrorCode() + " " + e.getMessage(), e);
97 }
98
99 LOG.debug("\nDeleting " + constraintList.size() + " FK Constraints");
100
101 for (ForeignKeyConstraint constraint : constraintList) {
102 constraint.deleteFKConstraint(context.getConnection());
103 }
104 }
105
106 public void closeConn() throws SQLException {
107 if (context.getConnection() != null) {
108 context.getConnection().close();
109 }
110 }
111
112 }