1 17 18 package org.objectweb.jac.aspects.persistence; 19 20 import java.sql.Connection ; 21 import java.sql.DriverManager ; 22 import java.sql.ResultSet ; 23 import java.sql.SQLException ; 24 import java.util.HashSet ; 25 import java.util.Hashtable ; 26 import java.util.Iterator ; 27 import java.util.Map.Entry; 28 import java.util.Map ; 29 import org.apache.log4j.Level; 30 import org.apache.log4j.Logger; 31 import org.objectweb.jac.util.Log; 32 import org.objectweb.jac.util.Strings; 33 34 35 38 39 public class PostgresStorage extends SQLStorage { 40 static Logger logger = Logger.getLogger("persistence.storage"); 41 42 43 static final int version = 1; 44 45 57 public PostgresStorage(PersistenceAC ac, 58 String database, String user, String password) 59 throws SQLException , Exception 60 { 61 super(ac); 62 try { 63 Class.forName("org.postgresql.Driver"); 64 } catch (ClassNotFoundException e) { 65 logger.error("failed to load postgresql JDBC driver",e); 66 return; 67 } 68 try { 69 Connection db; 70 db = DriverManager.getConnection("jdbc:postgresql:"+database,user,password); 71 setConnection(db); 72 } catch (SQLException e) { 73 logger.error("failed to connect to the database with "+ 74 "jdbc:postgresql:"+database+","+user+","+password,e); 75 return; 76 } 77 78 try { 79 doUpdates(); 80 } catch (Exception e) { 81 logger.error("doUpdates failed on "+database,e); 82 } 83 } 84 85 protected String [] getClassNames() throws Exception { 86 ResultSet rs = executeQuery("SELECT DISTINCT classid FROM classes"); 87 HashSet names = new HashSet (); 88 while (rs.next()) { 89 names.add(rs.getString("classid")); 90 } 91 return (String [])names.toArray(new String [0]); 92 } 93 94 protected void doUpdates() throws Exception , SQLException { 95 if (!hasTable("storage")) { 96 execute( 97 "create table \"storage\" ("+ 98 "\"key\" character varying PRIMARY KEY, "+ 99 "\"value\" character varying )"); 100 } 101 int currentVersion = getInt("select value from storage where key='version'",0); 102 103 if (currentVersion<=0) { 104 logger.info("Upgrading from version 0"); 105 String [] classes = getClassNames(); 107 HashSet seqs = new HashSet (); 108 for (int i=0; i<classes.length; i++) { 109 String seq = Strings.getShortClassName(classes[i]).toLowerCase()+"_seq"; 110 if (seqs.contains(seq)) 111 throw new RuntimeException ( 112 "Cannot upgrade storage: two classes have the same seq name '"+seq+"'"); 113 seqs.add(seq); 114 } 115 116 for (int i=0; i<classes.length; i++) { 117 String seq = Strings.getShortClassName(classes[i]).toLowerCase()+"_seq"; 118 if (hasSequence(seq)) { 119 logger.debug("Renaming sequence "+seq+" to "+classes[i]); 120 executeUpdate("ALTER TABLE "+seq+" RENAME to \""+classes[i]+"\""); 121 } else { 122 logger.debug("No such sequence "+seq); 123 } 124 } 125 126 } 127 128 if (currentVersion==0) 129 executeUpdate("insert into storage values ('version',"+version+") "); 130 else 131 executeUpdate("update storage set value="+version+" where key='version'"); 132 } 133 134 public long getNextVal(String sequence) throws Exception { 135 ensureSequenceExists(sequence); 136 return getLong("select nextval('\""+sequence+"\"')"); 137 } 138 139 public long getCurrVal(String sequence) throws Exception { 140 ensureSequenceExists(sequence); 141 return getLong("select last_value from \""+sequence+"\""); 142 } 143 144 protected boolean ensureSequenceExists(String sequence) throws Exception { 145 boolean created = false; 146 if (!createdSequences.contains(sequence)) { 147 if (!hasSequence(sequence)) { 148 execute("create sequence \""+sequence+"\""); 149 created = true; 150 } 151 createdSequences.add(sequence); 152 } 153 return created; 154 } 155 156 HashSet createdSequences = new HashSet (); 157 public String newName(String className) throws Exception { 158 String prefix = Strings.getShortClassName(className).toLowerCase(); 159 String seq = getClassSeqName(className); 160 return prefix+"#"+(getNextVal(seq)-1); 161 } 162 163 public Map getNameCounters() throws Exception { 164 Hashtable counters = new Hashtable (); 165 String [] classes = getClassNames(); 166 for (int i=0; i<classes.length; i++) { 167 String seq = getClassSeqName(classes[i]); 168 counters.put(classes[i],new Long (getCurrVal(seq))); 169 } 170 171 return counters; 172 } 173 174 protected String getClassSeqName(String className) { 175 return className; 176 } 177 178 protected boolean hasTable(String name) throws SQLException { 179 ResultSet rs = 180 executeQuery("select * from pg_tables where tablename='"+name+"'"); 181 return rs.next(); 182 } 183 184 protected boolean hasSequence(String name) throws Exception { 185 ResultSet rs = 186 executeQuery("select * from pg_class where relname='"+name+"' and relkind='S'"); 187 return rs.next(); 188 } 189 190 public void updateNameCounters(Map counters) throws Exception { 191 Iterator i = counters.entrySet().iterator(); 192 while (i.hasNext()) { 193 Entry entry = (Entry)i.next(); 194 String sequence = getClassSeqName((String )entry.getKey()); 195 ensureSequenceExists(sequence); 196 if (getCurrVal(sequence)<((Long )entry.getValue()).longValue()) 197 execute("select setval('\""+sequence+"\"',"+entry.getValue()+",true)"); 198 } 199 } 200 201 } 202 | Popular Tags |