📄 informix.c
字号:
#include <stdlib.h>#include <string.h>#include <errno.h>#include <math.h>#include <ctype.h>#include <limits.h>#include <ecpgtype.h>#include <ecpg_informix.h>#include <pgtypes_error.h>#include <pgtypes_date.h>#include <pgtypes_numeric.h>#include <sqltypes.h>char *ECPGalloc(long, int);static intdeccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *)){ numeric *a1, *a2; int i; if ((a1 = PGTYPESnumeric_new()) == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if ((a2 = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } i = (*ptr) (a1, a2); PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return (i);}static intdeccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *)){ numeric *a1, *a2, *nres; int i; /* * we must NOT set the result to NULL here because it may be the same * variable as one of the arguments */ if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2)) return 0; if ((a1 = PGTYPESnumeric_new()) == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if ((a2 = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); return ECPG_INFORMIX_OUT_OF_MEMORY; } if ((nres = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } i = (*ptr) (a1, a2, nres); if (i == 0) /* No error */ { /* set the result to null in case it errors out later */ rsetnull(CDECIMALTYPE, (char *) result); PGTYPESnumeric_to_decimal(nres, result); } PGTYPESnumeric_free(nres); PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return (i);}/* we start with the numeric functions */intdecadd(decimal *arg1, decimal *arg2, decimal *sum){ deccall3(arg1, arg2, sum, PGTYPESnumeric_add); if (errno == PGTYPES_NUM_OVERFLOW) return ECPG_INFORMIX_NUM_OVERFLOW; else if (errno != 0) return ECPG_INFORMIX_NUM_UNDERFLOW; else return 0;}intdeccmp(decimal *arg1, decimal *arg2){ return (deccall2(arg1, arg2, PGTYPESnumeric_cmp));}voiddeccopy(decimal *src, decimal *target){ memcpy(target, src, sizeof(decimal));}static char *ecpg_strndup(const char *str, size_t len){ int real_len = strlen(str); int use_len = (real_len > len) ? len : real_len; char *new = malloc(use_len + 1); if (new) { memcpy(new, str, use_len); new[use_len] = '\0'; } else errno = ENOMEM; return new;}intdeccvasc(char *cp, int len, decimal *np){ char *str; int ret = 0; numeric *result; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CSTRINGTYPE, cp)) return 0; str = ecpg_strndup(cp, len); /* decimal_in always converts the complete string */ if (!str) ret = ECPG_INFORMIX_NUM_UNDERFLOW; else { result = PGTYPESnumeric_from_asc(str, NULL); if (!result) { switch (errno) { case PGTYPES_NUM_OVERFLOW: ret = ECPG_INFORMIX_NUM_OVERFLOW; break; case PGTYPES_NUM_BAD_NUMERIC: ret = ECPG_INFORMIX_BAD_NUMERIC; break; default: ret = ECPG_INFORMIX_BAD_EXPONENT; break; } } else { if (PGTYPESnumeric_to_decimal(result, np) != 0) ret = ECPG_INFORMIX_NUM_OVERFLOW; free(result); } } free(str); return ret;}intdeccvdbl(double dbl, decimal *np){ numeric *nres = PGTYPESnumeric_new(); int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CDOUBLETYPE, (char *) &dbl)) return 0; if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_double(dbl, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdeccvint(int in, decimal *np){ numeric *nres = PGTYPESnumeric_new(); int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CINTTYPE, (char *) &in)) return 0; if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_int(in, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdeccvlong(long lng, decimal *np){ numeric *nres = PGTYPESnumeric_new(); int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CLONGTYPE, (char *) &lng)) return 0; if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_long(lng, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdecdiv(decimal *n1, decimal *n2, decimal *result){ int i; i = deccall3(n1, n2, result, PGTYPESnumeric_div); if (i != 0) switch (errno) { case PGTYPES_NUM_DIVIDE_ZERO: return ECPG_INFORMIX_DIVIDE_ZERO; break; case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdecmul(decimal *n1, decimal *n2, decimal *result){ int i; i = deccall3(n1, n2, result, PGTYPESnumeric_mul); if (i != 0) switch (errno) { case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdecsub(decimal *n1, decimal *n2, decimal *result){ int i; i = deccall3(n1, n2, result, PGTYPESnumeric_sub); if (i != 0) switch (errno) { case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdectoasc(decimal *np, char *cp, int len, int right){ char *str; numeric *nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; rsetnull(CSTRINGTYPE, (char *) cp); if (risnull(CDECIMALTYPE, (char *) np)) return 0; if (PGTYPESnumeric_from_decimal(np, nres) != 0) return ECPG_INFORMIX_OUT_OF_MEMORY; if (right >= 0) str = PGTYPESnumeric_to_asc(nres, right); else str = PGTYPESnumeric_to_asc(nres, nres->dscale); PGTYPESnumeric_free(nres); if (!str) return -1; /* * TODO: have to take care of len here and create exponatial notion if * necessary */ strncpy(cp, str, len); free(str); return 0;}intdectodbl(decimal *np, double *dblp){ numeric *nres = PGTYPESnumeric_new(); int i; if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) return ECPG_INFORMIX_OUT_OF_MEMORY; i = PGTYPESnumeric_to_double(nres, dblp); PGTYPESnumeric_free(nres); return i;}intdectoint(decimal *np, int *ip){ int ret; numeric *nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) return ECPG_INFORMIX_OUT_OF_MEMORY; ret = PGTYPESnumeric_to_int(nres, ip); if (ret == PGTYPES_NUM_OVERFLOW) ret = ECPG_INFORMIX_NUM_OVERFLOW; return ret;}intdectolong(decimal *np, long *lngp){ int ret; numeric *nres = PGTYPESnumeric_new();; if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) return ECPG_INFORMIX_OUT_OF_MEMORY; ret = PGTYPESnumeric_to_long(nres, lngp); if (ret == PGTYPES_NUM_OVERFLOW) ret = ECPG_INFORMIX_NUM_OVERFLOW; return ret;}/* Now the date functions */intrdatestr(date d, char *str){ char *tmp = PGTYPESdate_to_asc(d); if (!tmp) return ECPG_INFORMIX_DATE_CONVERT; /* move to user allocated buffer */ strcpy(str, tmp); free(tmp); return 0;}/*** the input for this function is mmddyyyy and any non-numeric* character can be used as a separator**/intrstrdate(char *str, date * d){ date dat; char strbuf[10]; int i, j; rsetnull(CDATETYPE, (char *) &dat); /* * we have to flip the year month date around for postgres expects * yyyymmdd * */ for (i = 0, j = 0; i < 10; i++) { /* ignore non-digits */ if (isdigit((unsigned char) str[i])) { /* j only increments if it is a digit */ switch (j) { /* stick the month into the 4th, 5th position */ case 0: case 1: strbuf[j + 4] = str[i]; break; /* stick the day into the 6th, and 7th position */ case 2: case 3: strbuf[j + 4] = str[i]; break; /* stick the year into the first 4 positions */ case 4: case 5: case 6: case 7: strbuf[j - 4] = str[i]; break; } j++; } } strbuf[8] = '\0'; dat = PGTYPESdate_from_asc(strbuf, NULL); if (errno && errno != PGTYPES_DATE_BAD_DATE) return ECPG_INFORMIX_BAD_DATE; *d = dat; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -