]>
Commit | Line | Data |
---|---|---|
5580185e | 1 | /* |
2 | * $Source$ | |
3 | * $Header$ | |
4 | */ | |
5 | ||
6 | #ifndef lint | |
7 | static char *rcsid_samp1a_c = "$Header$"; | |
8 | #endif lint | |
9 | ||
10 | #define terminatedb(x) /* nothin doin yet */ | |
11 | /* | |
12 | * sample 1 | |
13 | * | |
14 | * A simple database query program. | |
15 | * | |
16 | * This sample program illustrates the use of the 'client library' | |
17 | * for remote access to a relational database. This version of | |
18 | * the sample is about the simplest possible. It accesses only | |
19 | * a single database, it does the access syncrhonously, and it uses | |
20 | * only system defined types. Many real applications will fit this | |
21 | * model. | |
22 | * | |
23 | * For purposes of illustration, this program accesses a database | |
24 | * of parts. For each part where the value of current inventory, | |
25 | * defined as number on hand times cost per unit, exceeds $1000, | |
26 | * this routine prints the description of the part, a code number, | |
27 | * the manufacturer, the cost, and the number on hand. | |
28 | * | |
29 | * Because this program accesses the database using the client | |
30 | * library, it may be run from any Berkeley Unix system on the internet. | |
31 | * Necessary data conversions are done automatically if the database | |
32 | * itself happens to live on an incompatible machine. | |
33 | * | |
34 | * Author: Noah Mendelsohn | |
35 | */ | |
36 | ||
37 | #include <stdio.h> | |
38 | #include "gdb.h" | |
39 | ||
40 | char *field_names[] = {"desc", | |
41 | "code", | |
42 | "man", | |
43 | "cost", | |
44 | "cnt"}; | |
45 | FIELD_TYPE field_types[] = {STRING_T, /* desc */ | |
46 | INTEGER_T, /* code */ | |
47 | STRING_T, /* man */ | |
48 | REAL_T, /* cost */ | |
49 | INTEGER_T}; /* count */ | |
50 | ||
51 | int | |
52 | main(argc, argv) | |
53 | int argc; | |
54 | char *argv[]; | |
55 | { | |
56 | ||
57 | \f /************************************************************ | |
58 | * DECLARATIONS * | |
59 | ************************************************************/ | |
60 | ||
61 | /* | |
62 | * Declare the names of fields to be retrieved and their types | |
63 | */ | |
64 | ||
65 | int field_count = 5; | |
66 | ||
67 | ||
68 | /* | |
69 | * The following defines are for convenience in addressing | |
70 | * the fields. | |
71 | */ | |
72 | ||
73 | #define DESC 0 | |
74 | #define CODE 1 | |
75 | #define MAN 2 | |
76 | #define COST 3 | |
77 | #define CNT 4 | |
78 | ||
79 | /* | |
80 | * Declare the relation and related data structures for | |
81 | * storing the retrieved data. | |
82 | */ | |
83 | ||
84 | TUPLE_DESCRIPTOR tuple_desc; | |
85 | RELATION retrieved_data; | |
86 | ||
87 | /* | |
88 | * Declare a handle to identify our session with the database | |
89 | * server. | |
90 | */ | |
91 | ||
92 | DATABASE parts_data; | |
93 | ||
94 | /* | |
95 | * Declarations for misc. variables | |
96 | */ | |
97 | ||
98 | TUPLE t; /* next tuple to print */ | |
99 | int rc; /* A return code */ | |
100 | ||
101 | \f /************************************************************ | |
102 | * EXECUTION BEGINS HERE * | |
103 | ************************************************************/ | |
104 | /* | |
105 | * Initialize gdb | |
106 | */ | |
107 | gdb_init(); | |
108 | ||
109 | /* | |
110 | * Open a connection to the database - identify session as parts_data | |
111 | */ | |
112 | ||
113 | if (access_db("noah@menelaus", &parts_data) != DB_OPEN) { | |
114 | printf("Cannot connect to parts database--giving up\n"); | |
115 | return; | |
116 | } | |
117 | ||
118 | /* | |
119 | * Build the descriptor describing the layout of the tuples | |
120 | * to be retrieved, and create an empty relation into which | |
121 | * the retrieval will be done. | |
122 | */ | |
123 | ||
124 | tuple_desc = create_tuple_descriptor(field_count, field_names, | |
125 | field_types); | |
126 | retrieved_data = create_relation(tuple_desc); | |
127 | ||
128 | /* | |
129 | * Do the query for parts with inventory over $1000 | |
130 | * Put results in the relation named retrieved_data. | |
131 | */ | |
132 | ||
133 | rc = db_query(parts_data, retrieved_data, | |
134 | "(>*desc*< = parts.desc,>*code*< = parts.code,>*man*< = parts.man,>*cost*< = parts.cost,>*cnt*< = parts.cnt) where (parts.cnt * parts.cost > 1000.00)"); | |
135 | ||
136 | if (rc != OP_SUCCESS) { | |
137 | printf("Error during retrieval--giving up\n"); | |
138 | terminatedb(parts_data); | |
139 | return; | |
140 | } | |
141 | ||
142 | /* | |
143 | * Print out the results | |
144 | */ | |
145 | ||
146 | for (t = FIRST_TUPLE_IN_RELATION(retrieved_data); t!= NULL; | |
147 | t = NEXT_TUPLE_IN_RELATION(retrieved_data,t)) | |
148 | print_a_line(t); | |
149 | ||
150 | printf("\nEnd of Report.\n\n"); | |
151 | ||
152 | /* | |
153 | * Clean up and leave | |
154 | */ | |
155 | ||
156 | terminatedb(parts_data); | |
157 | return; | |
158 | } | |
159 | ||
160 | \f/* | |
161 | * print_a_line | |
162 | * | |
163 | * Given a tuple with parts data, print it on standard output. | |
164 | * NOTE: for clarity, we've left out the casts which should be | |
165 | * done on the pointers returned from FIELD_FROM_TUPLE. | |
166 | */ | |
167 | int | |
168 | print_a_line(tup) | |
169 | TUPLE tup; | |
170 | { | |
171 | printf("desc=%s ", STRING_DATA(*(STRING *)(FIELD_FROM_TUPLE(tup, DESC)))); | |
172 | printf("code=%d ", *(int *)(FIELD_FROM_TUPLE(tup, CODE))); | |
173 | printf("manufacturer=%s ",STRING_DATA(*(STRING *)(FIELD_FROM_TUPLE(tup, MAN)))); | |
174 | printf("cost=%f ", *(double *)(FIELD_FROM_TUPLE(tup, COST))); | |
175 | printf("count=%d\n", *(int *)(FIELD_FROM_TUPLE(tup, CNT))); | |
176 | } |