/* mysqludf_blobfile - a library for load and save blob to file. */ #include #include #include #include #include #include #include //#include #include #include using namespace std; /************************ Example show 3-Dimensional data. int,int,int,int;3;3;2; { { {1,4}{3,5}{3,6} } { {4,7}{5,8}{6,9} } { {6,1}{8,1}{5,1} } } The structure will be filled like this: dim = 3 noEle = 18 dimVal_size = 12 (The length of characters used for defining dimensions datatype in this case it will be "int,int,int,".) dimVal = int,int,int, (This pointer contains the actual dimension type.) eleType_size = 3 (size of the charactors used to define element type.) eleType = int (Actuall datatype in elements.) dimA_size = 1 1 1 (Contains the number of charactors used to define length of each dimension. in this case we have "3;3;2"m required 1 charactor for each dinmension.) dimA = 3 3 2 (Actuall length of each dimension.) intA = (pointer contains all the integer elements.) doubleA = (pointer contains all the double elements.) stringA_size = (In case of strings, this variable contains the length of a string in each dimension.) stringA = (Contains the actual string.) Example show 2-Dimensional data. int,int,int;10;10; { {1,3,5,3,6,6,7,8,9,23} {4,7,5,8,9,5,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} {6,1,8,1,1,9,7,8,9,23} } dim = 2 noEle = 100 dimVal_size = 8 dimVal = int,int, eleType_size = 3 eleType = int dimA_size = 2 2 dimA = 10 10 intA = ------- (All the elements. ) *************************/ struct Matrix{ int dim; // long int noEle; int dimVal_size; char* dimVal; int eleType_size; char* eleType; // datatype of the values to be stored in intA or int* dimA_size; char ** dimA; // diamension data int * intA;// int value array double* doubleA;// double value array int* stringA_size; char** stringA;// string value array } ; #if defined(_WIN32) || defined(_WIN64) #define DLLEXP __declspec(dllexport) #else #define DLLEXP #endif /****************************************************************************** ** FUNCTION DECLARATIONS ******************************************************************************/ #ifdef __cplusplus extern "C" { #endif DLLEXP my_bool file_to_blob_init(UDF_INIT *initid, UDF_ARGS *args, char *message); DLLEXP void file_to_blob_deinit(UDF_INIT *initid); DLLEXP char* file_to_blob(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long* length, char *is_null, char *error); #ifdef __cplusplus } #endif /****************************************************************************** ** FUNCTION DEFINITIONS ******************************************************************************/ //find the numeric value of queried diamension // --- bool writeData(const Matrix * mm, const char* filename){ FILE *fp; fp=fopen(filename, "wb"); if(!fp) return false; fwrite(&mm->dim, sizeof(int), 1, fp); fwrite(&mm->noEle, sizeof(long int), 1, fp); fwrite(&mm->dimVal_size, sizeof(int), 1, fp); fwrite(mm->dimVal, sizeof(char), mm->dimVal_size+1, fp); fwrite(&mm->eleType_size, sizeof(int), 1, fp); fwrite(mm->eleType, sizeof(char), mm->eleType_size+1, fp); fwrite(mm->dimA_size, sizeof(int), mm->dim, fp); for(int i=0; idim; i++) fwrite(mm->dimA[i], sizeof(char), mm->dimA_size[i]+1, fp); if ( strcmp(mm->eleType,"int") == 0) fwrite(mm->intA, sizeof(int), mm->noEle, fp); else if (strcmp(mm->eleType,"float") == 0) fwrite(mm->doubleA, sizeof(double), mm->noEle, fp); else if (strcmp(mm->eleType,"string") == 0){ fwrite(mm->stringA_size, sizeof(int), mm->noEle, fp); for(long i = 0; inoEle;i++) fwrite(mm->stringA[i], sizeof(char), mm->stringA_size[i], fp); } fclose(fp); return(true); } bool readData(Matrix * mm, const char* filename){ FILE *f; f=fopen(filename, "rb"); if(!f) return false; fread(&mm->dim, sizeof(int), 1, f); fread(&mm->noEle, sizeof(long int), 1, f); fread(&mm->dimVal_size, sizeof(int), 1, f); mm->dimVal = (char*)calloc(mm->dimVal_size+1,sizeof(char)); fread(mm->dimVal, sizeof(char), mm->dimVal_size+1, f); fread(&mm->eleType_size, sizeof(int), 1, f); mm->eleType = (char*)calloc(mm->eleType_size+1,sizeof(char)); fread(mm->eleType, sizeof(char), mm->eleType_size+1, f); mm->dimA_size = (int*)calloc(mm->dim, sizeof(int)); fread(mm->dimA_size, sizeof(int), mm->dim, f); mm->dimA = (char**)calloc(mm->dim,sizeof(char*)); for (int i=0; idim; i++) mm->dimA[i] = (char*)calloc(mm->dimA_size[i]+1,sizeof(char)); for(int i=0; idim; i++) fread(mm->dimA[i], sizeof(char), mm->dimA_size[i]+1, f); if (strcmp(mm->eleType,"int") == 0) { mm->intA = (int*)calloc(mm->noEle,sizeof(int)); if(mm->intA == NULL) return false; else fread(mm->intA, sizeof(int), mm->noEle, f); } else if ( strcmp(mm->eleType,"float") == 0) { mm->doubleA = (double*)calloc(mm->noEle,sizeof(double)); if(mm->doubleA == NULL) return false; else fread(mm->doubleA, sizeof(double), mm->noEle, f); } else if (strcmp(mm->eleType,"string") == 0) { mm->stringA_size = (int*)calloc(mm->noEle,sizeof(int)); fread(mm->stringA_size, sizeof(int), mm->noEle, f); mm->stringA = (char**)calloc(mm->noEle,sizeof(char*)); for(long int i = 0; inoEle;i++){ mm->stringA[i] = (char*)calloc(mm->stringA_size[i]+1,sizeof(char)); fread(mm->stringA[i], sizeof(char), mm->stringA_size[i], f); } } fclose(f); return true; } bool fillStructure(Matrix* mm, char* obj){ memcpy(&mm->dim,obj, sizeof(int)); obj+=sizeof(int); memcpy(&mm->noEle,obj, sizeof(long int)); obj+=sizeof(long int); memcpy(&mm->dimVal_size,obj, sizeof(int)); obj+=sizeof(int); mm->dimVal = (char*)calloc(mm->dimVal_size+1,sizeof(char)); memcpy(mm->dimVal, obj, sizeof(char)*mm->dimVal_size+1); obj+=(sizeof(char)*mm->dimVal_size)+1; memcpy(&mm->eleType_size, obj,sizeof(int)); obj+=sizeof(int); mm->eleType = (char*)calloc(mm->eleType_size+1,sizeof(char)); memcpy(mm->eleType, obj, sizeof(char)*mm->eleType_size+1); obj+=(sizeof(char)*mm->eleType_size)+1; mm->dimA_size = (int*)calloc(mm->dim, sizeof(int)); memcpy(mm->dimA_size, obj, sizeof(int)*mm->dim); obj+=(sizeof(int)*mm->dim); mm->dimA = (char**)calloc(mm->dim,sizeof(char*)); for (int i=0; idim; i++) { mm->dimA[i] = (char*)calloc(mm->dimA_size[i]+1,sizeof(char)); memcpy(mm->dimA[i], obj, (mm->dimA_size[i]*sizeof(char))+1); obj+=(sizeof(char)*mm->dimA_size[i])+1; } ////// INTEGERS if ( strcmp(mm->eleType,"int") == 0) { long int i = 0; //memcpy(mm->intA, obj,sizeof(int)*mm->noEle); mm->intA = (int*)calloc(mm->noEle,sizeof(int)); int *tt = mm->intA; if (mm->noEle < 1000) { memcpy(tt, obj, sizeof(int)*mm->noEle); i = mm->noEle; } else{ for (i=1000; inoEle; i+=1000){ memcpy(tt, obj,sizeof(int)*1000); tt+=1000; obj+=sizeof(int)*1000; } if ((mm->noEle-i) > 0 ) memcpy(tt, obj, sizeof(int)*(mm->noEle-i)); } } ////// ////// DOUBLES else if ( strcmp(mm->eleType,"float") == 0){ long int i = 0; mm->doubleA = (double*)calloc(mm->noEle,sizeof(double)); double *tt = mm->doubleA; if (mm->noEle < 1000) { memcpy(tt, obj, sizeof(double)*mm->noEle); i = mm->noEle; } else{ for (i=1000; inoEle; i+=1000){ memcpy(tt, obj, sizeof(double)*1000); tt+=1000; obj+=sizeof(double)*1000; } if ((mm->noEle-i) > 0 ) memcpy(tt, obj, sizeof(double)*(mm->noEle-i)); } } ////// ////// STRING else if ( strcmp(mm->eleType,"string") == 0){ long int i = 0; mm->stringA_size = (int*)calloc(mm->noEle,sizeof(int)); memcpy(mm->stringA_size, obj, sizeof(int)*mm->noEle); obj+=sizeof(int)*mm->noEle; mm->stringA = (char**)calloc(mm->noEle,sizeof(char*)); for (i=0; inoEle; i++) { mm->stringA[i] = (char*)calloc(mm->stringA_size[i]+1,sizeof(char)); memcpy(mm->stringA[i], obj, (mm->stringA_size[i]*sizeof(char))+1); obj+=(sizeof(char)*mm->stringA_size[i])+1; } } ////// return true; } bool copyData(Matrix * mm, char*& obj){ memcpy(obj, &mm->dim, sizeof(int)); obj+=sizeof(int); memcpy(obj, &mm->noEle, sizeof(long int)); obj+=sizeof(long int); memcpy(obj, &mm->dimVal_size, sizeof(int)); obj+=sizeof(int); memcpy(obj, mm->dimVal,sizeof(char)*mm->dimVal_size+1); obj+=(sizeof(char)*mm->dimVal_size)+1; memcpy(obj, &mm->eleType_size,sizeof(int)); obj+=sizeof(int); memcpy(obj, mm->eleType,sizeof(char)*mm->eleType_size+1); obj+=(sizeof(char)*mm->eleType_size)+1; memcpy(obj, mm->dimA_size, sizeof(int)*mm->dim); obj+=(sizeof(int)*mm->dim); for (int i=0; idim; i++) { memcpy(obj, mm->dimA[i], (mm->dimA_size[i]*sizeof(char))+1); obj+=(sizeof(char)*mm->dimA_size[i])+1; } ////// INTEGERS if ( strcmp(mm->eleType,"int") == 0) { int *tt = mm->intA; long int i = 0; //memcpy(obj, mm->intA, sizeof(int)*mm->noEle); if (mm->noEle < 1000) { memcpy(obj, tt, sizeof(int)*mm->noEle); i = mm->noEle; } else{ for (i=1000; inoEle; i+=1000){ memcpy(obj, tt, sizeof(int)*1000); tt+=1000; obj+=sizeof(int)*1000; } if ((mm->noEle-i) > 0 ) memcpy(obj, tt, sizeof(int)*(mm->noEle-i)); } } ////// ////// DOUBLES else if ( strcmp(mm->eleType,"float") == 0){ double *tt = mm->doubleA; long int i = 0; if (mm->noEle < 1000) { memcpy(obj, tt, sizeof(double)*mm->noEle); i = mm->noEle; } else{ for (i=1000; inoEle; i+=1000){ memcpy(obj, tt, sizeof(double)*1000); tt+=1000; obj+=sizeof(double)*1000; } if ((mm->noEle-i) > 0 ) memcpy(obj, tt, sizeof(double)*(mm->noEle-i)); } } ////// ////// STRING else if ( strcmp(mm->eleType,"string") == 0){ long int i = 0; memcpy(obj, mm->stringA_size, sizeof(int)*mm->noEle); obj+=sizeof(int)*mm->noEle; for (i=0; inoEle; i++) { memcpy(obj, mm->stringA[i], (mm->stringA_size[i]*sizeof(char))+1); obj+=(sizeof(char)*mm->stringA_size[i])+1; } } ////// return true; } bool freeData(Matrix * mt){ free(mt->dimVal); for(int i=0; idim; i++) free(mt->dimA[i]); free(mt->dimA); free(mt->dimA_size); if ( strcmp(mt->eleType,"int") == 0) free(mt->intA); else if ( strcmp(mt->eleType,"float") == 0) free(mt->doubleA); else if ( strcmp(mt->eleType,"string") == 0) { free(mt->stringA_size); for(long int i=0; inoEle; i++) free(mt->stringA[i]); free(mt->stringA); } free(mt->eleType); return true; } bool inputData (Matrix * mpt, const char* filename, long int* totalSize){ char x='x'; int count=0; int dim=0; int intval=0; double dval=0.0; bool end=false; string eleTypeS(""); string dimValS(""); ifstream inFile(filename); if (!inFile) { return false; } while ((inFile >> x)&& (x!=';')) { eleTypeS+=x; count +=1; if (x==',') { dimValS+=eleTypeS; eleTypeS=""; dim += 1; } } *totalSize +=sizeof(int); mpt->dim=dim; mpt->eleType_size = eleTypeS.length(); *totalSize += (eleTypeS.length()+1); if( ( mpt->eleType = (char*)calloc(eleTypeS.length()+1 ,sizeof(char)) ) == NULL) { //free(mpt->eleType); return false; } strcpy(mpt->eleType, eleTypeS.c_str()); mpt->dimVal_size = dimValS.length(); *totalSize += (dimValS.length()+1); if( ( mpt->dimVal = (char*)calloc(dimValS.length()+1,sizeof(char)) ) == NULL) { //free(mpt->dimVal); return false; } strcpy(mpt->dimVal, dimValS.c_str()); string a ; string* dimA = new string[dim]; count=0; int dimCount=0; long int numEle=1; string dimS; //=(""); int dimEleCount=0; //acessing the diamension data while ((inFile >> x)&& count < dim) { if (x==';') { if (dimEleCount>0) { numEle *= (dimEleCount+1); dimEleCount=0; } else { numEle *= atoi(dimS.c_str()); } dimA[dimCount++] = dimS.c_str(); dimS.clear(); ++count; } else { if (x==','){ dimEleCount+=1; } dimS+=x; } } //cout<<"number of elements "<noEle=numEle; *totalSize += (dimCount*sizeof(int)); // I have removed 1 from here. mpt->dimA_size = (int*)calloc(dimCount,sizeof(int)); for(int i=0; idimA_size[i] = dimA[i].length(); *totalSize += (dim*sizeof(char*)); mpt->dimA = (char**)calloc(dim,sizeof(char*)); if (mpt->dimA == NULL) return false; for(int i=0; idimA[i] = (char*)calloc(dimA[i].length()+1,sizeof(char)); if(mpt->dimA[i] == NULL) return false; } for(int i=0; idimA[i],dimA[i].c_str()); delete [] dimA; if (eleTypeS=="int"){ *totalSize += (numEle*sizeof(int)); mpt->intA=(int *)calloc(numEle,sizeof(int)); if(mpt->intA == NULL) return false; } else if (eleTypeS=="float"){ *totalSize += (numEle*sizeof(double)); mpt->doubleA=(double *)calloc(numEle,sizeof(double)); if(mpt->doubleA == NULL) return false; } else if (eleTypeS=="string"){ *totalSize += (numEle*sizeof(int)); mpt->stringA_size = (int*) calloc(numEle,sizeof(int)); *totalSize += (numEle*sizeof(char*)); mpt->stringA=(char **)calloc(numEle,sizeof(char*)); } count=0; long int arrCount=0; string valS; //datatype conversion while ((inFile >> x)&& (x!=';')) { if ((x!='}')&&(x!='{')){ if (x==',') { //cout<<"vals "<intA[arrCount++]=intval; } else if (eleTypeS=="float"){ //cout<<"float "<doubleA[arrCount++]=dval; //mpt->doubleA = &dval; //mpt->doubleA++; } else if (eleTypeS=="string"){ //cout<<"string "<stringA[++arrCount]=valS; //mpt->stringA = &valS; //mpt->stringA++; mpt->stringA_size[arrCount] = valS.length(); *totalSize += ((mpt->stringA_size[arrCount]+1)*sizeof(char)); mpt->stringA[arrCount] = (char*)calloc(mpt->stringA_size[arrCount]+1,sizeof(char)); strcpy(mpt->stringA[arrCount], valS.c_str()); arrCount++; } valS.clear(); } else { valS+=x; } } else { if ((x=='}') && (!end)) { //cout<<"vals>> "<intA[arrCount++]=intval; //mpt->intA = &intval; //mpt->intA++; //cout<<"int "<doubleA[arrCount++]=dval; //mpt->doubleA = &dval; //mpt->doubleA++; } else { //cout<<"string "<stringA[++arrCount]=valS; // NOW mpt->stringA = &valS; //mpt->stringA++; mpt->stringA_size[arrCount] = valS.length(); *totalSize += (mpt->stringA_size[arrCount]+1); mpt->stringA[arrCount] = (char*)calloc(mpt->stringA_size[arrCount]+1,sizeof(char)); strcpy(mpt->stringA[arrCount], valS.c_str()); arrCount++; } } else if (x=='{') { end=false; } valS.clear(); } } inFile.close(); return true; } // ***** file_to_blob ***** ///// my_bool file_to_blob_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { if (args->arg_count != 2) { strcpy(message,"file_to_blob() requires input and output data file."); return 1; } return 0; } void file_to_blob_deinit(UDF_INIT *initid) { free(initid->ptr); } char* file_to_blob(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long* length, char *is_null, char *error) { //char* comData = (char*)initid->ptr; char* comData; Matrix* mpt = (Matrix*)malloc(sizeof(Matrix)); string status = "Done"; if (mpt == NULL) { status = "mpt is NULL"; } const char* inputFile = args->args[0]; const char* outputFile = args->args[1]; long int totalSize = 0; if (inputData(mpt, inputFile, &totalSize)) { status = "Yes"; } else{ status = "No"; } comData = (char*)malloc(totalSize*sizeof(char)); initid->ptr = comData; char* dd = comData; copyData(mpt, comData); comData = dd; freeData(mpt); free(mpt); result = comData; *length = totalSize; return result; }