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

📄 basicdependencymanager.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*   Derby - Class org.apache.derby.impl.sql.depend.BasicDependencyManager   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package org.apache.derby.impl.sql.depend;import	org.apache.derby.catalog.Dependable;import	org.apache.derby.catalog.DependableFinder;import org.apache.derby.iapi.services.context.ContextManager;import org.apache.derby.iapi.services.context.ContextService;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.sql.compile.CompilerContext;import org.apache.derby.iapi.sql.compile.Parser;import org.apache.derby.impl.sql.compile.CreateViewNode;import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;import org.apache.derby.iapi.sql.conn.StatementContext;import org.apache.derby.iapi.sql.depend.DependencyManager;import org.apache.derby.iapi.sql.depend.Dependency;import org.apache.derby.iapi.sql.depend.Dependent;import org.apache.derby.iapi.sql.depend.Provider;import org.apache.derby.iapi.sql.depend.ProviderInfo;import org.apache.derby.iapi.sql.depend.ProviderList;import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;import org.apache.derby.iapi.sql.dictionary.DependencyDescriptor;import org.apache.derby.iapi.sql.dictionary.TableDescriptor;import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;import org.apache.derby.impl.sql.catalog.DDColumnDependableFinder;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.catalog.UUID;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.io.FormatableBitSet;import org.apache.derby.iapi.reference.MessageId;import org.apache.derby.iapi.error.StandardException;import java.util.Hashtable;import java.util.Enumeration;import java.util.ListIterator;import java.util.List;/**	The dependency manager tracks needs that dependents have of providers. */public class BasicDependencyManager implements DependencyManager {	//	// DependencyManager interface	//	/**		adds a dependency from the dependent on the provider.		This will be considered to be the default type of		dependency, when dependency types show up.		<p>		Implementations of addDependency should be fast --		performing alot of extra actions to add a dependency would		be a detriment.		@param d the dependent		@param p the provider		@exception StandardException thrown if something goes wrong	 */	public void addDependency(Dependent d, Provider p, ContextManager cm) throws StandardException {		synchronized(this)		{			Dependency dy = new BasicDependency(d, p);			/* Dependencies are either in-memory or stored, but not both */			if (! d.isPersistent() || ! p.isPersistent())			{				/* Duplicate dependencies are not added to the lists.				 * If we find that the dependency we are trying to add in				 * one list is a duplicate, then it should be a duplicate in the				 * other list.				 */				boolean addedToDeps = false;				boolean addedToProvs = false;								addedToDeps = addDependencyToTable(dependents, d.getObjectID(), dy);				if (addedToDeps)				{					addedToProvs = addDependencyToTable(providers, p.getObjectID(), dy);				}				else if (SanityManager.DEBUG)				{					addedToProvs = addDependencyToTable(providers, p.getObjectID(), dy);				}				/* Dependency should have been added to both or neither */				if (SanityManager.DEBUG)				{                    if (addedToDeps != addedToProvs)                    {                        SanityManager.THROWASSERT(                            "addedToDeps (" + addedToDeps +                             ") and addedToProvs (" +                            addedToProvs + ") are expected to agree");                    }				}				/* Add the dependency to the StatementContext, so that			 	* it can be cleared on a pre-execution error.			 	*/				StatementContext sc = (StatementContext) cm.getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT);				sc.addDependency(dy);			}			else			{				/* Add a stored dependency */				LanguageConnectionContext	lcc = getLanguageConnectionContext(cm);				DataDictionary				dd = getDataDictionary();				DependencyDescriptor		dependencyDescriptor;							dependencyDescriptor = new DependencyDescriptor(d, p);				/* We can finally call the DataDictionary to store the dependency */				dd.addDescriptor(dependencyDescriptor, null,								 DataDictionary.SYSDEPENDS_CATALOG_NUM, true,								 lcc.getTransactionExecute());			}		}	}	/**		drops a single dependency		@param d the dependent		@param p the provider		@exception StandardException thrown if something goes wrong	 */	private	void dropDependency(LanguageConnectionContext lcc, Dependent d, Provider p) throws StandardException	{		if (SanityManager.DEBUG) {			// right now, this routine isn't called for in-memory dependencies			if (! d.isPersistent() || ! p.isPersistent())			{				SanityManager.NOTREACHED();			}		}		DataDictionary				dd = getDataDictionary();				DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(d, p);		dd.dropStoredDependency( dependencyDescriptor, 								 lcc.getTransactionExecute() );	}	/**		mark all dependencies on the named provider as invalid.		When invalidation types show up, this will use the default		invalidation type. The dependencies will still exist once		they are marked invalid; clearDependencies should be used		to remove dependencies that a dependent has or provider gives.		<p>		Implementations of this can take a little time, but are not		really expected to recompile things against any changes		made to the provider that caused the invalidation. The		dependency system makes no guarantees about the state of		the provider -- implementations can call this before or		after actually changing the provider to its new state.		<p>		Implementations should throw StandardException		if the invalidation should be disallowed.		@param p the provider		@param action	The action causing the invalidate		@exception StandardException thrown if unable to make it invalid	 */	public void invalidateFor(Provider p, int action,				  LanguageConnectionContext lcc)		 throws StandardException	{		/*		** Non-persistent dependencies are stored in memory, and need to		** use "synchronized" to ensure their lists don't change while		** the invalidation is taking place.  Persistent dependencies are		** stored in the data dictionary, and we should *not* do anything		** transactional (like reading from a system table) from within		** a synchronized method, as it could cause deadlock.		**		** Presumably, the transactional locking in the data dictionary		** is enough to protect us, so that we don't have to put any		** synchronization in the DependencyManager.		*/		if (p.isPersistent())			coreInvalidateFor(p, action, lcc);		else {			synchronized (this) {				coreInvalidateFor(p, action, lcc);			}		}	}	/**	 * A version of invalidateFor that does not provide synchronization among	 * invalidators.  If parameter "forSync" is true, it also provides	 * synchronization on the dependents.  Currently, this means synchronizing	 * on the prepared statements, which might be being executed on other	 * threads.	 * @param p			provider	 * @param action	The action causing the invalidate	 * @param lcc		Language connection context	 *	 * @return		array of locked dependents (to be unlocked by caller later)	 *	 * @exception StandardException		Thrown on error.	 */	private void coreInvalidateFor(Provider p, int action, LanguageConnectionContext lcc)		throws StandardException	{		List list = getDependents(p);		if (list == null)		{			return;		}		// affectedCols is passed in from table descriptor provider to indicate		// which columns it cares; subsetCols is affectedCols' intersection		// with column bit map found in the provider of SYSDEPENDS line to		// find out which columns really matter.  If SYSDEPENDS line's		// dependent is view (or maybe others), provider is table, yet it 		// doesn't have column bit map because the view was created in a		// previous version of server which doesn't support column dependency,		// and we really want it to have (such as in drop column), in any case		// if we passed in table descriptor to this function with a bit map,		// we really need this, we generate the bitmaps on the fly and update		// SYSDEPENDS		FormatableBitSet affectedCols = null, subsetCols = null;		if (p instanceof TableDescriptor)		{			affectedCols = ((TableDescriptor) p).getReferencedColumnMap();			if (affectedCols != null)				subsetCols = new FormatableBitSet(affectedCols.getLength());		}		{			StandardException noInvalidate = null;			// We cannot use an iterator here as the invalidations can remove			// entries from this list. 			for (int ei = list.size() - 1; ei >= 0; ei--)			{				if (ei >= list.size())					continue;				Dependency dependency = (Dependency) list.get(ei);				Dependent dep = dependency.getDependent();				if (affectedCols != null)				{					TableDescriptor td = (TableDescriptor) dependency.getProvider();					FormatableBitSet providingCols = td.getReferencedColumnMap();					if (providingCols == null)					{						if (dep instanceof ViewDescriptor)						{							ViewDescriptor vd = (ViewDescriptor) dep;							DataDictionary dd = getDataDictionary();							SchemaDescriptor compSchema;							compSchema = dd.getSchemaDescriptor(vd.getCompSchemaId(), null);							CompilerContext newCC = lcc.pushCompilerContext(compSchema);							Parser	pa = newCC.getParser();							LanguageConnectionFactory	lcf = lcc.getLanguageConnectionFactory();							// Since this is always nested inside another SQL							// statement, so topLevel flag should be false							CreateViewNode cvn = (CreateViewNode)pa.parseStatement(												vd.getViewText());							// need a current dependent for bind							newCC.setCurrentDependent(dep);							cvn = (CreateViewNode) cvn.bind();							ProviderInfo[] providerInfos = cvn.getProviderInfo();							lcc.popCompilerContext(newCC);							boolean		interferent = false;							for (int i = 0; i < providerInfos.length; i++)							{								Provider provider = null;								try								{									provider = (Provider) providerInfos[i].													getDependableFinder().													getDependable(													providerInfos[i].getObjectId());								}								catch(java.sql.SQLException te)								{									if (SanityManager.DEBUG)									{										SanityManager.THROWASSERT("unexpected java.sql.SQLException - " + te);									}								}								if (provider instanceof TableDescriptor)								{									TableDescriptor tab = (TableDescriptor)provider;									FormatableBitSet colMap = tab.getReferencedColumnMap();									if (colMap == null)										continue;									// if later on an error is raised such as in									// case of interference, this dependency line									// upgrade will not happen due to rollback									tab.setReferencedColumnMap(null);									dropDependency(lcc, vd, tab);									tab.setReferencedColumnMap(colMap);									addDependency(vd, tab, lcc.getContextManager());									if (tab.getObjectID().equals(td.getObjectID()))									{										System.arraycopy(affectedCols.getByteArray(), 0, 											subsetCols.getByteArray(), 0, 											affectedCols.getLengthInBytes());										subsetCols.and(colMap);										if (subsetCols.anySetBit() != -1)										{											interferent = true;											((TableDescriptor) p).setReferencedColumnMap(subsetCols);										}									}								}	// if provider instanceof TableDescriptor							}	// for providerInfos							if (! interferent)								continue;						}	// if dep instanceof ViewDescriptor						else							((TableDescriptor) p).setReferencedColumnMap(null);					}	// if providingCols == null					else					{						System.arraycopy(affectedCols.getByteArray(), 0, subsetCols.getByteArray(), 0, affectedCols.getLengthInBytes());						subsetCols.and(providingCols);						if (subsetCols.anySetBit() == -1)							continue;						((TableDescriptor) p).setReferencedColumnMap(subsetCols);					}				}				// generate a list of invalidations that fail.				try {					dep.prepareToInvalidate(p, action, lcc);				} catch (StandardException sqle) {					if (noInvalidate != null)						sqle.setNestedException(noInvalidate);					noInvalidate = sqle;				}				if (noInvalidate == null) {					if (affectedCols != null)						((TableDescriptor) p).setReferencedColumnMap(affectedCols);					// REVISIT: future impl will want to mark the individual					// dependency as invalid as well as the dependent...					dep.makeInvalid(action, lcc);				}			}			if (noInvalidate != null)				throw noInvalidate;		}	}	/**		Erases all of the dependencies the dependent has, be they		valid or invalid, of any dependency type.  This action is		usually performed as the first step in revalidating a		dependent; it first erases all the old dependencies, then		revalidates itself generating a list of new dependencies,		and then marks itself valid if all its new dependencies are		valid.		<p>		There might be a future want to clear all dependencies for		a particular provider, e.g. when destroying the provider.		However, at present, they are assumed to stick around and		it is the responsibility of the dependent to erase them when		revalidating against the new version of the provider.		<p>		clearDependencies will delete dependencies if they are		stored; the delete is finalized at the next commit.		@param d the dependent		@param p the provider	 *	 * @exception StandardException		Thrown on failure	 */	public void clearDependencies(LanguageConnectionContext lcc, Dependent d) throws StandardException {		List deps = (List) dependents.get(d.getObjectID());		synchronized(this)		{			/* Remove all the stored dependencies */			if (d.isPersistent())			{				DataDictionary			  dd = getDataDictionary();				dd.dropDependentsStoredDependencies(d.getObjectID(),													lcc.getTransactionExecute());			}			/* Now remove the in-memory dependencies */			if (deps == null) return; // already removed			// go through the list notifying providers to remove			// the dependency from their lists			for (ListIterator depsIterator = deps.listIterator();				depsIterator.hasNext(); ) {				Dependency dy = (Dependency)depsIterator.next();				clearProviderDependency(dy.getProviderKey(), dy);			}			dependents.remove(d.getObjectID());		}	}	/**	 * Clear the specified in memory dependency.	 * This is useful for clean-up when an exception occurs.	 * (We clear all in-memory dependencies added in the current	 * StatementContext.)	 */	public void clearInMemoryDependency(Dependency dy)

⌨️ 快捷键说明

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