4 Copyright (C) 1999 MDlink online service center GmbH and Helge Hess
6 Author: Helge Hess (helge.hess@mdlink.de)
8 This file is part of the FB Adaptor Library
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
20 You should have received a copy of the GNU Library General Public
21 License along with this library; see the file COPYING.LIB.
22 If not, write to the Free Software Foundation,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 // $Id: FBAdaptor+Types.m 1 2004-08-20 10:38:46Z znek $
28 #include "FrontBase2Adaptor.h"
29 #include "FBChannel.h"
30 #include "FBContext.h"
32 @interface FrontBase2Adaptor(DomainResolver)
33 - (BOOL)fetchDomainInfo;
36 @implementation FrontBase2Adaptor(DomainResolver)
38 typedef struct _InternalTypeMapping {
41 } InternalTypeMapping;
43 static InternalTypeMapping internalTypeMappings[] = {
44 { FB_PrimaryKey, @"PRIMARYKEY" },
45 { FB_Boolean, @"BOOLEAN" },
46 { FB_Integer, @"INTEGER" },
47 { FB_SmallInteger, @"SMALLINT" },
48 { FB_Float, @"FLOAT" },
50 { FB_Double, @"DOUBLE" },
51 { FB_Numeric, @"NUMERIC" },
52 { FB_Decimal, @"DECIMAL" },
53 { FB_Character, @"CHAR" },
54 { FB_VCharacter, @"VARCHAR" },
56 { FB_VBit, @"VARBIT" },
59 { FB_TimeTZ, @"TIME WITH TIME ZONE" },
60 { FB_Timestamp, @"TIMESTAMP" },
61 { FB_TimestampTZ, @"TIMESTAMP WITH TIME ZONE" },
62 { FB_YearMonth, @"INTERVAL YEAR TO MONTH" },
63 { FB_DayTime, @"INTERVAL DAY TO SECOND" },
66 { -1, nil } // end marker
69 static NSString *DomainQuery =
70 @"SELECT \"DOMAIN_NAME\" FROM INFORMATION_SCHEMA.domains";
72 - (void)_resetTypeMapping {
73 if (self->typeNameToCode) {
74 NSFreeMapTable(self->typeNameToCode);
75 self->typeNameToCode = NULL;
77 if (self->typeCodeToName) {
78 NSFreeMapTable(self->typeCodeToName);
79 self->typeCodeToName = NULL;
83 - (void)_loadStandardTypes {
84 register InternalTypeMapping *mapping;
86 if (self->typeNameToCode == NULL) {
87 self->typeNameToCode = NSCreateMapTable(NSObjectMapKeyCallBacks,
88 NSIntMapValueCallBacks,
91 if (self->typeCodeToName == NULL) {
92 self->typeCodeToName = NSCreateMapTable(NSIntMapKeyCallBacks,
93 NSObjectMapValueCallBacks,
97 mapping = &(internalTypeMappings[1]);
99 while (mapping->name != nil) {
100 NSMapInsert(self->typeCodeToName,
101 (void *)(mapping->code),
102 (void *)mapping->name);
103 NSMapInsert(self->typeNameToCode,
104 (void *)mapping->name,
105 (void *)(mapping->code));
110 - (BOOL)fetchDomainInfo {
111 FrontBaseContext *ctx;
112 FrontBaseChannel *channel;
115 if (self->typeNameToCode == NULL)
116 [self _loadStandardTypes];
119 ctx = (FrontBaseContext *)[self createAdaptorContext];
120 channel = (FrontBaseChannel *)[ctx createAdaptorChannel];
122 if ([channel openChannel]) {
123 if ([ctx beginTransaction]) {
124 if ([channel evaluateExpression:DomainQuery]) {
126 NSDictionary *record;
127 NSMutableArray *domains;
129 attributes = [channel describeResults];
132 while ((record = [channel fetchAttributes:attributes withZone:NULL])) {
133 NSString *domainName;
135 if ((domainName = [record objectForKey:@"domainName"])) {
136 if (![domainName hasPrefix:@"T_"])
140 domains = [NSMutableArray arrayWithCapacity:32];
141 [domains addObject:domainName];
144 NSLog(@"no domain name in record %@ ?", record);
147 /* no get the meta-info of the domains */
149 if ([domains count] > 0) {
150 /* we need to resolve domains, construct a VALUES expression .. */
151 NSMutableString *expr;
153 NSString *domainName;
156 expr = [NSMutableString stringWithCapacity:512];
157 [expr appendString:@"VALUES("];
159 e = [domains objectEnumerator];
160 while ((domainName = [e nextObject])) {
161 if (isFirst) isFirst = NO;
162 else [expr appendString:@","];
164 [expr appendString:@"CAST(NULL AS \""];
165 [expr appendString:domainName];
166 [expr appendString:@"\")"];
169 [expr appendString:@")"];
171 //NSLog(@"expr: %@", expr);
173 /* now execute expression */
175 if ([channel evaluateExpression:expr]) {
176 int *dc = channel->datatypeCodes;
179 for (i = 0; i < channel->numberOfColumns; i++) {
181 NSString *domainName;
183 domainName = [[domains objectAtIndex:i] uppercaseString];
185 //NSMapInsert(self->typeCodeToName, (void *)dc[i], domainName);
186 NSMapInsert(self->typeNameToCode, domainName, (void *)dc[i]);
188 NSLog(@"domain %@ is code %i type %@",
191 NSMapGet(self->typeCodeToName, (void*)dc[i]));
196 [channel cancelFetch];
199 if (![ctx commitTransaction])
200 NSLog(@"couldn't common tx for domain-resolver ..");
203 NSLog(@"couldn't evaluate expression: %@", expr);
207 NSLog(@"couldn't evaluate expression: %@", DomainQuery);
208 if (!result) [ctx rollbackTransaction];
211 NSLog(@"couldn't begin tx for domain-resolver ..");
213 [channel closeChannel];
216 NSLog(@"couldn't open channel for domain-resolver ..");
223 @implementation FrontBase2Adaptor(ExternalTyping)
225 - (int)typeCodeForExternalName:(NSString *)_typeName {
228 _typeName = [_typeName uppercaseString];
230 if (self->typeNameToCode == NULL)
231 [self fetchDomainInfo];
233 if (self->typeNameToCode == NULL)
234 return FB_VCharacter;
236 if ((code = (int)NSMapGet(self->typeNameToCode, _typeName)))
239 return FB_VCharacter;
242 - (NSString *)externalNameForTypeCode:(int)_typeCode {
246 if (self->typeCodeToName == NULL)
247 [self fetchDomainInfo];
249 return NSMapGet(self->typeCodeToName, (void *)_typeCode);
252 - (BOOL)isInternalBlobType:(int)_type {
263 - (BOOL)isBlobAttribute:(EOAttribute *)_attr {
266 NSAssert(_attr, @"missing attribute parameter");
268 fbType = [self typeCodeForExternalName:[_attr externalType]];
270 return [self isInternalBlobType:fbType];
273 - (BOOL)isValidQualifierType:(NSString *)_typeName {
274 switch ([self typeCodeForExternalName:_typeName]) {
284 - (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr {
285 NSAssert(_attr, @"missing attribute parameter");