The dependency manager tracks needs that dependents have of providers.
Method from org.apache.derby.impl.sql.depend.BasicDependencyManager Detail: |
public void addDependency(Dependent d,
Provider p,
ContextManager cm) throws StandardException {
addDependency(d, p, cm, null);
}
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.
Implementations of addDependency should be fast --
performing alot of extra actions to add a dependency would
be a detriment. |
public void clearColumnInfoInProviders(ProviderList pl) throws StandardException {
Enumeration e = pl.elements();
while (e.hasMoreElements())
{
Provider pro = (Provider) e.nextElement();
if (pro instanceof TableDescriptor)
((TableDescriptor) pro).setReferencedColumnMap(null);
}
}
|
public void clearDependencies(LanguageConnectionContext lcc,
Dependent d) throws StandardException {
clearDependencies(lcc, d, null);
}
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.
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.
clearDependencies will delete dependencies if they are
stored; the delete is finalized at the next commit. |
public void clearDependencies(LanguageConnectionContext lcc,
Dependent d,
TransactionController tc) throws StandardException {
List deps = (List) dependents.get(d.getObjectID());
synchronized(this)
{
/* Remove all the stored dependencies */
if (d.isPersistent())
{
boolean wait = (tc == null);
dd.dropDependentsStoredDependencies(d.getObjectID(),
((wait)?lcc.getTransactionExecute():tc),
wait);
}
/* 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());
}
}
|
public void clearInMemoryDependency(Dependency dy) {
synchronized(this)
{
List deps =
(List) dependents.get(dy.getDependent().getObjectID());
// NOTE - this is a NEGATIVE Sanity mode check, in sane mode we continue
// to ensure the dependency manager is consistent.
if (!SanityManager.DEBUG) {
// dependency has already been removed
if (deps == null)
return;
}
List provs =
(List) providers.get(dy.getProvider().getObjectID());
if (SanityManager.DEBUG)
{
// if both are null then everything is OK
if ((deps != null) || (provs != null)) {
// ensure that the Dependency dy is either
// in both lists or in neither. Even if dy
// is out of the list we can have non-null
// deps and provs here because other dependencies
// with the the same providers or dependents can exist
//
int depCount = 0;
if (deps != null) {
for (int ci = 0; ci < deps.size(); ci++) {
if (dy.equals(deps.get(ci)))
depCount++;
}
}
int provCount = 0;
if (provs != null) {
for (int ci = 0; ci < provs.size(); ci++) {
if (dy.equals(provs.get(ci)))
provCount++;
}
}
if (depCount != provCount) {
SanityManager.THROWASSERT("Dependency count mismatch count in deps: " + depCount +
", count in provs " + provCount +
", dy.getDependent().getObjectID() = " + dy.getDependent().getObjectID() +
", dy.getProvider().getObjectID() = " + dy.getProvider().getObjectID());
}
}
// dependency has already been removed,
// matches code that is protected by !DEBUG above
if (deps == null)
return;
}
// dependency has already been removed
if (provs == null)
return;
deps.remove(dy);
if (deps.size() == 0)
dependents.remove(dy.getDependent().getObjectID());
provs.remove(dy);
if (provs.size() == 0)
providers.remove(dy.getProvider().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.) |
protected void clearProviderDependency(UUID p,
Dependency d) {
List deps = (List) providers.get(p);
if (deps == null)
return;
deps.remove(d);
if (deps.size() == 0)
providers.remove(p);
}
removes a dependency for a given provider. assumes
that the dependent removal is being dealt with elsewhere.
Won't assume that the dependent only appears once in the list. |
public void copyDependencies(Dependent copy_From,
Dependent copyTo,
boolean persistentOnly,
ContextManager cm) throws StandardException {
copyDependencies(copy_From, copyTo, persistentOnly, cm, null);
}
Copy dependencies from one dependent to another. |
public synchronized void copyDependencies(Dependent copy_From,
Dependent copyTo,
boolean persistentOnly,
ContextManager cm,
TransactionController tc) throws StandardException {
List list = getProviders(copy_From);
if (list == null)
return;
for (ListIterator depsIterator = list.listIterator(); depsIterator.hasNext(); )
{
Provider provider = ((Dependency) depsIterator.next()).getProvider();
if (!persistentOnly || provider.isPersistent())
{
this.addDependency(copyTo, provider, cm, tc);
}
}
}
|
public int countDependencies() throws StandardException {
synchronized(this)
{
int numDependencies = 0;
Enumeration deps = dependents.elements();
Enumeration provs = providers.elements();
List storedDeps = dd.getAllDependencyDescriptorsList();
/* Count the in memory dependencies */
while (deps.hasMoreElements())
{
numDependencies += ((List) deps.nextElement()).size();
}
while (provs.hasMoreElements())
{
numDependencies += ((List) provs.nextElement()).size();
}
/* Add in the stored dependencies */
numDependencies += storedDeps.size();
return numDependencies;
}
}
Count the number of active dependencies, both stored and in memory,
in the system. |
public String dumpDependencies() throws StandardException, SQLException {
synchronized(this)
{
boolean foundInMemory = false;
boolean foundStored = false;
StringBuffer debugBuf = new StringBuffer();
if (SanityManager.DEBUG)
{
Enumeration deps = dependents.keys();
UUID[] depKeys = new UUID[dependents.size()];
/* Record the in memory dependencies */
for (int i = 0; deps.hasMoreElements(); i++)
{
/*
** Get all the keys and sort them, so that they will always
** be printed in the same order (we have tests that canonize
** the order of printing the dependencies, and since the key
** is a UUID, the order they are returned from
** hasMoreElements() changes from run to run).
*/
depKeys[i] = (UUID) deps.nextElement();
}
/* Do a bubble sort - there aren't likely to be many elements */
bubbleSort(depKeys);
/* Iterate through the sorted keys */
for (int i = 0; i < depKeys.length; i++)
{
List depsSList = (List) dependents.get(depKeys[i]);
for (ListIterator depsIterator = depsSList.listIterator();
depsIterator.hasNext(); )
{
Dependency dy = (Dependency)depsIterator.next();
if (! foundInMemory)
{
debugBuf.append("In Memory Dependencies:\n");
foundInMemory = true;
}
debugBuf.append(dy.getDependent().toString() +
", type " +
dy.getDependent().getClassType() +
", " +
" is dependent on " +
dy.getProvider().getObjectName() +
", type " +
dy.getProvider().getClassType() +
"\n");
}
}
/* Record the in memory dependencies */
Enumeration provs = providers.keys();
UUID[] provKeys = new UUID[providers.size()];
for (int i = 0; provs.hasMoreElements(); i++)
{
/*
** Get all the keys and sort them, so that they will always
** be printed in the same order (we have tests that canonize
** the order of printing the dependencies, and since the key
** is a UUID, the order they are returned from
** hasMoreElements() changes from run to run).
*/
provKeys[i] = (UUID) provs.nextElement();
}
/* Do a bubble sort - there aren't likely to be many elements */
bubbleSort(provKeys);
/* Iterate through the sorted keys */
for (int i = 0; i < provKeys.length; i++)
{
List depsSList = (List) providers.get(provKeys[i]);
for (ListIterator depsIterator = depsSList.listIterator();
depsIterator.hasNext(); )
{
Dependency dy = (Dependency)depsIterator.next();
if (! foundInMemory)
{
debugBuf.append("In Memory Dependencies:\n");
foundInMemory = true;
}
debugBuf.append(
dy.getProvider().toString() +
", type " +
dy.getProvider().getClassType() +
", provides for " +
dy.getDependent().getObjectName() +
", type " +
dy.getDependent().getClassType() +
"\n");
}
}
/* Record the stored dependencies in sorted order to avoid
ordering problems in canons. Also the dependencyDescriptor.getUUID()
in this list is not unique, hence the sort on the output string values instead
*/
List storedDeps = dd.getAllDependencyDescriptorsList();
String[] dependStr = new String[storedDeps.size()];
int i = 0;
for (ListIterator depsIterator = storedDeps.listIterator();
depsIterator.hasNext(); )
{
DependencyDescriptor dependDescr =
(DependencyDescriptor) depsIterator.next();
if (! foundStored)
{
debugBuf.append("Stored Dependencies:\n");
foundStored = true;
}
DependableFinder providerFinder = dependDescr.getProviderFinder();
DependableFinder dependentFinder = dependDescr.getDependentFinder();
dependStr[i++] =
providerFinder.getDependable(dd, dependDescr.getProviderID()).getObjectName() +
", type " + providerFinder.getSQLObjectType() +
", provides for " +
dependentFinder.getDependable(dd, dependDescr.getUUID()).getObjectName() +
", type " + dependentFinder.getSQLObjectType() +
"\n";
}
// sort stored dependencies; dependStr
for (i = 0; i < dependStr.length; i++)
{
for (int j = i + 1; j < dependStr.length; j++)
{
if (dependStr[i].compareTo(dependStr[j]) > 0)
{
String save = dependStr[i];
dependStr[i] = dependStr[j];
dependStr[j] = save;
}
}
}
for(i=0; i < dependStr.length; i++)
debugBuf.append(dependStr[i]);
}
return debugBuf.toString();
}
}
Dump out debugging info on all of the dependencies currently
within the system. |
public String getActionString(int action) {
switch (action)
{
case ALTER_TABLE:
return "ALTER TABLE";
case RENAME: //for rename table and column
return "RENAME";
case RENAME_INDEX:
return "RENAME INDEX";
case COMPILE_FAILED:
return "COMPILE FAILED";
case DROP_TABLE:
return "DROP TABLE";
case DROP_INDEX:
return "DROP INDEX";
case DROP_VIEW:
return "DROP VIEW";
case CREATE_INDEX:
return "CREATE INDEX";
case ROLLBACK:
return "ROLLBACK";
case CHANGED_CURSOR:
return "CHANGED CURSOR";
case CREATE_CONSTRAINT:
return "CREATE CONSTRAINT";
case DROP_CONSTRAINT:
return "DROP CONSTRAINT";
case DROP_METHOD_ALIAS:
return "DROP ROUTINE";
case PREPARED_STATEMENT_RELEASE:
return "PREPARED STATEMENT RELEASE";
case DROP_SPS:
return "DROP STORED PREPARED STATEMENT";
case USER_RECOMPILE_REQUEST:
return "USER REQUESTED INVALIDATION";
case BULK_INSERT:
return "BULK INSERT";
case CREATE_VIEW:
return "CREATE_VIEW";
case DROP_JAR:
return "DROP_JAR";
case REPLACE_JAR:
return "REPLACE_JAR";
case SET_CONSTRAINTS_ENABLE:
return "SET_CONSTRAINTS_ENABLE";
case SET_CONSTRAINTS_DISABLE:
return "SET_CONSTRAINTS_DISABLE";
case INTERNAL_RECOMPILE_REQUEST:
return "INTERNAL RECOMPILE REQUEST";
case CREATE_TRIGGER:
return "CREATE TRIGGER";
case DROP_TRIGGER:
return "DROP TRIGGER";
case SET_TRIGGERS_ENABLE:
return "SET TRIGGERS ENABLED";
case SET_TRIGGERS_DISABLE:
return "SET TRIGGERS DISABLED";
case MODIFY_COLUMN_DEFAULT:
return "MODIFY COLUMN DEFAULT";
case COMPRESS_TABLE:
return "COMPRESS TABLE";
case DROP_COLUMN:
return "DROP COLUMN";
case DROP_COLUMN_RESTRICT:
return "DROP COLUMN RESTRICT";
case DROP_STATISTICS:
return "DROP STATISTICS";
case UPDATE_STATISTICS:
return "UPDATE STATISTICS";
case TRUNCATE_TABLE:
return "TRUNCATE TABLE";
case DROP_SYNONYM:
return "DROP SYNONYM";
case REVOKE_PRIVILEGE:
return "REVOKE PRIVILEGE";
case REVOKE_PRIVILEGE_RESTRICT:
return "REVOKE PRIVILEGE RESTRICT";
case REVOKE_ROLE:
return "REVOKE ROLE";
case RECHECK_PRIVILEGES:
return "RECHECK PRIVILEGES";
default:
if (SanityManager.DEBUG)
{
SanityManager.THROWASSERT("getActionString() passed an invalid value (" + action + ")");
}
// NOTE: This is not internationalized because we should never
// reach here.
return "UNKNOWN";
}
}
Returns a string representation of the SQL action, hence no
need to internationalize, which is causing the invokation
of the Dependency Manager. |
public synchronized ProviderInfo[] getPersistentProviderInfos(Dependent dependent) throws StandardException {
List list = getProviders(dependent);
if (list == null)
{
return EMPTY_PROVIDER_INFO;
}
java.util.ArrayList pih = new java.util.ArrayList();
for (ListIterator depsIterator = list.listIterator();
depsIterator.hasNext(); )
{
Dependency dep = (Dependency) depsIterator.next();
if (dep.getProvider().isPersistent())
{
pih.add(new BasicProviderInfo(
dep.getProvider().getObjectID(),
dep.getProvider().getDependableFinder(),
dep.getProvider().getObjectName()
));
}
}
return (ProviderInfo[]) pih.toArray(EMPTY_PROVIDER_INFO);
}
|
public ProviderInfo[] getPersistentProviderInfos(ProviderList pl) throws StandardException {
Enumeration e = pl.elements();
int numProviders = 0;
ProviderInfo[] retval;
/*
** We make 2 passes - the first to count the number of persistent
** providers and the second to populate the array of ProviderInfos.
*/
while (e != null && e.hasMoreElements())
{
Provider prov = (Provider) e.nextElement();
if (prov.isPersistent())
{
numProviders++;
}
}
e = pl.elements();
retval = new ProviderInfo[numProviders];
int piCtr = 0;
while (e != null && e.hasMoreElements())
{
Provider prov = (Provider) e.nextElement();
if (prov.isPersistent())
{
retval[piCtr++] = new BasicProviderInfo(
prov.getObjectID(),
prov.getDependableFinder(),
prov.getObjectName()
);
}
}
return retval;
}
|
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);
}
}
}
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.
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.
Implementations should throw StandardException
if the invalidation should be disallowed. |