1 34 package smallsql.database; 35 36 import java.io.File ; 37 import java.io.RandomAccessFile ; 38 import java.sql.DriverManager ; 39 import java.sql.SQLException ; 40 41 42 43 final class IndexDescription { 44 45 static final int MAGIC_INDEX = 'S' << 24 | 'Q' << 16 | 'L' << 8 | 'I'; 46 static final int INDEX_VERSION = 1; 47 48 private final String name; 49 final private int constraintType; final private Strings columns; 51 private int[] matrix; 52 final private Expressions expressions; 53 private Index index; 54 private RandomAccessFile raFile; 55 56 57 62 IndexDescription( String name, String tableName, int constraintType, Expressions expressions, Strings columns){ 63 this.constraintType = constraintType; 64 this.expressions = expressions; 65 this.columns = columns; 66 this.name = createName(name, tableName); 67 } 68 69 70 private static String createName( String defaultName, String tableName ){ 71 if(defaultName == null){ 72 defaultName = tableName + "_" + Long.toHexString(System.currentTimeMillis()) + Integer.toHexString(new Object ().hashCode()); 73 } 74 return defaultName; 75 } 76 77 78 final String getName(){ 79 return name; 80 } 81 82 83 final boolean isPrimary(){ 84 return constraintType == SQLTokenizer.PRIMARY; 85 } 86 87 88 final boolean isUnique(){ 89 return constraintType == SQLTokenizer.PRIMARY || constraintType == SQLTokenizer.UNIQUE; 90 } 91 92 93 final Strings getColumns(){ 94 return columns; 95 } 96 97 98 103 final int matchFactor(Strings strings){ 104 if(strings.size() < columns.size()) 105 return Integer.MAX_VALUE; 107 nextColumn: 108 for(int c=0; c<columns.size(); c++){ 109 String colName = columns.get(c); 110 for(int s=0; s<strings.size(); s++){ 111 if(colName.equalsIgnoreCase(strings.get(s)) ) 112 continue nextColumn; 113 } 114 return Integer.MAX_VALUE; } 116 return strings.size() - columns.size(); 117 } 118 119 120 126 final void init(Database database, TableView tableView){ 127 int size = tableView.columns.size(); 128 matrix = new int[size]; 129 for(int i=0; i<matrix.length; i++){ 130 matrix[i] = -1; 131 } 132 133 for(int i=0; i<columns.size(); i++){ 134 matrix[tableView.findColumnIdx(columns.get(i))] = i; 135 } 136 } 137 138 139 142 final void create(Database database, TableView tableView) throws Exception { 143 init( database, tableView ); 144 raFile = createFile( database ); 145 } 146 147 148 static File getFile(Database database, String name) throws Exception { 149 return new File ( Utils.createIdxFileName( database, name ) ); 150 } 151 152 153 private RandomAccessFile createFile(Database database) throws Exception { 154 File file = getFile( database, name ); 155 boolean ok = file.createNewFile(); 156 if(!ok) throw Utils.createSQLException("Index '" + name + "' already exists."); 157 RandomAccessFile randomFile = new RandomAccessFile ( file, "rw" ); 158 writeMagic(randomFile); 159 return randomFile; 160 } 161 162 163 private void load(Database database) throws SQLException { 164 try{ 165 File file = getFile( database, name ); 166 if(!file.exists()) 167 throw Utils.createSQLException("Index '" + name + "' does not exist"); 168 raFile = new RandomAccessFile ( file, "rw" ); 169 int magic = raFile.readInt(); 170 int version = raFile.readInt(); 171 if(magic != MAGIC_INDEX){ 172 throw Utils.createSQLException("File '" + file.getName() + "' is not a valid Index store."); 173 } 174 if(version > INDEX_VERSION){ 175 throw Utils.createSQLException("File version (" + version + ") of file '" + file.getName() + "' is to new for this runtume."); 176 } 177 }catch(Throwable e){ 178 if(raFile != null) 179 try{ 180 raFile.close(); 181 }catch(Exception e2){ 182 DriverManager.println(e2.toString()); 183 } 184 throw Utils.createSQLException(e); 185 } 186 } 187 188 189 void drop(Database database) throws Exception { 190 close(); 191 boolean ok = getFile( database, name).delete(); 192 if(!ok) throw Utils.createSQLException("Table '" + name + "' can't drop."); 193 } 194 195 196 void close() throws Exception { 197 if(raFile != null){ 198 raFile.close(); 199 raFile = null; 200 } 201 } 202 203 204 private final void writeMagic(RandomAccessFile raFile) throws Exception { 205 raFile.writeInt(MAGIC_INDEX); 206 raFile.writeInt(INDEX_VERSION); 207 } 208 209 210 215 final void writeExpression( int columnIdx, Expression valueExpression) { 216 int idx = matrix[columnIdx]; 217 if(idx >= 0) expressions.set(idx, valueExpression); 219 } 220 221 222 226 final void writeFinsh(SSConnection con) { 227 } 230 231 232 235 final void save(StoreImpl store) throws SQLException { 236 store.writeInt(constraintType); 237 store.writeInt(columns.size()); 238 for(int c=0; c<columns.size(); c++){ 239 store.writeString( columns.get(c) ); 240 } 241 store.writeString(name); 242 } 243 244 245 248 final static IndexDescription load(Database database, TableView tableView, StoreImpl store) throws SQLException { 249 int constraintType = store.readInt(); 250 int count = store.readInt(); 251 Strings columns = new Strings(); 252 Expressions expressions = new Expressions(); 253 SQLParser sqlParser = new SQLParser(); 254 for(int c=0; c<count; c++){ 255 String column = store.readString(); 256 columns.add( column ); 257 expressions.add( sqlParser.parseExpression(column)); 258 } 259 IndexDescription indexDesc = new IndexDescription( store.readString(), tableView.name, constraintType, expressions, columns); 260 indexDesc.init( database, tableView ); 261 indexDesc.load(database); 262 return indexDesc; 263 } 264 265 266 } 267 | Popular Tags |