]> err.no Git - sope/blob - sope-gdl1/PostgreSQL/NSNumber+PGVal.m
added an ivar to WOComponent, minor cleanups
[sope] / sope-gdl1 / PostgreSQL / NSNumber+PGVal.m
1 // $Id: NSNumber+PGVal.m 1 2004-08-20 10:38:46Z znek $
2
3 #import <Foundation/NSString.h>
4 #include "PostgreSQL72Channel.h"
5 #include "common.h"
6
7 @implementation NSNumber(PostgreSQL72Values)
8
9 static BOOL     debugOn       = NO;
10 static Class    NSNumberClass = Nil;
11 static NSNumber *yesNum       = nil;
12 static NSNumber *noNum        = nil;
13
14 + (id)valueFromCString:(const char *)_cstr length:(int)_length
15   postgreSQLType:(NSString *)_type
16   attribute:(EOAttribute *)_attribute
17   adaptorChannel:(PostgreSQL72Channel *)_channel
18 {
19   // TODO: can we avoid the lowercaseString?
20   unsigned len;
21   unichar  c1;
22
23   if ((len = [_type length]) == 0)
24     return nil;
25
26   if (NSNumberClass == Nil) NSNumberClass = [NSNumber class];
27   
28   c1 = [_type characterAtIndex:0];
29   switch (c1) {
30   case 'f': case 'F': {
31     if (len < 5)
32       break;
33     if ([[_type lowercaseString] hasPrefix:@"float"])
34       return [NSNumberClass numberWithDouble:atof(_cstr)];
35     break;
36   }
37   case 's': case 'S': {
38     if (len < 8)
39       break;
40     if ([[_type lowercaseString] hasPrefix:@"smallint"])
41       return [NSNumberClass numberWithShort:atoi(_cstr)];
42     break;
43   }
44   case 'i': case 'I': {
45     if (len < 3)
46       break;
47     if ([[_type lowercaseString] hasPrefix:@"int"])
48       return [NSNumberClass numberWithInt:atoi(_cstr)];
49   }
50   case 'b': case 'B': {
51     if (len < 4)
52       break;
53     if (![[_type lowercaseString] hasPrefix:@"bool"])
54       break;
55     
56     if (yesNum == nil) yesNum = [[NSNumberClass numberWithBool:YES] retain];
57     if (noNum  == nil) noNum  = [[NSNumberClass numberWithBool:NO]  retain];
58     
59     if (_length == 0)
60       return noNum;
61     
62     switch (*_cstr) {
63     case 't': case 'T':
64     case 'y': case 'Y':
65     case '1':
66       return yesNum;
67     default:
68       return noNum;
69     }
70   }
71   }
72   return nil;
73 }
74
75 + (id)valueFromBytes:(const void *)_bytes length:(int)_length
76   postgreSQLType:(NSString *)_type
77   attribute:(EOAttribute *)_attribute
78   adaptorChannel:(PostgreSQL72Channel *)_channel
79 {
80 #if COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY
81   NSLog(@"%s: not implemented!", __PRETTY_FUNCTION__);
82   return nil;
83 #else
84   return [self notImplemented:_cmd];
85 #endif
86 }
87
88 - (NSString *)stringValueForPostgreSQLType:(NSString *)_type
89   attribute:(EOAttribute *)_attribute
90 {
91   // TODO: can we avoid the lowercaseString?
92   unsigned len;
93   unichar  c1;
94
95   if (debugOn)
96     NSLog(@"%s(type=%@,attr=%@)", __PRETTY_FUNCTION__, _type, _attribute);
97   
98   if ((len = [_type length]) == 0) {
99     if (debugOn) NSLog(@"  no type, return string");
100     return [self stringValue];
101   }
102   if (len < 4) { /* apparently this is 'INT'? */
103     if (debugOn) NSLog(@"  type len < 4 (%@), return string", _type);
104 #if GNUSTEP_BASE_LIBRARY
105     /* 
106        on gstep-base -stringValue of bool's return YES or NO, which seems to
107        be different on Cocoa and liBFoundation.
108     */
109     {
110       Class BoolClass = Nil;
111       
112       if (BoolClass == Nil) BoolClass = NSClassFromString(@"NSBoolNumber");
113       if ([self isKindOfClass:BoolClass])
114         return [self boolValue] ? @"1" : @"0";
115     }
116 #endif
117     return [self stringValue];
118   }
119   
120   c1 = [_type characterAtIndex:0];
121   if (debugOn) NSLog(@"  typecode '%c' ...", c1);
122   switch (c1) {
123   case 'b': case 'B':
124     if (![[_type lowercaseString] hasPrefix:@"bool"])
125       break;
126     return [self boolValue] ? @"true" : @"false";
127     
128   case 'm': case 'M': {
129     if (![[_type lowercaseString] hasPrefix:@"money"])
130       break;
131     return [@"$" stringByAppendingString:[self stringValue]];
132   }
133   
134   case 'c': case 'C':
135   case 't': case 'T':
136   case 'v': case 'V': {
137     static NSMutableString *ms = nil; // reuse mstring, THREAD
138     
139     _type = [_type lowercaseString];
140     if (!([_type hasPrefix:@"char"] ||
141           [_type hasPrefix:@"varchar"] ||
142           [_type hasPrefix:@"text"]))
143       break;
144     
145     // TODO: can we get this faster?!
146     if (ms == nil) ms = [[NSMutableString alloc] initWithCapacity:256];
147     [ms setString:@"'"];
148     [ms appendString:[self stringValue]];
149     [ms appendString:@"'"];
150     return [[ms copy] autorelease];
151   }
152   }
153   return [self stringValue];
154 }
155
156 @end /* NSNumber(PostgreSQL72Values) */