001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.DD_Version
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.catalog;
023:
024: import org.apache.derby.iapi.services.monitor.Monitor;
025: import org.apache.derby.iapi.services.sanity.SanityManager;
026: import org.apache.derby.iapi.services.io.Formatable;
027: import org.apache.derby.iapi.error.StandardException;
028: import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
029: import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
030: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
031: import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
032: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
033: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
034: import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
035: import org.apache.derby.iapi.types.DataValueFactory;
036: import org.apache.derby.iapi.types.RowLocation;
037: import org.apache.derby.iapi.reference.SQLState;
038: import org.apache.derby.iapi.store.access.ConglomerateController;
039: import org.apache.derby.iapi.store.access.TransactionController;
040: import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
041: import org.apache.derby.iapi.store.access.ScanController;
042: import org.apache.derby.iapi.sql.execute.ExecRow;
043: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
044: import org.apache.derby.iapi.services.io.StoredFormatIds;
045:
046: import org.apache.derby.iapi.services.io.FormatableBitSet;
047: import org.apache.derby.iapi.services.info.ProductGenusNames;
048: import org.apache.derby.iapi.services.info.ProductVersionHolder;
049: import org.apache.derby.iapi.reference.JDBC30Translation;
050: import org.apache.derby.iapi.reference.Limits;
051: import org.apache.derby.iapi.util.IdUtil;
052:
053: import org.apache.derby.iapi.services.uuid.UUIDFactory;
054: import org.apache.derby.catalog.UUID;
055: import org.apache.derby.catalog.types.RoutineAliasInfo;
056: import org.apache.derby.catalog.AliasInfo;
057: import org.apache.derby.catalog.TypeDescriptor;
058: import org.apache.derby.iapi.types.DataTypeDescriptor;
059: import java.io.IOException;
060: import java.io.ObjectInput;
061: import java.io.ObjectOutput;
062: import java.sql.Types;
063: import java.util.Enumeration;
064: import java.util.Properties;
065:
066: /**
067: * Generic code for upgrading data dictionaries.
068: * Currently has all minor version upgrade logic.
069: * <p>
070: * A word about minor vs. major upgraded. Minor
071: * upgrades must be backwards/forwards compatible.
072: * So they cannot version classes or introduce new
073: * classes. Major releases are only backwards compatible;
074: * they will run against an old database, but not the
075: * other way around. So they can introduce new classes,
076: * etc.
077: *
078: * @author Rick
079: */
080:
081: public class DD_Version implements Formatable {
082: ////////////////////////////////////////////////////////////////////////
083: //
084: // STATE
085: //
086: ////////////////////////////////////////////////////////////////////////
087:
088: private transient DataDictionaryImpl bootingDictionary;
089:
090: int majorVersionNumber;
091: private int minorVersionNumber;
092:
093: ////////////////////////////////////////////////////////////////////////
094: //
095: // CONSTRUCTORS
096: //
097: ////////////////////////////////////////////////////////////////////////
098:
099: /**
100: * Public niladic constructor needed for Formatable interface.
101: */
102: public DD_Version() {
103: }
104:
105: /**
106: * Construct a Version for the currently booting data dictionary.
107: * The minor version is set by the subclass.
108: *
109: * @param bootingDictionary The booting dictionary that needs to be upgraded.
110: */
111: DD_Version(DataDictionaryImpl bootingDictionary,
112: int majorVersionNumber) {
113: this .majorVersionNumber = majorVersionNumber;
114: this .minorVersionNumber = getJBMSMinorVersionNumber();
115: this .bootingDictionary = bootingDictionary;
116: }
117:
118: ////////////////////////////////////////////////////////////////////////
119: //
120: // OVERRIDE OBJECT METHODS
121: //
122: ////////////////////////////////////////////////////////////////////////
123:
124: /**
125: * Stringify this Version.
126: *
127: * @return String representation of this Version.
128: */
129: public String toString() {
130: return DD_Version.majorToString(majorVersionNumber);
131: }
132:
133: private static String majorToString(int majorVersionNumber) {
134: switch (majorVersionNumber) {
135: case DataDictionary.DD_VERSION_CS_5_0:
136: return "5.0";
137: case DataDictionary.DD_VERSION_CS_5_1:
138: return "5.1";
139: case DataDictionary.DD_VERSION_CS_5_2:
140: return "5.2";
141: case DataDictionary.DD_VERSION_CS_8_1:
142: return "8.1";
143: case DataDictionary.DD_VERSION_CS_10_0:
144: return "10.0";
145: case DataDictionary.DD_VERSION_DERBY_10_1:
146: return "10.1";
147: case DataDictionary.DD_VERSION_DERBY_10_2:
148: return "10.2";
149: default:
150: return null;
151: }
152: }
153:
154: ////////////////////////////////////////////////////////////////////////
155: //
156: // DataDictionary SPECIFIC
157: //
158: ////////////////////////////////////////////////////////////////////////
159:
160: /**
161: * Upgrade the data dictionary catalogs to the version represented by this
162: * DD_Version.
163: *
164: * @param dictionaryVersion the version of the data dictionary tables.
165: * @exception StandardException Ooops
166: */
167: void upgradeIfNeeded(DD_Version dictionaryVersion,
168: TransactionController tc, Properties startParams)
169: throws StandardException {
170: // database has been upgrade with a later engine version than this?
171: if (dictionaryVersion.majorVersionNumber > majorVersionNumber) {
172: throw StandardException.newException(
173: SQLState.LANG_CANT_UPGRADE_CATALOGS,
174: dictionaryVersion, this );
175: }
176:
177: boolean minorOnly = false;
178: boolean performMajorUpgrade = false;
179: boolean softUpgradeRun = false;
180: boolean isReadOnly = bootingDictionary.af.isReadOnly();
181:
182: if (dictionaryVersion.majorVersionNumber == majorVersionNumber) {
183:
184: // exact match of engine to database, do nothing.
185: if (dictionaryVersion.minorVersionNumber == minorVersionNumber)
186: return;
187:
188: // database and engine at same major level
189: minorOnly = true;
190:
191: } else {
192:
193: if (Monitor.isFullUpgrade(startParams, dictionaryVersion
194: .toString())) {
195: performMajorUpgrade = true;
196: } else {
197: softUpgradeRun = true;
198: }
199: }
200:
201: // make sure we have a clean transaction for the upgrade
202: tc.commit();
203:
204: if (performMajorUpgrade) {
205: // real upgrade changes. Get user name of current user.
206: String userName = IdUtil
207: .getUserNameFromURLProps(startParams);
208: doFullUpgrade(tc, dictionaryVersion.majorVersionNumber,
209: IdUtil.getUserAuthorizationId(userName));
210: }
211:
212: if (!minorOnly && !isReadOnly) {
213: // apply changes that can be made and will continue to work
214: // against previous version.
215:
216: // See if we have already applied these changes.
217: DD_Version softUpgradeVersion = (DD_Version) tc
218: .getProperty(DataDictionary.SOFT_DATA_DICTIONARY_VERSION);
219:
220: // need to apply them if we have never performed a soft upgrade
221: // or only a soft upgrade using a previous version.
222: int softUpgradeMajorVersion = 0;
223: if (softUpgradeVersion != null)
224: softUpgradeMajorVersion = softUpgradeVersion.majorVersionNumber;
225:
226: if (softUpgradeMajorVersion < majorVersionNumber) {
227: applySafeChanges(tc,
228: dictionaryVersion.majorVersionNumber,
229: softUpgradeMajorVersion);
230: }
231: }
232:
233: // changes such as invalidating SPS so they will recompile against
234: // the new internal classes.
235: // this method also changes the on-disk format version on the disk and in-memory as well.
236: handleMinorRevisionChange(tc, dictionaryVersion, softUpgradeRun);
237:
238: // commit any upgrade
239: tc.commit();
240: }
241:
242: /**
243: Apply changes that can safely be made in soft upgrade.
244: Any changes must not prevent the database from being re-booted
245: by the a Derby engine at the older version fromMajorVersionNumber.
246: <BR>
247: Examples are fixes to catalog meta data, e.g. fix nullability of
248: a system column.
249:
250: <BR>
251: <B>Upgrade items for 10.1</B>
252: <UL>
253: <LI> None.
254: </UL>
255: *
256: * @param tc transaction controller
257: * @param fromMajorVersionNumber version of the on-disk database
258: @param lastSoftUpgradeVersion last engine to perform a soft upgrade that made changes.
259: *
260: * @exception StandardException Standard Cloudscape error policy.
261: */
262: private void applySafeChanges(TransactionController tc,
263: int fromMajorVersionNumber, int lastSoftUpgradeVersion)
264: throws StandardException {
265:
266: /*
267: * OLD Cloudscape 5.1 upgrade code, Derby does not support
268: * upgrade from Cloudscape 5.x databases. If it ever is changed
269: * to do so, this code would be useful.
270: *
271: *
272: if (lastSoftUpgradeVersion <= DataDictionary.DD_VERSION_CS_5_1)
273: {
274:
275: // All these soft upgrade actions are new in 5.2 (first ever soft upgrade)
276: if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_0)
277: modifySysTableNullability(tc,
278: DataDictionaryImpl.SYSALIASES_CATALOG_NUM);
279:
280: if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_1)
281: modifySysTableNullability(tc,
282: DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM);
283:
284: }
285: */
286:
287: tc.setProperty(DataDictionary.SOFT_DATA_DICTIONARY_VERSION,
288: this , true);
289: }
290:
291: /**
292: Do full upgrade. Apply changes that can NOT be safely made in soft upgrade.
293:
294: <BR>
295: <B>Upgrade items for every new release</B>
296: <UL>
297: <LI> Drop and recreate the stored versions of the JDBC database metadata queries
298: </UL>
299:
300: <BR>
301: <B>Upgrade items for 10.1</B>
302: <UL>
303: <LI> None.
304: </UL>
305:
306: *
307: * @param tc transaction controller
308: * @param fromMajorVersionNumber version of the on-disk database
309: * @param aid AuthorizationID of current user to be made Database Owner
310: *
311: * @exception StandardException Standard Cloudscape error policy.
312: */
313: private void doFullUpgrade(TransactionController tc,
314: int fromMajorVersionNumber, String aid)
315: throws StandardException {
316: // Only supports upgrade from Derby 10.0 releases onwards
317: if (fromMajorVersionNumber < DataDictionary.DD_VERSION_CS_10_0) {
318: throw StandardException.newException(
319: SQLState.UPGRADE_UNSUPPORTED, DD_Version
320: .majorToString(fromMajorVersionNumber),
321: this );
322: }
323:
324: //Drop and recreate the stored versions of the JDBC database metadata queries
325: //This is to make sure that we have the stored versions of JDBC database
326: //metadata queries matching with this release of the engine.
327: dropJDBCMetadataSPSes(tc, false);
328: bootingDictionary.createSystemSps(tc);
329:
330: /*
331: * OLD Cloudscape 5.1 upgrade code, Derby does not support
332: * upgrade from Cloudscape 5.x databases. If it ever is changed
333: * to do so, this code would be useful.
334:
335: if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_1)
336: {
337: // drop sps in SYSIBM, SYSIBM, recreate SYSIBM, SYSDUMMY1, populate SYSDUMMY1, create procs
338: dropJDBCMetadataSPSes(tc, true);
339: SchemaDescriptor sd = bootingDictionary.getSchemaDescriptor("SYSIBM", null, false);
340: if (sd != null)
341: bootingDictionary.dropSchemaDescriptor("SYSIBM", tc);
342: sd = bootingDictionary.getSysIBMSchemaDescriptor();
343: bootingDictionary.addDescriptor(sd, null, DataDictionary.SYSSCHEMAS_CATALOG_NUM, false, tc);
344: bootingDictionary.upgradeMakeCatalog(tc, DataDictionary.SYSDUMMY1_CATALOG_NUM);
345: bootingDictionary.populateSYSDUMMY1(tc);
346: bootingDictionary.create_SYSIBM_procedures(tc);
347: bootingDictionary.createSystemSps(tc);
348: }
349:
350: */
351:
352: if (fromMajorVersionNumber == DataDictionary.DD_VERSION_CS_10_0) {
353: // This upgrade depends on the SYSUTIL schema, which only exists
354: // since 10.0. Will not work to upgrade any db previous to 10.0,
355: // thus only checks for 10.0 rather than <= 10.0.
356: bootingDictionary.create_10_1_system_procedures(tc,
357: bootingDictionary.getSystemUtilSchemaDescriptor()
358: .getUUID());
359: }
360:
361: if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_1) {
362: // On ugrade from versions before 10.2, create system procedures
363: // added in 10.2.
364: bootingDictionary.create_10_2_system_procedures(tc,
365: bootingDictionary.getSystemUtilSchemaDescriptor()
366: .getUUID());
367:
368: if (SanityManager.DEBUG)
369: SanityManager
370: .ASSERT((aid != null),
371: "Failed to get new Database Owner authorization");
372:
373: // Add new system catalogs created for grant and revoke
374: bootingDictionary.upgradeMakeCatalog(tc,
375: DataDictionary.SYSTABLEPERMS_CATALOG_NUM);
376: bootingDictionary.upgradeMakeCatalog(tc,
377: DataDictionary.SYSCOLPERMS_CATALOG_NUM);
378: bootingDictionary.upgradeMakeCatalog(tc,
379: DataDictionary.SYSROUTINEPERMS_CATALOG_NUM);
380:
381: // Change system schemas to be owned by aid
382: bootingDictionary.updateSystemSchemaAuthorization(aid, tc);
383:
384: // Grant PUBLIC access to some system routines
385: bootingDictionary
386: .grantPublicAccessToSystemRoutines(tc, aid);
387: }
388:
389: }
390:
391: /**
392: * Do any work needed for a minor revision change.
393: * For the data dictionary this is always invalidating
394: * stored prepared statements. When we are done
395: * with the upgrade, we always recompile all SPSes
396: * so the customer doesn't have to (and isn't going
397: * to get deadlocks because of the recomp).
398: *
399: * @param tc the xact
400: *
401: * @exception StandardException Standard Cloudscape error policy.
402: */
403: private void handleMinorRevisionChange(TransactionController tc,
404: DD_Version fromVersion, boolean softUpgradeRun)
405: throws StandardException {
406: boolean isReadOnly = bootingDictionary.af.isReadOnly();
407:
408: if (!isReadOnly) {
409: bootingDictionary.clearSPSPlans();
410:
411: DD_Version lastRun;
412:
413: if (softUpgradeRun) {
414: // log a version that will cause a minor revision change
415: // for any subsequent re-boot, including an old Cloudscape version
416: fromVersion.minorVersionNumber = 1; // see getJBMSMinorVersionNumber
417: lastRun = fromVersion;
418: } else {
419: // log the new version
420: lastRun = this ;
421:
422: // and change the in-memory version.
423: fromVersion.majorVersionNumber = majorVersionNumber;
424: fromVersion.minorVersionNumber = minorVersionNumber;
425: }
426:
427: tc.setProperty(DataDictionary.CORE_DATA_DICTIONARY_VERSION,
428: fromVersion, true);
429: } else {
430: // For a readonly database where we need some kind of upgrade
431: // (either minor release or soft upgrade) then since we cannot
432: // invalidate all the procedures we need to indicate that
433: // any procedure we read off disk is automatically invalid,
434: // so we do not try to load the generated class.
435: bootingDictionary.readOnlyUpgrade = true;
436: }
437:
438: bootingDictionary.clearCaches();
439: }
440:
441: /**
442: * Drop all jdbc metadata spses. This
443: * it to ensure that we don't have any problems
444: * with old metadata queries that have outdated
445: * query text (the plans are always cleared out
446: * on upgrade time).
447: *
448: * @param tc the xact
449: * @param removeSYSIBMonly if <code>true</code>, remove stored
450: * prepared statements in the SYSIBM schema only; otherwise,
451: * remove stored prepared statements in all system schemas
452: * (including SYSIBM)
453: *
454: * @exception StandardException Standard Cloudscape error policy.
455: */
456: protected void dropJDBCMetadataSPSes(TransactionController tc,
457: boolean removeSYSIBMonly) throws StandardException {
458: for (java.util.Iterator it = bootingDictionary
459: .getAllSPSDescriptors().iterator(); it.hasNext();) {
460: SPSDescriptor spsd = (SPSDescriptor) it.next();
461: SchemaDescriptor sd = spsd.getSchemaDescriptor();
462: // need to compare the name, old SYSIBM is not built-in
463: boolean isSYSIBM = sd.getSchemaName().equals(
464: SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME);
465:
466: // don't drop statements in non-system schemas
467: if (!sd.isSystemSchema() && !isSYSIBM) {
468: continue;
469: }
470:
471: // don't drop statements outside the SYSIBM schema if
472: // we're told not to
473: if (removeSYSIBMonly && !isSYSIBM) {
474: continue;
475: }
476:
477: bootingDictionary.dropSPSDescriptor(spsd, tc);
478: bootingDictionary.dropDependentsStoredDependencies(spsd
479: .getUUID(), tc);
480: }
481: }
482:
483: /**
484: * Make a catalog.
485: * @param tc TransactionController
486: * @exception StandardException Standard Cloudscape error policy.
487: */
488: protected void makeSystemCatalog(TransactionController tc,
489: TabInfoImpl ti) throws StandardException {
490: SchemaDescriptor sd = bootingDictionary
491: .getSystemSchemaDescriptor();
492: bootingDictionary.makeCatalog(ti, sd, tc);
493: }
494:
495: /**
496: Remove the description of a System table from the data dictionary.
497: This does not delete the conglomerates that hold the catalog or
498: its indexes.
499: @param tc TransactionController
500: @param td Table descriptor for the catalog to drop.
501: @exception StandardException Standard Cloudscape error policy.
502: */
503: protected void dropSystemCatalogDescription(
504: TransactionController tc, TableDescriptor td)
505: throws StandardException {
506: /* Drop the columns */
507: bootingDictionary.dropAllColumnDescriptors(td.getUUID(), tc);
508:
509: /* Drop the conglomerate descriptors */
510: bootingDictionary.dropAllConglomerateDescriptors(td, tc);
511:
512: /* Drop table descriptor */
513: bootingDictionary.dropTableDescriptor(td, td
514: .getSchemaDescriptor(), tc);
515: bootingDictionary.clearCaches();
516: }
517:
518: /**
519: * Drop a System catalog.
520: * @param tc TransactionController
521: * @param crf CatalogRowFactory for the catalog to drop.
522: * @exception StandardException Standard Cloudscape error policy.
523: */
524: protected void dropSystemCatalog(TransactionController tc,
525: CatalogRowFactory crf) throws StandardException {
526: SchemaDescriptor sd = bootingDictionary
527: .getSystemSchemaDescriptor();
528: TableDescriptor td = bootingDictionary.getTableDescriptor(crf
529: .getCatalogName(), sd);
530: ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
531: for (int index = 0; index < cds.length; index++) {
532: tc.dropConglomerate(cds[index].getConglomerateNumber());
533: }
534: dropSystemCatalogDescription(tc, td);
535: }
536:
537: /**
538: * Populates a new system index from the base system table.
539: *
540: * @param tc transaction controller
541: * @param heapConglomerateNumber identifies system table to Store
542: * @param tabInfo describes base system table
543: * @param indexNumber index to populate
544: *
545: *
546: * @exception StandardException Thrown on failure
547: */
548: protected void fillIndex(TransactionController tc,
549: long heapConglomerateNumber, TabInfoImpl tabInfo,
550: int indexNumber) throws StandardException {
551: long indexConglomerateNumber = tabInfo
552: .getIndexConglomerate(indexNumber);
553: IndexRowGenerator indexRowGenerator = tabInfo
554: .getIndexRowGenerator(indexNumber);
555: CatalogRowFactory rowFactory = tabInfo.getCatalogRowFactory();
556: ExecRow heapRow = rowFactory.makeEmptyRow();
557: ExecIndexRow indexableRow = indexRowGenerator
558: .getIndexRowTemplate();
559:
560: ScanController heapScan = tc.openScan(
561: heapConglomerateNumber, // conglomerate to open
562: false, // don't hold open across commit
563: 0, // for read
564: TransactionController.MODE_TABLE,
565: TransactionController.ISOLATION_REPEATABLE_READ,
566: (FormatableBitSet) null, // all fields as objects
567: null, // start position - first row
568: ScanController.GE, // startSearchOperation
569: null, //scanQualifier,
570: null, //stop position-through last row
571: ScanController.GT); // stopSearchOperation
572:
573: RowLocation heapLocation = heapScan.newRowLocationTemplate();
574:
575: ConglomerateController indexController = tc.openConglomerate(
576: indexConglomerateNumber, false,
577: TransactionController.OPENMODE_FORUPDATE,
578: TransactionController.MODE_TABLE,
579: TransactionController.ISOLATION_REPEATABLE_READ);
580:
581: while (heapScan.fetchNext(heapRow.getRowArray())) {
582: heapScan.fetchLocation(heapLocation);
583:
584: indexRowGenerator.getIndexRow(heapRow, heapLocation,
585: indexableRow, (FormatableBitSet) null);
586:
587: indexController.insert(indexableRow.getRowArray());
588: }
589:
590: indexController.close();
591: heapScan.close();
592: }
593:
594: ////////////////////////////////////////////////////////////////////////
595: //
596: // FORMATABLE INTERFACE
597: //
598: ////////////////////////////////////////////////////////////////////////
599: /**
600: * Get the formatID which corresponds to this class.
601: Map to the 5.0 version identifier so that 5.0 will understand
602: this object when we write it out in soft upgrade mode.
603: CS 5.0 will de-serialize it correctly.
604: When we are writing out a 5.1 version number we write out
605: the 5.1 version just to ensure no problems.
606:
607: *
608: * @return the formatID of this class
609: */
610: public int getTypeFormatId() {
611: return majorVersionNumber == DataDictionary.DD_VERSION_CS_5_1 ? StoredFormatIds.DD_ARWEN_VERSION_ID
612: : StoredFormatIds.DD_DB2J72_VERSION_ID;
613: }
614:
615: /**
616: * Read this object from a stream of stored objects. Set
617: * the minor version. Ignore the major version.
618: *
619: * @param in read this.
620: *
621: * @exception IOException on error
622: */
623: public final void readExternal(ObjectInput in) throws IOException {
624: majorVersionNumber = in.readInt();
625: minorVersionNumber = in.readInt();
626: }
627:
628: /**
629: * Write this object to a stream of stored objects. Write
630: * out the minor version which is bumped across minor release.
631: * Just to be safe, write out the major version too. This
632: * will allow us to do versioning of a specific Version impl
633: * in the future.
634: *
635: * @param out write bytes here.
636: *
637: * @exception IOException on error
638: */
639: public final void writeExternal(ObjectOutput out)
640: throws IOException {
641: out.writeInt(majorVersionNumber);
642: out.writeInt(minorVersionNumber);
643: }
644:
645: /**
646: * Get the minor version from the JBMS product minor version/maint version.
647: * Bumps it up by 1 if production, or 0 if beta to ensure
648: * minor upgrade across beta. Starts at 2 because of an
649: * old convention. We use this starting at 2 to allow soft upgrade to
650: * write a version of 1 with the old major number to ensure a minor upgrade
651: when reverting to an old version afer a soft upgrade. E.g run with 5.0.2,
652: then 5.2.1.1, then 5.0.2. Want to ensure 5.0.2 does the minor upgrade.
653: *
654: * @return the minor version
655:
656: For 5.0 and 5.1 the minor number was calculated as
657:
658: jbmsVersion.getMinorVersion()*100 +jbmsVersion.getMaintVersion() + (jbmsVersion.isBeta() ? 0 : 1) + 2
659:
660: 5.0.22 => (0*100) + 22 + 2 = 24 - (5.0 has a unique major number)
661: 5.1.2 => (1*100) + 2 + 2 = 104 - (5.1 has a unique major number)
662:
663:
664: With the switch to the four part scheme in 5.2, the maint number now is in increments of one million,
665: thus the above scheme could lead to duplicate numbers. Note that the major number may not change
666: when the minor external release changes, e.g. 5.2 and 5.3 could share a DD_Version major number.
667:
668: 5.2.1.100 => (2*100) + 1000100 + 2 = 1000302
669: 5.3.1.0 => (3*100) + 1000000 + 2 = 1000302
670:
671:
672:
673: */
674: private int getJBMSMinorVersionNumber() {
675: ProductVersionHolder jbmsVersion = Monitor.getMonitor()
676: .getEngineVersion();
677:
678: return jbmsVersion.getMinorVersion() * 100
679: + jbmsVersion.getMaintVersion()
680: + (jbmsVersion.isBeta() ? 0 : 1) + 2;
681: }
682:
683: /**
684: *
685: * Modifies the nullability of the system table corresponding
686: * to the received catalog number.
687: * OLD Cloudscape 5.1 upgrade code
688: * @param tc TransactionController.
689: * @param catalogNum The catalog number corresponding
690: * to the table for which we will modify the nullability.
691: * If this corresponds to SYSALIASES, then the nullability of
692: * the SYSALIASES.ALIASINFO column will be changed to true
693: * (Beetle 4430). If this corresponds to SYSSTATEMENTS,
694: * the nullability of the SYSSTATEMENTS.LASTCOMPILED
695: * column will be changed to true.
696: *
697: * @exception StandardException
698: */
699:
700: /* OLD Cloudscape 5.1 upgrade code. See applySafeChanges().
701:
702: private void modifySysTableNullability(TransactionController tc, int catalogNum)
703: throws StandardException
704: {
705:
706: TabInfo ti = bootingDictionary.getNonCoreTIByNumber(catalogNum);
707: CatalogRowFactory rowFactory = ti.getCatalogRowFactory();
708: if (catalogNum == DataDictionaryImpl.SYSALIASES_CATALOG_NUM) {
709: // SYSALIASES table ==> ALIASINFO needs to be modified.
710: bootingDictionary.upgrade_setNullability(rowFactory,
711: SYSALIASESRowFactory.SYSALIASES_ALIASINFO, true, tc);
712: }
713: else if (catalogNum == DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM) {
714: // SYSSTATEMENTS table ==> LASTCOMPILED needs to be modified.
715: bootingDictionary.upgrade_setNullability(rowFactory,
716: SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED, true, tc);
717: }
718: }
719: */
720: /**
721: Check to see if a database has been upgraded to the required
722: level in order to use a language feature.
723:
724: @param requiredMajorVersion Data Dictionary major version
725: @param feature Non-null to throw an error, null to return the state of the version match.
726:
727: @return True if the database has been upgraded to the required level, false otherwise.
728: */
729: boolean checkVersion(int requiredMajorVersion, String feature)
730: throws StandardException {
731:
732: if (majorVersionNumber < requiredMajorVersion) {
733:
734: if (feature != null)
735: throw StandardException.newException(
736: SQLState.LANG_STATEMENT_UPGRADE_REQUIRED,
737: feature, DD_Version
738: .majorToString(majorVersionNumber),
739: DD_Version.majorToString(requiredMajorVersion));
740:
741: return false;
742: }
743:
744: return true;
745: }
746:
747: }
|