|
|
1.1 ! root 1: ! 2: /* ! 3: MultiBinder.h ! 4: A Binder that knows about multiple result sets ! 5: ! 6: MultiBinders are used instead of DBBinders in order to retrieve ! 7: non-rectangular return results from Sybase or other similar stored ! 8: procedures. ! 9: ! 10: MultiBinders only work in the mode where the binder itself creates ! 11: the recordPrototype for the binder. You cannot provide your own ! 12: recordPrototypes for the MultiBinder. ! 13: ! 14: If you know exactly the sequence of properties the stored procedure ! 15: will be returning to you, then: ! 16: 1. Create a List for each [rectangular] result set the stored ! 17: procedure returns. Each List should contain, in the order the ! 18: stored procedure will return them, the attributes returned from ! 19: the database model. Note that the attributes need not, in ! 20: the case of the MultiBinder, be from the same entity. ! 21: 2. Place all these Lists, in the order in which those result ! 22: sets will be returned by the stored procedure, into a temporary ! 23: List. Pass that temporary list as the argument to ! 24: [multiBinder initFromPropertyLists:]. After initializing the binder, ! 25: the temporary list may be freed. The underlying lists created in ! 26: step #1 are now owned by the MultiBinder, and will be freed ! 27: when the MultiBinder is freed. ! 28: 3. Invoke the stored procedure via [multiBinder evaluateString:]. ! 29: 4. Repeatedley call [multiBinder setNext]. You can then call ! 30: [multiBinder valueForProperty:] for each property. Use the ! 31: delegate method binderDidChangeResultSet: to find out when you ! 32: cross result set boundaries. ! 33: 5. All result sets have been retrieved when [multiBinder setNext] ! 34: returns nil. Note that you should have received as many calls ! 35: to binderDidChangeResultSet: as there were result sets returned ! 36: from your stored procedure. ! 37: ! 38: If you want to simply receive whatever the stored procedure happens ! 39: to return, either because of your programs' task or because the ! 40: stored procedure conditionally returns different things: ! 41: 1. Pass nil as the argument to [MultiBinder initFromPropertyLists:]. ! 42: 2. Repeatedley call [multiBinder setNext]. You should interrogate ! 43: the binder via [multiBinder getCurrentProperies:] to get the ! 44: new list of properties whenever the delegate method ! 45: binderDidChangeResultSet: is called. DO NOT call getProperties:. ! 46: 3. All rows of all result sets are retrieved when ! 47: [multiBinder setNext] returns nil. ! 48: ! 49: */ ! 50: ! 51: #import <dbkit/dbkit.h> ! 52: ! 53: @interface MultiBinder:DBBinder ! 54: { ! 55: unsigned int currentResultSet; /* index into the list of lists */ ! 56: List *propListList; /* a list of property lists for the result sets */ ! 57: } ! 58: ! 59: - initFromPropertyLists:(List *)propLists; /* copies subsidiary lists out of propLists */ ! 60: - (unsigned int)currentResultSet; /* returns the index of the current result set */ ! 61: - (List *)getCurrentProperties:(List *)aList; /* fills aList with the current properties */ ! 62: ! 63: @end ! 64: ! 65: @interface Object (MultiBinderDelegateMethods) ! 66: - binderWillChangeResultSet:binder; /* called before changing result sets */ ! 67: - binderDidChangeResultSet:binder; /* called before fetching from a new result set */ ! 68: @end ! 69: ! 70: @interface DBBinder (MultiBinderMethods) ! 71: - (List *)getCurrentProperties:(List *)aList; ! 72: @end ! 73:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.