1 | /* |
2 | * $Id: print.c,v 1.3 2005/10/28 02:56:22 jms Exp $ |
3 | * |
4 | * Revision History |
5 | * =================== |
6 | * $Log: print.c,v $ |
7 | * Revision 1.3 2005/10/28 02:56:22 jms |
8 | * add platform-specific printf formats to allow for DSS_HUGE data type |
9 | * |
10 | * Revision 1.2 2005/01/03 20:08:59 jms |
11 | * change line terminations |
12 | * |
13 | * Revision 1.1.1.1 2004/11/24 23:31:47 jms |
14 | * re-establish external server |
15 | * |
16 | * Revision 1.4 2004/02/18 16:26:49 jms |
17 | * 32/64 bit changes for overflow handling needed additional changes when ported back to windows |
18 | * |
19 | * Revision 1.3 2004/02/18 14:05:53 jms |
20 | * porting changes for LINUX and 64 bit RNG |
21 | * |
22 | * Revision 1.2 2004/01/22 05:49:29 jms |
23 | * AIX porting (AIX 5.1) |
24 | * |
25 | * Revision 1.1.1.1 2003/08/07 17:58:34 jms |
26 | * recreation after CVS crash |
27 | * |
28 | * Revision 1.2 2003/08/07 17:58:34 jms |
29 | * Convery RNG to 64bit space as preparation for new large scale RNG |
30 | * |
31 | * Revision 1.1.1.1 2003/04/03 18:54:21 jms |
32 | * initial checkin |
33 | * |
34 | * |
35 | */ |
36 | /* generate flat files for data load */ |
37 | #include <stdio.h> |
38 | #ifndef VMS |
39 | #include <sys/types.h> |
40 | #endif |
41 | #if defined(SUN) |
42 | #include <unistd.h> |
43 | #endif |
44 | #include <math.h> |
45 | |
46 | #include "dss.h" |
47 | #include "dsstypes.h" |
48 | #include <string.h> |
49 | |
50 | /* |
51 | * Function Prototypes |
52 | */ |
53 | FILE *print_prep PROTO((int table, int update)); |
54 | int pr_drange PROTO((int tbl, DSS_HUGE min, DSS_HUGE cnt, long num)); |
55 | |
56 | FILE * |
57 | print_prep(int table, int update) |
58 | { |
59 | char upath[128]; |
60 | FILE *res; |
61 | |
62 | if (updates) |
63 | { |
64 | if (update > 0) /* updates */ |
65 | if ( insert_segments ) |
66 | { |
67 | int this_segment; |
68 | if(strcmp(tdefs[table].name,"orders.tbl" )) |
69 | this_segment=++insert_orders_segment; |
70 | else |
71 | this_segment=++insert_lineitem_segment; |
72 | sprintf(upath, "%s%c%s.u%d.%d" , |
73 | env_config(PATH_TAG, PATH_DFLT), |
74 | PATH_SEP, tdefs[table].name, update%10000,this_segment); |
75 | } |
76 | else |
77 | { |
78 | sprintf(upath, "%s%c%s.u%d" , |
79 | env_config(PATH_TAG, PATH_DFLT), |
80 | PATH_SEP, tdefs[table].name, update); |
81 | } |
82 | else /* deletes */ |
83 | if ( delete_segments ) |
84 | { |
85 | ++delete_segment; |
86 | sprintf(upath, "%s%cdelete.u%d.%d" , |
87 | env_config(PATH_TAG, PATH_DFLT), PATH_SEP, -update%10000, |
88 | delete_segment); |
89 | } |
90 | else |
91 | { |
92 | sprintf(upath, "%s%cdelete.%d" , |
93 | env_config(PATH_TAG, PATH_DFLT), PATH_SEP, -update); |
94 | } |
95 | return(fopen(upath, "w" )); |
96 | } |
97 | res = tbl_open(table, "w" ); |
98 | OPEN_CHECK(res, tdefs[table].name); |
99 | return(res); |
100 | } |
101 | |
102 | int |
103 | dbg_print(int format, FILE *target, void *data, int len, int sep) |
104 | { |
105 | int dollars, |
106 | cents; |
107 | |
108 | switch(format) |
109 | { |
110 | case DT_STR: |
111 | fprintf(target, "%s" , (char *)data); |
112 | break; |
113 | #ifdef MVS |
114 | case DT_VSTR: |
115 | /* note: only used in MVS, assumes columnar output */ |
116 | fprintf(target, "%c%c%-*s" , |
117 | (len >> 8) & 0xFF, len & 0xFF, len, (char *)data); |
118 | break; |
119 | #endif /* MVS */ |
120 | case DT_INT: |
121 | fprintf(target, "%ld" , (long)data); |
122 | break; |
123 | case DT_HUGE: |
124 | fprintf(target, HUGE_FORMAT, *(DSS_HUGE *)data); |
125 | break; |
126 | case DT_KEY: |
127 | fprintf(target, "%ld" , (long)data); |
128 | break; |
129 | case DT_MONEY: |
130 | cents = (int)*(DSS_HUGE *)data; |
131 | if (cents < 0) |
132 | { |
133 | fprintf(target, "-" ); |
134 | cents = -cents; |
135 | } |
136 | dollars = cents / 100; |
137 | cents %= 100; |
138 | fprintf(target, "%d.%02d" , dollars, cents); |
139 | break; |
140 | case DT_CHR: |
141 | fprintf(target, "%c" , *(char *)data); |
142 | break; |
143 | } |
144 | |
145 | #ifdef EOL_HANDLING |
146 | if (sep) |
147 | #endif /* EOL_HANDLING */ |
148 | fprintf(target, "%c" , SEPARATOR); |
149 | |
150 | return(0); |
151 | } |
152 | |
153 | int |
154 | pr_cust(customer_t *c, int mode) |
155 | { |
156 | static FILE *fp = NULL; |
157 | |
158 | if (fp == NULL) |
159 | fp = print_prep(CUST, 0); |
160 | |
161 | PR_STRT(fp); |
162 | PR_HUGE(fp, &c->custkey); |
163 | if (scale <= 3000) |
164 | PR_VSTR(fp, c->name, C_NAME_LEN); |
165 | else |
166 | PR_VSTR(fp, c->name, C_NAME_LEN + 3); |
167 | PR_VSTR(fp, c->address, c->alen); |
168 | PR_HUGE(fp, &c->nation_code); |
169 | PR_STR(fp, c->phone, PHONE_LEN); |
170 | PR_MONEY(fp, &c->acctbal); |
171 | PR_STR(fp, c->mktsegment, C_MSEG_LEN); |
172 | PR_VSTR_LAST(fp, c->comment, c->clen); |
173 | PR_END(fp); |
174 | |
175 | return(0); |
176 | } |
177 | |
178 | /* |
179 | * print the numbered order |
180 | */ |
181 | int |
182 | pr_order(order_t *o, int mode) |
183 | { |
184 | static FILE *fp_o = NULL; |
185 | static int last_mode = 0; |
186 | |
187 | if (fp_o == NULL || mode != last_mode) |
188 | { |
189 | if (fp_o) |
190 | fclose(fp_o); |
191 | fp_o = print_prep(ORDER, mode); |
192 | last_mode = mode; |
193 | } |
194 | PR_STRT(fp_o); |
195 | PR_HUGE(fp_o, &o->okey); |
196 | PR_HUGE(fp_o, &o->custkey); |
197 | PR_CHR(fp_o, &o->orderstatus); |
198 | PR_MONEY(fp_o, &o->totalprice); |
199 | PR_STR(fp_o, o->odate, DATE_LEN); |
200 | PR_STR(fp_o, o->opriority, O_OPRIO_LEN); |
201 | PR_STR(fp_o, o->clerk, O_CLRK_LEN); |
202 | PR_INT(fp_o, o->spriority); |
203 | PR_VSTR_LAST(fp_o, o->comment, o->clen); |
204 | PR_END(fp_o); |
205 | |
206 | return(0); |
207 | } |
208 | |
209 | /* |
210 | * print an order's lineitems |
211 | */ |
212 | int |
213 | pr_line(order_t *o, int mode) |
214 | { |
215 | static FILE *fp_l = NULL; |
216 | static int last_mode = 0; |
217 | long i; |
218 | |
219 | if (fp_l == NULL || mode != last_mode) |
220 | { |
221 | if (fp_l) |
222 | fclose(fp_l); |
223 | fp_l = print_prep(LINE, mode); |
224 | last_mode = mode; |
225 | } |
226 | |
227 | for (i = 0; i < o->lines; i++) |
228 | { |
229 | PR_STRT(fp_l); |
230 | PR_HUGE(fp_l, &o->l[i].okey); |
231 | PR_HUGE(fp_l, &o->l[i].partkey); |
232 | PR_HUGE(fp_l, &o->l[i].suppkey); |
233 | PR_HUGE(fp_l, &o->l[i].lcnt); |
234 | PR_HUGE(fp_l, &o->l[i].quantity); |
235 | PR_MONEY(fp_l, &o->l[i].eprice); |
236 | PR_MONEY(fp_l, &o->l[i].discount); |
237 | PR_MONEY(fp_l, &o->l[i].tax); |
238 | PR_CHR(fp_l, &o->l[i].rflag[0]); |
239 | PR_CHR(fp_l, &o->l[i].lstatus[0]); |
240 | PR_STR(fp_l, o->l[i].sdate, DATE_LEN); |
241 | PR_STR(fp_l, o->l[i].cdate, DATE_LEN); |
242 | PR_STR(fp_l, o->l[i].rdate, DATE_LEN); |
243 | PR_STR(fp_l, o->l[i].shipinstruct, L_INST_LEN); |
244 | PR_STR(fp_l, o->l[i].shipmode, L_SMODE_LEN); |
245 | PR_VSTR_LAST(fp_l, o->l[i].comment,o->l[i].clen); |
246 | PR_END(fp_l); |
247 | } |
248 | |
249 | return(0); |
250 | } |
251 | |
252 | /* |
253 | * print the numbered order *and* its associated lineitems |
254 | */ |
255 | int |
256 | pr_order_line(order_t *o, int mode) |
257 | { |
258 | tdefs[ORDER].name = tdefs[ORDER_LINE].name; |
259 | pr_order(o, mode); |
260 | pr_line(o, mode); |
261 | |
262 | return(0); |
263 | } |
264 | |
265 | /* |
266 | * print the given part |
267 | */ |
268 | int |
269 | pr_part(part_t *part, int mode) |
270 | { |
271 | static FILE *p_fp = NULL; |
272 | |
273 | if (p_fp == NULL) |
274 | p_fp = print_prep(PART, 0); |
275 | |
276 | PR_STRT(p_fp); |
277 | PR_HUGE(p_fp, &part->partkey); |
278 | PR_VSTR(p_fp, part->name,part->nlen); |
279 | PR_STR(p_fp, part->mfgr, P_MFG_LEN); |
280 | PR_STR(p_fp, part->brand, P_BRND_LEN); |
281 | PR_VSTR(p_fp, part->type,part->tlen); |
282 | PR_HUGE(p_fp, &part->size); |
283 | PR_STR(p_fp, part->container, P_CNTR_LEN); |
284 | PR_MONEY(p_fp, &part->retailprice); |
285 | PR_VSTR_LAST(p_fp, part->comment,part->clen); |
286 | PR_END(p_fp); |
287 | |
288 | return(0); |
289 | } |
290 | |
291 | /* |
292 | * print the given part's suppliers |
293 | */ |
294 | int |
295 | pr_psupp(part_t *part, int mode) |
296 | { |
297 | static FILE *ps_fp = NULL; |
298 | long i; |
299 | |
300 | if (ps_fp == NULL) |
301 | ps_fp = print_prep(PSUPP, mode); |
302 | |
303 | for (i = 0; i < SUPP_PER_PART; i++) |
304 | { |
305 | PR_STRT(ps_fp); |
306 | PR_HUGE(ps_fp, &part->s[i].partkey); |
307 | PR_HUGE(ps_fp, &part->s[i].suppkey); |
308 | PR_HUGE(ps_fp, &part->s[i].qty); |
309 | PR_MONEY(ps_fp, &part->s[i].scost); |
310 | PR_VSTR_LAST(ps_fp, part->s[i].comment,part->s[i].clen); |
311 | PR_END(ps_fp); |
312 | } |
313 | |
314 | return(0); |
315 | } |
316 | |
317 | /* |
318 | * print the given part *and* its suppliers |
319 | */ |
320 | int |
321 | pr_part_psupp(part_t *part, int mode) |
322 | { |
323 | tdefs[PART].name = tdefs[PART_PSUPP].name; |
324 | pr_part(part, mode); |
325 | pr_psupp(part, mode); |
326 | |
327 | return(0); |
328 | } |
329 | |
330 | int |
331 | pr_supp(supplier_t *supp, int mode) |
332 | { |
333 | static FILE *fp = NULL; |
334 | |
335 | if (fp == NULL) |
336 | fp = print_prep(SUPP, mode); |
337 | |
338 | PR_STRT(fp); |
339 | PR_HUGE(fp, &supp->suppkey); |
340 | PR_STR(fp, supp->name, S_NAME_LEN); |
341 | PR_VSTR(fp, supp->address, supp->alen); |
342 | PR_HUGE(fp, &supp->nation_code); |
343 | PR_STR(fp, supp->phone, PHONE_LEN); |
344 | PR_MONEY(fp, &supp->acctbal); |
345 | PR_VSTR_LAST(fp, supp->comment, supp->clen); |
346 | PR_END(fp); |
347 | |
348 | return(0); |
349 | } |
350 | |
351 | int |
352 | pr_nation(code_t *c, int mode) |
353 | { |
354 | static FILE *fp = NULL; |
355 | |
356 | if (fp == NULL) |
357 | fp = print_prep(NATION, mode); |
358 | |
359 | PR_STRT(fp); |
360 | PR_HUGE(fp, &c->code); |
361 | PR_STR(fp, c->text, NATION_LEN); |
362 | PR_INT(fp, c->join); |
363 | PR_VSTR_LAST(fp, c->comment, c->clen); |
364 | PR_END(fp); |
365 | |
366 | return(0); |
367 | } |
368 | |
369 | int |
370 | pr_region(code_t *c, int mode) |
371 | { |
372 | static FILE *fp = NULL; |
373 | |
374 | if (fp == NULL) |
375 | fp = print_prep(REGION, mode); |
376 | |
377 | PR_STRT(fp); |
378 | PR_HUGE(fp, &c->code); |
379 | PR_STR(fp, c->text, REGION_LEN); |
380 | PR_VSTR_LAST(fp, c->comment, c->clen); |
381 | PR_END(fp); |
382 | |
383 | return(0); |
384 | } |
385 | |
386 | /* |
387 | * NOTE: this routine does NOT use the BCD2_* routines. As a result, |
388 | * it WILL fail if the keys being deleted exceed 32 bits. Since this |
389 | * would require ~660 update iterations, this seems an acceptable |
390 | * oversight |
391 | */ |
392 | int |
393 | pr_drange(int tbl, DSS_HUGE min, DSS_HUGE cnt, long num) |
394 | { |
395 | static int last_num = 0; |
396 | static FILE *dfp = NULL; |
397 | DSS_HUGE child = -1; |
398 | DSS_HUGE start, last, new; |
399 | |
400 | static DSS_HUGE rows_per_segment=0; |
401 | static DSS_HUGE rows_this_segment=0; |
402 | |
403 | if (last_num != num) |
404 | { |
405 | if (dfp) |
406 | fclose(dfp); |
407 | dfp = print_prep(tbl, -num); |
408 | if (dfp == NULL) |
409 | return(-1); |
410 | last_num = num; |
411 | rows_this_segment=0; |
412 | } |
413 | |
414 | start = MK_SPARSE(min, num/ (10000 / UPD_PCT)); |
415 | last = start - 1; |
416 | for (child=min; cnt > 0; child++, cnt--) |
417 | { |
418 | new = MK_SPARSE(child, num/ (10000 / UPD_PCT)); |
419 | if (delete_segments) |
420 | { |
421 | |
422 | if(rows_per_segment==0) |
423 | rows_per_segment = (cnt / delete_segments) + 1; |
424 | if((++rows_this_segment) > rows_per_segment) |
425 | { |
426 | fclose(dfp); |
427 | dfp = print_prep(tbl, -num); |
428 | if (dfp == NULL) return(-1); |
429 | last_num = num; |
430 | rows_this_segment=1; |
431 | } |
432 | } |
433 | PR_STRT(dfp); |
434 | PR_HUGE(dfp, &new); |
435 | PR_END(dfp); |
436 | start = new; |
437 | last = new; |
438 | } |
439 | |
440 | return(0); |
441 | } |
442 | |
443 | |
444 | |
445 | |