|
|
1.1 root 1: /* BinderHanlder.m:
2: * You may freely copy, distribute, and reuse the code in this example.
3: * NeXT disclaims any warranty of any kind, expressed or implied, as to its
4: * fitness for any particular use.
5: *
6: * Written by: Mai Nguyen, NeXT Developer Support
7: *
8: *
9: */
10:
11: #import "BinderHandler.h"
12: #import <appkit/appkit.h>
13: #import <dbkit/dbkit.h>
14: #import <libc.h>
15:
16: /* Define localized strings */
17: #define FAILURE NXLocalizedString("Failure:", NULL, "Message given to user when an operation has failed.")
18: #define CANNOT_CONNECT NXLocalizedString("Couldn't connect to database", NULL, "Message given to user to explain what fails. ")
19: #define OK NXLocalizedString("OK", NULL, "Okay to continue ")
20: #define NO_BINDER_OBJECT NXLocalizedString("Binder object not properly allocated", NULL, "Message given to user about a system problem.")
21:
22: /* Global to be used by Author object */
23: static id myHandler;
24: @implementation BinderHandler
25:
26: - appDidInit:sender
27: {
28: /* Connect to the Sybase Adaptor */
29: if ( myDatabase == nil ) {
30: myDatabase = [[DBDatabase alloc]init];
31: [myDatabase connectUsingAdaptor:"SybaseAdaptor"
32: andString:"sa@SYBASE/pubs"];
33: }
34:
35: /* TESTING */
36: if (![myDatabase isConnected]) {
37: NXRunAlertPanel(FAILURE, CANNOT_CONNECT,OK, NULL, NULL);
38: return self;
39: }
40: [myDatabase setDelegate:self];
41: authorEntity = [myDatabase entityNamed:"authors"];
42:
43: myHandler = self;
44:
45: return self;
46: }
47:
48: /* Stuff the binder with attributes from the authors table
49: */
50: - initBinder
51: {
52:
53: authorPrototype = [[Author alloc]init];
54: propertyList = [[List alloc] init];
55: containerList = [[List alloc] init];
56: myBinder = [[DBBinder alloc] init];
57:
58: [myBinder setDatabase:myDatabase];
59: [myBinder setProperties:propertyList];
60: [myBinder setRecordPrototype:authorPrototype];
61:
62: [myBinder associateRecordIvar:"first"
63: withProperty: [[DBExpression alloc] initForEntity:authorEntity
64: fromDescription:"au_fname"]];
65: [myBinder associateRecordIvar:"last"
66: withProperty: [[DBExpression alloc] initForEntity:authorEntity
67: fromDescription:"au_lname"]];
68: [myBinder associateRecordIvar:"address"
69: withProperty:[[DBExpression alloc] initForEntity:authorEntity
70: fromDescription:"address"]];
71: [myBinder associateRecordIvar:"state"
72: withProperty:[[DBExpression alloc] initForEntity:authorEntity
73: fromDescription:"state"]];
74: [myBinder associateRecordIvar:"zip"
75: withProperty:[[DBExpression alloc] initForEntity:authorEntity
76: fromDescription:"zip"]];
77: [myBinder associateRecordIvar:"phone"
78: withProperty:[[DBExpression alloc] initForEntity:authorEntity
79: fromDescription:"phone"]];
80:
81: return self;
82: }
83:
84:
85: - free
86: {
87: if (authorPrototype)
88: [authorPrototype free];
89: if (propertyList)
90: [propertyList free];
91: if (containerList)
92: [containerList free];
93: if (myBinder)
94: [myBinder free];
95:
96: return [super free];
97: }
98:
99: - showAllRecords:sender
100: {
101: [self initBinder];
102: [self findAllRecords];
103:
104: return self;
105: }
106:
107:
108: - findAllRecords
109: {
110: int recordCount;
111:
112: if ( myBinder == nil ) {
113: NXRunAlertPanel(FAILURE, NO_BINDER_OBJECT,
114: "Binder object not properly allocated",
115: "OK", NULL, NULL);
116: return self;
117: }
118:
119: [myBinder setContainer:containerList];
120: [myBinder select];
121:
122: recordCount = [containerList count];
123: sprintf(buf, "\n------------------------\n");
124: [self appendToText:buf];
125: sprintf(buf, "%s\t%d\n", "Total Number of Records:", recordCount);
126: [self appendToText:buf];
127: [containerList makeObjectsPerform:@selector(printSelf)];
128: /* Make the input field first responder */
129: [lastNameField selectText:0];
130: return self;
131: }
132:
133:
134: /* Build a simple SQL query with DBQualifier and retrieve the data via the
135: * binder object.
136: */
137: - findByName:sender
138: {
139: const char * name;
140: id aProp;
141: id theQualifier;
142:
143: name = [lastNameField stringValue];
144:
145: aProp = [[DBExpression alloc] initForEntity:authorEntity
146: fromDescription:"au_lname"];
147: theQualifier = [[DBQualifier allocFromZone:[self zone] ]
148: initForEntity:authorEntity
149: fromDescription:"%@ LIKE %s", aProp, name];
150:
151: /* Must allocate a new binder object */
152: [self initBinder];
153: [myBinder setQualifier:theQualifier];
154: [self findAllRecords];
155: [aProp free];
156: [theQualifier free];
157: return self;
158: }
159:
160:
161: - findByState:sender
162: {
163: const char * state;
164: id aProp;
165: id theQualifier;
166:
167:
168: state = [stateField stringValue];
169:
170: aProp = [[DBExpression alloc] initForEntity:authorEntity
171: fromDescription:"state"];
172: theQualifier = [[DBQualifier allocFromZone:[self zone] ]
173: initForEntity:authorEntity
174: fromDescription:"%@ LIKE %s", aProp, state];
175:
176: /* Must allocate a new binder object with a different qualifier */
177: [self initBinder];
178: [myBinder setQualifier:theQualifier];
179: [self findAllRecords];
180: [aProp free];
181: [theQualifier free];
182: return self;
183: }
184:
185:
186: /* Appends the string passed to the doc view of the text view
187: */
188: - appendToText:(const char *)newText
189: {
190: int currentLength = [theTextView textLength];
191: [theTextView setSel:currentLength :currentLength];
192: [theTextView replaceSel:newText];
193: [theTextView scrollSelToVisible];
194: return self;
195: }
196:
197:
198: /* DBDatabase delegate methods to log error messages and SQL queries */
199:
200: - (BOOL)db:aDb willEvaluateString:(const unsigned char*)aString usingBinder:aBinder
201: {
202: [self appendToText:"\n << SQL Query:\n"];
203: [self appendToText:aString];
204: [self appendToText:" >> \n"];
205: return YES;
206: }
207:
208: @end
209:
210: @implementation Author
211:
212: /* copyFromZone: is VERY important...this is how the prototype
213: * object is turned into records!
214: */
215:
216: - copyFromZone:(NXZone*)z
217: {
218: Author *theCopy = [[Author allocFromZone:z] init];
219: theCopy->first = NXCopyStringBufferFromZone(first, z);
220: theCopy->last = NXCopyStringBufferFromZone(last, z);
221: theCopy->address = NXCopyStringBufferFromZone(address, z);
222: theCopy->state = NXCopyStringBufferFromZone(state, z);
223: theCopy->zip = NXCopyStringBufferFromZone(zip, z);
224: theCopy->phone = NXCopyStringBufferFromZone(phone, z);
225: return theCopy;
226: }
227:
228:
229: /* Print data stored in the author object
230: */
231: - printSelf
232: {
233: char buf[200];
234:
235: sprintf(buf, "%s %s\n%s \t%s %s\n%s\n", first, last, address, state, zip,
236: phone);
237: if (myHandler != nil)
238: [myHandler appendToText: buf];
239: return self;
240: }
241:
242:
243: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.