#include #include #ifdef STANDARD #include #include #ifdef __WIN__ typedef unsigned __int64 ulonglong; typedef __int64 longlong; #else typedef unsigned long long ulonglong; typedef long long longlong; #endif /*__WIN__*/ #else #include #include #endif #include #include #include #define BUFFERSIZE 1024 using namespace std; extern "C" { my_bool udf_count_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); void udf_count_deinit( UDF_INIT* initid ); void udf_count_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); void udf_count_clear( UDF_INIT* initid, char* is_null, char* is_error ); void udf_count_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); double udf_count( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); } struct data { unsigned long long count; int id; ofstream logfile; }; my_bool udf_count_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) { if (args->arg_count < 1 || args->arg_count>2) { strcpy(message,"wrong number of arguments: udf_count() requires one or two arguments"); return 1; } if (args->arg_type[0]!= REAL_RESULT) { strcpy(message,"udf_count() requires a real for parameter 1"); return 1; } if (args->arg_count>1 && (args->arg_type[1]!=INT_RESULT)) { strcpy(message,"udf_count() requires an int as parameter 2"); return 1; } initid->decimals=2; if (args->arg_count==2 && (*((ulong*)args->args[1])<=16)) { initid->decimals=*((ulong*)args->args[1]); } // regression_data *buffer = (regression_data *) malloc(sizeof(struct regression_data)); data *buffer = new data; if (buffer == NULL) { strcpy(message, "Cannot allocate memory for data"); return 1; } buffer->count = 0; /* Seed the random-number generator with current time so that * the numbers will be different every time we run. */ srand( (unsigned)time( NULL ) ); buffer->id = rand(); try { buffer->logfile.open("c:\\ronUDF.log", ios::out | ios::app | ios::binary); if (!buffer->logfile.is_open()) { throw "Can't open logfile for writing"; } } catch (char * str) { strcpy(message, str); return 1; } initid->maybe_null = 1; initid->max_length = 32; //initid->const_item = 0; initid->ptr = (char*)buffer; buffer->logfile << "udf_count_init() initid " << initid << " internal id " << buffer->id << endl; return 0; } void udf_count_deinit( UDF_INIT* initid ) { if (initid != NULL && initid->ptr != NULL) { data *buffer = (data*)initid->ptr; if (buffer->logfile.is_open()) { buffer->logfile << "udf_count_deinit() initid " << initid << " internal id " << buffer->id << " closing logfile" << endl; buffer->logfile.close(); } // free(buffer); delete buffer; initid->ptr = NULL; } } void udf_count_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { data *buffer = (data*)initid->ptr; buffer->logfile << "udf_count_reset() " << buffer->id << endl; udf_count_clear(initid, is_null, is_error); udf_count_add( initid, args, is_null, is_error ); } void udf_count_clear( UDF_INIT* initid, char* is_null, char* is_error ) { data *buffer = (data*)initid->ptr; buffer->count = 0; *is_null = 0; *is_error = 0; buffer->logfile << "udf_count_clear() initid " << initid << " internal id " << buffer->id << " done" << endl; } void udf_count_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { data *buffer = (data*)initid->ptr; if (args->args[0]!=NULL) { double x = *((double*)args->args[0]); buffer->count++; buffer->logfile << "udf_count_add() initid " << initid << " internal id " << buffer->id << " added x " << x << " attribute " << args->attributes[0] << " count " << buffer->count << endl; } } double udf_count( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { data* buffer = (data*)initid->ptr; if (buffer == NULL) { *is_null = 1; *is_error = 1; return 0; } if (buffer->count == 0) { *is_null = 1; buffer->logfile << "udf_count() " << buffer->id << " count was 0" << endl; return 0; } if (is_error && *is_error != 0) { *is_null = 1; buffer->logfile << "udf_count() " << buffer->id << " is_error was not 0" << endl; return 0.0; } buffer->logfile << "udf_count() initid " << initid << " internal id " << buffer->id << " count " << buffer->count << endl; *is_null=0; return buffer->count; }