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