📄 convert.c
字号:
my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos, buf, used); npos += strlen(&new_statement[npos]); } else { strcpy(&new_statement[npos], param_string); npos += strlen(param_string); } if (param_sqltype == SQL_BIT) new_statement[npos++] = '\''; /* Close Quote */ break; } } /* end, for */ // make sure new_statement is always null-terminated new_statement[npos] = '\0'; if(stmt->hdbc->DriverToDataSource != NULL) { int length = strlen (new_statement); stmt->hdbc->DriverToDataSource (stmt->hdbc->translation_option, SQL_CHAR, new_statement, length, new_statement, length, NULL, NULL, 0, NULL); } return SQL_SUCCESS;}char *mapFunction(char *func){int i; for (i = 0; mapFuncs[i][0]; i++) if ( ! stricmp(mapFuncs[i][0], func)) return mapFuncs[i][1]; return NULL;}// This function returns a pointer to static memory!char *convert_escape(char *value){char key[32], val[256];static char escape[1024];char func[32], the_rest[1024];char *mapFunc; sscanf(value, "%s %[^\r]", key, val); mylog("convert_escape: key='%s', val='%s'\n", key, val); if ( ! strcmp(key, "d") || ! strcmp(key, "t") || ! strcmp(key, "ts")) { strcpy(escape, val); } else if ( ! strcmp(key, "fn")) { sscanf(val, "%[^(]%[^\r]", func, the_rest); mapFunc = mapFunction(func); if ( ! mapFunc) return NULL; else { strcpy(escape, mapFunc); strcat(escape, the_rest); } } else { return NULL; } return escape;}char *convert_money(char *s){size_t i = 0, out = 0; for (i = 0; i < strlen(s); i++) { if (s[i] == '$' || s[i] == ',' || s[i] == ')') ; // skip these characters else if (s[i] == '(') s[out++] = '-'; else s[out++] = s[i]; } s[out] = '\0'; return s;}/* This function parses a character string for date/time info and fills in SIMPLE_TIME *//* It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value */charparse_datetime(char *buf, SIMPLE_TIME *st){int y,m,d,hh,mm,ss;int nf; y = m = d = hh = mm = ss = 0; if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y,&m,&d,&hh,&mm,&ss); else nf = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &m,&d,&y,&hh,&mm,&ss); if (nf == 5 || nf == 6) { st->y = y; st->m = m; st->d = d; st->hh = hh; st->mm = mm; st->ss = ss; return TRUE; } if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d", &y, &m, &d); else nf = sscanf(buf, "%2d-%2d-%4d", &m, &d, &y); if (nf == 3) { st->y = y; st->m = m; st->d = d; return TRUE; } nf = sscanf(buf, "%2d:%2d:%2d", &hh, &mm, &ss); if (nf == 2 || nf == 3) { st->hh = hh; st->mm = mm; st->ss = ss; return TRUE; } return FALSE;}/* Change linefeed to carriage-return/linefeed */intconvert_linefeeds(char *si, char *dst, size_t max){size_t i = 0, out = 0; for (i = 0; i < strlen(si) && out < max - 1; i++) { if (si[i] == '\n') { /* Only add the carriage-return if needed */ if (i > 0 && si[i-1] == '\r') { dst[out++] = si[i]; continue; } dst[out++] = '\r'; dst[out++] = '\n'; } else dst[out++] = si[i]; } dst[out] = '\0'; return out;}/* Change carriage-return/linefeed to just linefeed Plus, escape any special characters.*/char *convert_special_chars(char *si, char *dst, int used){size_t i = 0, out = 0, max;static char sout[TEXT_FIELD_SIZE+5];char *p; if (dst) p = dst; else p = sout; p[0] = '\0'; if (used == SQL_NTS) max = strlen(si); else max = used; for (i = 0; i < max; i++) { if (si[i] == '\r' && i+1 < strlen(si) && si[i+1] == '\n') continue; else if (si[i] == '\'' || si[i] == '\\') p[out++] = '\\'; p[out++] = si[i]; } p[out] = '\0'; return p;}/* !!! Need to implement this function !!! */intconvert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax){ mylog("convert_pgbinary_to_char: value = '%s'\n", value); strncpy_null(rgbValue, value, cbValueMax); return 0;}unsigned intconv_from_octal(unsigned char *s){int i, y=0; for (i = 1; i <= 3; i++) { y += (s[i] - 48) * (int) pow(8, 3-i); } return y;}unsigned intconv_from_hex(unsigned char *s){int i, y=0, val; for (i = 1; i <= 2; i++) { if (s[i] >= 'a' && s[i] <= 'f') val = s[i] - 'a' + 10; else if (s[i] >= 'A' && s[i] <= 'F') val = s[i] - 'A' + 10; else val = s[i] - '0'; y += val * (int) pow(16, 2-i); } return y;}// convert octal escapes to bytesintconvert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax){size_t i;int o=0; for (i = 0; i < strlen(value); ) { if (value[i] == '\\') { rgbValue[o] = conv_from_octal(&value[i]); i += 4; } else { rgbValue[o] = value[i++]; } mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]); o++; } rgbValue[o] = '\0'; // extra protection return o;}char *conv_to_octal(unsigned char val){int i;static char x[6]; x[0] = '\\'; x[1] = '\\'; x[5] = '\0'; for (i = 4; i > 1; i--) { x[i] = (val & 7) + 48; val >>= 3; } return x;}// convert non-ascii bytes to octal escape sequencesintconvert_to_pgbinary(unsigned char *in, char *out, int len){int i, o=0; for (i = 0; i < len; i++) { mylog("convert_to_pgbinary: in[%d] = %d, %c\n", i, in[i], in[i]); if ( isalnum(in[i]) || in[i] == ' ') { out[o++] = in[i]; } else { strcpy(&out[o], conv_to_octal(in[i])); o += 5; } } mylog("convert_to_pgbinary: returning %d, out='%.*s'\n", o, o, out); return o;}voidencode(char *in, char *out){unsigned int i, o = 0; for (i = 0; i < strlen(in); i++) { if ( in[i] == '+') { sprintf(&out[o], "%%2B"); o += 3; } else if ( isspace(in[i])) { out[o++] = '+'; } else if ( ! isalnum(in[i])) { sprintf(&out[o], "%%%02x", in[i]); o += 3; } else out[o++] = in[i]; } out[o++] = '\0';}voiddecode(char *in, char *out){unsigned int i, o = 0; for (i = 0; i < strlen(in); i++) { if (in[i] == '+') out[o++] = ' '; else if (in[i] == '%') { sprintf(&out[o++], "%c", conv_from_hex(&in[i])); i+=2; } else out[o++] = in[i]; } out[o++] = '\0';}/* 1. get oid (from 'value') 2. open the large object 3. read from the large object (handle multiple GetData) 4. close when read less than requested? -OR- lseek/read each time handle case where application receives truncated and decides not to continue reading. CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only data type currently mapped to a PG_TYPE_LO. But, if any other types are desired to map to a large object (PG_TYPE_LO), then that would need to be handled here. For example, LONGVARCHAR could possibly be mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now.*/intconvert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue){Oid oid;int retval, result, left = -1;int bind_row = stmt->bind_row;BindInfoClass *bindInfo = NULL;/* If using SQLGetData, then current_col will be set */ if (stmt->current_col >= 0) { bindInfo = &stmt->bindings[stmt->current_col]; left = bindInfo->data_left; } /* if this is the first call for this column, open the large object for reading */ if ( ! bindInfo || bindInfo->data_left == -1) { oid = atoi(value); stmt->lobj_fd = lo_open(stmt->hdbc, oid, INV_READ); if (stmt->lobj_fd < 0) { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Couldnt open large object for reading."; return COPY_GENERAL_ERROR; } /* Get the size */ retval = lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_END); if (retval >= 0) { left = lo_tell(stmt->hdbc, stmt->lobj_fd); if (bindInfo) bindInfo->data_left = left; /* return to beginning */ lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_SET); } } if (left == 0) { return COPY_NO_DATA_FOUND; } if (stmt->lobj_fd < 0) { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Large object FD undefined for multiple read."; return COPY_GENERAL_ERROR; } retval = lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax); if (retval < 0) { lo_close(stmt->hdbc, stmt->lobj_fd); stmt->lobj_fd = -1; stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Error reading from large object."; return COPY_GENERAL_ERROR; } if (retval < left) result = COPY_RESULT_TRUNCATED; else result = COPY_OK; if (pcbValue) *pcbValue = left < 0 ? SQL_NO_TOTAL : left; if (bindInfo && bindInfo->data_left > 0) bindInfo->data_left -= retval; if (! bindInfo || bindInfo->data_left == 0) { lo_close(stmt->hdbc, stmt->lobj_fd); stmt->lobj_fd = -1; /* prevent further reading */ } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -