1 29 30 package com.caucho.db; 31 32 import com.caucho.db.sql.Parser; 33 import com.caucho.db.sql.Query; 34 import com.caucho.db.store.BlockManager; 35 import com.caucho.db.store.Lock; 36 import com.caucho.db.store.Store; 37 import com.caucho.db.table.Table; 38 import com.caucho.db.table.TableFactory; 39 import com.caucho.lifecycle.Lifecycle; 40 import com.caucho.loader.CloseListener; 41 import com.caucho.loader.Environment; 42 import com.caucho.log.Log; 43 import com.caucho.sql.SQLExceptionWrapper; 44 import com.caucho.util.L10N; 45 import com.caucho.util.LruCache; 46 import com.caucho.vfs.Path; 47 48 import javax.annotation.PostConstruct; 49 import java.io.IOException ; 50 import java.sql.SQLException ; 51 import java.util.HashMap ; 52 import java.util.logging.Level ; 53 import java.util.logging.Logger ; 54 55 58 public class Database { 59 private static final Logger log = Log.open(Database.class); 60 private static final L10N L = new L10N(Database.class); 61 62 private Path _dir; 63 64 private BlockManager _blockManager; 65 private HashMap <String ,Table> _tables = new HashMap <String ,Table>(); 66 67 private LruCache<String ,Query> _cachedQueries = new LruCache<String ,Query>(128); 68 69 private Lock _databaseLock = new Lock("db"); 70 71 private boolean _removeOnError; 72 73 private long _timeout = 1000L; 74 75 private final Lifecycle _lifecycle = new Lifecycle(log, null, Level.FINER); 76 77 80 public Database() 81 { 82 this(null); 83 } 84 85 88 public Database(Path dir) 89 { 90 Environment.addClassLoaderListener(new CloseListener(this)); 91 92 _lifecycle.setName(toString()); 93 94 if (dir != null) 95 setPath(dir); 96 97 long minSize = 8 * 1024 * 1024; 98 99 long memorySize = Runtime.getRuntime().maxMemory() / 8; 100 101 if (minSize < memorySize) 102 minSize = memorySize; 103 104 _blockManager = BlockManager.create((int) (minSize / Store.BLOCK_SIZE)); 105 } 106 107 110 public void setPath(Path dir) 111 { 112 _dir = dir; 113 } 114 115 118 public void setRemoveOnError(boolean remove) 119 { 120 _removeOnError = remove; 121 } 122 123 128 public void ensureMemoryCapacity(long minCapacity) 129 { 130 int minBlocks = (int) ((minCapacity + Store.BLOCK_SIZE - 1) / 131 Store.BLOCK_SIZE); 132 133 _blockManager.ensureCapacity(minBlocks); 134 } 135 136 140 @PostConstruct 141 public void init() 142 throws SQLException 143 { 144 if (! _lifecycle.toActive()) 145 return; 146 147 Path dir = _dir; 148 149 if (dir != null) { 150 String []list = null; 151 152 try { 153 list = dir.list(); 154 } catch (IOException e) { 155 log.log(Level.WARNING, e.toString(), e); 156 } 157 158 for (int i = 0; i < list.length; i++) { 159 String name = list[i]; 160 161 if (! name.endsWith(".db")) 162 continue; 163 164 name = name.substring(0, name.length() - 3); 165 166 try { 167 Table table = Table.loadFromFile(this, name); 168 169 table.init(); 170 171 _tables.put(name, table); 172 } catch (Throwable e) { 173 if (_removeOnError) { 174 if (log.isLoggable(Level.FINER)) 175 log.log(Level.FINER, e.toString(), e); 176 else 177 log.warning(e.toString()); 178 179 try { 180 dir.lookup(name + ".db").remove(); 181 } catch (IOException e1) { 182 } 183 } 184 else 185 throw new SQLExceptionWrapper(e); 186 } 187 } 188 } 189 } 190 191 194 public Path getPath() 195 { 196 return _dir; 197 } 198 199 202 public BlockManager getBlockManager() 203 { 204 return _blockManager; 205 } 206 207 210 public Lock getDatabaseLock() 211 { 212 return _databaseLock; 213 } 214 215 218 public TableFactory createTableFactory() 219 { 220 return new TableFactory(this); 221 } 222 223 226 public void addTable(Table table) 227 throws IOException 228 { 229 log.fine("adding table " + table.getName()); 230 231 table.init(); 232 233 _tables.put(table.getName(), table); 234 } 235 236 239 public Table getTable(String name) 240 { 241 return _tables.get(name); 242 } 243 244 247 public void dropTable(String name) 248 throws SQLException 249 { 250 Table table = null; 251 252 synchronized (this) { 253 table = _tables.get(name); 254 if (table == null) 255 throw new SQLException (L.l("Table {0} does not exist. DROP TABLE can only drop an existing table.", 256 name)); 257 258 _tables.remove(name); 259 260 _cachedQueries.clear(); 261 } 262 263 table.remove(); 264 } 265 266 269 278 279 282 291 292 295 public Query parseQuery(String sql) 296 throws SQLException 297 { 298 307 if (log.isLoggable(Level.FINER)) 308 log.finer(this + ": " + sql); 309 310 Query query = Parser.parse(this, sql); 311 312 return query; 313 } 314 315 335 336 339 public void close() 340 { 341 if (! _lifecycle.toDestroy()) 342 return; 343 344 for (Table table : _tables.values()) { 345 try { 346 table.close(); 347 } catch (Throwable e) { 348 log.log(Level.WARNING, e.toString(), e); 349 } 350 } 351 } 352 353 public String toString() 354 { 355 return "Database[" + _dir + "]"; 356 } 357 } 358 | Popular Tags |