*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ---------------
* IndexDescription.java
* ---------------
* Author: Volker Berlin
*
* Created on 19.04.2005
*/
package smallsql.database;
import java.io.File;
import java.io.RandomAccessFile;
import java.sql.SQLException;
final class IndexDescription {
static final int MAGIC_INDEX = 'S' << 24 | 'Q' << 16 | 'L' << 8 | 'I';
static final int INDEX_VERSION = 1;
private String name;
final private int constraintType; final private Strings columns;
private int[] matrix;
final private Expressions expressions;
private Index index;
IndexDescription(int constraintType, Expressions expressions, Strings columns){
this.constraintType = constraintType;
this.expressions = expressions;
this.columns = columns;
}
final void setName(String name){
this.name = name;
}
final String getName(){
return name;
}
final boolean isPrimary(){
return constraintType == SQLTokenizer.PRIMARY;
}
final boolean isUnique(){
return constraintType == SQLTokenizer.PRIMARY || constraintType == SQLTokenizer.UNIQUE;
}
final Strings getColumns(){
return columns;
}
final int matchFactor(Strings strings){
if(strings.size() < columns.size())
return Integer.MAX_VALUE;
nextColumn:
for(int c=0; c<columns.size(); c++){
String colName = columns.get(c);
for(int s=0; s<strings.size(); s++){
if(colName.equalsIgnoreCase(strings.get(s)) )
continue nextColumn;
}
return Integer.MAX_VALUE; }
return strings.size() - columns.size();
}
final void init(Database database, TableView tableView){
int size = tableView.columns.size();
matrix = new int[size];
for(int i=0; i<matrix.length; i++){
matrix[i] = -1;
}
for(int i=0; i<columns.size(); i++){
matrix[tableView.findColumnIdx(columns.get(i))] = i;
}
if(name == null){
name = tableView.name + "_" + Long.toHexString(System.currentTimeMillis()) + Integer.toHexString(hashCode());
}
}
final void create(Database database, TableView tableView) throws Exception{
init( database, tableView );
createFile( database ).close();
}
static File getFile(Database database, String name) throws Exception{
return new File( Utils.createIdxFileName( database, name ) );
}
private RandomAccessFile createFile(Database database) throws Exception{
File file = getFile( database, name );
boolean ok = file.createNewFile();
if(!ok) throw Utils.createSQLException("Index '" + name + "' allready exists.");
RandomAccessFile raFile = new RandomAccessFile( file, "rw" );
writeMagic(raFile);
return raFile;
}
public void drop(Database database) throws Exception {
boolean ok = getFile( database, name).delete();
if(!ok) throw Utils.createSQLException("Table '" + name + "' can't drop.");
}
private final void writeMagic(RandomAccessFile raFile) throws Exception{
raFile.writeInt(MAGIC_INDEX);
raFile.writeInt(INDEX_VERSION);
}
final void writeExpression( int columnIdx, Expression valueExpression) {
int idx = matrix[columnIdx];
if(idx >= 0) expressions.set(idx, valueExpression);
}
final void writeFinsh(SSConnection con) {
}
final void save(StoreImpl store) throws SQLException{
store.writeInt(constraintType);
store.writeInt(columns.size());
for(int c=0; c<columns.size(); c++){
store.writeString( columns.get(c) );
}
store.writeString(name);
}
final static IndexDescription load(Database database, TableView tableView, StoreImpl store) throws SQLException{
int constraintType = store.readInt();
int count = store.readInt();
Strings columns = new Strings();
Expressions expressions = new Expressions();
SQLParser sqlParser = new SQLParser();
for(int c=0; c<count; c++){
String column = store.readString();
columns.add( column );
expressions.add( sqlParser.parseExpression(column));
}
IndexDescription indexDesc = new IndexDescription(constraintType, expressions, columns);
indexDesc.setName( store.readString() );
indexDesc.init( database, tableView );
return indexDesc;
}
}