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 /*----------------------------------------------------------*/
243 g_iadb(op, hcon, arg)
245 HALF_CONNECTION hcon;
246 struct adb_data *arg;
251 * Figure out how the receipt went
253 rc = OP_STATUS(arg->get_retcode);
256 * Release all transient data structures.
258 if (rc != OP_COMPLETE || op->result != DB_OPEN)
259 g_tear_down(arg->db);
261 DB_STATUS(arg->db) = DB_OPEN;
263 delete_operation(arg->get_retcode);
264 db_free((char *)arg, sizeof(struct adb_data));
269 /************************************************************************/
273 /* this is called by access_db and perf_db_op when a fatal error
274 /* is reached. It is an attempt to intelligently handle the error,
275 /* and tear down connections and data structures if necessary.
277 /* The current version simply tears down everything, perhaps later
278 /* versions should make provision for closing the db as necessary,
279 /* and/or other less drastic ways to handle the errors.
281 /************************************************************************/
284 g_tear_down (db_handle)
287 register DATABASE db = db_handle;
289 /*----------------------------------------------------------*/
291 /* If the db is opened, and the connexn is severed,
292 /* some error handling, closing of the db should be done
295 /* Also, at the server, perhaps a return code to indicate
296 /* that user tried to open non-existant db???
298 /*----------------------------------------------------------*/
305 (void) sever_connection (db->connection);
308 * Free up the separately allocated strings to which the
309 * database descriptor points
311 gdb_fstring(db->server);
312 gdb_fstring(db->name);
315 * Free the descriptor itself
317 db_free ((char *)db,sizeof(struct db_struct));
321 /************************************************************************/
325 /* Allocate and initialize a database descriptor structure.
327 /************************************************************************/
332 register DATABASE db;
334 db = (DATABASE)db_alloc (sizeof(struct db_struct));
336 db->connection = NULL;
339 DB_STATUS(db) = DB_CLOSED;
343 \f/************************************************************************/
345 /* access_db (access_db)
347 /* Does a start_accessing_db and waits for it to complete.
349 /************************************************************************/
352 access_db (db_ident, db_handle)
356 register OPERATION op;
363 * Create an operation and use it to asynchronously access
366 op = create_operation();
367 (void) start_accessing_db(op, db_ident, db_handle);
370 * Wait for it to complete, note whether the operation completed
371 * at all, and if so, whether it returned a successful result
372 * in accessing the database. Then reclaim the space used for
375 (void) complete_operation(op);
376 status = OP_STATUS(op);
377 result = OP_RESULT(op);
379 delete_operation(op);
382 * Tell the caller either that we were interrupted, or pass
383 * on the actual result of accessing the database. If it
384 * failed, then tear everything down after all.
386 if (status==OP_COMPLETE)
391 \f/************************************************************************/
393 /* start_performing_db_operation (start_performing_db_operation)
395 /* Asynchronously performs any operation except for a query
396 /* on the remote database.
398 /* The operation is encoded as a GDB string and sent to the server.
400 /* An integer return code is received back and returned to the caller.
402 /* Note that this operation executes on both the outbound and inbound
403 /* half connections. Since there is no explicit sync between the two
404 /* directions, operations like this pipeline freely from requestor
405 /* to server, but there is no way to cancel this operation once it
406 /* has started without severing the accompanying connection.
408 /************************************************************************/
413 DATABASE db; /* the database we're */
415 OPERATION send_request; /* used to send the string */
416 /* containing the db oper. */
417 /* to be performed */
418 OPERATION get_retcode; /* used to get back the */
419 /* response to our request */
420 STRING s; /* the operation string */
421 /* itself. This is sent. */
424 #define MIN_REQUEST_LEN 1 /*completely arbitrary */
429 start_performing_db_operation (op, db_handle,request)
434 /*----------------------------------------------------------*/
438 /*----------------------------------------------------------*/
440 register struct pdb_data *arg; /* holds our state */
441 /* during async operation*/
442 register DATABASE db = db_handle; /* fast working copy */
444 /*----------------------------------------------------------*/
446 /* Execution begins here
448 /* Make sure parameters are correct, then allocate a
451 /*----------------------------------------------------------*/
453 GDB_CHECK_OP(op, "start_performing_db_operation ")
455 fprintf (gdb_log, "gdb: start_performing_db_operation: supplied database is NULL\n");
456 OP_STATUS(op) = OP_CANCELLED;
460 GDB_CHECK_DB(db, "start_performing_db_operation")
462 if (DB_STATUS(db) != DB_OPEN) {
463 fprintf (gdb_log, "gdb: start_performing_db_operation: request to closed database ");
464 OP_STATUS(op) = OP_CANCELLED;
468 if (db->connection == NULL) {
470 "gdb: start_performing_db_operation: connection severed, request cancelled\n");
471 OP_STATUS(op) = OP_CANCELLED;
475 if (connection_status(db->connection) != CON_UP ) {
476 fprintf (gdb_log, "gdb: start_performing_db_operation: problems maintaining connection ");
477 connection_perror(db->connection, "Reason for connection failure");
478 fprintf (gdb_log, "request cancelled \n");
479 OP_STATUS(op) = OP_CANCELLED;
483 if ((request == NULL) || (strlen (request)<MIN_REQUEST_LEN)) {
484 fprintf (gdb_log, "gdb: start_performing_db_operation: request either missing or too short\n");
485 OP_STATUS(op) = OP_CANCELLED;
487 /*should we disallow empty requests? */
491 /*----------------------------------------------------------*/
493 /* Asynchronously send the request to the server
495 /*----------------------------------------------------------*/
498 * Allocate a structure to hold our state while we're gone
499 * waiting for this to complete.
502 arg = (struct pdb_data *)db_alloc(sizeof(struct pdb_data));
504 arg->send_request = create_operation();
507 * Send the request string to the server
509 STRING_DATA(arg->s) = request;
510 MAX_STRING_SIZE(arg->s) = strlen (request) +1;
511 start_sending_object (arg->send_request, db->connection,
512 (char *)&(arg->s), STRING_T);
513 if (OP_STATUS(arg->send_request) == OP_CANCELLED) {
514 OP_STATUS(op) = OP_CANCELLED;
515 delete_operation(arg->send_request);
516 db_free((char *)arg, sizeof(struct pdb_data));
520 /*----------------------------------------------------------*/
522 /* Asynchronously receive the return code (note, we
523 /* really don't know whether the request has even been
524 /* sent yet...doesn't really matter.)
526 /*----------------------------------------------------------*/
528 arg->get_retcode = create_operation();
530 * This must come here as it sets op_result
532 initialize_operation(op, g_ipdb, (char *)arg, (int (*)())NULL);
534 start_receiving_object (arg->get_retcode, db->connection,
535 (char *)&(OP_RESULT(op)), INTEGER_T);
536 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
537 OP_STATUS(op) = OP_CANCELLED;
538 (void) cancel_operation(arg->send_request);/* this could be a bug, */
539 /* because we introduce */
540 /* indeterminism into */
541 /* the reply stream, probably */
542 /* should shutdown the whole */
544 delete_operation(arg->send_request);
545 delete_operation(arg->get_retcode);
546 db_free((char *)arg, sizeof(struct adb_data));
551 * We've successfully queued the receive of the return code.
552 * That's about all we have to do if things go well, but if the
553 * operation fails later, we have to be there to clean up. To
554 * get control back, we queue ourselves as a second operation
555 * so we can see how the first did, and so we can free up arg.
557 (void) queue_operation(db->connection, CON_INPUT, op);
561 /*----------------------------------------------------------*/
565 /* Init routine for getting return code on performin a db
566 /* operation. If all went well, (or even if it didn't),
567 /* then we are done. All we have to do is clean up the
568 /* stuff we've allocated.
570 /*----------------------------------------------------------*/
574 g_ipdb(op, hcon, arg)
576 HALF_CONNECTION hcon;
577 struct pdb_data *arg;
582 * Figure out how the receipt went
584 rc1 = OP_STATUS(arg->send_request);
585 rc2 = OP_STATUS(arg->get_retcode);
588 * Release all transient data structures.
590 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE)
591 g_tear_down(arg->db);
593 delete_operation(arg->send_request);
594 delete_operation(arg->get_retcode);
595 db_free((char *)arg, sizeof(struct pdb_data));
600 /************************************************************************/
602 /* perform_db_operation (perform_db_operation)
604 /* Do a database operation synchronously. This just calls
605 /* the async routine and waits for it to complete.
607 /************************************************************************/
609 perform_db_operation (db_handle,request)
613 register OPERATION op;
618 * Create an operation and use it to asynchronously perform
621 op = create_operation();
622 (void) start_performing_db_operation(op, db_handle, request);
625 * Wait for it to complete, note whether the operation
626 * completed at all, and if so, whether it returned a
627 * successful result. Then reclaim the space used for the
630 (void) complete_operation(op);
631 status = OP_STATUS(op);
632 result = OP_RESULT(op);
634 delete_operation(op);
637 * Tell the caller either that we were interrupted, or pass
638 * on the actual result of accessing the database. If it
639 * failed, then tear everything down after all.
641 if (status==OP_COMPLETE)
646 \f/************************************************************************/
648 /* start_db_query (start_db_query)
650 /* Asynchronously performs a database query on the remote
653 /* The operation is encoded as a GDB string and sent to the server.
655 /* An integer return code is received back and returned to the caller.
657 /* If the return code indicates success, then we go into a loop
658 /* receiving the retrieved data. Each returned tuple is preceeded by
659 /* a so-called yes/no flag, which indicates whether tuple data is really
660 /* to follow. Last tuple is followed by a NO flag.
662 /* Note that this operation executes on both the outbound and inbound
663 /* half connections. Since there is no explicit sync between the two
664 /* directions, operations like this pipeline freely from requestor
665 /* to server, but there is no way to cancel this operation once it
666 /* has started without severing the accompanying connection.
668 /************************************************************************/
675 * Following may be used throughout processing
677 DATABASE db; /* the database we're */
680 TUPLE_DESCRIPTOR tpd;
682 * used primarily in first phase for sending query and getting
685 OPERATION send_query; /* used to send the string */
686 /* containing the query */
687 /* to be performed */
688 OPERATION send_descriptor; /* used to send the tuple */
689 /* descriptor to the server */
690 OPERATION get_retcode; /* used to get back the */
691 /* response to our request */
692 STRING s; /* the operation string */
693 /* itself. This is sent. */
695 * Following are used during later phase to receive the tuples
697 int state; /* are we expecting a yes/no */
698 /* or a tuple next? */
701 int yesno; /* an indicator of whether */
702 /* another tuple is to follow*/
704 OPERATION receive_yesno_or_data;
705 TUPLE tup; /* a place to put */
710 start_db_query (op, db_handle,rel, query)
716 /*----------------------------------------------------------*/
720 /*----------------------------------------------------------*/
722 register struct dbq_data *arg; /* holds our state */
723 /* during async operation*/
724 register DATABASE db = db_handle; /* fast working copy */
726 /*----------------------------------------------------------*/
728 /* Execution begins here
730 /* Make sure parameters are correct, then allocate a
733 /*----------------------------------------------------------*/
735 GDB_CHECK_OP(op, "start_db_query ")
738 fprintf (gdb_log, "gdb: query_db: input rel is null \n");
739 OP_STATUS(op) = OP_CANCELLED;
744 fprintf (gdb_log, "gdb: start_db_query: supplied database is NULL\n");
745 OP_STATUS(op) = OP_CANCELLED;
749 GDB_CHECK_DB(db, "start_db_query")
751 if (DB_STATUS(db) != DB_OPEN) {
752 fprintf (gdb_log, "gdb: start_db_query: request to closed database ");
753 OP_STATUS(op) = OP_CANCELLED;
757 if (db->connection == NULL) {
758 fprintf (gdb_log,"gdb: start_db_query: connection severed, request cancelled\n");
759 OP_STATUS(op) = OP_CANCELLED;
763 if (connection_status(db->connection) != CON_UP ) {
764 fprintf (gdb_log,"gdb: start_db_query: problems maintaining connection ");
765 connection_perror(db->connection, "Reason for connection failure");
766 fprintf (gdb_log,"request cancelled \n");
767 OP_STATUS(op) = OP_CANCELLED;
771 if (query == NULL || *query == '\0') {
772 fprintf (gdb_log, "gdb: start_db_query: request string is null\n");
773 OP_STATUS(op) = OP_CANCELLED;
778 /*----------------------------------------------------------*/
780 /* Asynchronously send the query to the server
782 /*----------------------------------------------------------*/
785 * Allocate a structure to hold our state while we're gone
786 * waiting for this to complete.
789 arg = (struct dbq_data *)db_alloc(sizeof(struct dbq_data));
792 arg->send_query = create_operation();
795 * Send the query string to the server
797 (void) string_alloc(&(arg->s), strlen(query)+11);
798 (void) strcpy(STRING_DATA(arg->s), "retrieve ");
799 (void) strcat(STRING_DATA(arg->s), query);
800 MAX_STRING_SIZE(arg->s) = strlen (query) +11;
801 start_sending_object (arg->send_query, db->connection,
802 (char *)&(arg->s), STRING_T);
803 if (OP_STATUS(arg->send_query) == OP_CANCELLED) {
804 OP_STATUS(op) = OP_CANCELLED;
805 delete_operation(arg->send_query);
806 string_free(&(arg->s));
807 db_free((char *)arg, sizeof(struct dbq_data));
812 * Send the tuple descriptor to the server
815 arg->send_descriptor = create_operation();
816 arg->tpd = DESCRIPTOR_FROM_RELATION(arg->rel);
818 start_sending_object (arg->send_descriptor, db->connection,
819 (char *)&(arg->tpd), TUPLE_DESCRIPTOR_T);
820 if (OP_STATUS(arg->send_descriptor) == OP_CANCELLED) {
821 OP_STATUS(op) = OP_CANCELLED;
822 (void) cancel_operation(arg->send_query);/* this could be a bug, */
823 /* because we introduce */
824 /* indeterminism into */
825 /* the reply stream, probably */
826 /* should shutdown the whole */
828 delete_operation(arg->send_query);
829 delete_operation(arg->send_descriptor);
830 string_free(&(arg->s));
831 db_free((char *)arg, sizeof(struct dbq_data));
835 /*----------------------------------------------------------*/
837 /* Asynchronously receive the return code (note, we
838 /* really don't know whether the query/and the descriptor
839 /* have even been sent yet...doesn't really matter.)
841 /*----------------------------------------------------------*/
843 arg->get_retcode = create_operation();
844 start_receiving_object (arg->get_retcode, db->connection,
845 (char *)&(OP_RESULT(op)), INTEGER_T);
846 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
847 OP_STATUS(op) = OP_CANCELLED;
848 (void) cancel_operation(arg->send_query);/* this could be a bug, */
849 /* because we introduce */
850 /* indeterminism into */
851 /* the reply stream, probably */
852 /* should shutdown the whole */
854 (void) cancel_operation(arg->send_descriptor);
855 string_free(&(arg->s));
856 delete_operation(arg->send_query);
857 delete_operation(arg->send_descriptor);
858 delete_operation(arg->get_retcode);
859 db_free((char *)arg, sizeof(struct adb_data));
864 * We've successfully queued the receive of the return code.
865 * That's about all we have to do if things go well, but if the
866 * operation fails later, we have to be there to clean up. To
867 * get control back, we queue ourselves as a second operation
868 * so we can see how the first did, and so we can free up arg.
870 initialize_operation(op, g_idbq, (char *)arg, (int (*)())NULL);
871 (void) queue_operation(db->connection, CON_INPUT, op);
876 /*----------------------------------------------------------*/
880 /* Init routine for getting return code on performing a
881 /* bd query. If there was an error, then we are done except for
882 /* cleaning up all the dynamic memory we allocated.
883 /* If the return code was 0,then we must asynchronously
884 /* do the following iteratively until a no is received:
886 /* while (async_receive(yes/no) == yes) {
887 /* async receive new tuple
888 /* add it to the relation
891 /*----------------------------------------------------------*/
895 g_idbq(op, hcon, arg)
897 HALF_CONNECTION hcon;
898 struct dbq_data *arg;
902 /*----------------------------------------------------------*/
904 /* See how the three asynchronous operations went,and
905 /* clean up after them.
907 /*----------------------------------------------------------*/
910 * Figure out how the receipt went
912 rc1 = OP_STATUS(arg->send_query);
913 rc2 = OP_STATUS(arg->send_descriptor);
914 rc3 = OP_STATUS(arg->get_retcode);
917 * Release all transient data structures which were used in the
918 * preliminary operations.
920 delete_operation(arg->send_query);
921 delete_operation(arg->get_retcode);
922 string_free(&(arg->s));
924 * If we've failed for any reason, then mark ourselves complete and
927 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE|| rc3 != OP_COMPLETE
928 || OP_RESULT(op) != OP_SUCCESS) {
929 OP_STATUS(op) = rc3; /* we must have done */
930 /* about as well as */
933 db_free((char *)arg, sizeof(struct dbq_data));
934 return rc3; /* tell the dispatcher */
935 /* that we're either */
936 /* cancelled or complete */
939 /*----------------------------------------------------------*/
941 /* We've successfully received a return code of 0 from
942 /* Ingres, which means we are now going to begin the
945 /*----------------------------------------------------------*/
947 op->fcn.cont = g_cdbq; /* after the preempting */
948 /* receive completes, the */
949 /* dispatcher will call */
951 arg->state = YESNO; /* tell continuation routine */
952 /* that we're receiving */
954 arg->tup = NULL; /* so we won't try to clean */
956 arg->receive_yesno_or_data = create_operation();
958 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
960 (char *)&(arg->yesno),
965 /*----------------------------------------------------------*/
969 /* Continuation routine for receiving results of a query.
970 /* Tbis is called repeatedly each time either a yes/no or
971 /* a new tuple is received. It repeatedly preempts itself
972 /* to receive the next yes/no or tuple until a 'no'
973 /* is finally received.
975 /*----------------------------------------------------------*/
979 g_cdbq(op, hcon, arg)
981 HALF_CONNECTION hcon;
982 struct dbq_data *arg;
984 /*----------------------------------------------------------*/
986 /* See whether the preempting operation completed
987 /* successfully. If not, we just clean up and cancel
989 /*----------------------------------------------------------*/
991 if (OP_STATUS(arg->receive_yesno_or_data) != OP_COMPLETE) {
992 delete_operation(arg->receive_yesno_or_data);
993 if (arg->tup != NULL)
994 delete_tuple(arg->tup);
995 db_free((char *)arg, sizeof(struct dbq_data));
996 OP_STATUS(op) = OP_CANCELLED;
1000 /*----------------------------------------------------------*/
1002 /* Whatever it was, we received it cleanly. If it
1003 /* was tuple data, then accept it and prepare to receive
1004 /* a yesno. If it was a yes, then prepare to receive
1005 /* the tuple data. If it was a NO, then we're all done.
1007 /* Note that g_cdbg will be recalled by the dispatcher
1008 /* after the preempting routines have completed.
1010 /*----------------------------------------------------------*/
1016 if (arg->state == TUPDATA) {
1017 ADD_TUPLE_TO_RELATION(arg->rel, arg->tup);
1018 arg->tup = NULL; /* so we won't try to */
1019 /* delete it in case of error*/
1020 reset_operation(arg->receive_yesno_or_data);
1022 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1024 (char *)&(arg->yesno),
1026 return OP_PREEMPTED;
1030 * We just received a yes or no. If it's a YES, prepare to
1031 * receive some more tuple data.
1033 if (arg->yesno == YES) {
1034 arg->tup = create_tuple(arg->tpd);
1035 reset_operation(arg->receive_yesno_or_data);
1036 arg->state = TUPDATA;
1037 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1041 return OP_PREEMPTED;
1044 * We just received a NO. Looks like we're all done cleanly.
1046 delete_operation(arg->receive_yesno_or_data);
1047 if (arg->tup != NULL)
1048 delete_tuple(arg->tup);
1049 db_free((char *)arg, sizeof(struct dbq_data));
1050 OP_STATUS(op) = OP_COMPLETE;
1055 /************************************************************************/
1057 /* db_query (db_query)
1059 /* Perform a relational query on the specified database.
1061 /* This just calls the asynchronous form of doing a query and
1062 /* waits for it to complete.
1065 /************************************************************************/
1068 db_query(db_handle, rel, query)
1073 register OPERATION op;
1074 register int status;
1075 register int result;
1078 * Create an operation and use it to asynchronously perform
1081 op = create_operation();
1082 (void) start_db_query(op, db_handle, rel, query);
1085 * Wait for it to complete, note whether the operation
1086 * completed at all, and if so, whether it returned a
1087 * successful result. Then reclaim the space used for the
1090 (void) complete_operation(op);
1091 status = OP_STATUS(op);
1092 result = OP_RESULT(op);
1094 delete_operation(op);
1097 * Tell the caller either that we were interrupted, or pass
1098 * on the actual result of accessing the database. If it
1099 * failed, then tear everything down after all.
1101 if (status==OP_COMPLETE)