Annotation of Examples/EnterpriseObjects/UniqueKey/UniqueKey_oracle/UniqueKey.m, revision 1.1

1.1     ! root        1: #import <appkit/appkit.h>
        !             2: #import "UniqueKey.h"
        !             3: 
        !             4: 
        !             5: static BOOL  _Debug = YES;
        !             6: static id    _connectionDictionary = nil;
        !             7: 
        !             8: 
        !             9: @implementation UniqueKey
        !            10: 
        !            11: /******************************************************************************
        !            12: * Allow the programmer to specify login information for our separate UniqueKey
        !            13: * channel.  If no information is supplied, we display our own login panel.
        !            14: ******************************************************************************/
        !            15: + setConnectionDictionary:(NSDictionary *)connectionDictionary
        !            16: {
        !            17:     if(_connectionDictionary) [_connectionDictionary autorelease];
        !            18:     _connectionDictionary = [connectionDictionary retain];
        !            19:     return self;
        !            20: }
        !            21: + connectionDictionary
        !            22: {
        !            23:     return [[_connectionDictionary retain] autorelease];
        !            24: }
        !            25: 
        !            26: 
        !            27: /******************************************************************************
        !            28: * The UniqueKey objects share a database channel that is sure
        !            29: * to be free to allow immediate reservation of a block of keys.
        !            30: ******************************************************************************/
        !            31: - initSharedChannel
        !            32: {              
        !            33:     NSString                                   *modelName = @"UniqueKey";
        !            34:     NSString                                   *path;
        !            35:     NSString                                   *_entityName = @"UniqueKey";
        !            36:     EOModel                                            *eoModel;
        !            37:     EOAdaptor                                  *eoAdaptor;
        !            38:     EODatabase                                 *db;
        !            39:     static EODatabaseContext   *_sharedContext;
        !            40:     static EODatabaseChannel   *_sharedChannel;
        !            41:     static EOEntity                            *_sharedEntity;
        !            42:     static BOOL                                        initFlag = NO;
        !            43:     
        !            44:     if(!initFlag) {
        !            45:        path = [EOModel findPathForModelNamed:modelName];
        !            46:        if(!path) {
        !            47:                NXRunAlertPanel([NXApp appName],
        !            48:                        "UniqueKey is unable to find %s",NULL,NULL,NULL,[modelName cString]);
        !            49:                return nil;
        !            50:        }
        !            51:        
        !            52:        eoModel=[[EOModel alloc] initWithContentsOfFile:path];
        !            53:        if(!eoModel) {
        !            54:                NXRunAlertPanel([NXApp appName],
        !            55:                        "UniqueKey is unable to open %s",NULL,NULL,NULL,[path cString]);
        !            56:                return nil;
        !            57:         }
        !            58:         
        !            59:        eoAdaptor= [EOAdaptor adaptorWithModel:eoModel];
        !            60:        if(!eoAdaptor) {
        !            61:                NXRunAlertPanel([NXApp appName],
        !            62:                        "UniqueKey is unable to create adaptorWithModel:",NULL,NULL,NULL);
        !            63:                return nil;
        !            64:         }
        !            65:         
        !            66:        if([UniqueKey connectionDictionary]!=nil)
        !            67:                [eoAdaptor setConnectionDictionary:[UniqueKey connectionDictionary]];
        !            68:        if(![eoAdaptor hasValidConnectionDictionary])
        !            69:                [eoAdaptor runLoginPanelAndValidateConnectionDictionary];
        !            70: 
        !            71:        db=[[EODatabase alloc] initWithAdaptor:eoAdaptor];
        !            72:        if(!db) {
        !            73:                NXRunAlertPanel([NXApp appName],
        !            74:                        "UniqueKey is unable to initWithAdaptor:",NULL,NULL,NULL);
        !            75:                return nil;
        !            76:        }
        !            77:     
        !            78:        _sharedContext=[[EODatabaseContext alloc] initWithDatabase:db];
        !            79:        if(!_sharedContext) {
        !            80:                NXRunAlertPanel([NXApp appName],
        !            81:                        "UniqueKey is unable to initWithDatabase:",NULL,NULL,NULL);
        !            82:                return nil;
        !            83:        }
        !            84:     
        !            85:        _sharedChannel=[[EODatabaseChannel alloc] initWithDatabaseContext:_sharedContext];
        !            86:        if(!_sharedChannel) {
        !            87:                NXRunAlertPanel([NXApp appName],
        !            88:                        "UniqueKey is unable to initWithDatabaseContext:",NULL,NULL,NULL);
        !            89:                return nil;
        !            90:        }
        !            91:     
        !            92:        _sharedEntity= [eoModel entityNamed:_entityName];
        !            93:        if(!_sharedEntity) {
        !            94:                NXRunAlertPanel([NXApp appName],
        !            95:                        "UniqueKey is unable to find entityNamed:%s",NULL,NULL,NULL,[_entityName cString]);
        !            96:                return nil;
        !            97:        }
        !            98: 
        !            99:        [[_sharedChannel adaptorChannel] openChannel];
        !           100:        if(_Debug) [[_sharedChannel adaptorChannel] setDelegate:self];
        !           101: 
        !           102:        initFlag=TRUE;
        !           103:     }
        !           104:     
        !           105:     dbContext        = [_sharedContext retain];
        !           106:     dbChannel        = [_sharedChannel retain];
        !           107:     uniqueKeyEntity  = [_sharedEntity retain];
        !           108:     return self;
        !           109: }
        !           110: 
        !           111: 
        !           112: /******************************************************************************
        !           113: * Init a UniqueKey object to reserve integer keys in blocks of <count> keys.  Hold
        !           114: * off reserving any keys until the first call to nextKey.  Each call to nextKey
        !           115: * returns a unique integer key.  The first call reserves a block of <count> keys.
        !           116: * When the block has been used, a new block is reserved.
        !           117: *
        !           118: * UniqueKey uses a separate table to hold the external entity name and current
        !           119: * max reserved integer key.  The UniqueKey objects share a database channel that
        !           120: * is sure to be free to allow immediate reservation of a block of keys.
        !           121: ******************************************************************************/
        !           122: - initWithEntity:(EOEntity*)entity count:(unsigned int)count
        !           123: {
        !           124:     NSString   *qualifierString;
        !           125:     EOQualifier        *tableNameQualifier;
        !           126:     NSNumber   *max;
        !           127: 
        !           128:     keyCount   = count;
        !           129:     nextKey    = 0;
        !           130:     maxKey     = 0;
        !           131:     
        !           132:     if(!entity || ![self initSharedChannel]) return nil;
        !           133: 
        !           134:     // Construct the qualifier for our name
        !           135:     qualifierString = [NSString stringWithFormat:@"EntityName = '%@'",[entity externalName]];
        !           136:     
        !           137:     tableNameQualifier = [[[EOQualifier allocWithZone:[self zone]]
        !           138:        initWithEntity:uniqueKeyEntity qualifierFormat:qualifierString] autorelease];
        !           139: 
        !           140:     // Select the object and check for the presence of our name and "MaxKey"
        !           141:     [dbContext beginTransaction];
        !           142:     [dbChannel selectObjectsDescribedByQualifier:tableNameQualifier fetchOrder:nil];
        !           143:     tableMax=[[dbChannel fetchWithZone:[dbChannel zone]] retain];
        !           144:     [dbChannel cancelFetch];
        !           145:     [dbContext commitTransaction];
        !           146:     
        !           147:     // Was there an entry for our table name?
        !           148:     if(!tableMax) {
        !           149:        NSLog(@"Unique key was unable to fetch EntityName = %@",[entity externalName]);
        !           150:        return nil;
        !           151:     }
        !           152:     
        !           153:     // Then there should be a value for "MaxKey" for our table
        !           154:     max=[tableMax objectForKey:@"MaxKey"];
        !           155:     if(!max) {
        !           156:        NSLog(@"Unique key method nextKey could not fine MaxKey");
        !           157:        return nil;
        !           158:     }
        !           159:     return self;
        !           160: }
        !           161: 
        !           162: 
        !           163: /******************************************************************************
        !           164: * Hand out the next unique key from our reserved block.  If the block is exhausted,
        !           165: * increment the max_id (high-water mark) and attempt to updateObject:.  This
        !           166: * writes the new max_id back to the table.  Under optimistic locking (the default)
        !           167: * the update will fail if another client has bumped up the max_id since our last use.
        !           168: * In that case, we need to refetchObject: and try again.
        !           169: ******************************************************************************/
        !           170: - (int) nextKey
        !           171: {
        !           172:     NSNumber   *max;
        !           173: 
        !           174:     // Hand out our next reserved key.  If we are out of keys, fall through to
        !           175:     // reserve another block of keyCount keys.
        !           176:     if(++nextKey<=maxKey) return nextKey;
        !           177:     
        !           178:     // Attempt to bump up the count by keyCount.  Fail on optomistic lock if someone
        !           179:     // else reserved a chunck since our original select (or our last update).
        !           180:     [dbContext beginTransaction];
        !           181:     while(1) {
        !           182:        max    = [tableMax objectForKey:@"MaxKey"];
        !           183:        maxKey = [max intValue]+keyCount;
        !           184:        [tableMax setObject:[NSNumber numberWithInt:maxKey] forKey:@"MaxKey"];
        !           185:        if([dbChannel updateObject:tableMax]) break;
        !           186: 
        !           187:        [dbContext rollbackTransaction];
        !           188:        [dbContext beginTransaction];
        !           189:        [dbChannel refetchObject:tableMax];
        !           190:     }
        !           191:     [dbContext commitTransaction];
        !           192:     
        !           193:     nextKey=maxKey-keyCount+1;
        !           194:     return nextKey;
        !           195: }
        !           196: 
        !           197: 
        !           198: /******************************************************************************
        !           199: * Echo SQL when debug is enabled.
        !           200: ******************************************************************************/
        !           201: - (EODelegateResponse)adaptorChannel:channel
        !           202:        willEvaluateExpression:(NSMutableString *)expression
        !           203: {
        !           204:        NSLog(expression);
        !           205:        return EODelegateApproves;
        !           206: }
        !           207: 
        !           208: 
        !           209: - (void)dealloc
        !           210: {
        !           211:        [dbContext release];
        !           212:        [dbChannel release];
        !           213:        [uniqueKeyEntity release];
        !           214:        [tableMax release];
        !           215:        if (_connectionDictionary)
        !           216:                [_connectionDictionary release];
        !           217:        [super dealloc];
        !           218:    
        !           219: }
        !           220: 
        !           221: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.