Add ability to execute FindBugs
[cfb.git] / prod / net / jaekl / cfb / db / Schema.java
1 package net.jaekl.cfb.db;
2
3 import java.sql.Connection;
4 import java.sql.DatabaseMetaData;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.HashSet;
9 import java.util.Locale;
10
11 import net.jaekl.cfb.db.driver.DbDriver;
12
13 public class Schema {
14         String m_name;
15         DbDriver m_driver;
16         ArrayList<Table> m_tables;
17         
18         public Schema(String name, DbDriver driver) {
19                 m_name = name;
20                 m_driver = driver;
21                 m_tables = new ArrayList<Table>();
22         }
23         
24         public boolean ensureDbInitialized(Connection con) throws SQLException {
25                 assert(null != con);
26                 
27                 if (allTablesPresent(con)) {
28                         return true;
29                 }
30                 
31                 if (!createAllTables(con)) {
32                         return false;
33                 }
34                 
35                 return true;
36         }
37         
38         boolean allTablesPresent(Connection con) throws SQLException 
39         {
40                 assert(null != con);
41                 
42                 DatabaseMetaData dbmd = con.getMetaData();
43                 HashSet<String> extantTables = new HashSet<String>();
44                 
45                 try (ResultSet rs = dbmd.getTables(null, null, null, new String[]{"TABLE"})) {
46                         while (rs.next()) {
47                                 extantTables.add(rs.getString(3).toUpperCase(Locale.CANADA));
48                         }
49                 }
50                 
51                 for (Table table : m_tables) {
52                         String name = table.getName().toUpperCase(Locale.CANADA);
53                         if ( ! extantTables.contains(name) ) {
54                                 // One or more tables missing
55                                 return false;
56                         }
57                 }
58                 
59                 // We could be more thorough here, and check that the expected columns are in place.
60                 // Also, eventually, some sort of DB schema versioning will be needed.
61                 
62                 return true;            
63         }
64         
65         boolean createAllTables(Connection con) throws SQLException {
66                 for (Table table : m_tables) {
67                         if (!m_driver.createTable(con, table)) {
68                                 return false;
69                         }
70                 }
71                 return true;
72         }
73         
74         void addTable(Table table) {
75                 m_tables.add(table);
76         }
77         
78         // Add a list of tables.
79         // Define each table in the list as follows:
80         // {
81         //   { table_name },
82         //   { column_name, type, width (-1 for default), null/not_null }
83         // }
84         void addTables(Object[][][] tables) 
85         {
86                 for (Object[][] table : tables) {
87                         addTable(Table.construct(table));
88                 }
89         }       
90 }