]> andersk Git - moira.git/blob - dbck/fix.pc
Rewrite functions to avoid having SQL DECLARE SECTIONs around function
[moira.git] / dbck / fix.pc
1 /* $Header$
2  *
3  * User interface routines for dbck (Moira database consistency checker)
4  *
5  *  (c) Copyright 1988 by the Massachusetts Institute of Technology.
6  *  For copying and distribution information, please see the file
7  *  <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include <moira.h>
12 #include <stdio.h>
13 #include "dbck.h"
14
15 EXEC SQL INCLUDE sqlca;  /* SQL Communications Area */
16 EXEC SQL INCLUDE sqlda;  /* SQL Descriptor Area */
17
18 static char fix_qc_rcsid[] = "$Header$";
19
20 EXEC SQL BEGIN DECLARE SECTION; 
21 char *_table;
22 char *_idfield;
23 char stmt_buf[500];
24 EXEC SQL END DECLARE SECTION; 
25
26 extern SQLDA *mr_sqlda;
27
28 generic_ffunc(id)
29 EXEC SQL BEGIN DECLARE SECTION; 
30 int id;
31 EXEC SQL END DECLARE SECTION; 
32 {
33     EXEC SQL BEGIN DECLARE SECTION; 
34     int rowcount;
35     EXEC SQL END DECLARE SECTION; 
36
37     sprintf(stmt_buf,"DELETE FROM %s WHERE %s.%s = %d",
38             _table,_table,_idfield,id);
39     EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
40     rowcount = sqlca.sqlerrd[2];
41     if (rowcount > 0)
42       printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies");
43     else
44       printf("Not deleted\n");
45     modified(_table);
46 }
47
48
49 generic_delete(sq, pfunc, table, idfield, preen)
50 struct save_queue *sq;
51 void (*pfunc)();
52 char *table, *idfield;
53 int preen;
54 {
55     _table = table;
56     _idfield = idfield;
57     generic_fix(sq, pfunc, "Delete", generic_ffunc, preen);
58 }
59
60
61 single_delete(table, idfield, id)
62 char *table, *idfield;
63 int id;
64 {
65     _table = table;
66     _idfield = idfield;
67     generic_ffunc(id);
68 }
69
70
71 zero_fix(tbl, zrfield, idfield, id)
72 EXEC SQL BEGIN DECLARE SECTION; 
73 char *tbl, *zrfield, *idfield;
74 int id;
75 EXEC SQL END DECLARE SECTION; 
76 {
77     EXEC SQL BEGIN DECLARE SECTION; 
78     int rowcount;
79     EXEC SQL END DECLARE SECTION; 
80
81     sprintf(stmt_buf,"UPDATE %s SET %s = 0 WHERE %s.%s = %d",
82             tbl,zrfield,tbl,idfield,id);
83     EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
84     rowcount = sqlca.sqlerrd[2];
85     if (rowcount > 0)
86       printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies");
87     else
88       printf("Not fixed\n");
89     modified(tbl);
90 }
91
92
93 int single_fix(msg, preen)
94 char *msg;
95 int preen;
96 {
97     if (mode == MODE_PREEN)
98       return(preen);
99
100     switch (mode) {
101     case MODE_ASK:
102         if (!prompt(msg))
103           break;
104     case MODE_YES:
105         return(1);
106         break;
107     case MODE_NO:
108         ;
109     }
110     return(0);
111 }
112
113
114 generic_fix(sq, pfunc, msg, ffunc, preen)
115 struct save_queue *sq;
116 char *msg;
117 int (*pfunc)(), (*ffunc)();
118 int preen;
119 {
120     int id;
121
122     while (sq_get_data(sq, &id)) {
123         if ((*pfunc)(id) == 0 && single_fix(msg, preen))
124           (*ffunc)(id);
125     }
126     sq_destroy(sq);
127 }
128
129
130 int prompt(msg)
131 char *msg;
132 {
133     char buf[BUFSIZ];
134     EXEC SQL BEGIN DECLARE SECTION; 
135     extern int dcmenable;
136     EXEC SQL END DECLARE SECTION; 
137
138     while (1) {
139         printf("%s (Y/N/Q)? ", msg);
140         fflush(stdout);
141         gets(buf);
142         if (buf[0] == 'Y' || buf[0] == 'y')
143           return(1);
144         if (buf[0] == 'N' || buf[0] == 'n')
145           return(0);
146         if (buf[0] == 'Q' || buf[0] == 'q') {
147             if (prompt("Are you sure you want to quit")) {
148                 if (prompt("Save database changes")) {
149                     EXEC SQL COMMIT WORK;
150                     cleanup();
151                     exit(0);
152                 } else {
153                     EXEC SQL ROLLBACK WORK;
154                     EXEC SQL UPDATE numvalues SET value = :dcmenable
155                         WHERE name='dcm_enable';
156                     exit(1);
157                 }
158             }
159         }
160     }
161 }
162
163
164 /**
165  ** set_next_object_id - set next object id in values table
166  **
167  ** Inputs: object - object name in values table and in objects
168  **         table - name of table objects are found in
169  **
170  ** - called before an APPEND operation to set the next object id to
171  **   be used for the new record to the next free value
172  **
173  **/
174
175 int set_next_object_id(object, tablename)
176 EXEC SQL BEGIN DECLARE SECTION;
177     char *object;
178 EXEC SQL END DECLARE SECTION;
179     char *tablename;
180 {
181     EXEC SQL BEGIN DECLARE SECTION; 
182     int value;
183     char stmt_buf[256], out_buf[256];
184     EXEC SQL END DECLARE SECTION; 
185     int starting_value, errcode=0;
186
187     EXEC SQL SELECT value INTO :value FROM numvalues WHERE name = :object;
188     if (sqlca.sqlerrd[2] != 1)
189         return(MR_NO_ID);
190
191     starting_value=value;
192     while(1) {
193         if (value > MAX_ID_VALUE) value = MIN_ID_VALUE;
194
195         sprintf(stmt_buf, "SELECT %s FROM %s WHERE %s=%d",
196                 object, tablename, object, value);
197         EXEC SQL PREPARE inc_stmt FROM :stmt_buf;
198         EXEC SQL DECLARE inc_crs CURSOR FOR inc_stmt;
199         EXEC SQL OPEN inc_crs;
200         mr_sqlda->N = 1;
201         EXEC SQL DESCRIBE SELECT LIST FOR inc_stmt INTO mr_sqlda;
202         mr_sqlda->N = mr_sqlda->F;
203         mr_sqlda->V[0]=out_buf;
204         mr_sqlda->T[0]=97;
205         mr_sqlda->L[0]=255;
206         EXEC SQL FETCH inc_crs USING DESCRIPTOR mr_sqlda;
207
208         /* if we got an error from the FETCH, we have to preserve it or the
209            close will reset it and the caller with think nothing happened */
210         if(sqlca.sqlcode) errcode=sqlca.sqlcode;
211
212         EXEC SQL CLOSE inc_crs;
213         if (errcode < 0) return(MR_DBMS_ERR);
214         if (errcode == 1403) break;
215
216         value++;
217         if (value == starting_value) return (MR_NO_ID);
218     }
219
220     printf("setting ID %s to %d\n", object, value);
221     EXEC SQL UPDATE numvalues SET value = :value WHERE name = :object;
222     modified("values");
223     return(MR_SUCCESS);
224 }
225
226
227 generic_fix_id(tbl, idfield, txtfield, oldid, name)
228     EXEC SQL BEGIN DECLARE SECTION; 
229     char *tbl;
230     char *idfield;
231     char *txtfield;
232     int oldid;
233     char *name;
234     EXEC SQL END DECLARE SECTION; 
235 {
236     EXEC SQL BEGIN DECLARE SECTION; 
237     int rowcount, id;
238     EXEC SQL END DECLARE SECTION; 
239
240     set_next_object_id(tbl, idfield);
241     EXEC SQL SELECT value INTO :id FROM numvalues
242         WHERE name = :idfield;
243     sprintf(stmt_buf,"UPDATE %s SET %s = %d WHERE %s=%d AND %s='%s'",
244             tbl,idfield,id,idfield,oldid,txtfield,name);
245     EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
246     rowcount = sqlca.sqlerrd[2];
247     if (rowcount == 1)
248       printf("Fixed\n");
249     else
250       printf("Not fixed, rowcount = %d\n", rowcount);
251     modified(tbl);
252     return(id);
253 }
This page took 0.053394 seconds and 5 git commands to generate.