示例#1
0
int datetime_as_string(PyObject *obj, char *text)
{
    CS_DATAFMT datetime_fmt;
    CS_DATAFMT char_fmt;
    CS_INT char_len;
    CS_CONTEXT *ctx;
    int type;
    void *data;

    type = ((DateTimeObj*)obj)->type;
    datetime_datafmt(&datetime_fmt, type);
    char_datafmt(&char_fmt);
    char_fmt.maxlength = DATETIME_LEN;

    if (type == CS_DATETIME_TYPE)
	data = &((DateTimeObj*)obj)->v.datetime;
    else
	data = &((DateTimeObj*)obj)->v.datetime4;
    ctx = global_ctx();
    if (ctx == NULL)
	return CS_FAIL;

    return cs_convert(ctx,
		      &datetime_fmt, data,
		      &char_fmt, text, &char_len);
}
示例#2
0
/* Implement the mssqldb.datetime() method
 */
PyObject *DateTimeType_new(PyObject *module, PyObject *args)
{
    CS_DATAFMT datetime_fmt;
    CS_DATAFMT char_fmt;
    CS_CONTEXT *ctx;
    int type = CS_DATETIME_TYPE;
    char *str;
    CS_DATETIME datetime;
    CS_INT datetime_len;
    CS_RETCODE conv_result;

    if (!PyArg_ParseTuple(args, "s|i", &str, &type))
	return NULL;

    datetime_datafmt(&datetime_fmt, type);
    char_datafmt(&char_fmt);
    char_fmt.maxlength = strlen(str);

    /* PyErr_Clear(); */
    ctx = global_ctx();
    if (ctx == NULL)
	return NULL;
    conv_result = cs_convert(ctx,
			     &char_fmt, str,
			     &datetime_fmt, &datetime, &datetime_len);
    if (PyErr_Occurred())
	return NULL;
    if (conv_result != CS_SUCCEED) {
	PyErr_SetString(PyExc_TypeError, "datetime from string conversion failed");
	return NULL;
    }

    return datetime_alloc(&datetime, type);
}
示例#3
0
static PyObject *DateTime_float(DateTimeObj *v)
{
    CS_DATAFMT datetime_fmt;
    CS_DATAFMT float_fmt;
    CS_FLOAT float_value;
    CS_INT float_len;
    CS_CONTEXT *ctx;
    void *value;
    CS_RETCODE conv_result;

    datetime_datafmt(&datetime_fmt, v->type);
    float_datafmt(&float_fmt);

    if (v->type == CS_DATETIME_TYPE)
	value = &v->v.datetime;
    else
	value = &v->v.datetime4;

    /* PyErr_Clear(); */
    ctx = global_ctx();
    if (ctx == NULL)
	return NULL;
    conv_result = cs_convert(ctx, &datetime_fmt, value,
			     &float_fmt, &float_value, &float_len);
    if (PyErr_Occurred())
	return NULL;
    if (conv_result != CS_SUCCEED) {
	PyErr_SetString(PyExc_TypeError, "float conversion failed");
	return NULL;
    }

    return PyFloat_FromDouble(float_value);
}
示例#4
0
PyObject *DateTime_FromString(PyObject *obj)
{
    CS_DATAFMT datetime_fmt;
    CS_DATAFMT char_fmt;
    CS_DATETIME datetime;
    CS_INT datetime_len;
    CS_CONTEXT *ctx;
    char *str = PyString_AsString(obj);
    CS_RETCODE conv_result;

    datetime_datafmt(&datetime_fmt, CS_DATETIME_TYPE);
    char_datafmt(&char_fmt);
    char_fmt.maxlength = strlen(str);

    /* PyErr_Clear(); */
    ctx = global_ctx();
    if (ctx == NULL)
	return NULL;
    conv_result = cs_convert(ctx,
			     &char_fmt, str,
			     &datetime_fmt, &datetime, &datetime_len);
    if (PyErr_Occurred())
	return NULL;
    if (conv_result != CS_SUCCEED) {
	PyErr_SetString(PyExc_TypeError, "datetime from string conversion failed");
	return NULL;
    }

    return datetime_alloc(&datetime, CS_DATETIME_TYPE);
}
示例#5
0
int datetime_assign(PyObject *obj, int type, void *buff)
{
    CS_DATAFMT src_fmt;
    CS_DATAFMT dest_fmt;
    void *src_buff;
    CS_RETCODE conv_result;
    CS_INT datetime_len;
    CS_CONTEXT *ctx;

    if (((DateTimeObj*)obj)->type == type) {
	if (type == CS_DATETIME_TYPE)
	    *(CS_DATETIME*)buff = ((DateTimeObj*)obj)->v.datetime;
	else
	    *(CS_DATETIME4*)buff = ((DateTimeObj*)obj)->v.datetime4;
	return CS_SUCCEED;
    }
    datetime_datafmt(&src_fmt, ((DateTimeObj*)obj)->type);
    datetime_datafmt(&dest_fmt, type);

    if (((DateTimeObj*)obj)->type == CS_DATETIME_TYPE)
	src_buff = &((DateTimeObj*)obj)->v.datetime;
    else
	src_buff = &((DateTimeObj*)obj)->v.datetime4;

    /* PyErr_Clear(); */

    ctx = global_ctx();
    if (ctx == NULL)
	return CS_FAIL;

    conv_result = cs_convert(ctx,
			     &src_fmt, src_buff,
			     &dest_fmt, buff, &datetime_len);
    if (PyErr_Occurred())
	return CS_FAIL;
    if (conv_result != CS_SUCCEED)
	PyErr_SetString(PyExc_TypeError, "datetime conversion failed");
    return conv_result;
}
示例#6
0
static int
DoTest(
	      /* source information */
	      CS_INT fromtype, void *fromdata, CS_INT fromlen,
	      /* to information */
	      CS_INT totype, CS_INT tomaxlen,
	      /* expected result */
	      CS_RETCODE tores, void *todata, CS_INT tolen,
	      /* fields in string format */
	      STR sdecl,
	      STR sfromtype, STR sfromdata, STR sfromlen, STR stotype, STR stomaxlen, STR stores, STR stodata, STR stolen,
	      /* source line number for error reporting */
	      int line)
{
	CS_DATAFMT destfmt, srcfmt;
	CS_INT reslen;
	CS_RETCODE retcode;
	int i;
	char buffer[1024];
	const char *err = "";

	assert(tolen >= 0);

	memset(&destfmt, 0, sizeof(destfmt));
	destfmt.datatype = totype;
	destfmt.maxlength = tomaxlen;

	memset(&srcfmt, 0, sizeof(srcfmt));
	srcfmt.datatype = fromtype;
	srcfmt.maxlength = fromlen;

	/*
	 * FIXME this fix some thing but if error cs_convert should return
	 * CS_UNUSED; note that this is defined 5.. a valid result ...
	 */
	reslen = 0;

	/*
	 * TODO: add special case for CS_CHAR_TYPE and give different
	 * flags and len
	 */

	/* do convert */
	memset(buffer, 23, sizeof(buffer));
	retcode = cs_convert(ctx, &srcfmt, fromdata, &destfmt, buffer, &reslen);

	/* test result of convert */
	if (tores != retcode) {
		err = "result";
		goto Failed;
	}

	/* test result len */
	if (reslen != tolen) {
		err = "result length";
		goto Failed;
	}

	/* test buffer */
	if (todata && memcmp(todata, buffer, tolen) != 0) {
		int n;
		for (n = 0; n < tolen; ++n)
			printf("%02x ", ((unsigned char*)todata)[n]);
		printf("\n");
		for (n = 0; n < tolen; ++n)
			printf("%02x ", ((unsigned char*)buffer)[n]);
		printf("\n");

		err = "result data";
		goto Failed;
	}

	/* test other part of buffer */
	if (todata)
		memset(buffer, 23, tolen);
	for (i = 0; i < sizeof(buffer); ++i)
		if (buffer[i] != 23) {
			err = "buffer left";
			goto Failed;
		}

	/* success */
	return 0;
      Failed:
	fprintf(stderr, "Test %s failed (ret=%d len=%d)\n", err, (int) retcode, (int) reslen);
	fprintf(stderr, "line: %d\n  DO_TEST(%s,\n"
		"\t   %s,%s,%s,\n"
		"\t   %s,%s,\n"
		"\t   %s,%s,%s);\n", line, sdecl, sfromtype, sfromdata, sfromlen, stotype, stomaxlen, stores, stodata, stolen);
	allSuccess = 0;
	return 1;
}
示例#7
0
static VALUE statement_Execute(VALUE self) {
	int i;
	CS_DATAFMT col;
	CS_DATAFMT *cols;
	EX_COLUMN_DATA *col_data;
	CS_INT rc;
	CS_INT resulttype;
	CS_INT num_cols;
	CS_INT col_len;
	CS_INT row_count = 0;
	CS_INT rows_read;
	
	CS_INT num_errors = 0;
	CS_SERVERMSG servermsg;
	VALUE err;
	char *error_msg;
	
	struct timeval start, stop;
	int print_rows = 1;
	char message[128];
	char* buf;
	CS_DATEREC date_rec;
	char output[200];
	CS_INT output_len;
	int tempInt;
	CS_BIGINT tempBigInt;
	double tempDouble;
	CS_NUMERIC tempNumeric;
	char* tempText;
	char* newTempText;
	int tempTextLen;
	CS_INT data_rc;
	int isNull = 0;
	CS_DATE tempDate;
	CS_DATETIME tempDateTime;

	TDS_Connection* conn;
	CS_COMMAND * cmd;
	
	VALUE connection;
	VALUE query;
	VALUE columns;
	VALUE rows;
	VALUE status;
	VALUE errors;
	
	VALUE date_parts[8];
	
	VALUE column;
	VALUE row;
	
	VALUE column_name = rb_str_new2("name");
	VALUE column_type = rb_str_new2("type");
	VALUE column_size = rb_str_new2("size");
	VALUE column_scale = rb_str_new2("scale");
	VALUE column_precision = rb_str_new2("precision");
	
	VALUE column_value;
	
	connection = rb_iv_get(self, "@connection");
	query = rb_iv_get(self, "@query");
	
	columns = rb_ary_new();
	rb_iv_set(self, "@columns", columns);

	rows = rb_ary_new();
	rb_iv_set(self, "@rows", rows);
	
	Data_Get_Struct(connection, TDS_Connection, conn);
	buf = value_to_cstr(query);

	rb_iv_set(self, "@status", Qnil);
	
	rb_iv_set(self, "@messages", rb_ary_new());
	errors = rb_ary_new();
	rb_iv_set(self, "@errors", errors);

	ct_diag(conn->connection, CS_INIT, CS_UNUSED, CS_UNUSED, NULL);
	// if ( ct_callback(conn->context, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)clientmsg_cb) != CS_SUCCEED ) {
	// 	error_message("ct_callback CS_CLIENTMSG_CB failed\n");
	// }
	// if ( ct_callback(conn->context, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)servermsg_cb) != CS_SUCCEED ) {
	// 	error_message("ct_callback CS_SERVERMSG_CB failed\n");
	// }
	ct_cmd_alloc(conn->connection, &cmd);
	ct_command(cmd, CS_LANG_CMD, buf, CS_NULLTERM, CS_UNUSED);
	ct_send(cmd);

	if ( ct_diag(conn->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &num_errors) != CS_SUCCEED ) {
		error_message("ct_diag CS_STATUS CS_SERVERMSG_TYPE failed");
	}
	if (num_errors > 0) {
		// fprintf(stderr, "%d errors found\n", num_errors);
		for (i = 0; i < num_errors; i++) {
			if ( ct_diag(conn->connection, CS_GET, CS_SERVERMSG_TYPE, i+1, &servermsg) != CS_SUCCEED ) {
				error_message("ct_diag CS_GET CS_SERVERMSG_TYPE failed");
			}
			if (servermsg.severity > 0) {
				// error_message(servermsg.text);
				rb_ary_push(errors, rb_str_new2(servermsg.text));
			}
		}
		if ( ct_diag(conn->connection, CS_CLEAR, CS_SERVERMSG_TYPE, CS_UNUSED, NULL) != CS_SUCCEED ) {
			error_message("ct_diag CS_CLEAR CS_SERVERMSG_TYPE failed");
		}
	}
	
	// Raise errors from ct_command/ct_send
	err = rb_funcall(errors, rb_intern("first"), 0); // FIXME: should probably display all errors instead of just first
	if(RTEST(err)) {
		error_msg = value_to_cstr(err);
		rb_raise(rb_eIOError, error_msg);

		ct_cmd_drop(cmd);

		return Qnil;
	}
	// TODO:
	// - We should have an array of malloc'd cols
	// - Then we bind / fetch to those
	// - Finish conversions...
	
	while ((rc = ct_results(cmd, &resulttype)) == CS_SUCCEED) {
		switch (resulttype) {
		case CS_ROW_RESULT:
			rc = ct_res_info(cmd, CS_NUMDATA, &num_cols, sizeof(num_cols), &col_len);
			if (rc != CS_SUCCEED)
			{
				fprintf(stderr, "ct_res_info() failed\n");
				return 1;
			}

			col_data = (EX_COLUMN_DATA *)malloc(num_cols * sizeof (EX_COLUMN_DATA));
			if (col_data == NULL)
			 {
			    fprintf(stderr, "ex_fetch_data: malloc() failed");
			    return CS_MEM_ERROR;
			 }
			 cols = (CS_DATAFMT *)malloc(num_cols * sizeof (CS_DATAFMT));
			 if (cols == NULL)
			 {
			    fprintf(stderr, "ex_fetch_data: malloc() failed");
			    free(col_data);
			    return CS_MEM_ERROR;
			 }
			
			
			// Get column information
			for (i = 0; i < num_cols; i++) {
				rc = ct_describe(cmd, (i+1), &cols[i]);
				if ( rc != CS_SUCCEED ) {
					fprintf(stderr, "ct_describe failed on col #%d", i+1);
				}

				column_value = rb_hash_new();
				// fprintf(stderr, "%s\n", cols[i].name);
				if (cols[i].name) {
					rb_hash_aset(column_value, column_name, rb_str_new2(cols[i].name));
				} else {
					rb_hash_aset(column_value, column_name, Qnil);
				}
				
				rb_hash_aset(column_value, column_type, rb_str_new2(column_type_name(cols[i])));
				rb_hash_aset(column_value, column_size, INT2FIX(cols[i].maxlength));
				rb_hash_aset(column_value, column_scale, INT2FIX(cols[i].scale));
				rb_hash_aset(column_value, column_precision, INT2FIX(cols[i].precision));

				rb_ary_push(columns, column_value);
			}
			
			// Fetch data
			while (((rc = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) == CS_SUCCEED) || (rc == CS_ROW_FAIL)) {
				row_count = row_count + rows_read;

				row = rb_hash_new();
				rb_ary_push(rows, row);
				
				// Create Ruby objects
				for (i = 0; i < num_cols; i++) {
					// if (col_data[i].indicator == -1) {
					// 	rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
					// 	continue;
					// }
					switch (cols[i].datatype) {
					case CS_TINYINT_TYPE:
					case CS_BIT_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempInt, sizeof(tempInt), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							if(tempInt == 1) {
								rb_hash_aset(row, rb_str_new2(cols[i].name), Qtrue);
							} else {
								rb_hash_aset(row, rb_str_new2(cols[i].name), Qfalse);
							}
						}
						tempInt = -1;
						break;
					case CS_INT_TYPE:
					case CS_SMALLINT_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempInt, sizeof(tempInt), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), INT2FIX(tempInt));
						}
						tempInt = -1;
						break;
					
					case CS_DATETIME_TYPE:
					case CS_DATETIME4_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempDateTime, sizeof(tempDateTime), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							if ( cs_dt_crack(conn->context, CS_DATETIME_TYPE, &tempDateTime, &date_rec) == CS_SUCCEED ) {
								if(date_rec.dateyear && date_rec.datemonth && date_rec.datedmonth) {
									date_parts[0] = INT2FIX(date_rec.dateyear);
									date_parts[1] = INT2FIX(date_rec.datemonth+1);
									date_parts[2] = INT2FIX(date_rec.datedmonth);
									date_parts[3] = INT2FIX(date_rec.datehour);
									date_parts[4] = INT2FIX(date_rec.dateminute);
									date_parts[5] = INT2FIX(date_rec.datesecond);
									date_parts[6] = INT2FIX(date_rec.datemsecond);
									date_parts[7] = INT2FIX(date_rec.datetzone);
							
									// String (fastest known so far, but pushes the burden to ActiveRecord for parsing)
									sprintf(output, "%d-%02d-%02d %02d:%02d:%02d.%03d", date_rec.dateyear, date_rec.datemonth+1, date_rec.datedmonth, date_rec.datehour, date_rec.dateminute, date_rec.datesecond, date_rec.datemsecond);
									rb_hash_aset(row, rb_str_new2(cols[i].name), rb_str_new2(output));
								
									// DateTime - this is slow a f*ck
									//rb_hash_aset(row, rb_str_new2(cols[i].name), rb_funcall2(rb_DateTime, rb_intern("civil"), 6, &date_parts[0]));
								
									// Time - way faster than DateTime
									// FIXME: should we be assuming utc?!
									// rb_hash_aset(row, rb_str_new2(cols[i].name), rb_funcall2(rb_cTime, rb_intern("utc"), 6, &date_parts[0]));
								} else {
									rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
								}
							} else {
								fprintf(stderr, "cs_dt_crack failed\n");
							}
						}
						// tempDateTime = 0; // not sure how to clear this...
						break;
					
					// case CS_REAL_TYPE:
					case CS_FLOAT_TYPE:
					// case CS_MONEY_TYPE:
					// case CS_MONEY4_TYPE: 
						data_rc = ct_get_data(cmd, (i + 1), &tempDouble, sizeof(tempDouble), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), rb_float_new(tempDouble));
						}
						tempDouble = -1.0;
						break;
					
					// case CS_BIGINT_TYPE:
					// 	error_message("HELLO BIGINT!");
					// 	break;
						
					case CS_DECIMAL_TYPE:
					case CS_NUMERIC_TYPE:
						// fprintf(stderr, "CS_NUMERIC_TYPE detected - name: %s\n", cols[i].name);
						
						data_rc = ct_get_data(cmd, (i + 1), &tempNumeric, sizeof(tempNumeric), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							// fprintf(stderr, "tempNumeric output_len: %d, precision: %d, scale: %d, array: %s\n", output_len, tempNumeric.precision, tempNumeric.scale, tempNumeric.array);
							col.datatype = CS_CHAR_TYPE;
							col.format = CS_FMT_NULLTERM;
							col.maxlength = 200;
							// col.maxlength = cols[i].precision + 1;
							data_rc = cs_convert(conn->context, &cols[i], &tempNumeric, &col, output, &output_len);
							if ( data_rc != CS_SUCCEED ) {
								error_message("CS_NUMERIC_TYPE conversion failed");
								fprintf(stderr, "cs_convert returned: %d\n", data_rc);
							}
							// fprintf(stderr, "numeric output_len: %d, output: %s\n", output_len, output);
							rb_hash_aset(row, rb_str_new2(cols[i].name), LL2NUM(strtoll(output, NULL, 10)));
						}
						break;
						
					case CS_CHAR_TYPE:
					case CS_LONGCHAR_TYPE:
					case CS_TEXT_TYPE:
					case CS_VARCHAR_TYPE:
					case CS_UNICHAR_TYPE:
					case CS_UNIQUE_TYPE: // @todo should this one be handled differently?
						isNull = 0;
						tempTextLen = 1; // 1 for \0
						do {
							newTempText = realloc((tempTextLen == 1 ? NULL : tempText), tempTextLen + (1000 * sizeof(char))); // allocate another 1000 chars
							if (newTempText != NULL) {
								tempText = newTempText;
							} else {
								fprintf(stderr, "realloc error\n");
							}
							
							data_rc = ct_get_data(cmd, (i + 1), tempText + tempTextLen - 1, 1000, &output_len);

							if (tempTextLen == 1 && output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
								isNull = 1;
							}
								
							tempTextLen = tempTextLen + output_len;
						} while (data_rc == CS_SUCCEED);
						if (data_rc != CS_END_DATA && data_rc != CS_END_ITEM)
						{
							fprintf(stderr, "ct_get_data failed, data_rc = %d\n", data_rc);
							return data_rc;
						}
						tempText[tempTextLen-1] = '\0';
						if (isNull == 1) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), rb_str_new2(tempText));
						}
						
						free(tempText);
						tempText = NULL;
						break;
					
					case CS_BINARY_TYPE:
					case CS_LONGBINARY_TYPE:
					case CS_VARBINARY_TYPE:
					case CS_IMAGE_TYPE:
						// rb_hash_aset(row, rb_str_new2(tds->res_info->columns[i]->column_name), rb_str_new((char *) ((TDSBLOB *) src)->textvalue, tds->res_info->columns[i]->column_cur_size));						
						rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						break;

					default:
						rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						printf("\nUnexpected datatype: %d\n", cols[i].datatype);
					}

				
				}
			}
			
			if( rc != CS_END_DATA )
			{
			    fprintf(stderr, "ct_fetch failed");
			}
			
			free(cols);
			cols = NULL;
			free(col_data);
			col_data = NULL;
			
			break;
		case CS_CMD_SUCCEED:
			rb_iv_set(self, "@status", Qnil);
			break;
		case CS_CMD_FAIL:
			if ( ct_diag(conn->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &num_errors) != CS_SUCCEED ) {
				error_message("ct_diag CS_STATUS CS_SERVERMSG_TYPE failed");
			}
			if (num_errors > 0) {
				// fprintf(stderr, "%d errors found\n", num_errors);
				for (i = 0; i < num_errors; i++) {
					if ( ct_diag(conn->connection, CS_GET, CS_SERVERMSG_TYPE, i+1, &servermsg) != CS_SUCCEED ) {
						error_message("ct_diag CS_GET CS_SERVERMSG_TYPE failed");
					}
					if (servermsg.severity > 0) {
						// error_message(servermsg.text);
						rb_ary_push(errors, rb_str_new2(servermsg.text));
					}
				}
				if ( ct_diag(conn->connection, CS_CLEAR, CS_SERVERMSG_TYPE, CS_UNUSED, NULL) != CS_SUCCEED ) {
					error_message("ct_diag CS_CLEAR CS_SERVERMSG_TYPE failed");
				}
			}
		
			err = rb_funcall(errors, rb_intern("first"), 0); // FIXME: should probably display all errors instead of just first
			if(RTEST(err)) {
				error_msg = value_to_cstr(err);
				rb_raise(rb_eIOError, error_msg);
			} else {
				rb_raise(rb_eIOError, "CS_CMD_FAIL without server error message");
			}
			// rb_iv_set(self, "@status", INT2FIX(0));
			break;
		case CS_CMD_DONE:
			rb_iv_set(self, "@status", Qnil);
			break;
		case CS_STATUS_RESULT:
			// FIXME: We should probably do something here, right?
			break;
		default:
			fprintf(stderr, "ct_results returned unexpected result type: %d\n", resulttype);
			break;
		}
	}

	ct_cmd_drop(cmd);
	
	return Qnil;	
}
示例#8
0
static int 
insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
{
	CS_CONTEXT *ctx;

	CS_RETCODE ret;
	CS_INT res_type;

	CS_DATAFMT datafmt;
	CS_DATAFMT srcfmt;
	CS_DATAFMT destfmt;
	CS_INT intvar;
	CS_FLOAT floatvar;
	CS_MONEY moneyvar;
	CS_DATEREC datevar;
	char moneystring[10];
	char dummy_name[30];
	char dummy_name2[20];
	CS_INT destlen;

	/* clear table */
	run_command(cmd, "delete #ctparam_lang");

	/*
	 * Assign values to the variables used for parameter passing.
	 */

	intvar = 2;
	floatvar = 0.12;
	strcpy(dummy_name, "joe blow");
	strcpy(dummy_name2, "");
	strcpy(moneystring, "300.90");

	/*
	 * Clear and setup the CS_DATAFMT structures used to convert datatypes.
	 */

	memset(&srcfmt, 0, sizeof(CS_DATAFMT));
	srcfmt.datatype = CS_CHAR_TYPE;
    srcfmt.maxlength = (CS_INT)strlen(moneystring);
	srcfmt.precision = 5;
	srcfmt.scale = 2;
	srcfmt.locale = NULL;

	memset(&destfmt, 0, sizeof(CS_DATAFMT));
	destfmt.datatype = CS_MONEY_TYPE;
	destfmt.maxlength = sizeof(CS_MONEY);
	destfmt.precision = 5;
	destfmt.scale = 2;
	destfmt.locale = NULL;

	/*
	 * Convert the string representing the money value
	 * to a CS_MONEY variable. Since this routine does not have the
	 * context handle, we use the property functions to get it.
	 */
	if ((ret = ct_cmd_props(cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL)) != CS_SUCCEED) {
		fprintf(stderr, "ct_cmd_props() failed\n");
		return 1;
	}
	if ((ret = ct_con_props(conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL)) != CS_SUCCEED) {
		fprintf(stderr, "ct_con_props() failed\n");
		return 1;
	}
	ret = cs_convert(ctx, &srcfmt, (CS_VOID *) moneystring, &destfmt, &moneyvar, &destlen);
	if (ret != CS_SUCCEED) {
		fprintf(stderr, "cs_convert() failed\n");
		return 1;
	}

	/*
	 * create the command
	 */
    if ((ret = ct_command(cmd, CS_LANG_CMD, query, (CS_INT)strlen(query),
		CS_UNUSED)) != CS_SUCCEED) 
	{
		fprintf(stderr, "ct_command(CS_LANG_CMD) failed\n");
		return 1;
	}

	/*
	 * Clear and setup the CS_DATAFMT structure, then pass
	 * each of the parameters for the query.
	 */
	memset(&datafmt, 0, sizeof(datafmt));
	if (useNames)
		strcpy(datafmt.name, "@in1");
	else
		datafmt.name[0] = 0;
	datafmt.maxlength = 255;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_CHAR_TYPE;
	datafmt.status = CS_INPUTVALUE;

	/*
	 * The character string variable is filled in by the RPC so pass NULL
	 * for the data 0 for data length, and -1 for the indicator arguments.
	 */
    ret = ct_param(cmd, &datafmt, dummy_name, (CS_INT)strlen(dummy_name), 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(char) failed\n");
		return 1;
	}

	if (useNames)
		strcpy(datafmt.name, "@in2");
	else
		datafmt.name[0] = 0;
	datafmt.maxlength = 255;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_CHAR_TYPE;
	datafmt.status = CS_INPUTVALUE;

    ret = ct_param(cmd, &datafmt, dummy_name2, (CS_INT)strlen(dummy_name2), 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(char) failed\n");
		return 1;
	}

	if (useNames)
		strcpy(datafmt.name, "@in3");
	else
		datafmt.name[0] = 0;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_INT_TYPE;
	datafmt.status = CS_INPUTVALUE;

	ret = ct_param(cmd, &datafmt, (CS_VOID *) & intvar, CS_SIZEOF(CS_INT), 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(int) failed\n");
		return 1;
	}

	if (useNames)
		strcpy(datafmt.name, "@moneyval");
	else
		datafmt.name[0] = 0;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_MONEY_TYPE;
	datafmt.status = CS_INPUTVALUE;

	ret = ct_param(cmd, &datafmt, (CS_VOID *) & moneyvar, CS_SIZEOF(CS_MONEY), 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(money) failed\n");
		return 1;
	}

	if (useNames)
		strcpy(datafmt.name, "@dateval");
	else
		datafmt.name[0] = 0;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_DATETIME_TYPE;
	datafmt.status = CS_INPUTVALUE;
	memset(&datevar, 0, sizeof(CS_DATEREC));
	datevar.dateyear = 2003;
	datevar.datemonth = 2;
	datevar.datedmonth = 1;

	ret = ct_param(cmd, &datafmt, &datevar, 0, 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(datetime) failed");
		return 1;
	}

	if (useNames)
		strcpy(datafmt.name, "@floatval");
	else
		datafmt.name[0] = 0;
	datafmt.namelen = CS_NULLTERM;
	datafmt.datatype = CS_FLOAT_TYPE;
	datafmt.status = CS_INPUTVALUE;

	ret = ct_param(cmd, &datafmt, &floatvar, 0, 0);
	if (CS_SUCCEED != ret) {
		fprintf(stderr, "ct_param(float) failed");
		return 1;
	}

	/*
	 * Send the command to the server
	 */
	if (ct_send(cmd) != CS_SUCCEED) {
		fprintf(stderr, "ct_send(CS_LANG_CMD) failed\n");
		return 1;
	}

	/*
	 * Process the results.
	 */
	while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
		switch ((int) res_type) {

		case CS_CMD_SUCCEED:
		case CS_CMD_DONE:
			{
				CS_INT rowsAffected=0;
				ct_res_info(cmd, CS_ROW_COUNT, &rowsAffected, CS_UNUSED, NULL);
				if (1 != rowsAffected) 
					fprintf(stderr, "insert touched %d rows instead of 1\n", rowsAffected);
			}
			break;

		case CS_CMD_FAIL:
			/*
			 * The server encountered an error while
			 * processing our command.
			 */
			fprintf(stderr, "ct_results returned CS_CMD_FAIL.\n");
			break;

		case CS_STATUS_RESULT:
			/*
			 * The server encountered an error while
			 * processing our command.
			 */
			fprintf(stderr, "ct_results returned CS_STATUS_RESULT.\n");
			break;

		default:
			/*
			 * We got something unexpected.
			 */
			fprintf(stderr, "ct_results returned unexpected result type %d\n", res_type);
			return 1;
		}
	}
	if (ret != CS_END_RESULTS)
		fprintf(stderr, "ct_results returned unexpected result %d.\n", (int) ret);

	/* test row inserted */
	ret = run_command(cmd, "if not exists(select * from #ctparam_lang where name = 'joe blow' and name2 is not null and age = 2) select 1");
	if (ret != CS_SUCCEED) {
		fprintf(stderr, "check row inserted failed\n");
		exit(1);
	}

	return 0;
}
示例#9
0
/*
 * ct_send SQL |select name = @@servername|
 * ct_bind variable
 * ct_fetch and print results
 */
int
main(int argc, char **argv)
{
	int verbose = 1;
	CS_CONTEXT *ctx;
	CS_RETCODE ret;
	CS_DATAFMT srcfmt;
	CS_INT src = 32768;
	CS_DATAFMT dstfmt;
	CS_SMALLINT dst;
	CS_DATETIME dst_date;

	int i;

	CS_INT num_msgs;
	CS_CLIENTMSG client_message;

	fprintf(stdout, "%s: Testing context callbacks\n", __FILE__);

	srcfmt.datatype = CS_INT_TYPE;
	srcfmt.maxlength = sizeof(CS_INT);
	srcfmt.locale = NULL;

	dstfmt.datatype = CS_SMALLINT_TYPE;
	dstfmt.maxlength = sizeof(CS_SMALLINT);
	dstfmt.locale = NULL;

	if (verbose) {
		fprintf(stdout, "Trying clientmsg_cb with context\n");
	}
	if (cs_ctx_alloc(CS_VERSION_100, &ctx) != CS_SUCCEED) {
		fprintf(stderr, "cs_ctx_alloc() failed\n");
	}
	if (ct_init(ctx, CS_VERSION_100) != CS_SUCCEED) {
		fprintf(stderr, "ct_init() failed\n");
	}

	if (cs_diag(ctx, CS_INIT, CS_UNUSED, CS_UNUSED, NULL) != CS_SUCCEED) {
		fprintf(stderr, "cs_diag(CS_INIT) failed\n");
		return 1;
	}

	if (cs_convert(ctx, &srcfmt, &src, &dstfmt, &dst, NULL) == CS_SUCCEED) {
		fprintf(stderr, "cs_convert() succeeded when failure was expected\n");
		return 1;
	}

	dstfmt.datatype = CS_DATETIME_TYPE;
	dstfmt.maxlength = sizeof(CS_DATETIME);
	dstfmt.locale = NULL;

	if (cs_convert(ctx, &srcfmt, &src, &dstfmt, &dst_date, NULL) == CS_SUCCEED) {
		fprintf(stderr, "cs_convert() succeeded when failure was expected\n");
		return 1;
	}

	if (cs_diag(ctx, CS_STATUS, CS_CLIENTMSG_TYPE, CS_UNUSED, &num_msgs) != CS_SUCCEED) {
		fprintf(stderr, "cs_diag(CS_STATUS) failed\n");
		return 1;
	}

	for (i = 0; i < num_msgs; i++ ) {

		if (cs_diag(ctx, CS_GET, CS_CLIENTMSG_TYPE, i + 1, &client_message) != CS_SUCCEED) {
			fprintf(stderr, "cs_diag(CS_GET) failed\n");
			return 1;
		}
	
	    cslibmsg_cb(NULL, &client_message);
	
	}

	if ((ret = cs_diag(ctx, CS_GET, CS_CLIENTMSG_TYPE, i + 1, &client_message)) != CS_NOMSG) {
		fprintf(stderr, "cs_diag(CS_GET) did not fail with CS_NOMSG\n");
		return 1;
	}

	if (cs_diag(ctx, CS_CLEAR, CS_CLIENTMSG_TYPE, CS_UNUSED, NULL) != CS_SUCCEED) {
		fprintf(stderr, "cs_diag(CS_CLEAR) failed\n");
		return 1;
	}

	if (cs_diag(ctx, CS_STATUS, CS_CLIENTMSG_TYPE, CS_UNUSED, &num_msgs) != CS_SUCCEED) {
		fprintf(stderr, "cs_diag(CS_STATUS) failed\n");
		return 1;
	}
	if (num_msgs != 0) {
		fprintf(stderr, "cs_diag(CS_CLEAR) failed there are still %d messages on queue\n", num_msgs);
		return 1;
	}

	if (ct_exit(ctx, CS_UNUSED) != CS_SUCCEED) {
		fprintf(stderr, "ct_exit() failed\n");
	}
	if (cs_ctx_drop(ctx) != CS_SUCCEED) {
		fprintf(stderr, "cx_ctx_drop() failed\n");
	}

	return 0;
}