7 static char *rcsid_gdb_db_c = "$Header$";
10 /************************************************************************/
14 /* Authors: Susan Ryan and Noah Mendelsohn
16 /* Copyright: 1986 MIT Project Athena
17 /* For copying and distribution information, please see
18 /* the file <mit-copyright.h>.
20 /************************************************************************/
22 #include <mit-copyright.h>
29 \f/************************************************************************/
31 /* start_accessing_db (start_accessing_db)
33 /* 1) Creates a new db structure to describe the database.
35 /* 2) Parses the supplied db_ident into a server and a db name
37 /* 3) Opens a connection to the server, sending the name of the
38 /* database as an argument
40 /* 4) Asynchronously receives a return code from the server
41 /* to indicate whether the database could be accessed
43 /* 5) If successful, the handle on the new structure is placed into
44 /* the variable supplied by the caller. Otherwise, the structure
45 /* is de_allocated and failure status is returned to the caller.
47 /* Note: this code was adapted from an earlier synchronous
48 /* implementation and there may yet be some loose ends.
50 /************************************************************************/
52 #define MIN_NAME_LEN 1 /*completely arbitrary */
53 #define FAILURE NULL /*until we decide what it should really be */
54 /*note if fails returns NULL for the db_handle value*/
62 OPERATION get_retcode;
66 start_accessing_db (op, db_ident, db_handle)
71 /*----------------------------------------------------------*/
75 /*----------------------------------------------------------*/
77 register DATABASE db; /* the newly created */
79 register struct adb_data *arg; /* holds our state */
80 /* during async operation*/
81 char *ident, *server, *temp_server; /* loop variables for */
83 char *db_name, *temp_name;
84 int count; /* counts chars during parse */
86 CONNECTION connexn; /* the connection to the */
89 /*----------------------------------------------------------*/
91 /* Execution begins here
93 /* Make sure parameters are correct, then allocate a
96 /*----------------------------------------------------------*/
105 GDB_CHECK_OP(op, "start_accessing_db")
107 if ((db_ident == NULL)|| (strlen(db_ident)<MIN_NAME_LEN)) {
108 fprintf (gdb_log,"access_db: correct syntax is db_name@server \n");
110 return (OP_CANCELLED);
116 /*----------------------------------------------------------*/
118 /* Loop to count lengths of server and database names
119 /* Allocate space for each and copy them both
121 /*----------------------------------------------------------*/
125 while (*ident++ != '@') {
129 db_name = db_alloc (count); /* space for db_name */
130 /* note: this is cleaned */
131 /* up by the tear down rtn*/
134 while (*ident++ != '\0')
137 count += strlen(GDB_DB_SERVICE)+1; /* leave room for :service */
138 server = db_alloc (count); /* space for host:service */
139 /* note: this is cleaned */
140 /* up by the tear down rtn*/
143 * copy head of db_ident string from db_name@server to db_name
146 while (*db_ident != '@') {
147 *temp_name = *db_ident;
156 * Set up server host name
158 temp_server = server;
159 db_ident++; /* skip the '@' */
160 while (*db_ident!= '\0') {
161 *temp_server = *db_ident;
167 * Append :service id to the server host name
169 *temp_server++ = ':';
171 (void) strcat(server, GDB_DB_SERVICE);
176 /*----------------------------------------------------------*/
178 /* Create a connection to the server.
180 /*----------------------------------------------------------*/
182 connexn = start_server_connection (server, db_name);
184 if (connexn==NULL || connection_status(connexn) != CON_UP) {
185 connection_perror(connexn, "Error starting server connection");
186 fprintf (gdb_log, "gdb:access_db: couldn't connect to server %s \n", server);
187 g_tear_down(*db_handle);
188 OP_STATUS(op) = OP_CANCELLED;
189 return (OP_CANCELLED);
192 db->connection = connexn;
195 * Start asynchronously receiving the return code from the
196 * data base server. May take awhile, since ingres is so
200 arg = (struct adb_data *)db_alloc(sizeof(struct adb_data));
201 arg->get_retcode = create_operation();
204 start_receiving_object (arg->get_retcode, connexn,
205 (char *)&(OP_RESULT(op)), INTEGER_T);
209 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
210 g_tear_down (*db_handle);
211 OP_STATUS(op) = OP_CANCELLED;
212 delete_operation(arg->get_retcode);
213 db_free((char *)arg, sizeof(struct adb_data));
218 * We've successfully queued the receive of the return code.
219 * That's about all we have to do if things go well, but if the
220 * operation fails later, we have to be there to clean up. To
221 * get control back, we queue ourselves as a second operation
222 * so we can see how the first did, and so we can free up arg.
224 initialize_operation(op, g_iadb, (char *)arg, (int (*)())NULL);
225 (void) queue_operation(connexn, CON_INPUT, op);
230 /*----------------------------------------------------------*/
234 /* Init routine for getting return code on accessing a
235 /* database. If all went well, (or even if it didn't), then
236 /* we are done. All we have to do is clean up the stuff we've
239 /*----------------------------------------------------------*/
242 g_iadb(op, hcon, arg)
244 HALF_CONNECTION hcon;
245 struct adb_data *arg;
250 * Figure out how the receipt went
252 rc = OP_STATUS(arg->get_retcode);
255 * Release all transient data structures.
257 if (rc != OP_COMPLETE || op->result != DB_OPEN)
258 g_tear_down(arg->db);
260 DB_STATUS(arg->db) = DB_OPEN;
262 delete_operation(arg->get_retcode);
263 db_free((char *)arg, sizeof(struct adb_data));
268 /************************************************************************/
272 /* this is called by access_db and perf_db_op when a fatal error
273 /* is reached. It is an attempt to intelligently handle the error,
274 /* and tear down connections and data structures if necessary.
276 /* The current version simply tears down everything, perhaps later
277 /* versions should make provision for closing the db as necessary,
278 /* and/or other less drastic ways to handle the errors.
280 /************************************************************************/
283 g_tear_down (db_handle)
286 register DATABASE db = db_handle;
288 /*----------------------------------------------------------*/
290 /* If the db is opened, and the connexn is severed,
291 /* some error handling, closing of the db should be done
294 /* Also, at the server, perhaps a return code to indicate
295 /* that user tried to open non-existant db???
297 /*----------------------------------------------------------*/
304 (void) sever_connection (db->connection);
307 * Free up the separately allocated strings to which the
308 * database descriptor points
310 gdb_fstring(db->server);
311 gdb_fstring(db->name);
314 * Free the descriptor itself
316 db_free ((char *)db,sizeof(struct db_struct));
320 /************************************************************************/
324 /* Allocate and initialize a database descriptor structure.
326 /************************************************************************/
331 register DATABASE db;
333 db = (DATABASE)db_alloc (sizeof(struct db_struct));
335 db->connection = NULL;
338 DB_STATUS(db) = DB_CLOSED;
342 \f/************************************************************************/
344 /* access_db (access_db)
346 /* Does a start_accessing_db and waits for it to complete.
348 /************************************************************************/
351 access_db (db_ident, db_handle)
355 register OPERATION op;
362 * Create an operation and use it to asynchronously access
365 op = create_operation();
366 (void) start_accessing_db(op, db_ident, db_handle);
369 * Wait for it to complete, note whether the operation completed
370 * at all, and if so, whether it returned a successful result
371 * in accessing the database. Then reclaim the space used for
374 (void) complete_operation(op);
375 status = OP_STATUS(op);
376 result = OP_RESULT(op);
378 delete_operation(op);
381 * Tell the caller either that we were interrupted, or pass
382 * on the actual result of accessing the database. If it
383 * failed, then tear everything down after all.
385 if (status==OP_COMPLETE)
390 \f/************************************************************************/
392 /* start_performing_db_operation (start_performing_db_operation)
394 /* Asynchronously performs any operation except for a query
395 /* on the remote database.
397 /* The operation is encoded as a GDB string and sent to the server.
399 /* An integer return code is received back and returned to the caller.
401 /* Note that this operation executes on both the outbound and inbound
402 /* half connections. Since there is no explicit sync between the two
403 /* directions, operations like this pipeline freely from requestor
404 /* to server, but there is no way to cancel this operation once it
405 /* has started without severing the accompanying connection.
407 /************************************************************************/
412 DATABASE db; /* the database we're */
414 OPERATION send_request; /* used to send the string */
415 /* containing the db oper. */
416 /* to be performed */
417 OPERATION get_retcode; /* used to get back the */
418 /* response to our request */
419 STRING s; /* the operation string */
420 /* itself. This is sent. */
423 #define MIN_REQUEST_LEN 1 /*completely arbitrary */
428 start_performing_db_operation (op, db_handle,request)
433 /*----------------------------------------------------------*/
437 /*----------------------------------------------------------*/
439 register struct pdb_data *arg; /* holds our state */
440 /* during async operation*/
441 register DATABASE db = db_handle; /* fast working copy */
443 /*----------------------------------------------------------*/
445 /* Execution begins here
447 /* Make sure parameters are correct, then allocate a
450 /*----------------------------------------------------------*/
452 GDB_CHECK_OP(op, "start_performing_db_operation ")
454 fprintf (gdb_log, "gdb: start_performing_db_operation: supplied database is NULL\n");
455 OP_STATUS(op) = OP_CANCELLED;
459 GDB_CHECK_DB(db, "start_performing_db_operation")
461 if (DB_STATUS(db) != DB_OPEN) {
462 fprintf (gdb_log, "gdb: start_performing_db_operation: request to closed database ");
463 OP_STATUS(op) = OP_CANCELLED;
467 if (db->connection == NULL) {
469 "gdb: start_performing_db_operation: connection severed, request cancelled\n");
470 OP_STATUS(op) = OP_CANCELLED;
474 if (connection_status(db->connection) != CON_UP ) {
475 fprintf (gdb_log, "gdb: start_performing_db_operation: problems maintaining connection ");
476 connection_perror(db->connection, "Reason for connection failure");
477 fprintf (gdb_log, "request cancelled \n");
478 OP_STATUS(op) = OP_CANCELLED;
482 if ((request == NULL) || (strlen (request)<MIN_REQUEST_LEN)) {
483 fprintf (gdb_log, "gdb: start_performing_db_operation: request either missing or too short\n");
484 OP_STATUS(op) = OP_CANCELLED;
486 /*should we disallow empty requests? */
490 /*----------------------------------------------------------*/
492 /* Asynchronously send the request to the server
494 /*----------------------------------------------------------*/
497 * Allocate a structure to hold our state while we're gone
498 * waiting for this to complete.
501 arg = (struct pdb_data *)db_alloc(sizeof(struct pdb_data));
503 arg->send_request = create_operation();
506 * Send the request string to the server
508 STRING_DATA(arg->s) = request;
509 MAX_STRING_SIZE(arg->s) = strlen (request) +1;
510 start_sending_object (arg->send_request, db->connection,
511 (char *)&(arg->s), STRING_T);
512 if (OP_STATUS(arg->send_request) == OP_CANCELLED) {
513 OP_STATUS(op) = OP_CANCELLED;
514 delete_operation(arg->send_request);
515 db_free((char *)arg, sizeof(struct pdb_data));
519 /*----------------------------------------------------------*/
521 /* Asynchronously receive the return code (note, we
522 /* really don't know whether the request has even been
523 /* sent yet...doesn't really matter.)
525 /*----------------------------------------------------------*/
527 arg->get_retcode = create_operation();
529 * This must come here as it sets op_result
531 initialize_operation(op, g_ipdb, (char *)arg, (int (*)())NULL);
533 start_receiving_object (arg->get_retcode, db->connection,
534 (char *)&(OP_RESULT(op)), INTEGER_T);
535 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
536 OP_STATUS(op) = OP_CANCELLED;
537 (void) cancel_operation(arg->send_request);/* this could be a bug, */
538 /* because we introduce */
539 /* indeterminism into */
540 /* the reply stream, probably */
541 /* should shutdown the whole */
543 delete_operation(arg->send_request);
544 delete_operation(arg->get_retcode);
545 db_free((char *)arg, sizeof(struct adb_data));
550 * We've successfully queued the receive of the return code.
551 * That's about all we have to do if things go well, but if the
552 * operation fails later, we have to be there to clean up. To
553 * get control back, we queue ourselves as a second operation
554 * so we can see how the first did, and so we can free up arg.
556 (void) queue_operation(db->connection, CON_INPUT, op);
560 /*----------------------------------------------------------*/
564 /* Init routine for getting return code on performin a db
565 /* operation. If all went well, (or even if it didn't),
566 /* then we are done. All we have to do is clean up the
567 /* stuff we've allocated.
569 /*----------------------------------------------------------*/
572 g_ipdb(op, hcon, arg)
574 HALF_CONNECTION hcon;
575 struct pdb_data *arg;
580 * Figure out how the receipt went
582 rc1 = OP_STATUS(arg->send_request);
583 rc2 = OP_STATUS(arg->get_retcode);
586 * Release all transient data structures.
588 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE)
589 g_tear_down(arg->db);
591 delete_operation(arg->send_request);
592 delete_operation(arg->get_retcode);
593 db_free((char *)arg, sizeof(struct pdb_data));
598 /************************************************************************/
600 /* perform_db_operation (perform_db_operation)
602 /* Do a database operation synchronously. This just calls
603 /* the async routine and waits for it to complete.
605 /************************************************************************/
607 perform_db_operation (db_handle,request)
611 register OPERATION op;
616 * Create an operation and use it to asynchronously perform
619 op = create_operation();
620 (void) start_performing_db_operation(op, db_handle, request);
623 * Wait for it to complete, note whether the operation
624 * completed at all, and if so, whether it returned a
625 * successful result. Then reclaim the space used for the
628 (void) complete_operation(op);
629 status = OP_STATUS(op);
630 result = OP_RESULT(op);
632 delete_operation(op);
635 * Tell the caller either that we were interrupted, or pass
636 * on the actual result of accessing the database. If it
637 * failed, then tear everything down after all.
639 if (status==OP_COMPLETE)
644 \f/************************************************************************/
646 /* start_db_query (start_db_query)
648 /* Asynchronously performs a database query on the remote
651 /* The operation is encoded as a GDB string and sent to the server.
653 /* An integer return code is received back and returned to the caller.
655 /* If the return code indicates success, then we go into a loop
656 /* receiving the retrieved data. Each returned tuple is preceeded by
657 /* a so-called yes/no flag, which indicates whether tuple data is really
658 /* to follow. Last tuple is followed by a NO flag.
660 /* Note that this operation executes on both the outbound and inbound
661 /* half connections. Since there is no explicit sync between the two
662 /* directions, operations like this pipeline freely from requestor
663 /* to server, but there is no way to cancel this operation once it
664 /* has started without severing the accompanying connection.
666 /************************************************************************/
673 * Following may be used throughout processing
675 DATABASE db; /* the database we're */
678 TUPLE_DESCRIPTOR tpd;
680 * used primarily in first phase for sending query and getting
683 OPERATION send_query; /* used to send the string */
684 /* containing the query */
685 /* to be performed */
686 OPERATION send_descriptor; /* used to send the tuple */
687 /* descriptor to the server */
688 OPERATION get_retcode; /* used to get back the */
689 /* response to our request */
690 STRING s; /* the operation string */
691 /* itself. This is sent. */
693 * Following are used during later phase to receive the tuples
695 int state; /* are we expecting a yes/no */
696 /* or a tuple next? */
699 int yesno; /* an indicator of whether */
700 /* another tuple is to follow*/
702 OPERATION receive_yesno_or_data;
703 TUPLE tup; /* a place to put */
708 start_db_query (op, db_handle,rel, query)
714 /*----------------------------------------------------------*/
718 /*----------------------------------------------------------*/
720 register struct dbq_data *arg; /* holds our state */
721 /* during async operation*/
722 register DATABASE db = db_handle; /* fast working copy */
724 /*----------------------------------------------------------*/
726 /* Execution begins here
728 /* Make sure parameters are correct, then allocate a
731 /*----------------------------------------------------------*/
733 GDB_CHECK_OP(op, "start_db_query ")
736 fprintf (gdb_log, "gdb: query_db: input rel is null \n");
737 OP_STATUS(op) = OP_CANCELLED;
742 fprintf (gdb_log, "gdb: start_db_query: supplied database is NULL\n");
743 OP_STATUS(op) = OP_CANCELLED;
747 GDB_CHECK_DB(db, "start_db_query")
749 if (DB_STATUS(db) != DB_OPEN) {
750 fprintf (gdb_log, "gdb: start_db_query: request to closed database ");
751 OP_STATUS(op) = OP_CANCELLED;
755 if (db->connection == NULL) {
756 fprintf (gdb_log,"gdb: start_db_query: connection severed, request cancelled\n");
757 OP_STATUS(op) = OP_CANCELLED;
761 if (connection_status(db->connection) != CON_UP ) {
762 fprintf (gdb_log,"gdb: start_db_query: problems maintaining connection ");
763 connection_perror(db->connection, "Reason for connection failure");
764 fprintf (gdb_log,"request cancelled \n");
765 OP_STATUS(op) = OP_CANCELLED;
769 if (query == NULL || *query == '\0') {
770 fprintf (gdb_log, "gdb: start_db_query: request string is null\n");
771 OP_STATUS(op) = OP_CANCELLED;
776 /*----------------------------------------------------------*/
778 /* Asynchronously send the query to the server
780 /*----------------------------------------------------------*/
783 * Allocate a structure to hold our state while we're gone
784 * waiting for this to complete.
787 arg = (struct dbq_data *)db_alloc(sizeof(struct dbq_data));
790 arg->send_query = create_operation();
793 * Send the query string to the server
795 (void) string_alloc(&(arg->s), strlen(query)+11);
796 (void) strcpy(STRING_DATA(arg->s), "retrieve ");
797 (void) strcat(STRING_DATA(arg->s), query);
798 MAX_STRING_SIZE(arg->s) = strlen (query) +11;
799 start_sending_object (arg->send_query, db->connection,
800 (char *)&(arg->s), STRING_T);
801 if (OP_STATUS(arg->send_query) == OP_CANCELLED) {
802 OP_STATUS(op) = OP_CANCELLED;
803 delete_operation(arg->send_query);
804 string_free(&(arg->s));
805 db_free((char *)arg, sizeof(struct dbq_data));
810 * Send the tuple descriptor to the server
813 arg->send_descriptor = create_operation();
814 arg->tpd = DESCRIPTOR_FROM_RELATION(arg->rel);
816 start_sending_object (arg->send_descriptor, db->connection,
817 (char *)&(arg->tpd), TUPLE_DESCRIPTOR_T);
818 if (OP_STATUS(arg->send_descriptor) == OP_CANCELLED) {
819 OP_STATUS(op) = OP_CANCELLED;
820 (void) cancel_operation(arg->send_query);/* this could be a bug, */
821 /* because we introduce */
822 /* indeterminism into */
823 /* the reply stream, probably */
824 /* should shutdown the whole */
826 delete_operation(arg->send_query);
827 delete_operation(arg->send_descriptor);
828 string_free(&(arg->s));
829 db_free((char *)arg, sizeof(struct dbq_data));
833 /*----------------------------------------------------------*/
835 /* Asynchronously receive the return code (note, we
836 /* really don't know whether the query/and the descriptor
837 /* have even been sent yet...doesn't really matter.)
839 /*----------------------------------------------------------*/
841 arg->get_retcode = create_operation();
842 start_receiving_object (arg->get_retcode, db->connection,
843 (char *)&(OP_RESULT(op)), INTEGER_T);
844 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
845 OP_STATUS(op) = OP_CANCELLED;
846 (void) cancel_operation(arg->send_query);/* this could be a bug, */
847 /* because we introduce */
848 /* indeterminism into */
849 /* the reply stream, probably */
850 /* should shutdown the whole */
852 (void) cancel_operation(arg->send_descriptor);
853 string_free(&(arg->s));
854 delete_operation(arg->send_query);
855 delete_operation(arg->send_descriptor);
856 delete_operation(arg->get_retcode);
857 db_free((char *)arg, sizeof(struct adb_data));
862 * We've successfully queued the receive of the return code.
863 * That's about all we have to do if things go well, but if the
864 * operation fails later, we have to be there to clean up. To
865 * get control back, we queue ourselves as a second operation
866 * so we can see how the first did, and so we can free up arg.
868 initialize_operation(op, g_idbq, (char *)arg, (int (*)())NULL);
869 (void) queue_operation(db->connection, CON_INPUT, op);
874 /*----------------------------------------------------------*/
878 /* Init routine for getting return code on performing a
879 /* bd query. If there was an error, then we are done except for
880 /* cleaning up all the dynamic memory we allocated.
881 /* If the return code was 0,then we must asynchronously
882 /* do the following iteratively until a no is received:
884 /* while (async_receive(yes/no) == yes) {
885 /* async receive new tuple
886 /* add it to the relation
889 /*----------------------------------------------------------*/
892 g_idbq(op, hcon, arg)
894 HALF_CONNECTION hcon;
895 struct dbq_data *arg;
899 /*----------------------------------------------------------*/
901 /* See how the three asynchronous operations went,and
902 /* clean up after them.
904 /*----------------------------------------------------------*/
907 * Figure out how the receipt went
909 rc1 = OP_STATUS(arg->send_query);
910 rc2 = OP_STATUS(arg->send_descriptor);
911 rc3 = OP_STATUS(arg->get_retcode);
914 * Release all transient data structures which were used in the
915 * preliminary operations.
917 delete_operation(arg->send_query);
918 delete_operation(arg->get_retcode);
919 string_free(&(arg->s));
921 * If we've failed for any reason, then mark ourselves complete and
924 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE|| rc3 != OP_COMPLETE
925 || OP_RESULT(op) != OP_SUCCESS) {
926 OP_STATUS(op) = rc3; /* we must have done */
927 /* about as well as */
930 db_free((char *)arg, sizeof(struct dbq_data));
931 return rc3; /* tell the dispatcher */
932 /* that we're either */
933 /* cancelled or complete */
936 /*----------------------------------------------------------*/
938 /* We've successfully received a return code of 0 from
939 /* Ingres, which means we are now going to begin the
942 /*----------------------------------------------------------*/
944 op->fcn.cont = g_cdbq; /* after the preempting */
945 /* receive completes, the */
946 /* dispatcher will call */
948 arg->state = YESNO; /* tell continuation routine */
949 /* that we're receiving */
951 arg->tup = NULL; /* so we won't try to clean */
953 arg->receive_yesno_or_data = create_operation();
955 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
957 (char *)&(arg->yesno),
962 /*----------------------------------------------------------*/
966 /* Continuation routine for receiving results of a query.
967 /* Tbis is called repeatedly each time either a yes/no or
968 /* a new tuple is received. It repeatedly preempts itself
969 /* to receive the next yes/no or tuple until a 'no'
970 /* is finally received.
972 /*----------------------------------------------------------*/
975 g_cdbq(op, hcon, arg)
977 HALF_CONNECTION hcon;
978 struct dbq_data *arg;
980 /*----------------------------------------------------------*/
982 /* See whether the preempting operation completed
983 /* successfully. If not, we just clean up and cancel
985 /*----------------------------------------------------------*/
987 if (OP_STATUS(arg->receive_yesno_or_data) != OP_COMPLETE) {
988 delete_operation(arg->receive_yesno_or_data);
989 if (arg->tup != NULL)
990 delete_tuple(arg->tup);
991 db_free((char *)arg, sizeof(struct dbq_data));
992 OP_STATUS(op) = OP_CANCELLED;
996 /*----------------------------------------------------------*/
998 /* Whatever it was, we received it cleanly. If it
999 /* was tuple data, then accept it and prepare to receive
1000 /* a yesno. If it was a yes, then prepare to receive
1001 /* the tuple data. If it was a NO, then we're all done.
1003 /* Note that g_cdbg will be recalled by the dispatcher
1004 /* after the preempting routines have completed.
1006 /*----------------------------------------------------------*/
1012 if (arg->state == TUPDATA) {
1013 ADD_TUPLE_TO_RELATION(arg->rel, arg->tup);
1014 arg->tup = NULL; /* so we won't try to */
1015 /* delete it in case of error*/
1016 reset_operation(arg->receive_yesno_or_data);
1018 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1020 (char *)&(arg->yesno),
1022 return OP_PREEMPTED;
1026 * We just received a yes or no. If it's a YES, prepare to
1027 * receive some more tuple data.
1029 if (arg->yesno == YES) {
1030 arg->tup = create_tuple(arg->tpd);
1031 reset_operation(arg->receive_yesno_or_data);
1032 arg->state = TUPDATA;
1033 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1037 return OP_PREEMPTED;
1040 * We just received a NO. Looks like we're all done cleanly.
1042 delete_operation(arg->receive_yesno_or_data);
1043 if (arg->tup != NULL)
1044 delete_tuple(arg->tup);
1045 db_free((char *)arg, sizeof(struct dbq_data));
1046 OP_STATUS(op) = OP_COMPLETE;
1051 /************************************************************************/
1053 /* db_query (db_query)
1055 /* Perform a relational query on the specified database.
1057 /* This just calls the asynchronous form of doing a query and
1058 /* waits for it to complete.
1061 /************************************************************************/
1064 db_query(db_handle, rel, query)
1069 register OPERATION op;
1070 register int status;
1071 register int result;
1074 * Create an operation and use it to asynchronously perform
1077 op = create_operation();
1078 (void) start_db_query(op, db_handle, rel, query);
1081 * Wait for it to complete, note whether the operation
1082 * completed at all, and if so, whether it returned a
1083 * successful result. Then reclaim the space used for the
1086 (void) complete_operation(op);
1087 status = OP_STATUS(op);
1088 result = OP_RESULT(op);
1090 delete_operation(op);
1093 * Tell the caller either that we were interrupted, or pass
1094 * on the actual result of accessing the database. If it
1095 * failed, then tear everything down after all.
1097 if (status==OP_COMPLETE)