7 static char *rcsid_gdb_db_c = "$Header$";
10 /************************************************************************/
14 /* Authors: Susan Ryan and Noah Mendelsohn
16 /* Copyright: 1986 MIT Project Athena
18 /************************************************************************/
26 \f/************************************************************************/
28 /* start_accessing_db (start_accessing_db)
30 /* 1) Creates a new db structure to describe the database.
32 /* 2) Parses the supplied db_ident into a server and a db name
34 /* 3) Opens a connection to the server, sending the name of the
35 /* database as an argument
37 /* 4) Asynchronously receives a return code from the server
38 /* to indicate whether the database could be accessed
40 /* 5) If successful, the handle on the new structure is placed into
41 /* the variable supplied by the caller. Otherwise, the structure
42 /* is de_allocated and failure status is returned to the caller.
44 /* Note: this code was adapted from an earlier synchronous
45 /* implementation and there may yet be some loose ends.
47 /************************************************************************/
49 #define MIN_NAME_LEN 1 /*completely arbitrary */
50 #define FAILURE NULL /*until we decide what it should really be */
51 /*note if fails returns NULL for the db_handle value*/
59 OPERATION get_retcode;
63 start_accessing_db (op, db_ident, db_handle)
68 /*----------------------------------------------------------*/
72 /*----------------------------------------------------------*/
74 register DATABASE db; /* the newly created */
76 register struct adb_data *arg; /* holds our state */
77 /* during async operation*/
78 char *ident, *server, *temp_server; /* loop variables for */
80 char *db_name, *temp_name;
81 int count; /* counts chars during parse */
83 CONNECTION connexn; /* the connection to the */
86 /*----------------------------------------------------------*/
88 /* Execution begins here
90 /* Make sure parameters are correct, then allocate a
93 /*----------------------------------------------------------*/
102 GDB_CHECK_OP(op, "start_accessing_db")
104 if ((db_ident == NULL)|| (strlen(db_ident)<MIN_NAME_LEN)) {
105 fprintf (gdb_log,"access_db: correct syntax is db_name@server \n");
107 return (OP_CANCELLED);
113 /*----------------------------------------------------------*/
115 /* Loop to count lengths of server and database names
116 /* Allocate space for each and copy them both
118 /*----------------------------------------------------------*/
122 while (*ident++ != '@') {
126 db_name = db_alloc (count); /* space for db_name */
127 /* note: this is cleaned */
128 /* up by the tear down rtn*/
131 while (*ident++ != '\0')
134 count += strlen(GDB_DB_SERVICE)+1; /* leave room for :service */
135 server = db_alloc (count); /* space for host:service */
136 /* note: this is cleaned */
137 /* up by the tear down rtn*/
140 * copy head of db_ident string from db_name@server to db_name
143 while (*db_ident != '@') {
144 *temp_name = *db_ident;
153 * Set up server host name
155 temp_server = server;
156 db_ident++; /* skip the '@' */
157 while (*db_ident!= '\0') {
158 *temp_server = *db_ident;
164 * Append :service id to the server host name
166 *temp_server++ = ':';
168 (void) strcat(server, GDB_DB_SERVICE);
173 /*----------------------------------------------------------*/
175 /* Create a connection to the server.
177 /*----------------------------------------------------------*/
179 connexn = start_server_connection (server, db_name);
181 if (connexn==NULL || connection_status(connexn) != CON_UP) {
182 connection_perror(connexn, "Error starting server connection");
183 fprintf (gdb_log, "gdb:access_db: couldn't connect to server %s \n", server);
184 g_tear_down(*db_handle);
185 OP_STATUS(op) = OP_CANCELLED;
186 return (OP_CANCELLED);
189 db->connection = connexn;
192 * Start asynchronously receiving the return code from the
193 * data base server. May take awhile, since ingres is so
197 arg = (struct adb_data *)db_alloc(sizeof(struct adb_data));
198 arg->get_retcode = create_operation();
201 start_receiving_object (arg->get_retcode, connexn,
202 (char *)&(OP_RESULT(op)), INTEGER_T);
206 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
207 g_tear_down (*db_handle);
208 OP_STATUS(op) = OP_CANCELLED;
209 delete_operation(arg->get_retcode);
210 db_free((char *)arg, sizeof(struct adb_data));
215 * We've successfully queued the receive of the return code.
216 * That's about all we have to do if things go well, but if the
217 * operation fails later, we have to be there to clean up. To
218 * get control back, we queue ourselves as a second operation
219 * so we can see how the first did, and so we can free up arg.
221 initialize_operation(op, g_iadb, (char *)arg, (int (*)())NULL);
222 (void) queue_operation(connexn, CON_INPUT, op);
227 /*----------------------------------------------------------*/
231 /* Init routine for getting return code on accessing a
232 /* database. If all went well, (or even if it didn't), then
233 /* we are done. All we have to do is clean up the stuff we've
236 /*----------------------------------------------------------*/
239 g_iadb(op, hcon, arg)
241 HALF_CONNECTION hcon;
242 struct adb_data *arg;
247 * Figure out how the receipt went
249 rc = OP_STATUS(arg->get_retcode);
252 * Release all transient data structures.
254 if (rc != OP_COMPLETE || op->result != DB_OPEN)
255 g_tear_down(arg->db);
257 DB_STATUS(arg->db) = DB_OPEN;
259 delete_operation(arg->get_retcode);
260 db_free((char *)arg, sizeof(struct adb_data));
265 /************************************************************************/
269 /* this is called by access_db and perf_db_op when a fatal error
270 /* is reached. It is an attempt to intelligently handle the error,
271 /* and tear down connections and data structures if necessary.
273 /* The current version simply tears down everything, perhaps later
274 /* versions should make provision for closing the db as necessary,
275 /* and/or other less drastic ways to handle the errors.
277 /************************************************************************/
280 g_tear_down (db_handle)
283 register DATABASE db = db_handle;
285 /*----------------------------------------------------------*/
287 /* If the db is opened, and the connexn is severed,
288 /* some error handling, closing of the db should be done
291 /* Also, at the server, perhaps a return code to indicate
292 /* that user tried to open non-existant db???
294 /*----------------------------------------------------------*/
301 (void) sever_connection (db->connection);
304 * Free up the separately allocated strings to which the
305 * database descriptor points
307 gdb_fstring(db->server);
308 gdb_fstring(db->name);
311 * Free the descriptor itself
313 db_free ((char *)db,sizeof(struct db_struct));
317 /************************************************************************/
321 /* Allocate and initialize a database descriptor structure.
323 /************************************************************************/
328 register DATABASE db;
330 db = (DATABASE)db_alloc (sizeof(struct db_struct));
332 db->connection = NULL;
335 DB_STATUS(db) = DB_CLOSED;
339 \f/************************************************************************/
341 /* access_db (access_db)
343 /* Does a start_accessing_db and waits for it to complete.
345 /************************************************************************/
348 access_db (db_ident, db_handle)
352 register OPERATION op;
359 * Create an operation and use it to asynchronously access
362 op = create_operation();
363 (void) start_accessing_db(op, db_ident, db_handle);
366 * Wait for it to complete, note whether the operation completed
367 * at all, and if so, whether it returned a successful result
368 * in accessing the database. Then reclaim the space used for
371 (void) complete_operation(op);
372 status = OP_STATUS(op);
373 result = OP_RESULT(op);
375 delete_operation(op);
378 * Tell the caller either that we were interrupted, or pass
379 * on the actual result of accessing the database. If it
380 * failed, then tear everything down after all.
382 if (status==OP_COMPLETE)
387 \f/************************************************************************/
389 /* start_performing_db_operation (start_performing_db_operation)
391 /* Asynchronously performs any operation except for a query
392 /* on the remote database.
394 /* The operation is encoded as a GDB string and sent to the server.
396 /* An integer return code is received back and returned to the caller.
398 /* Note that this operation executes on both the outbound and inbound
399 /* half connections. Since there is no explicit sync between the two
400 /* directions, operations like this pipeline freely from requestor
401 /* to server, but there is no way to cancel this operation once it
402 /* has started without severing the accompanying connection.
404 /************************************************************************/
409 DATABASE db; /* the database we're */
411 OPERATION send_request; /* used to send the string */
412 /* containing the db oper. */
413 /* to be performed */
414 OPERATION get_retcode; /* used to get back the */
415 /* response to our request */
416 STRING s; /* the operation string */
417 /* itself. This is sent. */
420 #define MIN_REQUEST_LEN 1 /*completely arbitrary */
425 start_performing_db_operation (op, db_handle,request)
430 /*----------------------------------------------------------*/
434 /*----------------------------------------------------------*/
436 register struct pdb_data *arg; /* holds our state */
437 /* during async operation*/
438 register DATABASE db = db_handle; /* fast working copy */
440 /*----------------------------------------------------------*/
442 /* Execution begins here
444 /* Make sure parameters are correct, then allocate a
447 /*----------------------------------------------------------*/
449 GDB_CHECK_OP(op, "start_performing_db_operation ")
451 fprintf (gdb_log, "gdb: start_performing_db_operation: supplied database is NULL\n");
452 OP_STATUS(op) = OP_CANCELLED;
456 GDB_CHECK_DB(db, "start_performing_db_operation")
458 if (DB_STATUS(db) != DB_OPEN) {
459 fprintf (gdb_log, "gdb: start_performing_db_operation: request to closed database ");
460 OP_STATUS(op) = OP_CANCELLED;
464 if (db->connection == NULL) {
466 "gdb: start_performing_db_operation: connection severed, request cancelled\n");
467 OP_STATUS(op) = OP_CANCELLED;
471 if (connection_status(db->connection) != CON_UP ) {
472 fprintf (gdb_log, "gdb: start_performing_db_operation: problems maintaining connection ");
473 connection_perror(db->connection, "Reason for connection failure");
474 fprintf (gdb_log, "request cancelled \n");
475 OP_STATUS(op) = OP_CANCELLED;
479 if ((request == NULL) || (strlen (request)<MIN_REQUEST_LEN)) {
480 fprintf (gdb_log, "gdb: start_performing_db_operation: request either missing or too short\n");
481 OP_STATUS(op) = OP_CANCELLED;
483 /*should we disallow empty requests? */
487 /*----------------------------------------------------------*/
489 /* Asynchronously send the request to the server
491 /*----------------------------------------------------------*/
494 * Allocate a structure to hold our state while we're gone
495 * waiting for this to complete.
498 arg = (struct pdb_data *)db_alloc(sizeof(struct pdb_data));
500 arg->send_request = create_operation();
503 * Send the request string to the server
505 STRING_DATA(arg->s) = request;
506 MAX_STRING_SIZE(arg->s) = strlen (request) +1;
507 start_sending_object (arg->send_request, db->connection,
508 (char *)&(arg->s), STRING_T);
509 if (OP_STATUS(arg->send_request) == OP_CANCELLED) {
510 OP_STATUS(op) = OP_CANCELLED;
511 delete_operation(arg->send_request);
512 db_free((char *)arg, sizeof(struct pdb_data));
516 /*----------------------------------------------------------*/
518 /* Asynchronously receive the return code (note, we
519 /* really don't know whether the request has even been
520 /* sent yet...doesn't really matter.)
522 /*----------------------------------------------------------*/
524 arg->get_retcode = create_operation();
526 * This must come here as it sets op_result
528 initialize_operation(op, g_ipdb, (char *)arg, (int (*)())NULL);
530 start_receiving_object (arg->get_retcode, db->connection,
531 (char *)&(OP_RESULT(op)), INTEGER_T);
532 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
533 OP_STATUS(op) = OP_CANCELLED;
534 (void) cancel_operation(arg->send_request);/* this could be a bug, */
535 /* because we introduce */
536 /* indeterminism into */
537 /* the reply stream, probably */
538 /* should shutdown the whole */
540 delete_operation(arg->send_request);
541 delete_operation(arg->get_retcode);
542 db_free((char *)arg, sizeof(struct adb_data));
547 * We've successfully queued the receive of the return code.
548 * That's about all we have to do if things go well, but if the
549 * operation fails later, we have to be there to clean up. To
550 * get control back, we queue ourselves as a second operation
551 * so we can see how the first did, and so we can free up arg.
553 (void) queue_operation(db->connection, CON_INPUT, op);
557 /*----------------------------------------------------------*/
561 /* Init routine for getting return code on performin a db
562 /* operation. If all went well, (or even if it didn't),
563 /* then we are done. All we have to do is clean up the
564 /* stuff we've allocated.
566 /*----------------------------------------------------------*/
569 g_ipdb(op, hcon, arg)
571 HALF_CONNECTION hcon;
572 struct pdb_data *arg;
577 * Figure out how the receipt went
579 rc1 = OP_STATUS(arg->send_request);
580 rc2 = OP_STATUS(arg->get_retcode);
583 * Release all transient data structures.
585 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE)
586 g_tear_down(arg->db);
588 delete_operation(arg->send_request);
589 delete_operation(arg->get_retcode);
590 db_free((char *)arg, sizeof(struct pdb_data));
595 /************************************************************************/
597 /* perform_db_operation (perform_db_operation)
599 /* Do a database operation synchronously. This just calls
600 /* the async routine and waits for it to complete.
602 /************************************************************************/
604 perform_db_operation (db_handle,request)
608 register OPERATION op;
613 * Create an operation and use it to asynchronously perform
616 op = create_operation();
617 (void) start_performing_db_operation(op, db_handle, request);
620 * Wait for it to complete, note whether the operation
621 * completed at all, and if so, whether it returned a
622 * successful result. Then reclaim the space used for the
625 (void) complete_operation(op);
626 status = OP_STATUS(op);
627 result = OP_RESULT(op);
629 delete_operation(op);
632 * Tell the caller either that we were interrupted, or pass
633 * on the actual result of accessing the database. If it
634 * failed, then tear everything down after all.
636 if (status==OP_COMPLETE)
641 \f/************************************************************************/
643 /* start_db_query (start_db_query)
645 /* Asynchronously performs a database query on the remote
648 /* The operation is encoded as a GDB string and sent to the server.
650 /* An integer return code is received back and returned to the caller.
652 /* If the return code indicates success, then we go into a loop
653 /* receiving the retrieved data. Each returned tuple is preceeded by
654 /* a so-called yes/no flag, which indicates whether tuple data is really
655 /* to follow. Last tuple is followed by a NO flag.
657 /* Note that this operation executes on both the outbound and inbound
658 /* half connections. Since there is no explicit sync between the two
659 /* directions, operations like this pipeline freely from requestor
660 /* to server, but there is no way to cancel this operation once it
661 /* has started without severing the accompanying connection.
663 /************************************************************************/
670 * Following may be used throughout processing
672 DATABASE db; /* the database we're */
675 TUPLE_DESCRIPTOR tpd;
677 * used primarily in first phase for sending query and getting
680 OPERATION send_query; /* used to send the string */
681 /* containing the query */
682 /* to be performed */
683 OPERATION send_descriptor; /* used to send the tuple */
684 /* descriptor to the server */
685 OPERATION get_retcode; /* used to get back the */
686 /* response to our request */
687 STRING s; /* the operation string */
688 /* itself. This is sent. */
690 * Following are used during later phase to receive the tuples
692 int state; /* are we expecting a yes/no */
693 /* or a tuple next? */
696 int yesno; /* an indicator of whether */
697 /* another tuple is to follow*/
699 OPERATION receive_yesno_or_data;
700 TUPLE tup; /* a place to put */
705 start_db_query (op, db_handle,rel, query)
711 /*----------------------------------------------------------*/
715 /*----------------------------------------------------------*/
717 register struct dbq_data *arg; /* holds our state */
718 /* during async operation*/
719 register DATABASE db = db_handle; /* fast working copy */
721 /*----------------------------------------------------------*/
723 /* Execution begins here
725 /* Make sure parameters are correct, then allocate a
728 /*----------------------------------------------------------*/
730 GDB_CHECK_OP(op, "start_db_query ")
733 fprintf (gdb_log, "gdb: query_db: input rel is null \n");
734 OP_STATUS(op) = OP_CANCELLED;
739 fprintf (gdb_log, "gdb: start_db_query: supplied database is NULL\n");
740 OP_STATUS(op) = OP_CANCELLED;
744 GDB_CHECK_DB(db, "start_db_query")
746 if (DB_STATUS(db) != DB_OPEN) {
747 fprintf (gdb_log, "gdb: start_db_query: request to closed database ");
748 OP_STATUS(op) = OP_CANCELLED;
752 if (db->connection == NULL) {
753 fprintf (gdb_log,"gdb: start_db_query: connection severed, request cancelled\n");
754 OP_STATUS(op) = OP_CANCELLED;
758 if (connection_status(db->connection) != CON_UP ) {
759 fprintf (gdb_log,"gdb: start_db_query: problems maintaining connection ");
760 connection_perror(db->connection, "Reason for connection failure");
761 fprintf (gdb_log,"request cancelled \n");
762 OP_STATUS(op) = OP_CANCELLED;
766 if (query == NULL || *query == '\0') {
767 fprintf (gdb_log, "gdb: start_db_query: request string is null\n");
768 OP_STATUS(op) = OP_CANCELLED;
773 /*----------------------------------------------------------*/
775 /* Asynchronously send the query to the server
777 /*----------------------------------------------------------*/
780 * Allocate a structure to hold our state while we're gone
781 * waiting for this to complete.
784 arg = (struct dbq_data *)db_alloc(sizeof(struct dbq_data));
787 arg->send_query = create_operation();
790 * Send the query string to the server
792 (void) string_alloc(&(arg->s), strlen(query)+11);
793 (void) strcpy(STRING_DATA(arg->s), "retrieve ");
794 (void) strcat(STRING_DATA(arg->s), query);
795 MAX_STRING_SIZE(arg->s) = strlen (query) +11;
796 start_sending_object (arg->send_query, db->connection,
797 (char *)&(arg->s), STRING_T);
798 if (OP_STATUS(arg->send_query) == OP_CANCELLED) {
799 OP_STATUS(op) = OP_CANCELLED;
800 delete_operation(arg->send_query);
801 string_free(&(arg->s));
802 db_free((char *)arg, sizeof(struct dbq_data));
807 * Send the tuple descriptor to the server
810 arg->send_descriptor = create_operation();
811 arg->tpd = DESCRIPTOR_FROM_RELATION(arg->rel);
813 start_sending_object (arg->send_descriptor, db->connection,
814 (char *)&(arg->tpd), TUPLE_DESCRIPTOR_T);
815 if (OP_STATUS(arg->send_descriptor) == OP_CANCELLED) {
816 OP_STATUS(op) = OP_CANCELLED;
817 (void) cancel_operation(arg->send_query);/* this could be a bug, */
818 /* because we introduce */
819 /* indeterminism into */
820 /* the reply stream, probably */
821 /* should shutdown the whole */
823 delete_operation(arg->send_query);
824 delete_operation(arg->send_descriptor);
825 string_free(&(arg->s));
826 db_free((char *)arg, sizeof(struct dbq_data));
830 /*----------------------------------------------------------*/
832 /* Asynchronously receive the return code (note, we
833 /* really don't know whether the query/and the descriptor
834 /* have even been sent yet...doesn't really matter.)
836 /*----------------------------------------------------------*/
838 arg->get_retcode = create_operation();
839 start_receiving_object (arg->get_retcode, db->connection,
840 (char *)&(OP_RESULT(op)), INTEGER_T);
841 if (OP_STATUS(arg->get_retcode) == OP_CANCELLED) {
842 OP_STATUS(op) = OP_CANCELLED;
843 (void) cancel_operation(arg->send_query);/* this could be a bug, */
844 /* because we introduce */
845 /* indeterminism into */
846 /* the reply stream, probably */
847 /* should shutdown the whole */
849 (void) cancel_operation(arg->send_descriptor);
850 string_free(&(arg->s));
851 delete_operation(arg->send_query);
852 delete_operation(arg->send_descriptor);
853 delete_operation(arg->get_retcode);
854 db_free((char *)arg, sizeof(struct adb_data));
859 * We've successfully queued the receive of the return code.
860 * That's about all we have to do if things go well, but if the
861 * operation fails later, we have to be there to clean up. To
862 * get control back, we queue ourselves as a second operation
863 * so we can see how the first did, and so we can free up arg.
865 initialize_operation(op, g_idbq, (char *)arg, (int (*)())NULL);
866 (void) queue_operation(db->connection, CON_INPUT, op);
871 /*----------------------------------------------------------*/
875 /* Init routine for getting return code on performing a
876 /* bd query. If there was an error, then we are done except for
877 /* cleaning up all the dynamic memory we allocated.
878 /* If the return code was 0,then we must asynchronously
879 /* do the following iteratively until a no is received:
881 /* while (async_receive(yes/no) == yes) {
882 /* async receive new tuple
883 /* add it to the relation
886 /*----------------------------------------------------------*/
889 g_idbq(op, hcon, arg)
891 HALF_CONNECTION hcon;
892 struct dbq_data *arg;
896 /*----------------------------------------------------------*/
898 /* See how the three asynchronous operations went,and
899 /* clean up after them.
901 /*----------------------------------------------------------*/
904 * Figure out how the receipt went
906 rc1 = OP_STATUS(arg->send_query);
907 rc2 = OP_STATUS(arg->send_descriptor);
908 rc3 = OP_STATUS(arg->get_retcode);
911 * Release all transient data structures which were used in the
912 * preliminary operations.
914 delete_operation(arg->send_query);
915 delete_operation(arg->get_retcode);
916 string_free(&(arg->s));
918 * If we've failed for any reason, then mark ourselves complete and
921 if (rc1 != OP_COMPLETE || rc2 != OP_COMPLETE|| rc3 != OP_COMPLETE
922 || OP_RESULT(op) != OP_SUCCESS) {
923 OP_STATUS(op) = rc3; /* we must have done */
924 /* about as well as */
927 db_free((char *)arg, sizeof(struct dbq_data));
928 return rc3; /* tell the dispatcher */
929 /* that we're either */
930 /* cancelled or complete */
933 /*----------------------------------------------------------*/
935 /* We've successfully received a return code of 0 from
936 /* Ingres, which means we are now going to begin the
939 /*----------------------------------------------------------*/
941 op->fcn.cont = g_cdbq; /* after the preempting */
942 /* receive completes, the */
943 /* dispatcher will call */
945 arg->state = YESNO; /* tell continuation routine */
946 /* that we're receiving */
948 arg->tup = NULL; /* so we won't try to clean */
950 arg->receive_yesno_or_data = create_operation();
952 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
954 (char *)&(arg->yesno),
959 /*----------------------------------------------------------*/
963 /* Continuation routine for receiving results of a query.
964 /* Tbis is called repeatedly each time either a yes/no or
965 /* a new tuple is received. It repeatedly preempts itself
966 /* to receive the next yes/no or tuple until a 'no'
967 /* is finally received.
969 /*----------------------------------------------------------*/
972 g_cdbq(op, hcon, arg)
974 HALF_CONNECTION hcon;
975 struct dbq_data *arg;
977 /*----------------------------------------------------------*/
979 /* See whether the preempting operation completed
980 /* successfully. If not, we just clean up and cancel
982 /*----------------------------------------------------------*/
984 if (OP_STATUS(arg->receive_yesno_or_data) != OP_COMPLETE) {
985 delete_operation(arg->receive_yesno_or_data);
986 if (arg->tup != NULL)
987 delete_tuple(arg->tup);
988 db_free((char *)arg, sizeof(struct dbq_data));
989 OP_STATUS(op) = OP_CANCELLED;
993 /*----------------------------------------------------------*/
995 /* Whatever it was, we received it cleanly. If it
996 /* was tuple data, then accept it and prepare to receive
997 /* a yesno. If it was a yes, then prepare to receive
998 /* the tuple data. If it was a NO, then we're all done.
1000 /* Note that g_cdbg will be recalled by the dispatcher
1001 /* after the preempting routines have completed.
1003 /*----------------------------------------------------------*/
1009 if (arg->state == TUPDATA) {
1010 ADD_TUPLE_TO_RELATION(arg->rel, arg->tup);
1011 arg->tup = NULL; /* so we won't try to */
1012 /* delete it in case of error*/
1013 reset_operation(arg->receive_yesno_or_data);
1015 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1017 (char *)&(arg->yesno),
1019 return OP_PREEMPTED;
1023 * We just received a yes or no. If it's a YES, prepare to
1024 * receive some more tuple data.
1026 if (arg->yesno == YES) {
1027 arg->tup = create_tuple(arg->tpd);
1028 reset_operation(arg->receive_yesno_or_data);
1029 arg->state = TUPDATA;
1030 preempt_and_start_receiving_object(arg->receive_yesno_or_data,
1034 return OP_PREEMPTED;
1037 * We just received a NO. Looks like we're all done cleanly.
1039 delete_operation(arg->receive_yesno_or_data);
1040 if (arg->tup != NULL)
1041 delete_tuple(arg->tup);
1042 db_free((char *)arg, sizeof(struct dbq_data));
1043 OP_STATUS(op) = OP_COMPLETE;
1048 /************************************************************************/
1050 /* db_query (db_query)
1052 /* Perform a relational query on the specified database.
1054 /* This just calls the asynchronous form of doing a query and
1055 /* waits for it to complete.
1058 /************************************************************************/
1061 db_query(db_handle, rel, query)
1066 register OPERATION op;
1067 register int status;
1068 register int result;
1071 * Create an operation and use it to asynchronously perform
1074 op = create_operation();
1075 (void) start_db_query(op, db_handle, rel, query);
1078 * Wait for it to complete, note whether the operation
1079 * completed at all, and if so, whether it returned a
1080 * successful result. Then reclaim the space used for the
1083 (void) complete_operation(op);
1084 status = OP_STATUS(op);
1085 result = OP_RESULT(op);
1087 delete_operation(op);
1090 * Tell the caller either that we were interrupted, or pass
1091 * on the actual result of accessing the database. If it
1092 * failed, then tear everything down after all.
1094 if (status==OP_COMPLETE)