/** * The lint that does the job * * @param table table * @param connection connection * @throws SchemaCrawlerException SchemaCrawlerException */ @Override protected void lint(final Table table, final Connection connection) throws SchemaCrawlerException { try (Statement stmt = connection.createStatement()) { String sql; List<Column> columns = table.getColumns(); for (Column column : columns) { if (LintUtils.isSqlTypeTextBased( column.getColumnDataType().getJavaSqlType().getJavaSqlType())) { sql = "select " + column.getName() + " from " + table.getName(); LOGGER.log(Level.INFO, "SQL : {0}", sql); ResultSet rs = stmt.executeQuery(sql); boolean found = false; while (rs.next() && !found) { String data = rs.getString(column.getName()); if (JSonUtils.isJsonContent(data)) { LOGGER.log( Level.INFO, "Adding lint as data is JSON but column type is not JSONB or JSON."); addLint(table, getDescription(), column.getFullName()); found = true; } } } } } catch (SQLException ex) { LOGGER.severe(ex.getMessage()); } }
/** * Looks up a column in the database. If the column and table are not found, they are created, and * added to the schema. This is prevent foreign key relationships from having a null pointer. */ private Column lookupOrCreateColumn( final String catalogName, final String schemaName, final String tableName, final String columnName) { Column column = null; final SchemaReference schema = new SchemaReference(catalogName, schemaName); final Optional<MutableTable> tableOptional = catalog.lookupTable(schema, tableName); if (tableOptional.isPresent()) { final Table table = tableOptional.get(); final Optional<? extends Column> columnOptional = table.lookupColumn(columnName); if (columnOptional.isPresent()) { column = columnOptional.get(); } } if (column == null) { // Create the table and column, but do not add it to the schema final Table table = new TablePartial(schema, tableName); column = new ColumnPartial(table, columnName); ((TablePartial) table).addColumn(column); LOGGER.log( Level.FINER, String.format( "Creating column reference for a column that is referenced by a foreign key: %s", column.getFullName())); } return column; }
@Test public void tables() throws Exception { final String referenceFile = "tables.txt"; final File testOutputFile = File.createTempFile("schemacrawler." + referenceFile + ".", ".test"); testOutputFile.delete(); final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(testOutputFile))); final Config config = Config.loadResource("/hsqldb.INFORMATION_SCHEMA.config.properties"); final SchemaCrawlerOptions schemaCrawlerOptions = new SchemaCrawlerOptions(config); schemaCrawlerOptions.setSchemaInfoLevel(SchemaInfoLevel.maximum()); schemaCrawlerOptions.setSchemaInclusionRule( new InclusionRule(InclusionRule.ALL, ".*\\.FOR_LINT")); final Database database = getDatabase(schemaCrawlerOptions); final Schema[] schemas = database.getSchemas().toArray(new Schema[0]); assertEquals("Schema count does not match", 5, schemas.length); for (final Schema schema : schemas) { final Table[] tables = database.getTables(schema).toArray(new Table[0]); Arrays.sort(tables, NamedObjectSort.alphabetical); for (final Table table : tables) { writer.println(String.format("o--> %s [%s]", table.getFullName(), table.getTableType())); final SortedMap<String, Object> tableAttributes = new TreeMap<String, Object>(table.getAttributes()); for (final Entry<String, Object> tableAttribute : tableAttributes.entrySet()) { writer.println( String.format(" ~ %s=%s", tableAttribute.getKey(), tableAttribute.getValue())); } final Column[] columns = table.getColumns().toArray(new Column[0]); for (final Column column : columns) { writer.println( String.format(" o--> %s [%s]", column.getFullName(), column.getColumnDataType())); final SortedMap<String, Object> columnAttributes = new TreeMap<String, Object>(column.getAttributes()); for (final Entry<String, Object> columnAttribute : columnAttributes.entrySet()) { writer.println( String.format( " ~ %s=%s", columnAttribute.getKey(), columnAttribute.getValue())); } } } } writer.flush(); writer.close(); final List<String> failures = TestUtility.compareOutput(METADATA_OUTPUT + referenceFile, testOutputFile); if (failures.size() > 0) { fail(failures.toString()); } }