}
}
+static inline int is_text(const struct odbc_cache_columns *column)
+{
+ return column->type == SQL_CHAR || column->type == SQL_VARCHAR || column->type == SQL_LONGVARCHAR
+ || column->type == SQL_WCHAR || column->type == SQL_WVARCHAR || column->type == SQL_WLONGVARCHAR;
+}
+
static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
{
int res, x = 1, count = 0;
char sql[256];
SQLLEN rowcount=0;
const struct ast_variable *field = fields;
- int res, count = 1;
+ int res, count = 0, paramcount = 0;
struct custom_prepare_struct cps = { .sql = sql, .extra = lookup, .fields = fields, };
struct odbc_cache_tables *tableptr;
struct odbc_cache_columns *column = NULL;
struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
- if (!table || !field) {
+ if (!table || !field || !keyfield) {
return -1;
}
return -1;
}
- if (tableptr && !ast_odbc_find_column(tableptr, field->name)) {
- ast_log(LOG_WARNING, "Key field '%s' does not exist in table '%s@%s'. Update will fail\n", field->name, table, database);
+ if (tableptr && !ast_odbc_find_column(tableptr, keyfield)) {
+ ast_log(LOG_WARNING, "Key field '%s' does not exist in table '%s@%s'. Update will fail\n", keyfield, table, database);
}
- snprintf(sql, sizeof(sql), "UPDATE %s SET %s=?", table, field->name);
- while ((field = field->next)) {
- if ((tableptr && (column = ast_odbc_find_column(tableptr, field->name))) || count > 63) {
- /* NULL test for integer-based columns */
- if (ast_strlen_zero(field->name) && tableptr && column && column->nullable && count < 64 &&
- (column->type == SQL_INTEGER || column->type == SQL_BIGINT ||
- column->type == SQL_SMALLINT || column->type == SQL_TINYINT ||
- column->type == SQL_NUMERIC || column->type == SQL_DECIMAL)) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s=NULL", field->name);
+ snprintf(sql, sizeof(sql), "UPDATE %s SET ", table);
+ while (field) {
+ if ((tableptr && (column = ast_odbc_find_column(tableptr, field->name))) || count >= 64) {
+ if (paramcount++) {
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", ");
+ }
+ /* NULL test for non-text columns */
+ if (count < 64 && ast_strlen_zero(field->value) && column->nullable && !is_text(column)) {
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=NULL", field->name);
cps.skip |= (1LL << count);
} else {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s=?", field->name);
+ /* Value is not an empty string, or column is of text type, or we couldn't fit any more into cps.skip (count >= 64 ?!). */
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", field->name);
}
} else { /* the column does not exist in the table */
cps.skip |= (1LL << count);
}
- count++;
+ ++count;
+ field = field->next;
}
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
ast_odbc_release_table(tableptr);