Home > Class Reference > ENSLIB namespace > %Library.Persistent


abstract persistent class %Library.Persistent extends %Library.SwizzleObject

SQL Table Name: %Library.Persistent

The %Persistent class provides the basic mechanism by which objects are stored to and retrieved from a database.



If a persistent class uses %Library.CacheStorage then the DEFAULTGLOBAL parameter is used as the default global root for the values of the storage keywords COUNTERLOCATION, DATALOCATION, IDLOCATION, INDEXLOCATION and STREAMLOCATION in the active storage definition. DEFAULTGLOBAL is only used to generate location keyword values that are not already defined. The location value is constructed by adding a location type to the end of DEFAULTGLOBAL. For example, if DEFAULTGLOBAL = "^GL.Account" the compiler will generate DATALOCATION = ^GL.AccountD.

If USEEXTENTSET is true, then DEFAULTGLOBAL is used as the default extent location.

The location types are:
parameter DSINTERVAL;
DSINTERVAL is the number of seconds between one DSTIME value and the next. The DSTIME value for DSINTERVAL > 0 is computed from $ZTIMESTAMP and is the number of seconds from day 0, time 0 to the nearest interval, rounded down. Using an interval has the effect of grouping all DSTIME entries for the class in some number of seconds.
parameter DSTIME;
If the DSTIME parameter is set to AUTO then the most recent filing operation in the current DSTIME value for each object will be recorded in a global, ^OBJ.DSTIME:
^OBJ.DSTIME(ExtentName,DSTIME,objectID) = filing operation
For DSTIME=AUTO the DSTIME value is recorded in ^OBJ.DSTIME and is set by the consumer of DSTIME data.
Refer to %DeepSee documentation for more information on how DSTIME is used by %DeepSee.
The filing operations are:

If the DSTIME parameter is set to MANUAL then the user is responsible for journaling object filing operations.
The EXTENTQUERYSPEC parameter defines the properties to be retrieved in addition to the IDKEY value for the built-in Extent query.

Persistent classes should define a value of for EXTENTQUERYSPEC if they wish to include additional properties in their built-in Extent query.

For example:

parameter EXTENTQUERYSPEC = "Name,SSN,Age";
parameter EXTENTSIZE = 100000;
The EXTENTSIZE parameter is used to inform the Caché SQL Query Optimizer of the approximate number of instances in the extent containing instances of this class.

For example, a class that expects to have about 1,000,000 instances should define:

parameter EXTENTSIZE = 1000000;
parameter GUIDENABLED = 0;
If this parameter is set to 1 then a GUID will be assigned (to the %GUID property) to each new object. When the object is saved for the first time this GUID value will be recorded in a namespace index which will allow GUID to be resolved to OIDs.
The IDENTIFIEDBY parameter can optionally be set to the name of a required property whose type is a reference to another class (not a literal). This property's IDKEY is then used as the prefix for the IDKEY of this class.
parameter MANAGEDEXTENT = 1;
The MANAGEDEXTENT parameter can be set to 0 (zero) to cause the Extent Manager to ignore this class. If set to 1 then the Extent Manager will register globals used by the class and detect collisions. Unmanaged extents (MANAGEDEXTENT = 0) are not checked. Currently, only classes using default storage (%Library.CacheStorage) can be managed.
parameter READONLY = 0;
READONLY = 1 means that objects can be created, opened but not saved or deleted. Tables are projected to SQL as READONLY.
ROWLEVELSECURITY = 1 | <property> means that row level security is active and the list of users/roles for a given instance/row is contained in a generated property. If the value of this parameter is a valid property name then that property will be used as the reader list and only generated if not already defined.
SQLPREVENTFULLSCAN = 1 means an attempt to prepare a query that will result in a full scan of the data map will result in an error. This applies only to queries that result in a master map scan (not indexes), with no subscript-limiting conditions on %ID or any of its components, including queries with aggregates, and including UPDATE/DELETE.
parameter USEEXTENTSET = 0;

If a persistent class uses %Library.CacheStorage then the USEEXTENTSET parameter is used to specify the global naming strategy used by the default storage class (%Library.CacheStorage). If TRUE, then global names are generated for each index that is not already allocated a LOCATION in the active storage definition.

If the storage definition specifies EXTENTLOCATION then that value is used as the base reference for all globals assigned to indices that do not have an explicit LOCATION assigned.

The global name generator for USEEXTENTSET = TRUE honors the package prefix defined in the Package Definition. If none is defined then the package prefix is generated using a based-62 encoded integer produced from CRC32 of the package name. The specific class identifier is generated from the unqualified class name using the same hash (class->crc32->base62) to form EXTENTLOCATION. Specific index suffixes are produced using a generated offset that is local to the first persistent class with an enumerated extent in which the index appears (either defined or inherited).

There are several factors that influence the generation of EXTENTLOCATION:

  1. If the EXTENTLOCATION keyword is defined then its value is used,
  2. If the DEFAULTGLOBAL class parameter is defined then its value is used,
  3. otherwise, the value is generated as two dot delimited segments. The first segment is either the defined package prefix retrieved from the package definition global or, if none is defined, a hash of the package name. The second segment is generated by a hash of the unqualified class name. The hash used is a base 62 encoded CRC32 of the value. For example, Sample.Person produces ^EW3K.wPC9 if no package prefix is defined.
The EXTENTLOCATION value is used as the base for specific globals allocated to indices. Each index is assigned an offset that is incremented from 1 by 1, offset = 1 is reserved for the IDKEY index.

EXTENTLOCATION is specific to each class. When a persistent class extends another persistent class, forming a subextent, then the subclass's EXTENTLOCATION is specific to that subclass. The index location for any inherited index is already defined specifically in the super class so the subclass's EXTENTLOCATION will only be used as the base for any index that originates in the subclass. For example, Sample.Employee extends Sample.Person. The EXTENTLOCATION generated for Sample.Person is ^EW3K.wPC9 and the EXTENTLOCATION for Sample.Employee is ^EW3K.D1Ex. Since Sample.Employee inherits several indices from Sample.Person, the global name assigned to each of those indices is already defined and inherited by Sample.Employee. However, any index defined in Sample.Employee and not inherited from Sample.Person will be assigned a global name based on Sample.Employee's EXTENTLOCATION, not on Sample.Person's EXTENTLOCATION. In other words, the EXTENTLOCATION storage keyword is not inherited.

The following tables show the indices and locations for Sample.Person and Sample.Employee. Notice the last index in the Sample.Employee table:

Class = Sample.Person
Class = Sample.Employee extends Sample.Person

Any generated global index locations and EXTENTLOCATION are updated back into the active storage definition after the class is compiled.

If USEEXTENTSET is FALSE, then global names are generated using the package-hash.class-hashSuffix strategy. For example, ^Sample.PersonD and ^Sample.PersonI("SSNKey") are globals used by Sample.Person and specific index structures are all stored in ^Sample.PersonI with the index name used as the first subscript.

VERSIONCLIENTNAME can be set to a valid CLIENTNAME (see property CLIENTNAME) value. This value will be used for client projections of the %Version property.
VERSIONPROPERTY = <property> means that the <property> in memory will be compared to the <property> on disk during an update. If different a concurrency conflict error will be reported and the save will fail.


classmethod %BuildIndices(pIndexList As %CacheString = "", pAutoPurge As %Integer = 1, pLockFlag As %Integer = 0, pJournalFlag As %Integer = 1, pStartID As %CacheString = "", pEndID As %CacheString = "", pIgnoreIndexList As %CacheString = "") as %Status

Builds entries for each index specified in the pIndexList argument. If pIndexList is empty then all indices that originate in the class are rebuilt. If there are other bitmap indexes specified in pIndexList and there is a bitmap extent index defined for the class then it will be implicitly included in pIndexList. If the bitmap extent index is included then the bitmap extent index for each subextent is also built.

If pAutoPurge is true then the indices contained in pIndexList will be purged before they are built as long as no range is specified, if a range is specified we will skip any purge. The default is TRUE (1).

If pLockFlag is one (1) then an extent lock will be acquired before the indices are built. If the lock cannot be acquired then an error is returned. The lock is released after the index build is completed. If pLockFlag is two (2) then a lock is acquired prior to filing indices for that instance and it is released as soon the indices for that instance are filed. If it is zero (0) then no locks are used while filing the indices. If it is three (3) then a shared extent lock will be acquired before the indices are built and released upon completion.

If pJournalFlag is false then journaling is disabled for the processes used to build the indices (except where the database is in a Mirror). If this flag is true then the journal status is not altered during BuildIndices(). The default value of this argument is 1 (TRUE).

pStartID and pEndID define a range of IDs for which indices will be built. The range is inclusive. If the starting ID is null then the range begins at the first ID defined in the extent. If the ending ID is null then the range ends at the last ID defined in the extent.

If pIgnoreIndexList is defined, it should be a $listbuild of index names that should not be built. This argument allows you to build all indices except those defined in pIgnoreIndexList. The default value of this argument is "", which means all indices, or all indices specified in pIndexList, will be built.

If %OnBeforeBuildIndices() is implemented and is runnable then it will be called just prior to purging and building any index structures. Refer to %OnBeforeBuildIndices() for more information.

If %OnAfterBuildIndices() is implemented and is runnable then it will be called after all index structures have been built completely. Refer to %OnAfterBuildIndices() for more information.

Returns a %Status value indicating success or failure. This method is normally generated by the storage class for persistent classes using %Library.CacheStorage or %Library.CacheSQLStorage.

If your index is corrupt running this function will not fix the corruption unless you rebuild the entire index and purge the existing indexes. If you have inserted some new items but have deferred building the index for these new items then you can run %BuildIndices on this range oif IDs to add the index entries for these new items.

classmethod %CheckConstraints(pID As %String(MAXLEN=""), pConstraintList As %List = "", pCheckDisabled As %Integer = 0, Output pErrorInfo As