-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcommon-ecpg.c
More file actions
131 lines (106 loc) · 2.69 KB
/
common-ecpg.c
File metadata and controls
131 lines (106 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Synopsis:
* Common routines used by PostgreSQL ecpg code, depends on ./common.c
* Note:
* Double check safetly of memove() call.
*
* Need to add explcit dependency on common.c
*
* The process exit status of both warnings and errors are remapped through
* the array _ecpg_state2exit[] array. Do we need two arrays,
* one for warnings and one for errors?
*/
// map sql state codes onto process exit status
// only used when query faults.
struct _ecpg_sql_state_fault
{
char *sql_state;
// -1 implies ignore fault, 0 <= 255 implies remap exit status
int action;
};
/*
* Synopsis:
* Low level handler for all sql faults that end with die().
*/
static void
_ecpg_sql_fault(int status, char *what, struct _ecpg_sql_state_fault *fault)
{
char msg[PIPE_MAX + 1];
msg[0] = 0;
_strcat(msg, sizeof msg, "SQL");
_strcat(msg, sizeof msg, what);
// add the sql state code to error message
if (sqlca.sqlstate[0] != 0) {
char state[6];
_strcat(msg, sizeof msg, ": ");
memmove(state, sqlca.sqlstate, 5);
state[5] = 0;
_strcat(msg, sizeof msg, state);
// remap the process exit code for a particular sql state code
if (fault) {
while (fault->sql_state) {
if (strcmp(state, fault->sql_state) == 0)
break;
fault++;
}
// change the default behavior of the fault based
// the sql state code
if (fault->sql_state) {
int act = fault->action;
// ignore the fault
if (act == -1)
return;
// change the process exit status
if (0 <= act && act <= 255)
status = act;
}
}
} else
_strcat(msg, sizeof msg, ": (WARN: missing sql state)");
// tack on the sql error message
if (sqlca.sqlerrm.sqlerrml > 0) {
char err[SQLERRMC_LEN + 1];
_strcat(msg, sizeof msg, ": ");
memmove(err, sqlca.sqlerrm.sqlerrmc, sqlca.sqlerrm.sqlerrml);
err[sqlca.sqlerrm.sqlerrml] = 0;
_strcat(msg, sizeof msg, err);
}
die(status, msg);
}
#ifdef COMMON_ECPG_NEED_SQL_ERROR
/*
* Synopsis:
* SQL error callback for EXEC SQL WHENEVER SQLERROR CALL ...
* Usage:
* #define EXIT_SQLERROR 5
* #define COMMON_ECPG_NEED_SQL_ERROR
* #include "../../common-ecpg.c"
*
* ...
*
* EXEC SQL WHENEVER SQLERROR CALL _ecpg_sql_error();
*/
static void
_ecpg_sql_error(struct _ecpg_sql_state_fault *fault)
{
_ecpg_sql_fault(EXIT_SQLERROR, "ERROR", fault);
}
#endif
#ifdef COMMON_ECPG_NEED_SQL_WARNING
/*
* Synopsis:
* SQL warning callback for EXEC SQL WHENEVER SQLWARNING CALL
* Usage:
* #define COMMON_ECPG_NEED_SQL_FAULT
* #include "../../common-ecpg.c"
*
* ...
*
* EXEC SQL WHENEVER SQLWARNING CALL _ecpg_sql_warning();
*/
static void
_ecpg_sql_warning(struct _ecpg_sql_state_fault *fault)
{
_ecpg_sql_fault(EXIT_SQLWARN, "WARNING", fault);
}
#endif