⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* =============================================================
 * SmallSQL : a free Java DBMS library for the Java(tm) platform
 * =============================================================
 *
 * (C) Copyright 2004-2006, by Volker Berlin.
 *
 * Project Info:  http://www.smallsql.de/
 *
 * 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.]
 *
 * ---------------
 * Table.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;

import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


class Table extends TableView{
	
	private static final int INDEX = 1;

    final Database database;
    RandomAccessFile raFile; // file handle of the table
	private Lobs lobs; // file handle of lob data for this table
    long firstPage; // offset of the first page

	final private HashMap locks = new HashMap();
	private SSConnection tabLockConnection; // wenn gesetzt die Connection die ein LOCK_TAB hat
	private int tabLockCount;
	final private ArrayList locksInsert = new ArrayList(); // liste der LOCK_INSERT
	final private HashMap serializeConnections = new HashMap();
	final IndexDescriptions indexes;
	final ForeignKeys references;


	/**
	 * Constructor for read existing tables.
	 */
    Table( Database database, SSConnection con, String name, RandomAccessFile raFile, long offset, int tableFormatVersion) throws Exception{
        super( name, new Columns() );
        this.database = database;
        this.raFile   = raFile;
		this.firstPage = offset;
		StoreImpl store = getStore(con, firstPage, SQLTokenizer.SELECT);
        if(store == null){
            throw Utils.createSQLException("File '" + getFile(database) + "' does not include a valid SmallSQL Table.");
        }
		int count = store.readInt();

		for(int i=0; i<count; i++){
			columns.add( store.readColumn(this, tableFormatVersion) );
		}
		indexes = new IndexDescriptions();
        references = new ForeignKeys();
		
		// read additional informations
		int type;
		while((type = store.readInt()) != 0){
			int offsetInPage = store.getCurrentOffsetInPage();
			int size = store.readInt();
			switch(type){
				case INDEX:
					indexes.add( IndexDescription.load( database, this, store) );
					break;
			}
			store.setCurrentOffsetInPage(offsetInPage + size);
		}
		
		firstPage = store.getNextPagePos();
    }
    

    /**
     * Constructor for creating of new tables.
     */
    Table(Database database, SSConnection con, String name, Columns columns, IndexDescriptions indexes, ForeignKeys foreignKeys) throws Exception{
        this(database, con, name, columns, null, indexes, foreignKeys);
    }
    
    /**
     * Constructor for alter an existing tables.
     */
    Table(Database database, SSConnection con, String name, Columns columns, IndexDescriptions existIndexes, IndexDescriptions newIndexes, ForeignKeys foreignKeys) throws Exception{
        super( name, columns );
        this.database = database;
        this.references = foreignKeys;
        newIndexes.create( database, this );
        if(existIndexes == null){
            this.indexes = newIndexes;
        }else{
            this.indexes = existIndexes;
            existIndexes.add(newIndexes);
        }
        
        write(con);
        for(int i=0; i<foreignKeys.size(); i++){
            ForeignKey foreignKey = foreignKeys.get(i);
            Table pkTable = (Table)database.getTableView(con, foreignKey.pkTable);
            pkTable.references.add(foreignKey);
        }
    }
    
    /**
     * Constructor for extends class Lobs.
     */
    Table(Database database, String name){
    	super( name, null);
    	this.database = database;
		indexes = null;
        references = null;
    }

	/**
	 * Drop the Table. This method is static that the file does not need to load and also corrupt files can be dropped.
	 */ 
    static void drop(Database database, String name) throws Exception{
        boolean ok = new File( Utils.createTableViewFileName( database, name ) ).delete();
        if(!ok) throw Utils.createSQLException("Table '" + name + "' can't drop.");
    }
    
    
    /**
     * Drop a loaded table.
     *
     */
    void drop(SSConnection con) throws Exception{
		TableStorePage storePage = requestLock( con, SQLTokenizer.CREATE, -1 );
		if(storePage == null){
			throw Utils.createSQLException("Table '" + name + "' can't drop because is locked.");
        }
		// remove the all commits that point to this table
		con.rollbackFile(raFile);
		close();
		if(lobs != null)
			lobs.drop(con);
		if(indexes != null)
			indexes.drop(database);
		boolean ok = getFile(database).delete();
		if(!ok) throw Utils.createSQLException("Table '" + name + "' can't drop.");
    }
    

    /**
     * Closed the file handle that the object can be garbaged.
     */
    void close() throws Exception{
        if(indexes != null)
            indexes.close();
        raFile.close();
        raFile = null;
    }


    private void write(SSConnection con) throws Exception{
        raFile = createFile( database );
        firstPage = 8;
        StoreImpl store = getStore( con, firstPage, SQLTokenizer.CREATE);
        int count = columns.size();
        store.writeInt( count );
        for(int i=0; i<count; i++){
            store.writeColumn( this, columns.get(i) );
        }

		// write additional informations
		for(int i=0; i<indexes.size(); i++){
			IndexDescription indexDesc = indexes.get(i);
			store.writeInt( INDEX );
			int offsetStart = store.getCurrentOffsetInPage();
			store.setCurrentOffsetInPage( offsetStart + 4 ); // place holder for length
			
			// write the IndexDescription
			indexDesc.save(store);
			
			// write the length information
			int offsetEnd = store.getCurrentOffsetInPage();
			store.setCurrentOffsetInPage( offsetStart );
			store.writeInt( offsetEnd - offsetStart);
			store.setCurrentOffsetInPage( offsetEnd );
		}
		store.writeInt( 0 ); // no more additional informations
		
		store.writeFinsh(null); //The connection parameter is null because the table header is written immediately.
        firstPage = store.getNextPagePos();
    }
    

	void writeMagic(RandomAccessFile raFile) throws Exception{
		raFile.writeInt(MAGIC_TABLE);
		raFile.writeInt(TABLE_VIEW_VERSION);
	}
	

    /*StoreImpl getStoreCreate( SSConnection con, long filePos ) throws Exception{
        return StoreImpl.createStore( con, raFile, SQLTokenizer.CREATE, filePos );
    }*/

    StoreImpl getStore( SSConnection con, long filePos, int pageOperation ) throws Exception{
		TableStorePage storePage = requestLock( con, pageOperation, filePos );
        return StoreImpl.createStore( this, storePage, pageOperation, filePos );
    }

    
	StoreImpl getStore( TableStorePage storePage, int pageOperation ) throws Exception{
		// is used for not commited INSERT pages, a new lock is not needed
		return StoreImpl.recreateStore( this, storePage, pageOperation );
	}
	
    /*StoreImpl getStoreUpdate( SSConnection con, long filePos ) throws Exception{
        return StoreImpl.createStore( con, raFile, SQLTokenizer.UPDATE, filePos );
    }

    StoreImpl getStoreDelete( SSConnection con, long filePos ) throws Exception{
        return StoreImpl.createStore( con, raFile, SQLTokenizer.DELETE, filePos );
    }*/
	

    StoreImpl getStoreInsert( SSConnection con ) throws Exception{
		TableStorePage storePage = requestLock( con, SQLTokenizer.INSERT, -1 );
        return StoreImpl.createStore( this, storePage, SQLTokenizer.INSERT, -1 );
    }
    
    
    /**
     * Create a Store that is not invoke in a transaction for copy of data.
     */
	StoreImpl getStoreTemp( SSConnection con ) throws Exception{
		TableStorePage storePage = new TableStorePage( con, this, LOCK_NONE, -2);
		return StoreImpl.createStore( this, storePage, SQLTokenizer.INSERT, -2 );
	}
        

	StoreImpl getLobStore(SSConnection con, long filePos, int pageOperation) throws Exception{
		if(lobs == null){
			lobs = new Lobs( this );
		}
		return lobs.getStore( con, filePos, pageOperation );
	}
    

	
	/**
	 * Return the file offset of the first page with data after the table declaration.
	 * This is equals to the first row.
	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -