]> err.no Git - sope/blob - sope-gdl1/GDLAccess/EOArrayProxy.m
fixed bug in GDL adaptor lookup
[sope] / sope-gdl1 / GDLAccess / EOArrayProxy.m
1 /* 
2    EOArrayProxy.m
3
4    Copyright (C) 1999 MDlink online service center GmbH, Helge Hess
5
6    Author: Helge Hess (hh@mdlink.de)
7    Date:   1999
8
9    This file is part of the GNUstep Database Library.
10
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Library General Public
13    License as published by the Free Software Foundation; either
14    version 2 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Library General Public License for more details.
20
21    You should have received a copy of the GNU Library General Public
22    License along with this library; see the file COPYING.LIB.
23    If not, write to the Free Software Foundation,
24    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26 // $Id: EOArrayProxy.m 1 2004-08-20 10:38:46Z znek $
27
28 #import "common.h"
29 #import "EOArrayProxy.h"
30 #import "EODatabaseChannel.h"
31 #import "EODatabaseContext.h"
32 #import "EOEntity.h"
33 #import "EOSQLQualifier.h"
34 #import "EOGenericRecord.h"
35
36 @implementation EOArrayProxy
37
38 - (id)initWithQualifier:(EOSQLQualifier *)_qualifier
39   fetchOrder:(NSArray *)_fetchOrder
40   channel:(EODatabaseChannel *)_channel
41 {
42   self->qualifier  = RETAIN(_qualifier);
43   self->fetchOrder = RETAIN(_fetchOrder);
44   self->channel    = RETAIN(_channel);
45   return self;
46 }
47
48 + (id)arrayProxyWithQualifier:(EOSQLQualifier *)_qualifier
49   fetchOrder:(NSArray *)_fetchOrder
50   channel:(EODatabaseChannel *)_channel
51 {
52   return AUTORELEASE([[self alloc] initWithQualifier:_qualifier
53                                    fetchOrder:_fetchOrder
54                                    channel:_channel]);
55 }
56
57 - (void)dealloc {
58   AUTORELEASE(self->content);
59   RELEASE(self->qualifier);
60   RELEASE(self->fetchOrder);
61   RELEASE(self->channel);
62   [super dealloc];
63 }
64
65 // accessors
66
67 - (BOOL)isFetched {
68   return self->content ? YES : NO;
69 }
70
71 - (EODatabaseChannel *)databaseChannel {
72   return self->channel;
73 }
74 - (EOEntity *)entity {
75   return [self->qualifier entity];
76 }
77 - (NSArray *)fetchOrder {
78   return self->fetchOrder;
79 }
80 - (EOSQLQualifier *)qualifier {
81   return self->qualifier;
82 }
83
84 // operations
85
86 - (void)clear {
87   RELEASE(self->content);
88   self->content = nil;
89 }
90
91 - (BOOL)fetch {
92   BOOL           inTransaction;
93   BOOL           didOpenChannel;
94   NSMutableArray *result;
95   
96   [self clear];
97   result = [NSMutableArray arrayWithCapacity:16];
98
99   didOpenChannel = (![self->channel isOpen])
100     ? [self->channel openChannel]
101     : NO;
102     
103   if ([self->channel isFetchInProgress]) {
104     [NSException raise:NSInvalidArgumentException
105                  format:@"attempt to fetch with busy channel: %@", self];
106   }
107
108   inTransaction = 
109     [[self->channel databaseContext] transactionNestingLevel] > 0;
110   if (!inTransaction) {
111     if (![[self->channel databaseContext] beginTransaction]) {
112       NSLog(@"WARNING: could not begin transaction to fetch array proxy !");
113
114       if (didOpenChannel)
115         [self->channel closeChannel];
116       return NO;
117     }
118   }
119     
120   if (![self->channel selectObjectsDescribedByQualifier:self->qualifier
121                       fetchOrder:self->fetchOrder]) {
122     if (!inTransaction)
123       [[self->channel databaseContext] rollbackTransaction];
124     if (didOpenChannel)
125       [self->channel closeChannel];
126     
127     NSLog(@"ERROR: select on array proxy failed ..");
128     return NO;
129   }
130
131   { // fetch objects
132     NSZone *z = [self zone];
133     id object;
134     
135     while ((object = [self->channel fetchWithZone:z]))
136       [result addObject:object];
137     object = nil;
138   }
139   [self->channel cancelFetch];
140
141   if (!inTransaction) {
142     if (![[self->channel databaseContext] commitTransaction]) {
143       NSLog(@"WARNING: could not commit array proxy's transaction !");
144       
145       if (didOpenChannel)
146         [self->channel closeChannel];
147       return NO;
148     }
149   }
150
151   if (didOpenChannel)
152     [self->channel closeChannel];
153   
154   self->content = [result copyWithZone:[self zone]];
155   return YES;
156 }
157
158 // turn fault to real array ..
159
160 void _checkFetch(EOArrayProxy *self) {
161   if (self->content) return;
162   [self fetch];
163 }
164
165 // NSArray operations
166
167 - (id)objectAtIndex:(unsigned int)_index {
168   _checkFetch(self);
169   return [self->content objectAtIndex:_index];
170 }
171 - (unsigned int)count {
172   _checkFetch(self);
173   return [self->content count];
174 }
175 - (unsigned int)indexOfObjectIdenticalTo:(id)_object {
176   _checkFetch(self);
177   return [self->content indexOfObjectIdenticalTo:_object];
178 }
179
180 // NSCopying
181
182 - (id)copyWithZone:(NSZone*)zone {
183   if (NSShouldRetainWithZone(self, zone))
184     return RETAIN(self);
185   else {
186     _checkFetch(self);
187     return [[NSArray allocWithZone:zone] initWithArray:self->content copyItems:NO];
188   }
189 }
190
191 - (id)mutableCopyWithZone:(NSZone*)zone {
192   _checkFetch(self);
193   return [[NSMutableArray alloc] initWithArray:self->content];
194 }
195
196
197 #if 0
198
199 // forwarding
200
201 - (void)forwardInvocation:(NSInvocation *)_invocation {
202   _checkFetch(self);
203   [_invocation invokeWithTarget:self->content];
204 }
205
206 - (retval_t)forward:(SEL)_selector:(arglist_t)_frame {
207   _checkFetch(self);
208   return objc_msg_sendv(self->content, _selector, _frame);
209 }
210
211 #endif
212
213 @end