001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.BaseContainerHandle
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.store.raw.data;
023:
024: import org.apache.derby.iapi.reference.SQLState;
025:
026: import org.apache.derby.iapi.services.locks.Lockable;
027: import org.apache.derby.iapi.services.locks.VirtualLockTable;
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029: import org.apache.derby.iapi.error.StandardException;
030: import org.apache.derby.iapi.store.access.SpaceInfo;
031: import org.apache.derby.iapi.store.raw.ContainerHandle;
032: import org.apache.derby.iapi.store.raw.ContainerLock;
033: import org.apache.derby.iapi.store.raw.LockingPolicy;
034: import org.apache.derby.iapi.store.raw.Page;
035: import org.apache.derby.iapi.store.raw.PageKey;
036: import org.apache.derby.iapi.store.raw.PageTimeStamp;
037: import org.apache.derby.iapi.store.raw.RecordHandle;
038: import org.apache.derby.iapi.store.raw.ContainerKey;
039:
040: import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
041: import org.apache.derby.iapi.store.raw.xact.RawTransaction;
042: import org.apache.derby.iapi.store.raw.log.LogInstant;
043:
044: import org.apache.derby.iapi.util.ByteArray;
045: import org.apache.derby.catalog.UUID;
046:
047: import java.util.Hashtable;
048: import java.util.Observable;
049: import java.util.Observer;
050: import java.util.Properties;
051:
052: /**
053: A handle to an open container, implememts RawContainerHandle.
054: <P>
055: This class is an Observer to observe RawTransactions
056: and is also a Observable to
057: handle the list of pages accessed thorough this handle.
058: <BR>
059: This class implements Lockable (defined to be ContainerHandle) and is
060: the object used to logically lock the container.
061:
062: <BR> MT - Mutable - Immutable identity - Thread Aware
063: */
064:
065: public class BaseContainerHandle extends Observable implements
066: RawContainerHandle, Observer {
067:
068: /*
069: ** Fields
070: */
071:
072: /**
073: Container identifier
074: <BR> MT - Immutable
075: */
076: protected/*final*/ContainerKey identity;
077:
078: /**
079: Is this ContainerHandle active.
080:
081: <BR> MT - Mutable : scoped
082: */
083: protected boolean active;
084:
085: /**
086: The actual container we are accessing. Only valid when active is true.
087:
088: <BR> MT - Mutable : scoped
089: */
090: protected BaseContainer container;
091:
092: /**
093: the locking policy we opened the container with.
094: Only valid when active is true.
095:
096: <BR> MT - Mutable : scoped
097: */
098:
099: private LockingPolicy locking;
100:
101: /**
102: our transaction. Only valid when active is true.
103:
104: <BR> MT - Mutable : scoped
105: */
106: protected RawTransaction xact;
107:
108: /**
109: are we going to update?
110:
111: <BR> MT - Immutable after container handle becomes active
112: */
113: private boolean forUpdate;
114:
115: protected int mode; // mode the container was opened in
116:
117: protected PageActions actionsSet;
118: protected AllocationActions allocActionsSet;
119:
120: /*
121: ** Constructor
122: */
123:
124: /**
125: Create an object that is only used for locking the container.
126: */
127: public BaseContainerHandle(UUID rawStoreId, RawTransaction xact,
128: ContainerKey identity, LockingPolicy locking, int mode) {
129: this .identity = identity;
130: this .xact = xact;
131: this .locking = locking;
132: this .mode = mode;
133: this .forUpdate = (mode & MODE_FORUPDATE) == MODE_FORUPDATE;
134: }
135:
136: /**
137: Create a container handle that is used to actually access the container.
138: */
139: public BaseContainerHandle(UUID rawStoreId, RawTransaction xact,
140: PageActions actionsSet, AllocationActions allocActionsSet,
141: LockingPolicy locking, BaseContainer container, int mode) {
142: this (rawStoreId, xact, (ContainerKey) container.getIdentity(),
143: locking, mode);
144:
145: this .actionsSet = actionsSet;
146: this .allocActionsSet = allocActionsSet;
147: this .container = container;
148:
149: // we are inactive until useContainer is called.
150: }
151:
152: /*
153: ** Methods from ContainerHandle
154: */
155:
156: /**
157: Add a page to the container
158: The page returned will be observing me.
159:
160: @see BaseContainer#addPage
161: @see ContainerHandle#addPage
162: @exception StandardException Standard Cloudscape error policy
163: */
164: public Page addPage() throws StandardException {
165: checkUpdateOpen();
166:
167: Page page = container
168: .addPage(this , false /* not an overflow page */);
169:
170: return page;
171: }
172:
173: /**
174: Release free space to the OS.
175: <P>
176: As is possible release any free space to the operating system. This
177: will usually mean releasing any free pages located at the end of the
178: file using the java truncate() interface.
179:
180: @exception StandardException Standard Cloudscape error policy
181: */
182: public void compressContainer() throws StandardException {
183: checkUpdateOpen();
184:
185: container.compressContainer(this );
186: }
187:
188: /**
189: * Get the reusable recordId sequence number.
190: * @return version sequence number
191: * @exception StandardException Standard Derby error policy
192: * @see ContainerHandle#getReusableRecordIdSequenceNumber
193: */
194: public long getReusableRecordIdSequenceNumber()
195: throws StandardException {
196: checkOpen();
197:
198: return container.getReusableRecordIdSequenceNumber();
199: }
200:
201: /**
202: Add a page to the container, if flag == ContainerHandle.ADD_PAGE_BULK,
203: tell the container about it.
204:
205: The page returned will be observing me.
206:
207: @see BaseContainer#addPage
208: @see ContainerHandle#addPage
209: @exception StandardException Standard Cloudscape error policy
210: */
211: public Page addPage(int flag) throws StandardException {
212:
213: if ((flag & ContainerHandle.ADD_PAGE_BULK) != 0 && active
214: && forUpdate) {
215: // start preallocating immediatelly, don't wait for the
216: // preallocation threshold to be crossed. Don't go wild and
217: // preallocate a bunch of pages either, use preAllocate for that.
218: container.clearPreallocThreshold();
219: }
220:
221: return addPage();
222: }
223:
224: /**
225: Preallocate numPage if possible.
226: */
227: public void preAllocate(int numPage) {
228: if (numPage > 0 && active && forUpdate)
229: container.prepareForBulkLoad(this , numPage);
230: }
231:
232: /**
233: * Request the system properties associated with a container.
234: * <p>
235: * Request the value of properties that are associated with a container.
236: * The following properties can be requested:
237: * derby.storage.pageSize
238: * derby.storage.pageReservedSpace
239: * derby.storage.minimumRecordSize
240: * <p>
241: * To get the value of a particular property add it to the property list,
242: * and on return the value of the property will be set to it's current
243: * value. For example:
244: *
245: * get_prop(BaseContainerHandle ch)
246: * {
247: * Properties prop = new Properties();
248: * prop.put("derby.storage.pageSize", "");
249: * ch.getContainerProperties(prop);
250: *
251: * System.out.println(
252: * "conatainer's page size = " +
253: * prop.getProperty("derby.storage.pageSize");
254: * }
255: *
256: * @param prop Property list to fill in.
257: *
258: * @exception StandardException Standard exception policy.
259: **/
260: public void getContainerProperties(Properties prop)
261: throws StandardException {
262: checkOpen();
263:
264: container.getContainerProperties(prop);
265:
266: return;
267: }
268:
269: /**
270: Remove a page from the container.
271:
272: @see ContainerHandle#removePage
273: @exception StandardException Standard Cloudscape error policy
274: */
275: public void removePage(Page page) throws StandardException {
276: if (!active) {
277: if (page != null)
278: page.unlatch();
279: throw StandardException
280: .newException(SQLState.DATA_CONTAINER_CLOSED);
281: }
282:
283: if (!forUpdate) {
284: if (page != null)
285: page.unlatch();
286: throw StandardException
287: .newException(SQLState.DATA_CONTAINER_READ_ONLY);
288: }
289:
290: container.removePage(this , (BasePage) page);
291: }
292:
293: public Page getPage(long pageNumber) throws StandardException {
294:
295: checkOpen();
296:
297: return container.getPage(this , pageNumber, true);
298: }
299:
300: public Page getAllocPage(long pageNumber) throws StandardException {
301: checkOpen();
302:
303: return container.getAllocPage(this , pageNumber, true);
304: }
305:
306: public Page getUserPageNoWait(long pageNumber)
307: throws StandardException {
308: checkOpen();
309:
310: return container.getHeadPage(this , pageNumber, false);
311: }
312:
313: public Page getUserPageWait(long pageNumber)
314: throws StandardException {
315: checkOpen();
316:
317: return container.getHeadPage(this , pageNumber, true);
318: }
319:
320: public Page getPageNoWait(long pageNumber) throws StandardException {
321: checkOpen();
322:
323: return container.getPage(this , pageNumber, false);
324: }
325:
326: public Page getFirstPage() throws StandardException {
327: checkOpen();
328:
329: return container.getFirstPage(this );
330: }
331:
332: public Page getNextPage(long pageNumber) throws StandardException {
333: checkOpen();
334:
335: return container.getNextPage(this , pageNumber);
336: }
337:
338: public Page getPageForInsert(int flag) throws StandardException {
339: checkUpdateOpen();
340:
341: return container.getPageForInsert(this , flag);
342: }
343:
344: public Page getPageForCompress(int flag, long pageno)
345: throws StandardException {
346: checkUpdateOpen();
347:
348: return container.getPageForCompress(this , flag, pageno);
349: }
350:
351: /**
352: @see ContainerHandle#isReadOnly()
353: */
354: public final boolean isReadOnly() {
355: return (!forUpdate);
356: }
357:
358: /**
359: @see ContainerHandle#close
360: */
361:
362: public void close() {
363:
364: if (xact == null) {
365: // Probably be closed explicitly by a client, after closing
366: // automatically after an abort.
367:
368: if (SanityManager.DEBUG)
369: SanityManager.ASSERT(!active);
370:
371: return;
372: }
373:
374: // notify our observers (Pages) that we are closing ...
375: informObservers();
376:
377: active = false;
378:
379: getLockingPolicy().unlockContainer(xact, this );
380:
381: // let go of the container
382: if (container != null) {
383: container.letGo(this );
384: container = null;
385: }
386:
387: // and remove ourseleves from this transaction
388: xact.deleteObserver(this );
389:
390: xact = null;
391:
392: }
393:
394: /* cost estimation */
395:
396: /**
397: @see ContainerHandle#getEstimatedRowCount
398: @exception StandardException Standard Cloudscape error policy
399: */
400: public long getEstimatedRowCount(int flag) throws StandardException {
401: checkOpen();
402:
403: return container.getEstimatedRowCount(flag);
404: }
405:
406: /**
407: @see ContainerHandle#setEstimatedRowCount
408: @exception StandardException Standard Cloudscape error policy
409: */
410: public void setEstimatedRowCount(long count, int flag)
411: throws StandardException {
412: checkOpen();
413:
414: container.setEstimatedRowCount(count, flag);
415: }
416:
417: /**
418: @see ContainerHandle#getEstimatedPageCount
419: @exception StandardException Standard Cloudscape error policy
420: */
421: public long getEstimatedPageCount(int flag)
422: throws StandardException {
423: checkOpen();
424:
425: return container.getEstimatedPageCount(this , flag);
426: }
427:
428: /**
429: @see ContainerHandle#flushContainer
430: @exception StandardException Standard Cloudscape error policy
431: */
432: public void flushContainer() throws StandardException {
433: checkUpdateOpen();
434:
435: // raw store may override unlog mode when log is Archived.
436: // if ((mode & MODE_CREATE_UNLOGGED) == 0)
437: // throw StandardException.newException(
438: // SQLState.DATA_NOT_CREATE_UNLOGGED, identity);
439:
440: container.flushAll();
441:
442: }
443:
444: /**
445: @see ContainerHandle#compactRecord
446: @exception StandardException Standard Cloudscape error policy
447: */
448: public void compactRecord(RecordHandle record)
449: throws StandardException {
450: if (!forUpdate) {
451: throw StandardException
452: .newException(SQLState.DATA_CONTAINER_READ_ONLY);
453: }
454:
455: PageKey pkey = (PageKey) record.getPageId();
456: BasePage headPage = (BasePage) getPage(pkey.getPageNumber());
457:
458: if (headPage != null) {
459: // The page could have been null if it was deallocated after the
460: // row lock is gotten. We are doing all of these post commit so
461: // the record may not even be there and we got a lock for nothing.
462: try {
463: headPage.compactRecord(record);
464: } finally {
465: headPage.unlatch();
466: }
467: }
468: }
469:
470: /*
471: ** Methods of RawContainerHandle - methods are called underneath the log
472: */
473:
474: /**
475: Get the container status.
476:
477: @exception StandardException Standard Cloudscape error policy
478: @see RawContainerHandle#getContainerStatus
479: */
480: public int getContainerStatus() throws StandardException {
481: checkOpen();
482:
483: return container.getContainerStatus();
484: }
485:
486: /**
487: remove the container
488:
489: @exception StandardException Standard Cloudscape error policy
490: @see RawContainerHandle#removeContainer
491: */
492: public void removeContainer(LogInstant instant)
493: throws StandardException {
494: checkUpdateOpen();
495:
496: // This call can only be issued by within rawStore.
497: // while the container is dropped, no client of raw store
498: // should be able to access the container (it is
499: // exclusively locked).
500: // Then as postcommit processing,
501: // the container iw
502:
503: container.removeContainer(instant, true);
504: }
505:
506: /**
507: @see ContainerHandle#getId
508: */
509: public ContainerKey getId() {
510: return identity;
511: }
512:
513: /**
514: @see ContainerHandle#getUniqueId
515: */
516: public Object getUniqueId() {
517: return (this );
518: }
519:
520: /**
521: @exception StandardException Standard cloudscape exception policy
522: @see RawContainerHandle#dropContainer
523: */
524: public void dropContainer(LogInstant instant, boolean drop)
525: throws StandardException {
526: checkUpdateOpen();
527:
528: container.dropContainer(instant, drop);
529: }
530:
531: /**
532: @exception StandardException Standard cloudscape exception policy
533: @see RawContainerHandle#getContainerVersion
534: */
535: public long getContainerVersion() throws StandardException {
536: checkOpen();
537:
538: return container.getContainerVersion();
539: }
540:
541: /**
542: Get this page with no check - any page type or status is fine.
543: Caller must be prepared to handle freed, deallocated,or alloc page
544: Called by recovery ONLY.
545:
546: @exception StandardException Cloudscape Standard error policy
547: */
548: public Page getAnyPage(long pageNumber) throws StandardException {
549: checkOpen();
550:
551: return container.getAnyPage(this , pageNumber, true /* wait */);
552: }
553:
554: /**
555: * ReCreate a page for rollforward recovery.
556: * <p>
557: * During redo recovery it is possible for the system to try to redo
558: * the creation of a page (ie. going from non-existence to version 0).
559: * It first trys to read the page from disk, but a few different types
560: * of errors can occur:
561: * o the page does not exist at all on disk, this can happen during
562: * rollforward recovery applied to a backup where the file was
563: * copied and the page was added to the file during the time frame
564: * of the backup but after the physical file was copied.
565: * o space in the file exists, but it was never initalized. This
566: * can happen if you happen to crash at just the right moment during
567: * the allocation process. Also
568: * on some OS's it is possible to read from a part of the file that
569: * was not ever written - resulting in garbage from the store's
570: * point of view (often the result is all 0's).
571: *
572: * All these errors are easy to recover from as the system can easily
573: * create a version 0 from scratch and write it to disk.
574: *
575: * Because the system does not sync allocation of data pages, it is also
576: * possible at this point that whlie writing the version 0 to disk to
577: * create it we may encounter an out of disk space error (caught in this
578: * routine as a StandardException from the create() call. We can't
579: * recovery from this without help from outside, so the caught exception
580: * is nested and a new exception thrown which the recovery system will
581: * output to the user asking them to check their disk for space/errors.
582: *
583: * @exception StandardException Standard exception policy.
584: **/
585: public Page reCreatePageForRedoRecovery(int pageFormat,
586: long pageNumber, long pageOffset) throws StandardException {
587: checkUpdateOpen();
588:
589: return container.reCreatePageForRedoRecovery(this , pageFormat,
590: pageNumber, pageOffset);
591: }
592:
593: /**
594: Log all information necessary to recreate the container during a load
595: tran.
596:
597: @exception StandardException Standard Cloudscape error policy
598: */
599: public ByteArray logCreateContainerInfo() throws StandardException {
600: checkUpdateOpen();
601:
602: return container.logCreateContainerInfo();
603: }
604:
605: /**
606: Return a record handle that is initialized to the given page number and
607: record id.
608:
609: @exception StandardException Standard cloudscape exception policy.
610:
611: @param pageNumber the page number of the RecordHandle.
612: @param recordId the record id of the RecordHandle.
613:
614: @see RecordHandle
615: */
616: public RecordHandle makeRecordHandle(long pageNumber, int recordId)
617: throws StandardException {
618: return new RecordId(identity, pageNumber, recordId);
619: }
620:
621: /*
622: ** Methods of Observer
623: */
624:
625: /**
626: Called when the transaction is about to complete.
627:
628: @see Observer#update
629: */
630: public void update(Observable obj, Object arg) {
631: if (SanityManager.DEBUG) {
632: if (arg == null)
633: SanityManager.THROWASSERT("still on observr list "
634: + this );
635: }
636:
637: // already been removed from the list
638: if (xact == null) {
639: return;
640: }
641:
642: if (SanityManager.DEBUG) {
643: // just check reference equality
644:
645: if (obj != xact) {
646: SanityManager
647: .THROWASSERT("Observable passed to update is incorrect expected "
648: + xact + " got " + obj);
649: }
650: }
651:
652: // close on a commit, abort or drop of this container.
653: if (arg.equals(RawTransaction.COMMIT)
654: || arg.equals(RawTransaction.ABORT)
655: || arg.equals(identity)) {
656: // close the container
657: close();
658: return;
659:
660: }
661:
662: if (arg.equals(RawTransaction.SAVEPOINT_ROLLBACK)) {
663:
664: // unlatch any pages but remain open
665: informObservers();
666:
667: // remain open
668: return;
669: }
670:
671: // Transaction is notifying us that our container
672: // has undergone some lock escalation. We re-get
673: // our table lock which will promote us
674: // if possible
675:
676: if (arg.equals(RawTransaction.LOCK_ESCALATE)) {
677:
678: // only attempt escalation on RowLocking modes.
679: if (getLockingPolicy().getMode() != LockingPolicy.MODE_RECORD)
680: return;
681:
682: try {
683: getLockingPolicy().lockContainer(getTransaction(),
684: this , false, forUpdate);
685: } catch (StandardException se) {
686: xact.setObserverException(se);
687: }
688: }
689: }
690:
691: /*
692: ** Implementation specific methods, these are public so that they can be
693: ** called in other packages that are specific implementations of Data, ie.
694: ** a directory at the level
695: **
696: ** com.ibm.db2j.impl.Database.Storage.RawStore.Data.*
697: */
698:
699: public PageActions getActionSet() {
700: return actionsSet;
701: }
702:
703: public AllocationActions getAllocationActionSet() {
704: return allocActionsSet;
705: }
706:
707: /**
708: Attach me to a container. If this method returns false then
709: I cannot be used anymore, and any reference to me must be discarded.
710:
711: @param droppedOK if true, use this container even if it is dropped,
712: otherwise, return false if container is dropped.
713:
714: @param waitForLock if true, wait on lock, otherwise, get lock no wait.
715:
716: @exception StandardException Standard Cloudscape error policy
717: */
718: public boolean useContainer(boolean droppedOK, boolean waitForLock)
719: throws StandardException {
720:
721: if (SanityManager.DEBUG) {
722: SanityManager.ASSERT(!active);
723: }
724:
725: boolean gotLock = getLockingPolicy().lockContainer(
726: getTransaction(), this , waitForLock, forUpdate);
727:
728: if (gotLock == false) {
729: // this is a lockingPolicy error, if waitForLock should either
730: // return true or throw a deadlock exception
731: if (SanityManager.DEBUG)
732: SanityManager.ASSERT(waitForLock == false,
733: "lockContainer wait returns false");
734:
735: container = null;
736:
737: throw StandardException.newException(SQLState.LOCK_TIMEOUT);
738: }
739:
740: if ((mode & ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY) == 0) {
741:
742: if (SanityManager.DEBUG) {
743: SanityManager.ASSERT(container != null);
744: }
745:
746: if (!container.use(this , forUpdate, droppedOK)) {
747:
748: // If we got a lock, but for some reason we can't open the
749: // table (like it doesn't exist), then call unlockContainer().
750: // In the normal case it would be called when the container
751: // handle was closed, but in this case the user is never going
752: // to get an "open" container handle back. We can't call
753: // close() here as we haven't done all the "open" stuff.
754: getLockingPolicy().unlockContainer(xact, this );
755:
756: container = null;
757:
758: return false;
759: }
760: active = true;
761: } else {
762: // lock only, we only observe the transaction if
763: // we are performing row level locking.
764: if (getLockingPolicy().getMode() != LockingPolicy.MODE_RECORD)
765: return true;
766: }
767:
768: // watch transaction so we will close handle just before xact completes.
769: xact.addObserver(this );
770:
771: // Add special objects implementing certain behaviour at commit/rollback
772:
773: if ((mode & (ContainerHandle.MODE_READONLY | ContainerHandle.MODE_NO_ACTIONS_ON_COMMIT)) == 0) {
774: if ((mode & MODE_TRUNCATE_ON_COMMIT) == MODE_TRUNCATE_ON_COMMIT) {
775: xact
776: .addObserver(new TruncateOnCommit(identity,
777: true /* always */));
778: } else if ((mode & MODE_TRUNCATE_ON_ROLLBACK) == MODE_TRUNCATE_ON_ROLLBACK) {
779: xact
780: .addObserver(new TruncateOnCommit(identity,
781: false /* rollbacks only */));
782: }
783:
784: if ((mode & MODE_DROP_ON_COMMIT) == MODE_DROP_ON_COMMIT) {
785: xact.addObserver(new DropOnCommit(identity));
786: }
787:
788: if ((mode & MODE_FLUSH_ON_COMMIT) == MODE_FLUSH_ON_COMMIT) {
789: xact.addObserver(new SyncOnCommit(identity));
790: }
791: }
792:
793: return true;
794: }
795:
796: /**
797: Return the RawTransaction I was opened in.
798: */
799: public final RawTransaction getTransaction() {
800: return xact;
801: }
802:
803: /**
804: Return my locking policy, may be different from the Transaction's
805: default locking policy.
806: */
807: public final LockingPolicy getLockingPolicy() {
808:
809: if (SanityManager.DEBUG) {
810: SanityManager.ASSERT(locking != null);
811: }
812:
813: return locking;
814: }
815:
816: public final void setLockingPolicy(LockingPolicy newLockingPolicy) {
817: locking = newLockingPolicy;
818: }
819:
820: /**
821: Was I opened for updates?
822: <p>
823:
824: <BR> MT - thread safe
825: */
826: public final boolean updateOK() {
827: return forUpdate;
828: }
829:
830: /**
831: Get the mode I was opened with.
832: */
833: public int getMode() {
834: return mode;
835: }
836:
837: /**
838: The container is about to be modified.
839: Loggable actions use this to make sure the container gets cleaned if a
840: checkpoint is taken after any log record is sent to the log stream but
841: before the container is actually dirtied.
842:
843: @exception StandardException Standard Cloudscape error policy
844: */
845: public void preDirty(boolean preDirtyOn) throws StandardException {
846:
847: checkUpdateOpen();
848:
849: container.preDirty(preDirtyOn);
850:
851: }
852:
853: /**
854: @see ContainerHandle#isTemporaryContainer
855: @exception StandardException Standard Cloudscape error policy
856: */
857: public boolean isTemporaryContainer() throws StandardException {
858:
859: checkOpen();
860:
861: return (identity != null && identity.getSegmentId() == ContainerHandle.TEMPORARY_SEGMENT);
862: }
863:
864: /*
865: ** Implementation specific methods for myself and my sub-classes
866: */
867:
868: protected void checkOpen() throws StandardException {
869: if (!active)
870: throw StandardException
871: .newException(SQLState.DATA_CONTAINER_CLOSED);
872: }
873:
874: private void checkUpdateOpen() throws StandardException {
875:
876: if (!active) {
877: throw StandardException
878: .newException(SQLState.DATA_CONTAINER_CLOSED);
879: }
880:
881: if (!forUpdate) {
882: throw StandardException
883: .newException(SQLState.DATA_CONTAINER_READ_ONLY);
884: }
885: }
886:
887: protected void informObservers() {
888:
889: // notify our observers (Pages) that we are closing,
890: // or undergoing some state change ...
891:
892: if (countObservers() != 0) {
893: setChanged();
894: notifyObservers();
895: }
896: }
897:
898: /**
899: Get information about space used by the container.
900: **/
901: public SpaceInfo getSpaceInfo() throws StandardException {
902: return container.getSpaceInfo(this );
903: }
904:
905: /**
906: * Backup the container to the specified path.
907: * @param backupContainerPath location of the backup container.
908: * @exception StandardException Standard Derby error policy
909: */
910: public void backupContainer(String backupContainerPath)
911: throws StandardException {
912: checkOpen();
913: container.backupContainer(this , backupContainerPath);
914: }
915:
916: /**
917: * Create encrypted version of the container with the
918: * user specified encryption properties.
919: * @param newFilePath file to store the new encrypted version of the container
920: * @exception StandardException Standard Derby error policy
921: */
922: public void encryptContainer(String newFilePath)
923: throws StandardException {
924: checkOpen();
925: container.encryptContainer(this , newFilePath);
926: }
927:
928: public String toString() {
929: if (SanityManager.DEBUG) {
930: String str = new String();
931: str += "BaseContainerHandle:(" + identity.toString() + ")";
932: return (str);
933: } else {
934: return (super.toString());
935: }
936: }
937:
938: }
|