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