📄 convert.c
字号:
*((UWORD *)rgbValue + bind_row) = atoi(value); } break; case SQL_C_SLONG: case SQL_C_LONG: len = 4; if (bind_size > 0) { *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); } else { *((SDWORD *)rgbValue + bind_row) = atol(value); } break; case SQL_C_ULONG: len = 4; if (bind_size > 0) { *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); } else { *((UDWORD *)rgbValue + bind_row) = atol(value); } break; case SQL_C_BINARY: // truncate if necessary // convert octal escapes to bytes len = convert_from_pgbinary(value, tempBuf, sizeof(tempBuf)); ptr = tempBuf; if (stmt->current_col >= 0) { /* No more data left for this column */ if (stmt->bindings[stmt->current_col].data_left == 0) return COPY_NO_DATA_FOUND; /* Second (or more) call to SQLGetData so move the pointer */ else if (stmt->bindings[stmt->current_col].data_left > 0) { ptr += len - stmt->bindings[stmt->current_col].data_left; len = stmt->bindings[stmt->current_col].data_left; } /* First call to SQLGetData so initialize data_left */ else stmt->bindings[stmt->current_col].data_left = len; } if (cbValueMax > 0) { copy_len = (len > cbValueMax) ? cbValueMax : len; /* Copy the data */ memcpy(rgbValueBindRow, ptr, copy_len); /* Adjust data_left for next time */ if (stmt->current_col >= 0) { stmt->bindings[stmt->current_col].data_left -= copy_len; } } /* Finally, check for truncation so that proper status can be returned */ if ( len > cbValueMax) result = COPY_RESULT_TRUNCATED; mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len); break; default: return COPY_UNSUPPORTED_TYPE; } } // store the length of what was copied, if there's a place for it if(pcbValue) { *(SDWORD *) ((char *)pcbValue + pcbValueOffset) = len; } return result;}/* This function inserts parameters into an SQL statements. It will also modify a SELECT statement for use with declare/fetch cursors. This function no longer does any dynamic memory allocation!*/intcopy_statement_with_parameters(StatementClass *stmt){static char *func="copy_statement_with_parameters";unsigned int opos, npos;char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5];int param_number;Int2 param_ctype, param_sqltype;char *old_statement = stmt->statement;char *new_statement = stmt->stmt_with_params;SIMPLE_TIME st;time_t t = time(NULL);struct tm *tim;SDWORD used;char *buffer, *buf;char in_quote = FALSE;Oid lobj_oid;int lobj_fd, retval; if ( ! old_statement) { SC_log_error(func, "No statement string", stmt); return SQL_ERROR; } memset(&st, 0, sizeof(SIMPLE_TIME)); /* Initialize current date */ tim = localtime(&t); st.m = tim->tm_mon + 1; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; /* If the application hasn't set a cursor name, then generate one */ if ( stmt->cursor_name[0] == '\0') sprintf(stmt->cursor_name, "SQL_CUR%p", stmt); // For selects, prepend a declare cursor to the statement if (stmt->statement_type == STMT_TYPE_SELECT && globals.use_declarefetch) { sprintf(new_statement, "declare %s cursor for ", stmt->cursor_name); npos = strlen(new_statement); } else { new_statement[0] = '0'; npos = 0; } param_number = -1; for (opos = 0; opos < strlen(old_statement); opos++) { // Squeeze carriage-returns/linfeed pairs to linefeed only if (old_statement[opos] == '\r' && opos+1<strlen(old_statement) && old_statement[opos+1] == '\n') { continue; } // Handle literals (date, time, timestamp) else if (old_statement[opos] == '{') { char *esc; char *begin = &old_statement[opos + 1]; char *end = strchr(begin, '}'); if ( ! end) continue; *end = '\0'; esc = convert_escape(begin); if (esc) { memcpy(&new_statement[npos], esc, strlen(esc)); npos += strlen(esc); } else { /* its not a valid literal so just copy */ *end = '}'; new_statement[npos++] = old_statement[opos]; continue; } opos += end - begin + 1; *end = '}'; continue; } /* Can you have parameter markers inside of quotes? I dont think so. All the queries I've seen expect the driver to put quotes if needed. */ else if (old_statement[opos] == '?' && !in_quote) ; /* ok */ else { if (old_statement[opos] == '\'') in_quote = (in_quote ? FALSE : TRUE); new_statement[npos++] = old_statement[opos]; continue; } /****************************************************/ /* Its a '?' parameter alright */ /****************************************************/ param_number++; if (param_number >= stmt->parameters_allocated) break; /* Assign correct buffers based on data at exec param or not */ if ( stmt->parameters[param_number].data_at_exec) { used = stmt->parameters[param_number].EXEC_used ? *stmt->parameters[param_number].EXEC_used : SQL_NTS; buffer = stmt->parameters[param_number].EXEC_buffer; } else { used = stmt->parameters[param_number].used ? *stmt->parameters[param_number].used : SQL_NTS; buffer = stmt->parameters[param_number].buffer; } /* Handle NULL parameter data */ if (used == SQL_NULL_DATA) { strcpy(&new_statement[npos], "NULL"); npos += 4; continue; } /* If no buffer, and its not null, then what the hell is it? Just leave it alone then. */ if ( ! buffer) { new_statement[npos++] = '?'; continue; } param_ctype = stmt->parameters[param_number].CType; param_sqltype = stmt->parameters[param_number].SQLType; mylog("copy_statement_with_params: from(fcType)=%d, to(fSqlType)=%d\n", param_ctype, param_sqltype); // replace DEFAULT with something we can use if(param_ctype == SQL_C_DEFAULT) param_ctype = sqltype_to_default_ctype(param_sqltype); buf = NULL; param_string[0] = '\0'; cbuf[0] = '\0'; /* Convert input C type to a neutral format */ switch(param_ctype) { case SQL_C_BINARY: case SQL_C_CHAR: buf = buffer; break; case SQL_C_DOUBLE: sprintf(param_string, "%f", *((SDOUBLE *) buffer)); break; case SQL_C_FLOAT: sprintf(param_string, "%f", *((SFLOAT *) buffer)); break; case SQL_C_SLONG: case SQL_C_LONG: sprintf(param_string, "%ld", *((SDWORD *) buffer)); break; case SQL_C_SSHORT: case SQL_C_SHORT: sprintf(param_string, "%d", *((SWORD *) buffer)); break; case SQL_C_STINYINT: case SQL_C_TINYINT: sprintf(param_string, "%d", *((SCHAR *) buffer)); break; case SQL_C_ULONG: sprintf(param_string, "%lu", *((UDWORD *) buffer)); break; case SQL_C_USHORT: sprintf(param_string, "%u", *((UWORD *) buffer)); break; case SQL_C_UTINYINT: sprintf(param_string, "%u", *((UCHAR *) buffer)); break; case SQL_C_BIT: { int i = *((UCHAR *) buffer); sprintf(param_string, "%d", i ? 1 : 0); break; } case SQL_C_DATE: { DATE_STRUCT *ds = (DATE_STRUCT *) buffer; st.m = ds->month; st.d = ds->day; st.y = ds->year; break; } case SQL_C_TIME: { TIME_STRUCT *ts = (TIME_STRUCT *) buffer; st.hh = ts->hour; st.mm = ts->minute; st.ss = ts->second; break; } case SQL_C_TIMESTAMP: { TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer; st.m = tss->month; st.d = tss->day; st.y = tss->year; st.hh = tss->hour; st.mm = tss->minute; st.ss = tss->second; mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); break; } default: // error stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters"; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; new_statement[npos] = '\0'; // just in case SC_log_error(func, "", stmt); return SQL_ERROR; } /* Now that the input data is in a neutral format, convert it to the desired output format (sqltype) */ switch(param_sqltype) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: new_statement[npos++] = '\''; /* Open Quote */ /* it was a SQL_C_CHAR */ if (buf) { convert_special_chars(buf, &new_statement[npos], used); npos += strlen(&new_statement[npos]); } /* it was a numeric type */ else if (param_string[0] != '\0') { strcpy(&new_statement[npos], param_string); npos += strlen(param_string); } /* it was date,time,timestamp -- use m,d,y,hh,mm,ss */ else { sprintf(tmp, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", st.y, st.m, st.d, st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); } new_statement[npos++] = '\''; /* Close Quote */ break; case SQL_DATE: if (buf) { /* copy char data to time */ my_strcpy(cbuf, sizeof(cbuf), buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.4d-%.2d-%.2d'", st.y, st.m, st.d); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_TIME: if (buf) { /* copy char data to time */ my_strcpy(cbuf, sizeof(cbuf), buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.2d:%.2d:%.2d'", st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_TIMESTAMP: if (buf) { my_strcpy(cbuf, sizeof(cbuf), buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'", st.y, st.m, st.d, st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_BINARY: case SQL_VARBINARY: /* non-ascii characters should be converted to octal */ new_statement[npos++] = '\''; /* Open Quote */ mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used); npos += convert_to_pgbinary(buf, &new_statement[npos], used); new_statement[npos++] = '\''; /* Close Quote */ break; case SQL_LONGVARBINARY: if ( stmt->parameters[param_number].data_at_exec) { lobj_oid = stmt->parameters[param_number].lobj_oid; } else { /* store the oid */ lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); if (lobj_oid == 0) { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Couldnt create (in-line) large object."; SC_log_error(func, "", stmt); return SQL_ERROR; } /* store the fd */ lobj_fd = lo_open(stmt->hdbc, lobj_oid, INV_WRITE); if ( lobj_fd < 0) { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Couldnt open (in-line) large object for writing."; SC_log_error(func, "", stmt); return SQL_ERROR; } retval = lo_write(stmt->hdbc, lobj_fd, buffer, used); lo_close(stmt->hdbc, lobj_fd); } /* the oid of the large object -- just put that in for the parameter marker -- the data has already been sent to the large object */ sprintf(param_string, "'%d'", lobj_oid); strcpy(&new_statement[npos], param_string); npos += strlen(param_string); break; // because of no conversion operator for bool and int4, SQL_BIT // must be quoted (0 or 1 is ok to use inside the quotes) default: /* a numeric type or SQL_BIT */ if (param_sqltype == SQL_BIT) new_statement[npos++] = '\''; /* Open Quote */ if (buf) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -