📄 propertyconglomerate.java
字号:
/* Derby - Class org.apache.derby.impl.store.access.PropertyConglomerate Copyright 1998, 2004 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.store.access;import org.apache.derby.iapi.reference.Attribute;import org.apache.derby.iapi.reference.Property;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.types.UserType;import org.apache.derby.impl.store.access.UTF;import org.apache.derby.impl.store.access.UTFQualifier;import org.apache.derby.iapi.services.io.FormatableBitSet;import org.apache.derby.iapi.services.io.FormatableHashtable; import org.apache.derby.iapi.services.locks.ShExLockable;import org.apache.derby.iapi.services.locks.ShExQual;import org.apache.derby.iapi.services.daemon.Serviceable;import org.apache.derby.iapi.services.locks.C_LockFactory;import org.apache.derby.iapi.services.locks.Latch;import org.apache.derby.iapi.services.locks.LockFactory;import org.apache.derby.iapi.services.property.PropertyUtil;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.Formatable;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.store.access.AccessFactory;import org.apache.derby.iapi.store.access.AccessFactoryGlobals;import org.apache.derby.iapi.store.access.ConglomerateController;import org.apache.derby.iapi.services.property.PropertyFactory;import org.apache.derby.iapi.services.property.PropertySetCallback;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.ScanController;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.types.DataValueDescriptor;import java.io.Serializable;import java.util.Dictionary;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;/**Stores properties in a congolmerate with complete transactional support.<p>The PropertyConglomerate contains one row with 2 columns per property.Column 0 is the UTF key, and column 1 is the data.<p><p>The property conglomerate manages the storage of database propertiesand thier defaults. Each property is stored as a row in thePropertyConglomerate <OL><LI>Column 0 is the UTF key,<LI>Column 1 is the data.</OL>All the property defaults are stored in a single row of the PropertyConglomerate:<OL><LI>Column 0 is the UTF key "derby.defaultPropertyName".<LI>Column 1 is a FormatableProperties object with one row per default property.</OL><p>In general a propery default defines it value if the propertyitself is not defined.<p>Because the properties conglomerate is stored in a conglomeratethe information it contains is not available before the raw storeruns recovery. To make a small number of properties (listed inservicePropertyList) available during early boot, this copiesthem to services.properties.**/class PropertyConglomerate{ protected long propertiesConglomId; protected Properties serviceProperties; private LockFactory lf; private Dictionary cachedSet; private CacheLock cachedLock; private PropertyFactory pf; /* Constructors for This class: */ PropertyConglomerate( TransactionController tc, boolean create, Properties serviceProperties, PropertyFactory pf) throws StandardException { this.pf = pf; if (!create) { String id = serviceProperties.getProperty(Property.PROPERTIES_CONGLOM_ID); if (id == null) { create = true; } else { try { propertiesConglomId = Long.valueOf(id).longValue(); } catch (NumberFormatException nfe) { throw Monitor.exceptionStartingModule(nfe) ; } } } if (create) { DataValueDescriptor[] template = makeNewTemplate(); Properties conglomProperties = new Properties(); conglomProperties.put( Property.PAGE_SIZE_PARAMETER, RawStoreFactory.PAGE_SIZE_STRING); conglomProperties.put( RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, RawStoreFactory.PAGE_RESERVED_ZERO_SPACE_STRING); propertiesConglomId = tc.createConglomerate( AccessFactoryGlobals.HEAP, template, null, conglomProperties, TransactionController.IS_DEFAULT); serviceProperties.put( Property.PROPERTIES_CONGLOM_ID, Long.toString(propertiesConglomId)); } this.serviceProperties = serviceProperties; lf = ((RAMTransaction) tc).getAccessManager().getLockFactory(); cachedLock = new CacheLock(this); PC_XenaVersion softwareVersion = new PC_XenaVersion(); if (create) setProperty(tc,DataDictionary.PROPERTY_CONGLOMERATE_VERSION, softwareVersion, true); else softwareVersion.upgradeIfNeeded(tc,this,serviceProperties); getCachedDbProperties(tc); } /* Private/Protected methods of This class: */ /** * Create a new PropertyConglomerate row, with values in it. **/ private DataValueDescriptor[] makeNewTemplate(String key, Serializable value) { DataValueDescriptor[] template = new DataValueDescriptor[2]; template[0] = new UTF(key); template[1] = new UserType(value); return(template); } /** * Create a new empty PropertyConglomerate row, to fetch values into. **/ private DataValueDescriptor[] makeNewTemplate() { DataValueDescriptor[] template = new DataValueDescriptor[2]; template[0] = new UTF(); template[1] = new UserType(); return(template); } /** * Open a scan on the properties conglomerate looking for "key". * <p> * Open a scan on the properties conglomerate qualified to * find the row with value key in column 0. Both column 0 * and column 1 are included in the scan list. * * @return an open ScanController on the PropertyConglomerate. * * @param tc The transaction to do the Conglomerate work under. * @param key The "key" of the property that is being requested. * @param open_mode Whether we are setting or getting the property. * * @exception StandardException Standard exception policy. **/ private ScanController openScan( TransactionController tc, String key, int open_mode) throws StandardException { Qualifier[][] qualifiers = null; if (key != null) { // Set up qualifier to look for the row with key value in column[0] qualifiers = new Qualifier[1][]; qualifiers[0] = new Qualifier[1]; qualifiers[0][0] = new UTFQualifier(0, key); } // open the scan, clients will do the fetches and close. ScanController scan = tc.openScan( propertiesConglomId, false, // don't hold over the commit open_mode, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, (DataValueDescriptor[]) null, // start key ScanController.NA, qualifiers, (DataValueDescriptor[]) null, // stop key ScanController.NA); return(scan); } /* Package Methods of This class: */ /** Set a property in the conglomerate. @param key The key used to lookup this property. @param value The value to be associated with this key. If null, delete the property from the properties list. */ /** * Set the default for a property. * @exception StandardException Standard exception policy. */ void setPropertyDefault(TransactionController tc, String key, Serializable value) throws StandardException { lockProperties(tc); Serializable valueToSave = null; // //If the default is visible we validate apply and map. //otherwise we just map. if (propertyDefaultIsVisible(tc,key)) { valueToSave = validateApplyAndMap(tc,key,value,false); } else { synchronized (this) { Hashtable defaults = new Hashtable(); getProperties(tc,defaults,false/*!stringsOnly*/,true/*defaultsOnly*/); validate(key,value,defaults); valueToSave = map(key,value,defaults); } } savePropertyDefault(tc,key,valueToSave); } boolean propertyDefaultIsVisible(TransactionController tc,String key) throws StandardException { lockProperties(tc); return(readProperty(tc,key) == null); } void saveProperty(TransactionController tc, String key, Serializable value) throws StandardException { if (saveServiceProperty(key,value)) return; // Do a scan to see if the property already exists in the Conglomerate. ScanController scan = this.openScan(tc, key, TransactionController.OPENMODE_FORUPDATE); DataValueDescriptor[] row = makeNewTemplate(); if (scan.fetchNext(row)) { if (value == null) { // A null input value means that we should delete the row scan.delete(); } else { // a value already exists, just replace the second columm row[1] = new UserType(value); scan.replace(row, (FormatableBitSet) null); } scan.close(); } else { // The value does not exist in the Conglomerate. scan.close(); scan = null; if (value != null) { // not a delete request, so insert the new property. row = makeNewTemplate(key, value); ConglomerateController cc = tc.openConglomerate( propertiesConglomId, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE); cc.insert(row); cc.close(); } } } private boolean saveServiceProperty(String key, Serializable value) { if (PropertyUtil.isServiceProperty(key)) { if (value != null) serviceProperties.put(key, value); else serviceProperties.remove(key); return true; } else { return false; } } void savePropertyDefault(TransactionController tc, String key, Serializable value) throws StandardException { if (saveServiceProperty(key,value)) return; Dictionary defaults = (Dictionary)readProperty(tc,AccessFactoryGlobals.DEFAULT_PROPERTY_NAME); if (defaults == null) defaults = new FormatableHashtable(); if (value==null) defaults.remove(key); else defaults.put(key,value); if (defaults.size() == 0) defaults = null; saveProperty(tc,AccessFactoryGlobals.DEFAULT_PROPERTY_NAME,(Serializable)defaults); } private Serializable validateApplyAndMap(TransactionController tc, String key, Serializable value, boolean dbOnlyProperty) throws StandardException { Dictionary d = new Hashtable(); getProperties(tc,d,false/*!stringsOnly*/,false/*!defaultsOnly*/); Serializable mappedValue = pf.doValidateApplyAndMap(tc, key, value, d, dbOnlyProperty); // // RESOLVE: log device cannot be changed on the fly right now if (key.equals(Attribute.LOG_DEVICE)) { throw StandardException.newException( SQLState.RAWSTORE_CANNOT_CHANGE_LOGDEVICE); } if (mappedValue == null) return value; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -