001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.cache.lazy; 019 020import java.sql.SQLException; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Map.Entry; 025import java.util.concurrent.atomic.AtomicReference; 026 027import net.sf.hajdbc.QualifiedName; 028import net.sf.hajdbc.SequenceProperties; 029import net.sf.hajdbc.SequencePropertiesFactory; 030import net.sf.hajdbc.SequenceSupport; 031import net.sf.hajdbc.TableProperties; 032import net.sf.hajdbc.cache.AbstractDatabaseProperties; 033import net.sf.hajdbc.cache.DatabaseMetaDataProvider; 034import net.sf.hajdbc.dialect.Dialect; 035 036/** 037 * @author Paul Ferraro 038 * 039 */ 040public class LazyDatabaseProperties extends AbstractDatabaseProperties 041{ 042 private final Dialect dialect; 043 private final DatabaseMetaDataProvider provider; 044 private final SequencePropertiesFactory sequenceFactory; 045 046 private final AtomicReference<Map<QualifiedName, TableProperties>> tablesRef = new AtomicReference<Map<QualifiedName, TableProperties>>(); 047 private final AtomicReference<Map<QualifiedName, SequenceProperties>> sequencesRef = new AtomicReference<Map<QualifiedName, SequenceProperties>>(); 048 private final AtomicReference<List<String>> defaultSchemasRef = new AtomicReference<List<String>>(); 049 private final AtomicReference<Map<Integer, Map.Entry<String, Integer>>> typesRef = new AtomicReference<Map<Integer, Map.Entry<String, Integer>>>(); 050 051 public LazyDatabaseProperties(DatabaseMetaDataProvider provider, Dialect dialect) throws SQLException 052 { 053 super(provider.getDatabaseMetaData(), dialect); 054 055 this.provider = provider; 056 this.dialect = dialect; 057 SequenceSupport support = dialect.getSequenceSupport(); 058 this.sequenceFactory = (support != null) ? support.createSequencePropertiesFactory(this.nameFactory) : null; 059 } 060 061 @Override 062 protected Map<QualifiedName, TableProperties> tables() throws SQLException 063 { 064 Map<QualifiedName, TableProperties> tables = this.tablesRef.get(); 065 066 if (tables == null) 067 { 068 tables = new HashMap<QualifiedName, TableProperties>(); 069 070 for (QualifiedName table: this.dialect.getTables(this.provider.getDatabaseMetaData(), this.nameFactory)) 071 { 072 TableProperties properties = new LazyTableProperties(table, this.provider, this.dialect, this.nameFactory); 073 074 tables.put(properties.getName(), properties); 075 } 076 077 if (!this.tablesRef.compareAndSet(null, tables)) 078 { 079 return this.tablesRef.get(); 080 } 081 } 082 083 return tables; 084 } 085 086 @Override 087 protected Map<QualifiedName, SequenceProperties> sequences() throws SQLException 088 { 089 Map<QualifiedName, SequenceProperties> sequences = this.sequencesRef.get(); 090 091 if (sequences == null) 092 { 093 sequences = new HashMap<QualifiedName, SequenceProperties>(); 094 095 if (this.sequenceFactory != null) 096 { 097 for (SequenceProperties sequence: this.dialect.getSequenceSupport().getSequences(this.provider.getDatabaseMetaData(), this.sequenceFactory)) 098 { 099 sequences.put(sequence.getName(), sequence); 100 } 101 } 102 103 if (!this.sequencesRef.compareAndSet(null, sequences)) 104 { 105 return this.sequencesRef.get(); 106 } 107 } 108 109 return sequences; 110 } 111 112 @Override 113 protected List<String> defaultSchemas() throws SQLException 114 { 115 List<String> schemas = this.defaultSchemasRef.get(); 116 117 if (schemas == null) 118 { 119 schemas = this.dialect.getDefaultSchemas(this.provider.getDatabaseMetaData()); 120 121 if (!this.defaultSchemasRef.compareAndSet(null, schemas)) 122 { 123 return this.defaultSchemasRef.get(); 124 } 125 } 126 127 return schemas; 128 } 129 130 @Override 131 protected Map<Integer, Entry<String, Integer>> types() throws SQLException 132 { 133 Map<Integer, Map.Entry<String, Integer>> types = this.typesRef.get(); 134 135 if (types == null) 136 { 137 types = this.dialect.getTypes(this.provider.getDatabaseMetaData()); 138 139 if (!this.typesRef.compareAndSet(null, types)) 140 { 141 return this.typesRef.get(); 142 } 143 } 144 145 return types; 146 } 147}